diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f571110a --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +AUTHORS +ChangeLog +.mypy_cache +*.pyc +__pycache__ +*~ +.#* +*.egg-info +*.spec +/dist +/bdist +/build +/results +/Notes.md +/.eggs +/.stestr +/.tox +/.coverage.* +/.coverage +*~ +poetry.lock +*.toml +*.code-workspace \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..8c646c0a --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# iserver + +iserver is command line tool using REST API with various Cisco products. + +Important note: documentation is partial and it will be uploaded again once sensitive information is removed + +## Features + +Compute +- [Intersight](./doc/intersight/README.md) +- [IMC](./doc/imc/README.md) +- [Redfish](./doc/redfish/README.md) +- [UCSM](./doc/ucsm/README.md) + +Networking +- [ACI](./doc/aci/README.md) +- [Nexus](./doc/nexus/README.md) + +Virtualization +- [OpenStack](./doc/osp/README.md) +- [vCenter](./doc/vcenter/README.md) + +Containers +- [Helm](./doc/helm/README.md) +- [Kubernetes](./doc/k8s/README.md) +- [OpenShift](./doc/ocp/README.md) + +Orchestration +- [Network Services Orchestrator](./doc/nso/README.md) + +Security +- [PSIRT](./doc/psirt/README.md) + +Other +- [Webex Bot](./doc/bot/README.md) + +## Installation + +- iserver binary is compiled for Windows, Linux and MAC +- download the latest release from the [Releases](https://wwwin-github.cisco.com/emear-telcocloud/iserver/releases/latest) page. +- move binary somewhere that is on your path (e.g. /usr/local/bin) + +If binary is not available or you prefer using source code, clone the repository and run iserver using Python3 with [required](requirements) pip3 packages. + +## Requirements + +Features using Intersight API require [isctl](https://github.com/cgascoig/isctl) and OS installation requires isctl version >= 0.1.18. + +No requiremets for non-Intersight related features. diff --git a/iserver.py b/iserver.py new file mode 100644 index 00000000..579d270d --- /dev/null +++ b/iserver.py @@ -0,0 +1,43 @@ +import sys + +from lib import output_helper +from lib import settings_helper +from lib import my_servers_helper +from lib import my_server_helper +from menu import main as menu_main + + +def initialize(): + my_output = output_helper.OutputHelper() + + settings_handler = settings_helper.Settings() + if not settings_handler.initialize_settings(): + my_output.error('Local settings initialization failure...') + return False + + my_servers = my_servers_helper.MyServers() + if not my_servers.initialize(): + my_output.error('My servers settings initialization failure...') + return False + + my_server = my_server_helper.MyServer() + if not my_server.initialize(): + my_output.error('My server settings initialization failure...') + return False + + return True + + +if __name__ == "__main__": + if not initialize(): + sys.exit(1) + + parameters = [] + for item in sys.argv: + if len(item.split(' ')) == 1: + parameters.append(item) + else: + parameters.append('"%s"' % (item)) + + USER_INPUT = ' '.join(parameters) + menu_main.run(USER_INPUT) diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/__init__.py b/lib/aci/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/__pycache__/__init__.cpython-310.pyc b/lib/aci/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d978d4bb Binary files /dev/null and b/lib/aci/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/aepg.cpython-310.pyc b/lib/aci/__pycache__/aepg.cpython-310.pyc new file mode 100644 index 00000000..2a8c6269 Binary files /dev/null and b/lib/aci/__pycache__/aepg.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/ap.cpython-310.pyc b/lib/aci/__pycache__/ap.cpython-310.pyc new file mode 100644 index 00000000..87b77e86 Binary files /dev/null and b/lib/aci/__pycache__/ap.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/api.cpython-310.pyc b/lib/aci/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2a002636 Binary files /dev/null and b/lib/aci/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/apic.cpython-310.pyc b/lib/aci/__pycache__/apic.cpython-310.pyc new file mode 100644 index 00000000..4242efcb Binary files /dev/null and b/lib/aci/__pycache__/apic.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/bd.cpython-310.pyc b/lib/aci/__pycache__/bd.cpython-310.pyc new file mode 100644 index 00000000..08fe79da Binary files /dev/null and b/lib/aci/__pycache__/bd.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/cache.cpython-310.pyc b/lib/aci/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..692f062d Binary files /dev/null and b/lib/aci/__pycache__/cache.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/cdp_adj_ep.cpython-310.pyc b/lib/aci/__pycache__/cdp_adj_ep.cpython-310.pyc new file mode 100644 index 00000000..79bb6424 Binary files /dev/null and b/lib/aci/__pycache__/cdp_adj_ep.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/common.cpython-310.pyc b/lib/aci/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..43d3aba5 Binary files /dev/null and b/lib/aci/__pycache__/common.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/contract.cpython-310.pyc b/lib/aci/__pycache__/contract.cpython-310.pyc new file mode 100644 index 00000000..e1f62b84 Binary files /dev/null and b/lib/aci/__pycache__/contract.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/endpoint.cpython-310.pyc b/lib/aci/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..ba3ddc5e Binary files /dev/null and b/lib/aci/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/if_mgmt.cpython-310.pyc b/lib/aci/__pycache__/if_mgmt.cpython-310.pyc new file mode 100644 index 00000000..b5aa4903 Binary files /dev/null and b/lib/aci/__pycache__/if_mgmt.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/interface_fault_counts.cpython-310.pyc b/lib/aci/__pycache__/interface_fault_counts.cpython-310.pyc new file mode 100644 index 00000000..84b7d59b Binary files /dev/null and b/lib/aci/__pycache__/interface_fault_counts.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/interface_management.cpython-310.pyc b/lib/aci/__pycache__/interface_management.cpython-310.pyc new file mode 100644 index 00000000..f664bf6d Binary files /dev/null and b/lib/aci/__pycache__/interface_management.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/interface_management_state.cpython-310.pyc b/lib/aci/__pycache__/interface_management_state.cpython-310.pyc new file mode 100644 index 00000000..6b89e907 Binary files /dev/null and b/lib/aci/__pycache__/interface_management_state.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/interface_management_stats.cpython-310.pyc b/lib/aci/__pycache__/interface_management_stats.cpython-310.pyc new file mode 100644 index 00000000..d5d6711f Binary files /dev/null and b/lib/aci/__pycache__/interface_management_stats.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/l1physif.cpython-310.pyc b/lib/aci/__pycache__/l1physif.cpython-310.pyc new file mode 100644 index 00000000..276e1d1c Binary files /dev/null and b/lib/aci/__pycache__/l1physif.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/l2out.cpython-310.pyc b/lib/aci/__pycache__/l2out.cpython-310.pyc new file mode 100644 index 00000000..1313519a Binary files /dev/null and b/lib/aci/__pycache__/l2out.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/l3out.cpython-310.pyc b/lib/aci/__pycache__/l3out.cpython-310.pyc new file mode 100644 index 00000000..e7775a8c Binary files /dev/null and b/lib/aci/__pycache__/l3out.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/lldp_adj_ep.cpython-310.pyc b/lib/aci/__pycache__/lldp_adj_ep.cpython-310.pyc new file mode 100644 index 00000000..b81482c8 Binary files /dev/null and b/lib/aci/__pycache__/lldp_adj_ep.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/node.cpython-310.pyc b/lib/aci/__pycache__/node.cpython-310.pyc new file mode 100644 index 00000000..50c04af2 Binary files /dev/null and b/lib/aci/__pycache__/node.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/output.cpython-310.pyc b/lib/aci/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..dbd3d3a8 Binary files /dev/null and b/lib/aci/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port.cpython-310.pyc b/lib/aci/__pycache__/port.cpython-310.pyc new file mode 100644 index 00000000..036e70d6 Binary files /dev/null and b/lib/aci/__pycache__/port.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_epg_stats.cpython-310.pyc b/lib/aci/__pycache__/port_epg_stats.cpython-310.pyc new file mode 100644 index 00000000..ba46cdb1 Binary files /dev/null and b/lib/aci/__pycache__/port_epg_stats.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_fc_stat.cpython-310.pyc b/lib/aci/__pycache__/port_fc_stat.cpython-310.pyc new file mode 100644 index 00000000..9b386937 Binary files /dev/null and b/lib/aci/__pycache__/port_fc_stat.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_fc_stats.cpython-310.pyc b/lib/aci/__pycache__/port_fc_stats.cpython-310.pyc new file mode 100644 index 00000000..ac6f9678 Binary files /dev/null and b/lib/aci/__pycache__/port_fc_stats.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_qos_stat.cpython-310.pyc b/lib/aci/__pycache__/port_qos_stat.cpython-310.pyc new file mode 100644 index 00000000..c21f56c7 Binary files /dev/null and b/lib/aci/__pycache__/port_qos_stat.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_qos_stats.cpython-310.pyc b/lib/aci/__pycache__/port_qos_stats.cpython-310.pyc new file mode 100644 index 00000000..cbb28b97 Binary files /dev/null and b/lib/aci/__pycache__/port_qos_stats.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_stat.cpython-310.pyc b/lib/aci/__pycache__/port_stat.cpython-310.pyc new file mode 100644 index 00000000..7121067b Binary files /dev/null and b/lib/aci/__pycache__/port_stat.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_stats.cpython-310.pyc b/lib/aci/__pycache__/port_stats.cpython-310.pyc new file mode 100644 index 00000000..c6585bed Binary files /dev/null and b/lib/aci/__pycache__/port_stats.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/port_vlan_stats.cpython-310.pyc b/lib/aci/__pycache__/port_vlan_stats.cpython-310.pyc new file mode 100644 index 00000000..1661a73f Binary files /dev/null and b/lib/aci/__pycache__/port_vlan_stats.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/settings.cpython-310.pyc b/lib/aci/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..0319ce16 Binary files /dev/null and b/lib/aci/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/tenant.cpython-310.pyc b/lib/aci/__pycache__/tenant.cpython-310.pyc new file mode 100644 index 00000000..4504862c Binary files /dev/null and b/lib/aci/__pycache__/tenant.cpython-310.pyc differ diff --git a/lib/aci/__pycache__/vrf.cpython-310.pyc b/lib/aci/__pycache__/vrf.cpython-310.pyc new file mode 100644 index 00000000..291bc993 Binary files /dev/null and b/lib/aci/__pycache__/vrf.cpython-310.pyc differ diff --git a/lib/aci/ap/__init__.py b/lib/aci/ap/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/ap/__pycache__/__init__.cpython-310.pyc b/lib/aci/ap/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d34a6cee Binary files /dev/null and b/lib/aci/ap/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/ap/__pycache__/api.cpython-310.pyc b/lib/aci/ap/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..460a7c61 Binary files /dev/null and b/lib/aci/ap/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/ap/__pycache__/info.cpython-310.pyc b/lib/aci/ap/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..7c93730c Binary files /dev/null and b/lib/aci/ap/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/ap/__pycache__/main.cpython-310.pyc b/lib/aci/ap/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..fe193417 Binary files /dev/null and b/lib/aci/ap/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/ap/__pycache__/output.cpython-310.pyc b/lib/aci/ap/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e4211c1e Binary files /dev/null and b/lib/aci/ap/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/ap/api.py b/lib/aci/ap/api.py new file mode 100644 index 00000000..119910d8 --- /dev/null +++ b/lib/aci/ap/api.py @@ -0,0 +1,55 @@ +class ApplicationProfileApi(): + def __init__(self): + self.application_profile_mo = None + + def get_application_profile_mo(self): + if self.application_profile_mo is not None: + return self.application_profile_mo + + cache = self.get_object_cache( + 'fvAp' + ) + if cache is not None: + self.application_profile_mo = cache + self.log.apic_mo( + 'fvAp', + self.application_profile_mo + ) + return self.application_profile_mo + + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + 'fvAp', + query=query + ) + if managed_objects is None: + return None + + self.application_profile_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvAp']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'fvAp', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'fvAp', + managed_object, + 'faultCounts' + ) + self.application_profile_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAp', + self.application_profile_mo + ) + + self.set_object_cache( + 'fvAp', + self.application_profile_mo + ) + + return self.application_profile_mo diff --git a/lib/aci/ap/audit/__init__.py b/lib/aci/ap/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/ap/audit/api.py b/lib/aci/ap/audit/api.py new file mode 100644 index 00000000..369ace8c --- /dev/null +++ b/lib/aci/ap/audit/api.py @@ -0,0 +1,48 @@ +class ApplicationProfileAuditApi(): + def __init__(self): + self.application_profile_audit_mo = None + + def get_application_profile_audit_mo(self): + cache = self.get_object_cache( + 'fvAp.audit' + ) + if cache is not None: + self.application_profile_audit_mo = cache + self.log.apic_mo( + 'fvAp.audit', + self.application_profile_audit_mo + ) + return self.application_profile_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'fvAp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_application_profile_audit_mo', + 'API failed' + ) + return None + + self.application_profile_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.application_profile_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAp.audit', + self.application_profile_audit_mo + ) + + self.set_object_cache( + 'fvAp.audit', + self.application_profile_audit_mo + ) + + return self.application_profile_audit_mo diff --git a/lib/aci/ap/audit/info.py b/lib/aci/ap/audit/info.py new file mode 100644 index 00000000..0bca1c2d --- /dev/null +++ b/lib/aci/ap/audit/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ApplicationProfileAuditInfo(): + def __init__(self): + self.application_profile_audit = None + + def get_application_profile_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['apName'] = None + info['epgName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-vk8s_1 + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['affected']: + info['apName'] = info['affected'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['affected']: + info['epgName'] = info['affected'].split('/epg-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['apName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['apName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_application_profile_audit(self): + if self.application_profile_audit is not None: + return self.application_profile_audit + + managed_objects = self.get_application_profile_audit_mo() + if managed_objects is None: + return None + + self.application_profile_audit = [] + for managed_object in managed_objects: + audit_info = self.get_application_profile_audit_info( + managed_object + ) + self.application_profile_audit.append( + audit_info + ) + + self.log.apic_mo( + 'fvAp.auditRecord.info', + self.application_profile_audit + ) + + return self.application_profile_audit + + def get_application_profile_id_audit(self, tenant_name, ap_name, audit_filter=None): + audits = [] + + all_audits = self.get_application_profile_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['apName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['apName'] == ap_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/ap/audit/main.py b/lib/aci/ap/audit/main.py new file mode 100644 index 00000000..65cf2fd6 --- /dev/null +++ b/lib/aci/ap/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.ap.audit.api import ApplicationProfileAuditApi +from lib.aci.ap.audit.info import ApplicationProfileAuditInfo + + +class ApplicationProfileAudit(ApplicationProfileAuditApi, ApplicationProfileAuditInfo): + def __init__(self): + ApplicationProfileAuditApi.__init__(self) + ApplicationProfileAuditInfo.__init__(self) diff --git a/lib/aci/ap/event/__init__.py b/lib/aci/ap/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/ap/event/api.py b/lib/aci/ap/event/api.py new file mode 100644 index 00000000..e17af33a --- /dev/null +++ b/lib/aci/ap/event/api.py @@ -0,0 +1,51 @@ +class ApplicationProfileEventApi(): + def __init__(self): + self.application_profile_event_mo = None + + def get_application_profile_event_mo(self): + if self.application_profile_event_mo is not None: + return self.application_profile_event_mo + + cache = self.get_object_cache( + 'fvAp.eventLog' + ) + if cache is not None: + self.application_profile_event_mo = cache + self.log.apic_mo( + 'fvAp.eventLog', + self.application_profile_event_mo + ) + return self.application_profile_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'fvAp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_application_profile_event_mo', + 'API failed' + ) + return None + + self.application_profile_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.application_profile_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAp.eventLog', + self.application_profile_event_mo + ) + + self.set_object_cache( + 'fvAp.eventLog', + self.application_profile_event_mo + ) + + return self.application_profile_event_mo diff --git a/lib/aci/ap/event/info.py b/lib/aci/ap/event/info.py new file mode 100644 index 00000000..7e26afa9 --- /dev/null +++ b/lib/aci/ap/event/info.py @@ -0,0 +1,130 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ApplicationProfileEventInfo(): + def __init__(self): + self.application_profile_event = None + + def get_application_profile_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['apName'] = None + info['epgName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-vk8s_1 + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['affected']: + info['apName'] = info['affected'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['affected']: + info['epgName'] = info['affected'].split('/epg-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['dn']: + info['apName'] = info['dn'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['dn']: + info['epgName'] = info['dn'].split('/epg-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['apName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['apName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_application_profile_event(self, deduplicate=True): + if self.application_profile_event is not None: + return self.application_profile_event + + managed_objects = self.get_application_profile_event_mo() + if managed_objects is None: + return None + + self.application_profile_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_application_profile_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.application_profile_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'fvAp.eventLog.info', + self.application_profile_event + ) + + return self.application_profile_event + + def get_application_profile_id_event(self, tenant_name, ap_name, event_filter=None): + events = [] + + all_events = self.get_application_profile_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['apName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['apName'] == ap_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/ap/event/main.py b/lib/aci/ap/event/main.py new file mode 100644 index 00000000..8f995bf7 --- /dev/null +++ b/lib/aci/ap/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.ap.event.api import ApplicationProfileEventApi +from lib.aci.ap.event.info import ApplicationProfileEventInfo + + +class ApplicationProfileEvent(ApplicationProfileEventApi, ApplicationProfileEventInfo): + def __init__(self): + ApplicationProfileEventApi.__init__(self) + ApplicationProfileEventInfo.__init__(self) diff --git a/lib/aci/ap/fault/__init__.py b/lib/aci/ap/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/ap/fault/api.py b/lib/aci/ap/fault/api.py new file mode 100644 index 00000000..90a51192 --- /dev/null +++ b/lib/aci/ap/fault/api.py @@ -0,0 +1,118 @@ +class ApplicationProfileFaultApi(): + def __init__(self): + self.application_profile_fault_mo = None + self.application_profile_fault_record_mo = None + + def get_application_profile_fault_mo(self): + cache = self.get_object_cache( + 'fvAp.fault' + ) + if cache is not None: + self.application_profile_fault_mo = cache + self.log.apic_mo( + 'fvAp.fault', + self.application_profile_fault_mo + ) + return self.application_profile_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'fvAp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_application_profile_fault_mo', + 'API failed' + ) + return None + + self.application_profile_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.application_profile_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.application_profile_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAp.fault', + self.application_profile_fault_mo + ) + + self.set_object_cache( + 'fvAp.fault', + self.application_profile_fault_mo + ) + + return self.application_profile_fault_mo + + def get_application_profile_fault_record_mo(self): + cache = self.get_object_cache( + 'fvAp.faultRecord' + ) + if cache is not None: + self.application_profile_fault_record_mo = cache + self.log.apic_mo( + 'fvAp.faultRecord', + self.application_profile_fault_record_mo + ) + return self.application_profile_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'fvAp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_application_profile_fault_record_mo', + 'API failed' + ) + return None + + self.application_profile_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.application_profile_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.application_profile_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAp.faultRecord', + self.application_profile_fault_record_mo + ) + + self.set_object_cache( + 'fvAp.faultRecord', + self.application_profile_fault_record_mo + ) + + return self.application_profile_fault_record_mo diff --git a/lib/aci/ap/fault/info.py b/lib/aci/ap/fault/info.py new file mode 100644 index 00000000..5980d119 --- /dev/null +++ b/lib/aci/ap/fault/info.py @@ -0,0 +1,161 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ApplicationProfileFaultInfo(): + def __init__(self): + self.application_profile_fault = None + self.application_profile_fault_record = None + + def get_application_profile_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['apName'] = None + info['epgName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-vk8s_1 + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['affected']: + info['apName'] = info['affected'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['affected']: + info['epgName'] = info['affected'].split('/epg-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['dn']: + info['apName'] = info['dn'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['dn']: + info['epgName'] = info['dn'].split('/epg-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['apName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['apName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_application_profile_fault(self): + if self.application_profile_fault is not None: + return self.application_profile_fault + + managed_objects = self.get_application_profile_fault_mo() + if managed_objects is None: + return None + + self.application_profile_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_application_profile_fault_info( + managed_object + ) + self.application_profile_fault.append( + fault_info + ) + + self.log.apic_mo( + 'fvAp.fault.info', + self.application_profile_fault + ) + + return self.application_profile_fault + + def get_application_profile_fault_record(self, deduplicate=True): + if self.application_profile_fault_record is not None: + return self.application_profile_fault_record + + managed_objects = self.get_application_profile_fault_record_mo() + if managed_objects is None: + return None + + self.application_profile_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_application_profile_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.application_profile_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'fvAp.faultRecord.info', + self.application_profile_fault_record + ) + + return self.application_profile_fault_record + + def get_application_profile_id_fault(self, tenant_name, ap_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_application_profile_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_application_profile_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['apName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['apName'] == ap_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/ap/fault/main.py b/lib/aci/ap/fault/main.py new file mode 100644 index 00000000..a6935b6f --- /dev/null +++ b/lib/aci/ap/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.ap.fault.api import ApplicationProfileFaultApi +from lib.aci.ap.fault.info import ApplicationProfileFaultInfo + + +class ApplicationProfileFault(ApplicationProfileFaultApi, ApplicationProfileFaultInfo): + def __init__(self): + ApplicationProfileFaultApi.__init__(self) + ApplicationProfileFaultInfo.__init__(self) diff --git a/lib/aci/ap/info.py b/lib/aci/ap/info.py new file mode 100644 index 00000000..4a6de404 --- /dev/null +++ b/lib/aci/ap/info.py @@ -0,0 +1,221 @@ +from lib import filter_helper + + +class ApplicationProfileInfo(): + def __init__(self): + self.application_profile = None + + def get_application_profile_count(self, tenant_name=None): + application_profile_filter = None + if tenant_name is not None: + application_profile_filter = ['tenant:%s' % (tenant_name)] + + application_profiles = self.get_application_profiles( + application_profile_filter=application_profile_filter, + epg_info=False + ) + return len(application_profiles) + + def get_application_profile_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name', + 'prio', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # [0]: uni/tn-{name}/ap-{name} + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_application_profiles_info(self): + if self.application_profile is not None: + return self.application_profile + + managed_objects = self.get_application_profile_mo() + if managed_objects is None: + return None + + self.application_profile = [] + for managed_object in managed_objects: + self.application_profile.append( + self.get_application_profile_info( + managed_object + ) + ) + + self.log.apic_mo( + 'fvAp.info', + self.application_profile + ) + + return self.application_profile + + def match_application_profile(self, application_profile_info, application_profile_filter): + if application_profile_filter is None or len(application_profile_filter) == 0: + return True + + for ap_rule in application_profile_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, application_profile_info['name']): + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, application_profile_info['dn']): + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, application_profile_info['tenant']): + return False + + if key == 'epg': + key_found = True + if 'epgs' in application_profile_info: + found = False + for epg_info in application_profile_info['epgs']: + if filter_helper.match_tenant_name(value, epg_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'fault': + if value == 'any': + if not application_profile_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_application_profile', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_application_profile', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_application_profiles( + self, + application_profile_filter=None, + epg_info=False, + node_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_profiles = self.get_application_profiles_info() + if all_profiles is None: + return None + + application_profiles = [] + + for application_profile_info in all_profiles: + if not self.match_application_profile(application_profile_info, application_profile_filter): + continue + + if epg_info: + epg_filter = [] + epg_filter.append( + 'tenant:%s' % (application_profile_info['tenant']) + ) + epg_filter.append( + 'profile:%s' % (application_profile_info['name']) + ) + application_profile_info['epgs'] = self.get_epgs( + epg_filter=epg_filter + ) + + if not self.match_application_profile(application_profile_info, application_profile_filter): + continue + + if node_info: + ap_node_info = self.get_application_profile_node( + application_profile_info['tenant'], + application_profile_info['name'] + ) + application_profile_info['node'] = None + application_profile_info['interface'] = None + if ap_node_info is not None: + application_profile_info['node'] = ap_node_info['node'] + application_profile_info['interface'] = ap_node_info['interface'] + + if fault_info: + application_profile_info['faultInst'] = self.get_application_profile_id_fault( + application_profile_info['tenant'], + application_profile_info['name'], + 'faultInst' + ) + + if hfault_info: + application_profile_info['faultRecord'] = self.get_application_profile_id_fault( + application_profile_info['tenant'], + application_profile_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + application_profile_info['eventLog'] = self.get_application_profile_id_event( + application_profile_info['tenant'], + application_profile_info['name'], + event_filter=event_filter + ) + + if audit_info: + application_profile_info['auditLog'] = self.get_application_profile_id_audit( + application_profile_info['tenant'], + application_profile_info['name'], + audit_filter=audit_filter + ) + + application_profiles.append(application_profile_info) + + application_profiles = sorted( + application_profiles, + key=lambda i: i['nameTenant'].lower() + ) + + return application_profiles diff --git a/lib/aci/ap/main.py b/lib/aci/ap/main.py new file mode 100644 index 00000000..76de4803 --- /dev/null +++ b/lib/aci/ap/main.py @@ -0,0 +1,23 @@ +from lib.aci.ap.api import ApplicationProfileApi +from lib.aci.ap.info import ApplicationProfileInfo +from lib.aci.ap.audit.main import ApplicationProfileAudit +from lib.aci.ap.event.main import ApplicationProfileEvent +from lib.aci.ap.fault.main import ApplicationProfileFault +from lib.aci.ap.node.main import ApplicationProfileNode + + +class ApplicationProfile( + ApplicationProfileApi, + ApplicationProfileInfo, + ApplicationProfileAudit, + ApplicationProfileEvent, + ApplicationProfileFault, + ApplicationProfileNode + ): + def __init__(self): + ApplicationProfileApi.__init__(self) + ApplicationProfileInfo.__init__(self) + ApplicationProfileAudit.__init__(self) + ApplicationProfileEvent.__init__(self) + ApplicationProfileFault.__init__(self) + ApplicationProfileNode.__init__(self) diff --git a/lib/aci/ap/node/__init__.py b/lib/aci/ap/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/ap/node/api.py b/lib/aci/ap/node/api.py new file mode 100644 index 00000000..8e3390d8 --- /dev/null +++ b/lib/aci/ap/node/api.py @@ -0,0 +1,61 @@ +class ApplicationProfileNodeApi(): + def __init__(self): + self.application_profile_node_mo = {} + + def get_application_profile_node_mo(self, tenant_name, ap_name): + key = '%s.%s' % (tenant_name, ap_name) + if key in self.application_profile_node_mo: + return self.application_profile_node_mo[key] + + cache = self.get_object_cache( + 'fvAp.%s' % (key) + ) + if cache is not None: + self.application_profile_node_mo[key] = cache + self.log.apic_mo( + 'fvAp.%s' % (key), + self.application_profile_node_mo[key] + ) + return self.application_profile_node_mo[key] + + distinguished_name = 'uni/tn-%s/ap-%s' % (tenant_name, ap_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=ApToNwIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_application_profile_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_application_profile_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvAp']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'fvAp', + managed_object + ) + self.application_profile_node_mo[key] = attributes + + self.log.apic_mo( + 'fvAp.%s' % (key), + self.application_profile_node_mo[key] + ) + + self.set_object_cache( + 'fvAp.%s' % (key), + self.application_profile_node_mo[key] + ) + + return self.application_profile_node_mo[key] diff --git a/lib/aci/ap/node/info.py b/lib/aci/ap/node/info.py new file mode 100644 index 00000000..717c4cfb --- /dev/null +++ b/lib/aci/ap/node/info.py @@ -0,0 +1,82 @@ +class ApplicationProfileNodeInfo(): + def __init__(self): + self.application_profile_node = {} + + def get_application_profile_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_application_profile_node(self, tenant_name, ap_name): + key = '%s.%s' % (tenant_name, ap_name) + if key in self.application_profile_node: + return self.application_profile_node[key] + + # one object or None value is expected + nodes_mo = self.get_application_profile_node_mo(tenant_name, ap_name) + if nodes_mo is None: + return None + + self.application_profile_node[key] = self.get_application_profile_node_info( + nodes_mo + ) + + self.log.apic_mo( + 'fvAp.%s.info' % (key), + self.application_profile_node[key] + ) + + return self.application_profile_node[key] diff --git a/lib/aci/ap/node/main.py b/lib/aci/ap/node/main.py new file mode 100644 index 00000000..aba09707 --- /dev/null +++ b/lib/aci/ap/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.ap.node.api import ApplicationProfileNodeApi +from lib.aci.ap.node.info import ApplicationProfileNodeInfo + + +class ApplicationProfileNode(ApplicationProfileNodeApi, ApplicationProfileNodeInfo): + def __init__(self): + ApplicationProfileNodeApi.__init__(self) + ApplicationProfileNodeInfo.__init__(self) diff --git a/lib/aci/ap/output.py b/lib/aci/ap/output.py new file mode 100644 index 00000000..affbbf8a --- /dev/null +++ b/lib/aci/ap/output.py @@ -0,0 +1,334 @@ +class ApplicationProfileOutput(): + def __init__(self): + pass + + def print_application_profiles(self, info, title=False): + if title: + self.my_output.default( + 'Application Profile [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'health', + 'faults', + 'nameTenant', + 'epgs.nameTenant', + 'prio' + ] + + headers = [ + 'Health', + 'Faults', + 'Application Profile', + 'Application EPGs', + 'Priority' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['epgs'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_application_profiles_node(self, info, title=False): + if title: + self.my_output.default( + 'Application Profile - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Application Profile', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_application_profiles_interface(self, info, title=False): + if title: + self.my_output.default( + 'Application Profile - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Application Profile', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_application_profiles_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Application Profile - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Application Profile - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Application Profile', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_application_profiles_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Application Profile - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Application Profile', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_application_profiles_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Application Profile - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Application Profile - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Application Profile', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_application_profiles_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Application Profile - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Application Profile - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Application Profile', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/api.py b/lib/aci/api.py new file mode 100644 index 00000000..f56c604a --- /dev/null +++ b/lib/aci/api.py @@ -0,0 +1,1174 @@ +import json +import time +import traceback +import requests + +from progress.bar import Bar + + +class Api(): + def __init__(self, apic_ip, apic_port, username, password): + self.apic_ip = apic_ip + self.apic_port = apic_port + self.apic_username = username + self.apic_password = password + + self.session_connected = False + self.token = None + self.request_info = {} + + self.api_fault_limit = 1000 + self.api_event_limit = 1000 + self.api_audit_limit = 1000 + + def get_apic_ip(self): + return self.apic_ip + + def get_request_info(self): + return self.request_info + + def get_token(self, generate_if_none=False): + if generate_if_none and self.token is None: + self.generate_token() + return self.token + + def generate_token(self): + url = "https://%s:%s/api/aaaLogin.json" % ( + self.apic_ip, + self.apic_port + ) + + payload = { + "aaaUser": { + "attributes": { + "name": self.apic_username, + "pwd": self.apic_password + } + } + } + + headers = { + "Content-Type": "application/json" + } + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + try: + response = requests.post( + url, + data=json.dumps( + payload + ), + headers=headers, + verify=False + ).json() + self.token = response['imdata'][0]['aaaLogin']['attributes']['token'] + self.session_connected = True + except BaseException: + self.log.error( + 'apic.connect', + traceback.format_exc() + ) + self.session_connected = False + self.my_output.error( + 'Failed to connect: %s:%s' % ( + self.apic_ip, + self.apic_port + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.apic( + 'connect %s:%s' % ( + self.apic_ip, + self.apic_port + ), + self.session_connected, + duration_ms + ) + + def is_connected(self): + if self.apic_settings is not None and not self.apic_settings['online']: + return False + + if self.token is None: + self.generate_token() + if self.token is None: + return False + + return True + + def get_mo_children_attributes(self, mo_name, managed_object, child_name, include_grandchildren=False): + attributes = [] + if 'children' in managed_object[mo_name]: + for child in managed_object[mo_name]['children']: + for key in child: + if key == child_name: + child_attributes = child[child_name]['attributes'] + if include_grandchildren: + if 'children' in child[child_name]: + for grandchild in child[child_name]['children']: + for grandkey in grandchild: + child_attributes[grandkey] = grandchild[grandkey]['attributes'] + + attributes.append( + child_attributes + ) + + return attributes + + def get_mo_child_attributes(self, mo_name, managed_object, child_name, include_grandchildren=False): + if 'children' in managed_object[mo_name]: + for child in managed_object[mo_name]['children']: + for key in child: + if key == child_name: + child_attributes = child[child_name]['attributes'] + if include_grandchildren: + if 'children' in child[child_name]: + for grandchild in child[child_name]['children']: + for grandkey in grandchild: + child_attributes[grandkey] = grandchild[grandkey]['attributes'] + + return child_attributes + + return None + + def get_mo_node_resource_ctx(self, mo_name, managed_object): + resources = [] + if 'children' in managed_object[mo_name]: + for child in managed_object[mo_name]['children']: + for key in child: + if key == 'pconsNodeDeployCtx': + if 'children' in child[key]: + for item in child[key]['children']: + for ckey in item: + if ckey == 'pconsResourceCtx': + resource = {} + resource['deployStatus'] = child[key]['attributes']['deployStatus'] + resource['nodeId'] = child[key]['attributes']['nodeId'] + resource['ctxClass'] = item[ckey]['attributes']['ctxClass'] + resource['ctxDn'] = item[ckey]['attributes']['ctxDn'] + resources.append( + resource + ) + return resources + + def get_class(self, class_name, response_format='json', query_target_filter=None, query=None, node_class=False): + self.request_info = {} + self.request_info['url'] = '--' + self.request_info['status_code'] = '--' + self.request_info['duration'] = '--' + self.request_info['error'] = None + self.request_info['connected'] = True + + if not self.is_connected(): + self.request_info['connected'] = False + return None + + if node_class: + url = "https://%s:%s/api/node/class/%s.%s" % ( + self.apic_ip, + self.apic_port, + class_name, + response_format + ) + else: + url = "https://%s:%s/api/class/%s.%s" % ( + self.apic_ip, + self.apic_port, + class_name, + response_format + ) + + # if query is None: + # query = 'page=0&page-size=10000' + # else: + # query = '%s&page=0&page-size=10000' % (query) + + if query is not None: + url = '%s?%s' % ( + url, + query + ) + + if query_target_filter is not None: + url = '%s?query-target-filter=%s' % ( + url, + query_target_filter + ) + + headers = { + "Cookie": "APIC-Cookie=%s" % (self.token), + } + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + success = True + item_count = '-' + try: + self.request_info['url'] = url + response = requests.get( + url, + headers=headers, + verify=False + ) + self.request_info['status_code'] = response.status_code + if response.status_code >= 300: + self.log.error( + 'apic.get_class', + 'Url %s response code %s' % ( + url, + response.status_code + ) + ) + + self.log.error( + 'apic.get_class', + 'Url %s response %s' % ( + url, + response.content + ) + ) + + self.request_info['error'] = response.content.decode('utf-8') + success = False + response = None + + if response is not None: + if response_format == 'json': + response = response.json() + item_count = len(response['imdata']) + else: + response = response.content + + except BaseException: + self.log.error( + 'apic.get_class', + traceback.format_exc() + ) + response = None + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.request_info['duration'] = duration_ms + + log_info = '%s:%s class %s' % ( + self.apic_ip, + self.apic_port, + class_name + ) + if query_target_filter is not None: + log_info = '%s filter %s' % ( + log_info, + query_target_filter + ) + if query is not None: + log_info = '%s query %s' % ( + log_info, + query + ) + + self.log.apic( + log_info, + success, + duration_ms, + item_count=item_count + ) + + return response + + def get_managed_object(self, distinguished_name, response_format='json', query_target_filter=None, query=None, node_mo=False): + self.request_info = {} + self.request_info['url'] = '--' + self.request_info['status_code'] = '--' + self.request_info['duration'] = '--' + self.request_info['error'] = None + self.request_info['connected'] = True + + if not self.is_connected(): + self.request_info['connected'] = False + return None + + if node_mo: + url = "https://%s:%s/api/node/mo/%s.%s" % ( + self.apic_ip, + self.apic_port, + distinguished_name, + response_format + ) + else: + url = "https://%s:%s/api/mo/%s.%s" % ( + self.apic_ip, + self.apic_port, + distinguished_name, + response_format + ) + + if query is not None: + url = '%s?%s' % ( + url, + query + ) + + if query_target_filter is not None: + url = '%s?query-target=%s' % ( + url, + query_target_filter + ) + + headers = { + "Cookie": "APIC-Cookie=%s" % (self.token), + } + + start_time = int(time.time() * 1000) + requests.packages.urllib3.disable_warnings() + success = True + item_count = None + try: + self.request_info['url'] = url + response = requests.get( + url, + headers=headers, + verify=False + ) + self.request_info['status_code'] = response.status_code + if response.status_code >= 300: + self.log.error( + 'apic.get_managed_object', + 'Url %s response code %s' % ( + url, + response.status_code + ) + ) + + self.log.error( + 'apic.get_managed_object', + 'Url %s response %s' % ( + url, + response.content + ) + ) + + self.request_info['error'] = response.content.decode('utf-8') + success = False + response = None + + if response is not None: + if response_format == 'json': + response = response.json() + item_count = len(response['imdata']) + else: + response = response.content + + except BaseException: + self.log.error( + 'apic.get_managed_object', + traceback.format_exc() + ) + response = None + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.request_info['duration'] = duration_ms + + log_info = '%s:%s mo %s' % ( + self.apic_ip, + self.apic_port, + distinguished_name + ) + if query_target_filter is not None: + log_info = '%s filter %s' % ( + log_info, + query_target_filter + ) + if query is not None: + log_info = '%s query %s' % ( + log_info, + query + ) + + self.log.apic( + log_info, + success, + duration_ms, + item_count=item_count + ) + + return response + + def get_mos(self, bar_enabled=False): + if bar_enabled: + bar_handler = Bar('Global Objects', max=79) + bar_handler.goto(0) + + self.get_application_profile_mo() + if bar_enabled: + bar_handler.next() + + self.get_bridge_domains_mo() + if bar_enabled: + bar_handler.next() + + self.get_contracts_mo() + if bar_enabled: + bar_handler.next() + + self.get_filters_mo() + if bar_enabled: + bar_handler.next() + + self.get_subjects_mo() + if bar_enabled: + bar_handler.next() + + self.get_taboos_mo() + if bar_enabled: + bar_handler.next() + + self.get_taboo_subjects_mo() + if bar_enabled: + bar_handler.next() + + self.get_domain_aaa_mo() + if bar_enabled: + bar_handler.next() + + self.get_domain_l2_mo() + if bar_enabled: + bar_handler.next() + + self.get_domain_l3_mo() + if bar_enabled: + bar_handler.next() + + self.get_domain_phy_mo() + if bar_enabled: + bar_handler.next() + + self.get_domain_vmm_mo() + if bar_enabled: + bar_handler.next() + + self.get_domain_vmm_epg_mo() + if bar_enabled: + bar_handler.next() + + self.get_endpoints_mo() + if bar_enabled: + bar_handler.next() + + self.get_endpoint_vmm_vnic_mo() + if bar_enabled: + bar_handler.next() + + self.get_endpoint_vmm_vm_mo() + if bar_enabled: + bar_handler.next() + + self.get_endpoint_vmm_hv_mo() + if bar_enabled: + bar_handler.next() + + self.get_epgs_mo() + if bar_enabled: + bar_handler.next() + + self.get_epg_locale_mo() + if bar_enabled: + bar_handler.next() + + self.get_l2out_mo() + if bar_enabled: + bar_handler.next() + + self.get_l3out_mo() + if bar_enabled: + bar_handler.next() + + self.get_l3out_logical_node_profile_mo() + if bar_enabled: + bar_handler.next() + + self.get_node_mo() + if bar_enabled: + bar_handler.next() + + self.get_node_power_mo() + if bar_enabled: + bar_handler.next() + + self.get_node_psu_mo() + if bar_enabled: + bar_handler.next() + + self.get_node_sensor_mo() + if bar_enabled: + bar_handler.next() + + self.get_node_system_mo() + if bar_enabled: + bar_handler.next() + + self.get_node_temp_mo() + if bar_enabled: + bar_handler.next() + + self.get_fabric_path_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_group_access_interface_breakout_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_group_access_interface_port_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_group_access_interface_vpc_node_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_group_access_interface_vpc_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_global_aae_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_auth_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_auth_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_cdp_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_cdp_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_copp_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_copp_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_copp_protocol_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_dpp_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_dpp_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_fc_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_fc_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_l2_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_l2_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_link_flap_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_link_flap_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_link_level_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_link_level_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_link_level_fc_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_link_level_fc_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_lldp_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_lldp_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_mcp_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_mcp_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_pfc_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_pfc_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_port_channel_mo() + if bar_enabled: + bar_handler.next() + + self.get_policies_interface_port_channel_info() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_port_channel_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_port_channel_member_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_port_channel_member_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_port_security_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_port_security_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_slow_drain_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_slow_drain_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_storm_control_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_storm_control_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_stp_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_stp_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_synce_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_synce_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_transceiver_mo() + if bar_enabled: + bar_handler.next() + + self.get_policy_interface_transceiver_attachment_mo() + if bar_enabled: + bar_handler.next() + + self.get_pool_vlan_mo() + if bar_enabled: + bar_handler.next() + + self.get_tenant_mo() + if bar_enabled: + bar_handler.next() + + self.get_vrfs_mo() + if bar_enabled: + bar_handler.next() + + if bar_enabled: + bar_handler.finish() + + nodes = self.get_nodes() + for node in nodes: + if bar_enabled: + bar_handler = Bar('Node Objects: %s' % (node['id']), max=59) + + self.get_adjacency_cdp_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_adjacency_lacp_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_adjacency_lldp_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_cloudsec_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_encap_routed_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_fc_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_fcpc_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_node_address_ipv4_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_node_interface_ipv4_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_node_address_ipv6_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_node_interface_ipv6_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interfaces_lacp_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_lacp_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_loopback_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_macsec_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_management_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_management_state_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_management_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_cap_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_eee_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_load_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_pc_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_rmon_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_ether_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_fc_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_phy_qos_stats_mo( + node['podId'], + node['id'], + cache_enabled=False + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_port_channels_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_svi_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_tunnel_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interface_vfc_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_interfaces_virtual_port_channel_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_vlan_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_node_interface_policy_profile_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_arp_domains_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_arp_adjacencies_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_bfd_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_bfd_interfaces_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_bfd_sessions_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_bgp_domains_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_bgp_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_bgp_neighbors_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_cdp_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_cdp_interfaces_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_cdp_neighbors_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_hsrp_domains_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_hsrp_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_hsrp_interfaces_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_ipv4_domains_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_ipv6_domains_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_isis_domains_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_isis_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_lacp_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_lldp_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_lldp_stats_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_nd_domain_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_nd_instance_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_nd_interface_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + self.get_protocol_nd_neighbor_mo( + node['podId'], + node['id'] + ) + if bar_enabled: + bar_handler.next() + + if bar_enabled: + bar_handler.finish() + + # get_interface_fault_counts_mo(self, pod_id, node_id, interface_type, interface_id) + + # get_interface_macsec_castats_mo(self, pod_id, node_id, interface_id) + # get_interface_macsec_rx_mo(self, pod_id, node_id, interface_id) + # get_interface_macsec_stats_mo(self, pod_id, node_id, interface_id) + # get_interface_macsec_tx_mo(self, pod_id, node_id, interface_id) + + # get_interface_phy_epg_stats_mo(self, pod_id, node_id, interface_id) + + # get_interface_policy_profile_mo(self, profile_name) + # get_interface_port_channel_relations_mo(self, pod_id, node_id, port_channel_id) + # get_policy_group_access_interface_vpc_port_mo(self, policy_group_name, node_id) + # get_policy_snoop_igmp_mo(self, tenant, name) + # get_policy_snoop_mld_mo(self, tenant, name) + # get_protocol_bfd_session_peer_mo(self, pod_id, node_id, session_id) + # get_protocol_bfd_session_stats_mo(self, pod_id, node_id, session_id) + # get_protocol_bgp_neighbor_stats_mo(self, pod_id, node_id, bgp_domain_name, bgp_peer_addr, bgp_state_addr) + # get_protocol_ipv4_routes_mo(self, pod_id, node_id, ipv4_domain_name) + # get_protocol_ipv6_routes_mo(self, pod_id, node_id, ipv6_domain_name) + # get_protocol_isis_domain_interfaces_mo(self, pod_id, node_id, instance_name, domain_name) + # get_protocol_isis_domain_lsps_mo(self, pod_id, node_id, instance_name, domain_name) + # get_protocol_isis_domain_neighbors_mo(self, pod_id, node_id, instance_name, domain_name) + # get_protocol_isis_domain_routes_mo(self, pod_id, node_id, instance_name, domain_name) + # get_protocol_isis_domain_trees_mo(self, pod_id, node_id, instance_name, domain_name) + # get_protocol_isis_domain_tunnels_mo(self, pod_id, node_id, instance_name, domain_name) + # get_vrf_ipv4_mo(self, tenant, name) + # get_vrf_ipv6_mo(self, tenant, name) diff --git a/lib/aci/apic.py b/lib/aci/apic.py new file mode 100644 index 00000000..dae29f70 --- /dev/null +++ b/lib/aci/apic.py @@ -0,0 +1,116 @@ +from lib import output_helper +from lib import log_helper +from lib import context + +from lib.aci import settings + +from lib.aci.api import Api +from lib.aci.cache import Cache +from lib.aci.common import Common +from lib.aci.ws import WebSocket + +from lib.aci.ap.main import ApplicationProfile +from lib.aci.bd.main import BridgeDomain +from lib.aci.context import Context +from lib.aci.contract.main import Contract +from lib.aci.domain.main import Domain +from lib.aci.endpoint.main import Endpoint +from lib.aci.epg.main import Epg +from lib.aci.intf.main import Interface +from lib.aci.l2out.main import L2Out +from lib.aci.l3out.main import L3Out +from lib.aci.node.main import Node +from lib.aci.path.main import FabricPath +from lib.aci.pg.main import PolicyGroup +from lib.aci.policy.main import Policy +from lib.aci.pool.main import Pool +from lib.aci.proto.main import Protocol +from lib.aci.server.main import Server +from lib.aci.system.main import System +from lib.aci.tenant.main import Tenant +from lib.aci.vrf.main import Vrf + + +class Apic( + Api, + ApplicationProfile, + BridgeDomain, + Cache, + Common, + Context, + Contract, + Domain, + Endpoint, + Epg, + FabricPath, + Interface, + L2Out, + L3Out, + Node, + Policy, + Pool, + PolicyGroup, + Protocol, + Server, + System, + Tenant, + Vrf, + WebSocket + ): + def __init__(self, apic_ip, apic_port, username, password, apic_name=None, verbose=False, debug=False, log_id=None, no_cache=False): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + + self.context_handler = context.Context(log_id=log_id) + self.apic_name = apic_name + self.apic_settings = None + if apic_name is not None: + settings_handler = settings.ApicSettings() + self.apic_settings = settings_handler.get_apic_controller( + apic_name + ) + + Api.__init__( + self, + apic_ip, + apic_port, + username, + password + ) + Cache.__init__(self, self.apic_name, no_cache=no_cache) + Common.__init__(self) + Context.__init__(self) + WebSocket.__init__( + self, + apic_ip, + debug=debug + ) + + ApplicationProfile.__init__(self) + BridgeDomain.__init__(self) + Contract.__init__(self) + Domain.__init__(self) + Endpoint.__init__(self) + Epg.__init__(self) + FabricPath.__init__(self) + Interface.__init__(self) + L2Out.__init__(self) + L3Out.__init__(self) + Node.__init__(self) + Policy.__init__(self) + Pool.__init__(self) + PolicyGroup.__init__(self) + Protocol.__init__(self) + Server.__init__(self) + System.__init__(self) + Tenant.__init__(self) + Vrf.__init__(self) + + def get_apic_name(self): + if self.apic_name is None: + return self.apic_ip + return self.apic_name diff --git a/lib/aci/bd/TODO.md b/lib/aci/bd/TODO.md new file mode 100644 index 00000000..b7628ae2 --- /dev/null +++ b/lib/aci/bd/TODO.md @@ -0,0 +1,5 @@ +Bridge domain +- l3out details in verbose output +- contract details for epg in verbose output +- stats (counters) +- related commands incl. context support \ No newline at end of file diff --git a/lib/aci/bd/__init__.py b/lib/aci/bd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..de81516b Binary files /dev/null and b/lib/aci/bd/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/api.cpython-310.pyc b/lib/aci/bd/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4389e87e Binary files /dev/null and b/lib/aci/bd/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/health.cpython-310.pyc b/lib/aci/bd/__pycache__/health.cpython-310.pyc new file mode 100644 index 00000000..c5f0d1da Binary files /dev/null and b/lib/aci/bd/__pycache__/health.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/igmp.cpython-310.pyc b/lib/aci/bd/__pycache__/igmp.cpython-310.pyc new file mode 100644 index 00000000..81a8f67b Binary files /dev/null and b/lib/aci/bd/__pycache__/igmp.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/info.cpython-310.pyc b/lib/aci/bd/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..be54fade Binary files /dev/null and b/lib/aci/bd/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/l3out.cpython-310.pyc b/lib/aci/bd/__pycache__/l3out.cpython-310.pyc new file mode 100644 index 00000000..15e36b52 Binary files /dev/null and b/lib/aci/bd/__pycache__/l3out.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/main.cpython-310.pyc b/lib/aci/bd/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..43c0d8d0 Binary files /dev/null and b/lib/aci/bd/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/mld.cpython-310.pyc b/lib/aci/bd/__pycache__/mld.cpython-310.pyc new file mode 100644 index 00000000..8e6ec80d Binary files /dev/null and b/lib/aci/bd/__pycache__/mld.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/nd.cpython-310.pyc b/lib/aci/bd/__pycache__/nd.cpython-310.pyc new file mode 100644 index 00000000..418e6714 Binary files /dev/null and b/lib/aci/bd/__pycache__/nd.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/output.cpython-310.pyc b/lib/aci/bd/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..540aab0b Binary files /dev/null and b/lib/aci/bd/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/retention.cpython-310.pyc b/lib/aci/bd/__pycache__/retention.cpython-310.pyc new file mode 100644 index 00000000..780761f3 Binary files /dev/null and b/lib/aci/bd/__pycache__/retention.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/subnet.cpython-310.pyc b/lib/aci/bd/__pycache__/subnet.cpython-310.pyc new file mode 100644 index 00000000..8b5111bb Binary files /dev/null and b/lib/aci/bd/__pycache__/subnet.cpython-310.pyc differ diff --git a/lib/aci/bd/__pycache__/vrf.cpython-310.pyc b/lib/aci/bd/__pycache__/vrf.cpython-310.pyc new file mode 100644 index 00000000..88f84b1d Binary files /dev/null and b/lib/aci/bd/__pycache__/vrf.cpython-310.pyc differ diff --git a/lib/aci/bd/api.py b/lib/aci/bd/api.py new file mode 100644 index 00000000..53194297 --- /dev/null +++ b/lib/aci/bd/api.py @@ -0,0 +1,108 @@ +class BridgeDomainApi(): + def __init__(self): + self.bridge_domain_mo = None + + def get_bridge_domains_mo(self): + if self.bridge_domain_mo is not None: + return self.bridge_domain_mo + + cache = self.get_object_cache( + 'fvBD' + ) + if cache is not None: + self.bridge_domain_mo = cache + self.log.apic_mo( + 'fvBD', + self.bridge_domain_mo + ) + return self.bridge_domain_mo + + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + + # fvRsCtx + # fvRsBdToEpRet + # fvRsIgmpsn + # fvRsMldsn + # fvRsBDToNdP + # fvRsBDToOut + # fvRtLIfCtxToBD + # fvSubnet + # fvRtEPpInfoToBD + # fvRtBDDefToBD + + children = [ + 'fvRsCtx', + 'fvRsBdToEpRet', + 'fvRsIgmpsn', + 'fvRsMldsn', + 'fvRsBDToOut', + 'fvSubnet' + ] + for child in children: + query = '%s&rsp-subtree-class=%s' % (query, child) + + managed_objects = self.get_class( + 'fvBD', + query=query + ) + if managed_objects is None: + self.log.error( + 'get_bridge_domains_mo', + 'API failed' + ) + return None + + self.bridge_domain_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvBD']['attributes'] + attributes['fvSubnet'] = self.get_mo_children_attributes( + 'fvBD', + managed_object, + 'fvSubnet' + ) + attributes['fvRsBDToOut'] = self.get_mo_children_attributes( + 'fvBD', + managed_object, + 'fvRsBDToOut' + ) + attributes['fvRsCtx'] = self.get_mo_child_attributes( + 'fvBD', + managed_object, + 'fvRsCtx' + ) + attributes['fvRsMldsn'] = self.get_mo_child_attributes( + 'fvBD', + managed_object, + 'fvRsMldsn' + ) + attributes['fvRsIgmpsn'] = self.get_mo_child_attributes( + 'fvBD', + managed_object, + 'fvRsIgmpsn' + ) + attributes['fvRsBdToEpRet'] = self.get_mo_child_attributes( + 'fvBD', + managed_object, + 'fvRsBdToEpRet' + ) + attributes['healthInst'] = self.get_mo_child_attributes( + 'fvBD', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'fvBD', + managed_object, + 'faultCounts' + ) + self.bridge_domain_mo.append( + attributes + ) + + self.set_object_cache( + 'fvBD', + self.bridge_domain_mo + ) + + return self.bridge_domain_mo diff --git a/lib/aci/bd/audit/__init__.py b/lib/aci/bd/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/audit/api.py b/lib/aci/bd/audit/api.py new file mode 100644 index 00000000..20ac03bd --- /dev/null +++ b/lib/aci/bd/audit/api.py @@ -0,0 +1,48 @@ +class BridgeDomainAuditApi(): + def __init__(self): + self.bridge_domain_audit_mo = None + + def get_bridge_domain_audit_mo(self): + cache = self.get_object_cache( + 'fvBD.audit' + ) + if cache is not None: + self.bridge_domain_audit_mo = cache + self.log.apic_mo( + 'fvBD.audit', + self.bridge_domain_audit_mo + ) + return self.bridge_domain_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'fvBD', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_bridge_domain_audit_mo', + 'API failed' + ) + return None + + self.bridge_domain_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.bridge_domain_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvBD.audit', + self.bridge_domain_audit_mo + ) + + self.set_object_cache( + 'fvBD.audit', + self.bridge_domain_audit_mo + ) + + return self.bridge_domain_audit_mo diff --git a/lib/aci/bd/audit/info.py b/lib/aci/bd/audit/info.py new file mode 100644 index 00000000..abac592b --- /dev/null +++ b/lib/aci/bd/audit/info.py @@ -0,0 +1,110 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class BridgeDomainAuditInfo(): + def __init__(self): + self.bridge_domain_audit = None + + def get_bridge_domain_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['bdName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/BD-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/BD-' in info['affected']: + info['bdName'] = info['affected'].split('/BD-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['bdName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['bdName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_bridge_domain_audit(self): + if self.bridge_domain_audit is not None: + return self.bridge_domain_audit + + managed_objects = self.get_bridge_domain_audit_mo() + if managed_objects is None: + return None + + self.bridge_domain_audit = [] + for managed_object in managed_objects: + audit_info = self.get_bridge_domain_audit_info( + managed_object + ) + self.bridge_domain_audit.append( + audit_info + ) + + self.log.apic_mo( + 'fvBD.auditRecord.info', + self.bridge_domain_audit + ) + + return self.bridge_domain_audit + + def get_bridge_domain_id_audit(self, tenant_name, bd_name, audit_filter=None): + audits = [] + + all_audits = self.get_bridge_domain_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['bdName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['bdName'] == bd_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/bd/audit/main.py b/lib/aci/bd/audit/main.py new file mode 100644 index 00000000..1634c007 --- /dev/null +++ b/lib/aci/bd/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.bd.audit.api import BridgeDomainAuditApi +from lib.aci.bd.audit.info import BridgeDomainAuditInfo + + +class BridgeDomainAudit(BridgeDomainAuditApi, BridgeDomainAuditInfo): + def __init__(self): + BridgeDomainAuditApi.__init__(self) + BridgeDomainAuditInfo.__init__(self) diff --git a/lib/aci/bd/event/__init__.py b/lib/aci/bd/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/event/api.py b/lib/aci/bd/event/api.py new file mode 100644 index 00000000..38b5af2d --- /dev/null +++ b/lib/aci/bd/event/api.py @@ -0,0 +1,51 @@ +class BridgeDomainEventApi(): + def __init__(self): + self.bridge_domain_event_mo = None + + def get_bridge_domain_event_mo(self): + if self.bridge_domain_event_mo is not None: + return self.bridge_domain_event_mo + + cache = self.get_object_cache( + 'fvBD.eventLog' + ) + if cache is not None: + self.bridge_domain_event_mo = cache + self.log.apic_mo( + 'fvBD.eventLog', + self.bridge_domain_event_mo + ) + return self.bridge_domain_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'fvBD', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_bridge_domain_event_mo', + 'API failed' + ) + return None + + self.bridge_domain_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.bridge_domain_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvBD.eventLog', + self.bridge_domain_event_mo + ) + + self.set_object_cache( + 'fvBD.eventLog', + self.bridge_domain_event_mo + ) + + return self.bridge_domain_event_mo diff --git a/lib/aci/bd/event/info.py b/lib/aci/bd/event/info.py new file mode 100644 index 00000000..b0af3ddf --- /dev/null +++ b/lib/aci/bd/event/info.py @@ -0,0 +1,124 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class BridgeDomainEventInfo(): + def __init__(self): + self.bridge_domain_event = None + + def get_bridge_domain_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['bdName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/BD-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/BD-' in info['affected']: + info['bdName'] = info['affected'].split('/BD-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/BD-bmk8s_2_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/BD-' in info['dn']: + info['bdName'] = info['dn'].split('/BD-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['bdName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['bdName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_bridge_domain_event(self, deduplicate=True): + if self.bridge_domain_event is not None: + return self.bridge_domain_event + + managed_objects = self.get_bridge_domain_event_mo() + if managed_objects is None: + return None + + self.bridge_domain_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_bridge_domain_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.bridge_domain_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'fvBD.eventLog.info', + self.bridge_domain_event + ) + + return self.bridge_domain_event + + def get_bridge_domain_id_event(self, tenant_name, bd_name, event_filter=None): + events = [] + + all_events = self.get_bridge_domain_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['bdName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['bdName'] == bd_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/bd/event/main.py b/lib/aci/bd/event/main.py new file mode 100644 index 00000000..0a052387 --- /dev/null +++ b/lib/aci/bd/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.bd.event.api import BridgeDomainEventApi +from lib.aci.bd.event.info import BridgeDomainEventInfo + + +class BridgeDomainEvent(BridgeDomainEventApi, BridgeDomainEventInfo): + def __init__(self): + BridgeDomainEventApi.__init__(self) + BridgeDomainEventInfo.__init__(self) diff --git a/lib/aci/bd/fault/__init__.py b/lib/aci/bd/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/fault/api.py b/lib/aci/bd/fault/api.py new file mode 100644 index 00000000..2d10c8a0 --- /dev/null +++ b/lib/aci/bd/fault/api.py @@ -0,0 +1,118 @@ +class BridgeDomainFaultApi(): + def __init__(self): + self.bridge_domain_fault_mo = None + self.bridge_domain_fault_record_mo = None + + def get_bridge_domain_fault_mo(self): + cache = self.get_object_cache( + 'fvBD.fault' + ) + if cache is not None: + self.bridge_domain_fault_mo = cache + self.log.apic_mo( + 'fvBD.fault', + self.bridge_domain_fault_mo + ) + return self.bridge_domain_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'fvBD', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_bridge_domain_fault_mo', + 'API failed' + ) + return None + + self.bridge_domain_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.bridge_domain_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.bridge_domain_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvBD.fault', + self.bridge_domain_fault_mo + ) + + self.set_object_cache( + 'fvBD.fault', + self.bridge_domain_fault_mo + ) + + return self.bridge_domain_fault_mo + + def get_bridge_domain_fault_record_mo(self): + cache = self.get_object_cache( + 'fvBD.faultRecord' + ) + if cache is not None: + self.bridge_domain_fault_record_mo = cache + self.log.apic_mo( + 'fvBD.faultRecord', + self.bridge_domain_fault_record_mo + ) + return self.bridge_domain_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'fvBD', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_bridge_domain_fault_record_mo', + 'API failed' + ) + return None + + self.bridge_domain_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.bridge_domain_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.bridge_domain_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvBD.faultRecord', + self.bridge_domain_fault_record_mo + ) + + self.set_object_cache( + 'fvBD.faultRecord', + self.bridge_domain_fault_record_mo + ) + + return self.bridge_domain_fault_record_mo diff --git a/lib/aci/bd/fault/info.py b/lib/aci/bd/fault/info.py new file mode 100644 index 00000000..6cb2330b --- /dev/null +++ b/lib/aci/bd/fault/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class BridgeDomainFaultInfo(): + def __init__(self): + self.bridge_domain_fault = None + self.bridge_domain_fault_record = None + + def get_bridge_domain_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['bdName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/BD-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/BD-' in info['affected']: + info['bdName'] = info['affected'].split('/BD-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/BD-bmk8s_2_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/BD-' in info['dn']: + info['bdName'] = info['dn'].split('/BD-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['bdName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['bdName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_bridge_domain_fault(self): + if self.bridge_domain_fault is not None: + return self.bridge_domain_fault + + managed_objects = self.get_bridge_domain_fault_mo() + if managed_objects is None: + return None + + self.bridge_domain_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_bridge_domain_fault_info( + managed_object + ) + self.bridge_domain_fault.append( + fault_info + ) + + self.log.apic_mo( + 'fvBD.fault.info', + self.bridge_domain_fault + ) + + return self.bridge_domain_fault + + def get_bridge_domain_fault_record(self, deduplicate=True): + if self.bridge_domain_fault_record is not None: + return self.bridge_domain_fault_record + + managed_objects = self.get_bridge_domain_fault_record_mo() + if managed_objects is None: + return None + + self.bridge_domain_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_bridge_domain_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.bridge_domain_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'fvBD.faultRecord.info', + self.bridge_domain_fault_record + ) + + return self.bridge_domain_fault_record + + def get_bridge_domain_id_fault(self, tenant_name, bd_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_bridge_domain_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_bridge_domain_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['bdName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['bdName'] == bd_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/bd/fault/main.py b/lib/aci/bd/fault/main.py new file mode 100644 index 00000000..bf15af07 --- /dev/null +++ b/lib/aci/bd/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.bd.fault.api import BridgeDomainFaultApi +from lib.aci.bd.fault.info import BridgeDomainFaultInfo + + +class BridgeDomainFault(BridgeDomainFaultApi, BridgeDomainFaultInfo): + def __init__(self): + BridgeDomainFaultApi.__init__(self) + BridgeDomainFaultInfo.__init__(self) diff --git a/lib/aci/bd/igmp/__init__.py b/lib/aci/bd/igmp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/igmp/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/igmp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9f823656 Binary files /dev/null and b/lib/aci/bd/igmp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/igmp/__pycache__/info.cpython-310.pyc b/lib/aci/bd/igmp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..8e961bec Binary files /dev/null and b/lib/aci/bd/igmp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/igmp/__pycache__/main.cpython-310.pyc b/lib/aci/bd/igmp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..04b6f64b Binary files /dev/null and b/lib/aci/bd/igmp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/igmp/info.py b/lib/aci/bd/igmp/info.py new file mode 100644 index 00000000..32f69cc4 --- /dev/null +++ b/lib/aci/bd/igmp/info.py @@ -0,0 +1,55 @@ +from lib import log_helper + + +# https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/2-x/KB/b_KB_Cisco_APIC_IGMP_Multicast.html + + +class BridgeDomainIgmpInfo(): + def __init__(self): + pass + + def get_bridge_domain_igmp_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "extMngdBy": "", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2021-10-27T15:21:50.404+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "rType": "mo", + # "rn": "rsigmpsn", + # "state": "formed", + # "stateQual": "default-target", + # "status": "", + # "tCl": "igmpSnoopPol", + # "tContextDn": "", + # "tDn": "uni/tn-common/snPol-default", + # "tRn": "snPol-default", + # "tType": "name", + # "tnIgmpSnoopPolName": "", + # "uid": "0", + # "userdom": "all" + info = {} + info['__Output'] = {} + + if managed_object['state'] == 'formed': + info['state'] = managed_object['state'] + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['configuredPolicyName'] = managed_object['tnIgmpSnoopPolName'] + info['actualPolicyName'] = managed_object['tDn'].split('/')[2].split('snPol-')[1] + info['name'] = info['actualPolicyName'] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + if managed_object['state'] != 'formed': + info['state'] = managed_object['state'] + info['tenant'] = None + info['configuredPolicyName'] = managed_object['tnIgmpSnoopPolName'] + info['actualPolicyName'] = managed_object['tRn'].split('snPol-')[1] + info['name'] = info['actualPolicyName'] + info['nameTenant'] = info['name'] + info['__Output']['nameTenant'] = 'Red' + + return info diff --git a/lib/aci/bd/igmp/main.py b/lib/aci/bd/igmp/main.py new file mode 100644 index 00000000..4487d6e3 --- /dev/null +++ b/lib/aci/bd/igmp/main.py @@ -0,0 +1,6 @@ +from lib.aci.bd.igmp.info import BridgeDomainIgmpInfo + + +class BridgeDomainIgmp(BridgeDomainIgmpInfo): + def __init__(self): + BridgeDomainIgmpInfo.__init__(self) diff --git a/lib/aci/bd/info.py b/lib/aci/bd/info.py new file mode 100644 index 00000000..5aec36b2 --- /dev/null +++ b/lib/aci/bd/info.py @@ -0,0 +1,507 @@ +import copy + +from lib import filter_helper +from lib import ip_helper + + +class BridgeDomainInfo(): + def __init__(self): + self.bridge_domains = None + + def get_bridge_domain_count(self, tenant_name=None): + bridge_domain_filter = None + if tenant_name is not None: + bridge_domain_filter = ['tenant:%s' % (tenant_name)] + + bridge_domains = self.get_bridge_domains( + bridge_domain_filter=bridge_domain_filter + ) + return len(bridge_domains) + + def get_bridge_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'arpFlood', + 'bcastP', + 'descr', + 'dn', + 'epClear', + 'epMoveDetectMode', + 'hostBasedRouting', + 'intersiteBumTrafficAllow', + 'intersiteL2Stretch', + 'ipLearning', + 'ipv6McastAllow', + 'limitIpLearnToSubnets', + 'llAddr', + 'mac', + 'mcastARPDrop', + 'mcastAllow', + 'mtu', + 'multiDstPktAct', + 'name', + 'pcTag', + 'seg', + 'type', + 'unicastRoute', + 'unkMacUcastAct', + 'unkMcastAct', + 'v6unkMcastAct', + 'vmac', + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['vmac'] == 'not-applicable': + info['vmac'] = '' + + info['unkMacUcastActT'] = info['unkMacUcastAct'] + if info['unkMacUcastAct'] == 'flood': + info['unkMacUcastActT'] = 'Flood' + if info['unkMacUcastAct'] == 'proxy': + info['unkMacUcastActT'] = 'Hardware Proxy' + + info['multiDstPktActT'] = info['multiDstPktAct'] + if info['multiDstPktAct'] == 'bd-flood': + info['multiDstPktActT'] = 'Flood in BD' + if info['multiDstPktAct'] == 'drop': + info['multiDstPktActT'] = 'Drop' + if info['multiDstPktAct'] == 'encap-flood': + info['multiDstPktActT'] = 'Flood in Encap' + + if info['arpFlood'] == 'yes': + info['arpFloodTick'] = '\u2713' + else: + info['arpFloodTick'] = '\u2717' + + if info['epClear'] == 'yes': + info['epClearTick'] = '\u2713' + else: + info['epClearTick'] = '\u2717' + + if info['intersiteL2Stretch'] == 'yes': + info['intersiteL2StretchTick'] = '\u2713' + else: + info['intersiteL2StretchTick'] = '\u2717' + + if info['unicastRoute'] == 'yes': + info['unicastRouteTick'] = '\u2713' + else: + info['unicastRouteTick'] = '\u2717' + + if info['ipLearning'] == 'yes': + info['ipLearningTick'] = '\u2713' + else: + info['ipLearningTick'] = '\u2717' + + if info['limitIpLearnToSubnets'] == 'yes': + info['limitIpLearnToSubnetsTick'] = '\u2713' + else: + info['limitIpLearnToSubnetsTick'] = '\u2717' + + if info['hostBasedRouting'] == 'yes': + info['hostBasedRoutingTick'] = '\u2713' + else: + info['hostBasedRoutingTick'] = '\u2717' + + info['vmacT'] = info['vmac'] + if info['vmac'] is None or len(info['vmac']) == 0: + info['vmacT'] = '--' + + info['epMoveDetectModeT'] = info['epMoveDetectMode'] + if info['epMoveDetectMode'] is None or len(info['epMoveDetectMode']) == 0: + info['epMoveDetectModeT'] = '--' + + if info['mcastAllow'] == 'yes': + info['mcastAllowTick'] = '\u2713' + info['__Output']['mcastAllowTick'] = 'Green' + else: + info['mcastAllowTick'] = '\u2717' + info['__Output']['mcastAllowTick'] = 'Red' + + info['unkMcastActT'] = info['unkMcastAct'] + if info['unkMcastAct'] == 'flood': + info['unkMcastActT'] = 'Flood' + if info['unkMcastAct'] == 'opt-flood': + info['unkMcastActT'] = 'Optimized Flood' + + if info['ipv6McastAllow'] == 'yes': + info['ipv6McastAllowTick'] = '\u2713' + info['__Output']['ipv6McastAllowTick'] = 'Green' + else: + info['ipv6McastAllowTick'] = '\u2717' + info['__Output']['ipv6McastAllowTick'] = 'Red' + + info['v6unkMcastActT'] = info['v6unkMcastAct'] + if info['v6unkMcastAct'] == 'flood': + info['v6unkMcastActT'] = 'Flood' + if info['v6unkMcastAct'] == 'opt-flood': + info['v6unkMcastActT'] = 'Optimized Flood' + + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + subnets = [] + info['fvSubnet'] = [] + for subnet_managed_object in managed_object['fvSubnet']: + subnet_info = self.get_bridge_domain_subnet_info( + subnet_managed_object + ) + info['fvSubnet'].append( + subnet_info + ) + subnets.append( + subnet_info['ip'] + ) + info['fvSubnetCount'] = len( + info['fvSubnet'] + ) + info['fvSubnets'] = ','.join(subnets) + + info['fvRsCtx'] = self.get_bridge_domain_vrf_info( + managed_object['fvRsCtx'] + ) + + info['fvRsBDToOut'] = [] + for l3out_managed_object in managed_object['fvRsBDToOut']: + info['fvRsBDToOut'].append( + self.get_bridge_domain_l3out_info( + l3out_managed_object + ) + ) + info['l3OutCount'] = len( + info['fvRsBDToOut'] + ) + + info['fvRsIgmpsn'] = self.get_bridge_domain_igmp_info( + managed_object['fvRsIgmpsn'] + ) + + info['fvRsMldsn'] = self.get_bridge_domain_mld_info( + managed_object['fvRsMldsn'] + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_bridge_domains_info(self): + if self.bridge_domains is not None: + return self.bridge_domains + + bridge_domains_mo = self.get_bridge_domains_mo() + if bridge_domains_mo is None: + return None + + self.bridge_domains = [] + for managed_object in bridge_domains_mo: + self.bridge_domains.append( + self.get_bridge_domain_info( + managed_object + ) + ) + + return self.bridge_domains + + def match_bridge_domain(self, bridge_domain_info, bridge_domain_filter): + if bridge_domain_filter is None or len(bridge_domain_filter) == 0: + return True + + for aepg_rule in bridge_domain_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, bridge_domain_info['name']): + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, bridge_domain_info['dn']): + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, bridge_domain_info['tenant']): + return False + + if key == 'vrf': + key_found = True + if bridge_domain_info['fvRsCtx'] is None or 'name' not in bridge_domain_info['fvRsCtx']: + return False + + if not filter_helper.match_tenant_name(value, bridge_domain_info['fvRsCtx']['nameTenant']): + return False + + if key == 'epg': + key_found = True + if 'fvAEPg' not in bridge_domain_info or bridge_domain_info['fvAEPg'] is None: + return False + + found = False + for epg_info in bridge_domain_info['fvAEPg']: + if filter_helper.match_tenant_name(value, epg_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'l3out': + key_found = True + if bridge_domain_info['fvRsBDToOut'] is None: + return False + + found = False + for l3out_info in bridge_domain_info['fvRsBDToOut']: + if filter_helper.match_tenant_name(value, l3out_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'subnet': + key_found = True + if bridge_domain_info['fvSubnet'] is None: + return False + + found = False + for bd_subnet in bridge_domain_info['fvSubnet']: + if ip_helper.is_subnet_in_subnet(bd_subnet['network'], value): + found = True + break + + if not found: + return False + + if key == 'ip': + key_found = True + if bridge_domain_info['fvSubnet'] is None: + return False + + found = False + for bd_subnet in bridge_domain_info['fvSubnet']: + if ip_helper.is_ipv4_in_cidr(value, bd_subnet['network']): + found = True + break + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not bridge_domain_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_bd', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_bd', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_bridge_domain( + self, + tenant_name, + bridge_domain_name, + endpoint_info=False, + endpoint_vm_info=False, + snoop_info=False, + vrf_info=False, + epg_info=False + ): + bridge_domain_filter = [] + bridge_domain_filter.append( + 'tenant:%s' % (tenant_name) + ) + bridge_domain_filter.append( + 'name:%s' % (bridge_domain_name) + ) + + bridge_domains = self.get_bridge_domains( + bridge_domain_filter=bridge_domain_filter, + endpoint_info=endpoint_info, + endpoint_vm_info=endpoint_vm_info, + snoop_info=snoop_info, + vrf_info=vrf_info, + epg_info=epg_info + ) + if len(bridge_domains) == 1: + return bridge_domains[0] + + self.log.error( + 'get_bridge_domain', + 'Not found: %s/%s (%s)' % ( + tenant_name, + bridge_domain_name, + len(bridge_domains) + ) + ) + + return None + + def get_bridge_domains( + self, + bridge_domain_filter=None, + endpoint_info=False, + endpoint_vm_info=False, + endpoint_fabric_info=False, + snoop_info=False, + vrf_info=False, + epg_info=False, + node_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_bridge_domains = self.get_bridge_domains_info() + if all_bridge_domains is None: + return None + + bridge_domains = [] + for bridge_domain_info in all_bridge_domains: + if vrf_info: + bridge_domain_info['fvCtx'] = copy.deepcopy( + self.get_vrf( + bridge_domain_info['fvRsCtx']['dn'] + ) + ) + + if epg_info: + epg_filter = ['bd:%s/%s' % (bridge_domain_info['tenant'], bridge_domain_info['name'])] + bridge_domain_info['fvAEPg'] = copy.deepcopy( + self.get_epgs( + epg_filter=epg_filter, + bd_info=True, + endpoint_info=True + ) + ) + bridge_domain_info['epgCount'] = len( + bridge_domain_info['fvAEPg'] + ) + + if not self.match_bridge_domain(bridge_domain_info, bridge_domain_filter): + continue + + if endpoint_info: + endpoint_filter = ['bd:%s/%s' % (bridge_domain_info['tenant'], bridge_domain_info['name'])] + bridge_domain_info['fvCEp'] = copy.deepcopy( + self.get_endpoints( + endpoint_filter=endpoint_filter, + vm_info=endpoint_vm_info, + fabric_info=endpoint_fabric_info + ) + ) + + bridge_domain_info['endpointCount'] = 0 + if bridge_domain_info['fvCEp'] is not None: + bridge_domain_info['endpointCount'] = len( + bridge_domain_info['fvCEp'] + ) + + bridge_domain_info['fvSubnet'] = copy.deepcopy( + self.get_subnet_usage( + bridge_domain_info['fvSubnet'], + bridge_domain_info['fvCEp'] + ) + ) + + if snoop_info: + bridge_domain_info['fvRsIgmpsn']['policy'] = copy.deepcopy( + self.get_policy_snoop_igmp( + bridge_domain_info['fvRsIgmpsn']['tenant'], + bridge_domain_info['fvRsIgmpsn']['actualPolicyName'] + ) + ) + + bridge_domain_info['fvRsMldsn']['policy'] = copy.deepcopy( + self.get_policy_snoop_mld( + bridge_domain_info['fvRsMldsn']['tenant'], + bridge_domain_info['fvRsMldsn']['actualPolicyName'] + ) + ) + + if node_info: + ap_node_info = self.get_bridge_domain_node( + bridge_domain_info['tenant'], + bridge_domain_info['name'] + ) + bridge_domain_info['node'] = None + bridge_domain_info['interface'] = None + if ap_node_info is not None: + bridge_domain_info['node'] = ap_node_info['node'] + bridge_domain_info['interface'] = ap_node_info['interface'] + + if fault_info: + bridge_domain_info['faultInst'] = self.get_bridge_domain_id_fault( + bridge_domain_info['tenant'], + bridge_domain_info['name'], + 'faultInst' + ) + + if hfault_info: + bridge_domain_info['faultRecord'] = self.get_bridge_domain_id_fault( + bridge_domain_info['tenant'], + bridge_domain_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + bridge_domain_info['eventLog'] = self.get_bridge_domain_id_event( + bridge_domain_info['tenant'], + bridge_domain_info['name'], + event_filter=event_filter + ) + + if audit_info: + bridge_domain_info['auditLog'] = self.get_bridge_domain_id_audit( + bridge_domain_info['tenant'], + bridge_domain_info['name'], + audit_filter=audit_filter + ) + + bridge_domains.append(bridge_domain_info) + + bridge_domains = sorted( + bridge_domains, + key=lambda i: i['nameTenant'].lower() + ) + + self.log.apic_mo( + 'fvBD.info', + bridge_domains + ) + + return bridge_domains diff --git a/lib/aci/bd/l3out/__init__.py b/lib/aci/bd/l3out/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/l3out/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/l3out/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..48e4845f Binary files /dev/null and b/lib/aci/bd/l3out/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/l3out/__pycache__/info.cpython-310.pyc b/lib/aci/bd/l3out/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..fc09b2e7 Binary files /dev/null and b/lib/aci/bd/l3out/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/l3out/__pycache__/main.cpython-310.pyc b/lib/aci/bd/l3out/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5be04206 Binary files /dev/null and b/lib/aci/bd/l3out/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/l3out/info.py b/lib/aci/bd/l3out/info.py new file mode 100644 index 00000000..c4ad6017 --- /dev/null +++ b/lib/aci/bd/l3out/info.py @@ -0,0 +1,16 @@ +class BridgeDomainL3OutInfo(): + def __init__(self): + pass + + def get_bridge_domain_l3out_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['tenant'] = managed_object['tDn'].split('/')[1].split('tn-')[1] + info['name'] = managed_object['tnL3extOutName'] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + managed_object['tnL3extOutName'] + ) + + return info diff --git a/lib/aci/bd/l3out/main.py b/lib/aci/bd/l3out/main.py new file mode 100644 index 00000000..85eb9a0d --- /dev/null +++ b/lib/aci/bd/l3out/main.py @@ -0,0 +1,6 @@ +from lib.aci.bd.l3out.info import BridgeDomainL3OutInfo + + +class BridgeDomainL3Out(BridgeDomainL3OutInfo): + def __init__(self): + BridgeDomainL3OutInfo.__init__(self) diff --git a/lib/aci/bd/main.py b/lib/aci/bd/main.py new file mode 100644 index 00000000..a7ce044d --- /dev/null +++ b/lib/aci/bd/main.py @@ -0,0 +1,41 @@ +from lib.aci.bd.api import BridgeDomainApi +from lib.aci.bd.info import BridgeDomainInfo +from lib.aci.bd.igmp.main import BridgeDomainIgmp +from lib.aci.bd.l3out.main import BridgeDomainL3Out +from lib.aci.bd.mld.main import BridgeDomainMld +from lib.aci.bd.retention.main import BridgeDomainRetention +from lib.aci.bd.subnet.main import BridgeDomainSubnet +from lib.aci.bd.vrf.main import BridgeDomainVrf +from lib.aci.bd.audit.main import BridgeDomainAudit +from lib.aci.bd.event.main import BridgeDomainEvent +from lib.aci.bd.fault.main import BridgeDomainFault +from lib.aci.bd.node.main import BridgeDomainNode + + +class BridgeDomain( + BridgeDomainApi, + BridgeDomainIgmp, + BridgeDomainInfo, + BridgeDomainL3Out, + BridgeDomainMld, + BridgeDomainRetention, + BridgeDomainSubnet, + BridgeDomainVrf, + BridgeDomainAudit, + BridgeDomainEvent, + BridgeDomainFault, + BridgeDomainNode + ): + def __init__(self): + BridgeDomainApi.__init__(self) + BridgeDomainIgmp.__init__(self) + BridgeDomainInfo.__init__(self) + BridgeDomainL3Out.__init__(self) + BridgeDomainMld.__init__(self) + BridgeDomainRetention.__init__(self) + BridgeDomainSubnet.__init__(self) + BridgeDomainVrf.__init__(self) + BridgeDomainAudit.__init__(self) + BridgeDomainEvent.__init__(self) + BridgeDomainFault.__init__(self) + BridgeDomainNode.__init__(self) diff --git a/lib/aci/bd/mld/__init__.py b/lib/aci/bd/mld/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/mld/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/mld/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8ab48d35 Binary files /dev/null and b/lib/aci/bd/mld/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/mld/__pycache__/info.cpython-310.pyc b/lib/aci/bd/mld/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..804c3c8b Binary files /dev/null and b/lib/aci/bd/mld/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/mld/__pycache__/main.cpython-310.pyc b/lib/aci/bd/mld/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b15c6218 Binary files /dev/null and b/lib/aci/bd/mld/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/mld/info.py b/lib/aci/bd/mld/info.py new file mode 100644 index 00000000..84411b66 --- /dev/null +++ b/lib/aci/bd/mld/info.py @@ -0,0 +1,41 @@ +# https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/4-x/L3-configuration/Cisco-APIC-Layer-3-Networking-Configuration-Guide-411/Cisco-APIC-Layer-3-Networking-Configuration-Guide-411_chapter_010100.html + + +class BridgeDomainMldInfo(): + def __init__(self): + pass + + def get_bridge_domain_mld_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "extMngdBy": "", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2021-10-27T15:21:50.404+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "rType": "mo", + # "rn": "rsmldsn", + # "state": "formed", + # "stateQual": "default-target", + # "status": "", + # "tCl": "mldSnoopPol", + # "tContextDn": "", + # "tDn": "uni/tn-common/mldsnoopPol-default", + # "tRn": "mldsnoopPol-default", + # "tType": "name", + # "tnMldSnoopPolName": "", + # "uid": "0", + # "userdom": "all" + info = {} + info['__Output'] = {} + + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['configuredPolicyName'] = managed_object['tnMldSnoopPolName'] + info['actualPolicyName'] = managed_object['tDn'].split('/')[2].split('mldsnoopPol-')[1] + info['name'] = info['actualPolicyName'] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + return info diff --git a/lib/aci/bd/mld/main.py b/lib/aci/bd/mld/main.py new file mode 100644 index 00000000..3424db0e --- /dev/null +++ b/lib/aci/bd/mld/main.py @@ -0,0 +1,6 @@ +from lib.aci.bd.mld.info import BridgeDomainMldInfo + + +class BridgeDomainMld(BridgeDomainMldInfo): + def __init__(self): + BridgeDomainMldInfo.__init__(self) diff --git a/lib/aci/bd/node/__init__.py b/lib/aci/bd/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/node/api.py b/lib/aci/bd/node/api.py new file mode 100644 index 00000000..6f561827 --- /dev/null +++ b/lib/aci/bd/node/api.py @@ -0,0 +1,61 @@ +class BridgeDomainNodeApi(): + def __init__(self): + self.bridge_domain_node_mo = {} + + def get_bridge_domain_node_mo(self, tenant_name, bd_name): + key = '%s.%s' % (tenant_name, bd_name) + if key in self.bridge_domain_node_mo: + return self.bridge_domain_node_mo[key] + + cache = self.get_object_cache( + 'fvBD.%s' % (key) + ) + if cache is not None: + self.bridge_domain_node_mo[key] = cache + self.log.apic_mo( + 'fvBD.%s' % (key), + self.bridge_domain_node_mo[key] + ) + return self.bridge_domain_node_mo[key] + + distinguished_name = 'uni/tn-%s/BD-%s' % (tenant_name, bd_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=BDToNwIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_bridge_domain_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_bridge_domain_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvBD']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'fvBD', + managed_object + ) + self.bridge_domain_node_mo[key] = attributes + + self.log.apic_mo( + 'fvBD.%s' % (key), + self.bridge_domain_node_mo[key] + ) + + self.set_object_cache( + 'fvBD.%s' % (key), + self.bridge_domain_node_mo[key] + ) + + return self.bridge_domain_node_mo[key] diff --git a/lib/aci/bd/node/info.py b/lib/aci/bd/node/info.py new file mode 100644 index 00000000..ea81c279 --- /dev/null +++ b/lib/aci/bd/node/info.py @@ -0,0 +1,82 @@ +class BridgeDomainNodeInfo(): + def __init__(self): + self.bridge_domain_node = {} + + def get_bridge_domain_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_bridge_domain_node(self, tenant_name, ap_name): + key = '%s.%s' % (tenant_name, ap_name) + if key in self.bridge_domain_node: + return self.bridge_domain_node[key] + + # one object or None value is expected + nodes_mo = self.get_bridge_domain_node_mo(tenant_name, ap_name) + if nodes_mo is None: + return None + + self.bridge_domain_node[key] = self.get_bridge_domain_node_info( + nodes_mo + ) + + self.log.apic_mo( + 'fvBD.%s.info' % (key), + self.bridge_domain_node[key] + ) + + return self.bridge_domain_node[key] diff --git a/lib/aci/bd/node/main.py b/lib/aci/bd/node/main.py new file mode 100644 index 00000000..c82ce432 --- /dev/null +++ b/lib/aci/bd/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.bd.node.api import BridgeDomainNodeApi +from lib.aci.bd.node.info import BridgeDomainNodeInfo + + +class BridgeDomainNode(BridgeDomainNodeApi, BridgeDomainNodeInfo): + def __init__(self): + BridgeDomainNodeApi.__init__(self) + BridgeDomainNodeInfo.__init__(self) diff --git a/lib/aci/bd/output.py b/lib/aci/bd/output.py new file mode 100644 index 00000000..e8d24dfe --- /dev/null +++ b/lib/aci/bd/output.py @@ -0,0 +1,777 @@ +class BridgeDomainOutput(): + def __init__(self): + pass + + def print_bridge_domain_properties(self, info): + order = [ + 'health', + 'faults', + 'tenant', + 'name', + 'dn', + 'descr', + 'type', + 'fvSubnetCount', + 'fvRsCtx.nameTenant', + 'l3OutCount', + 'endpointCount', + 'epgCount' + ] + + headers = [ + 'Health', + 'Faults', + 'Tenant', + 'Name', + 'Dn', + 'Description', + 'Type', + 'Subnet Count', + 'VRF', + 'L3Out', + 'Endpoint', + 'EPG' + ] + + self.my_output.dictionary( + info, + title='Bridge Domain Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_bridge_domain_l2_properties(self, info): + order = [ + 'unkMacUcastActT', + 'bcastP', + 'multiDstPktActT', + 'epClearTick', + 'intersiteL2StretchTick' + ] + + headers = [ + 'L2 Unknown Unicast', + 'Multicast Address (GIPo)', + 'Multi Destination Flooding', + 'Clear Remote MAC Entries', + 'Scaled L2 Only Mode' + ] + + self.my_output.dictionary( + info, + title='L2 Forwarding Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_bridge_domain_mcast_properties(self, info): + order = [ + 'fvRsIgmpsn.nameTenant', + 'fvRsMldsn.nameTenant', + 'mcastAllowTick', + 'unkMcastActT', + 'ipv6McastAllowTick', + 'v6unkMcastActT' + ] + + headers = [ + 'IGMP Snooping Policy', + 'MLD Snooping Policy', + 'IPv4 Multicast', + 'IPv4 L3 Unknown Multicast Flooding', + 'IPv6 Multicast', + 'IPv6 L3 Unknown Multicast' + ] + + self.my_output.dictionary( + info, + title='Multicast Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_bridge_domain_l3_properties(self, info): + order = [ + 'unicastRouteTick', + 'mac', + 'vmacT', + 'ipLearningTick', + 'hostBasedRoutingTick', + 'limitIpLearnToSubnetsTick', + 'arpFloodTick', + 'epMoveDetectModeT' + ] + + headers = [ + 'Unicast Routing', + 'BD MAC Address', + 'Virtual MAC Address', + 'IP Learning', + 'Advertise Host Routes', + 'Limit Local IP Learning to BD/EPG Subnets', + 'ARP Flooding', + 'EP Move Detection Mode' + ] + + self.my_output.dictionary( + info, + title='L3 Forwarding Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_bridge_domain_subnets(self, info): + order = [ + 'network', + 'gateway', + 'preferredTick', + 'virtualTick', + 'scope', + 'ipDPLearningTick', + 'usage', + 'available' + ] + + headers = [ + 'Network', + 'Gateway', + 'Preferred', + 'Virtual', + 'Scope', + 'IP Data Plane Learning', + 'IP Usage', + 'IP Available' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_bridge_domain_epgs(self, info): + self.my_output.default( + 'Endpoint Groups', + underline=True, + before_newline=True + ) + + order = [ + 'adminUpTick', + 'nameApTenant', + 'endpointCount', + 'contractCount' + ] + + headers = [ + 'Up', + 'EPG', + 'Endpoints', + 'Contract' + ] + + self.my_output.my_table( + info['fvAEPg'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_bridge_domain_endpoints(self, info): + self.my_output.default( + 'Bridge Domain Endpoints', + underline=True + ) + + self.print_endpoints( + info['fvCEp'] + ) + + vmm_endpoints = [] + for endpoint_info in info['fvCEp']: + if 'fvRsToVm' in endpoint_info and endpoint_info['fvRsToVm'] is not None: + vmm_endpoints.append( + endpoint_info + ) + + if len(vmm_endpoints) > 0: + self.my_output.default( + 'Bridge Domain Endpoints with VMM information', + underline=True, + before_newline=True + ) + self.print_endpoints_vmm( + vmm_endpoints + ) + + def print_bridge_domain(self, info): + self.print_bridge_domain_properties( + info + ) + + self.print_bridge_domain_l2_properties( + info + ) + + self.print_bridge_domain_mcast_properties( + info + ) + + self.print_policy_snoop_igmp( + info['fvRsIgmpsn']['policy'] + ) + + self.print_policy_snoop_mld( + info['fvRsMldsn']['policy'] + ) + + self.print_bridge_domain_l3_properties( + info + ) + + if len(info['fvSubnet']) > 0: + self.print_bridge_domain_subnets( + info['fvSubnet'] + ) + + if len(info['fvAEPg']) > 0: + self.print_bridge_domain_epgs( + info + ) + + self.print_vrf_properties( + info['fvCtx'] + ) + + if len(info['fvCEp']) > 0: + self.print_bridge_domain_endpoints( + info + ) + + def print_bridge_domains_l2(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - L2 Forwarding Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'unkMacUcastActT', + 'bcastP', + 'arpFloodTick', + 'multiDstPktActT', + 'epClearTick' + ] + + headers = [ + 'Bridge Domain', + 'L2 Unknown Ucast', + 'Mcast (GIPo)', + 'ARP Flooding', + 'Multi Dest Flooding', + 'Clear Remote MAC' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_bridge_domains_l3(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - L3 Forwarding Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'unicastRouteTick', + 'mac', + 'vmacT', + 'ipLearningTick', + 'limitIpLearnToSubnetsTick', + 'hostBasedRoutingTick', + 'epMoveDetectModeT' + ] + + headers = [ + 'Bridge Domain', + 'Ucast Routing', + 'BD MAC', + 'Virtual MAC', + 'IP Learning', + 'Limit Local IP Learning', + 'Adv Host Routes', + 'EP Move Detection Mode' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_bridge_domains_mcast(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - Multicast Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'mcastAllowTick', + 'unkMcastActT', + 'fvRsIgmpsn.nameTenant', + 'ipv6McastAllowTick', + 'v6unkMcastActT', + 'fvRsMldsn.nameTenant' + ] + + headers = [ + 'Bridge Domain', + 'PIM', + 'Unknown IPv4 Flooding', + 'IGMP Snooping Policy', + 'PIMv6', + 'Unknown IPv6 Flooding', + 'MLD Snooping Policy' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_bridge_domains_vrf(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - VRF Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'fvCtx.nameTenant', + 'fvCtx.ipDataPlaneLearningTick', + 'fvCtx.pcEnfDir', + 'fvCtx.pcEnfPref', + 'fvCtx.bdEnforcedEnableTick' + ] + + headers = [ + 'Bridge Domain', + 'VRF', + 'Learning', + 'PCE Direction', + 'PCE Preference', + 'BD Enforcement' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_bridge_domains(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'health', + 'faults', + 'nameTenant', + 'pcTag', + 'seg', + 'fvSubnet.ip', + 'fvSubnet.usage', + 'fvAEPg.nameTenant', + 'fvRsCtx.nameTenant', + 'fvRsBDToOut.nameTenant' + ] + + headers = [ + 'Health', + 'Faults', + 'Bridge Domain', + 'Class ID', + 'VNID', + 'Subnet', + 'Usage', + 'EPG', + 'VRF', + 'L3Out' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fvSubnet', 'fvRsBDToOut', 'fvAEPg'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_bridge_domains_node(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Bridge Domain', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_bridge_domains_interface(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Bridge Domain', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_bridge_domains_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Bridge Domain - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Bridge Domain - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Bridge Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_bridge_domains_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Bridge Domain - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Bridge Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_bridge_domains_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Bridge Domain - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Bridge Domain - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Bridge Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_bridge_domains_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Bridge Domain - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Bridge Domain - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Bridge Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/bd/retention/__init__.py b/lib/aci/bd/retention/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/retention/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/retention/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7765bc59 Binary files /dev/null and b/lib/aci/bd/retention/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/retention/__pycache__/info.cpython-310.pyc b/lib/aci/bd/retention/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..bd081845 Binary files /dev/null and b/lib/aci/bd/retention/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/retention/__pycache__/main.cpython-310.pyc b/lib/aci/bd/retention/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8e814e4f Binary files /dev/null and b/lib/aci/bd/retention/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/retention/info.py b/lib/aci/bd/retention/info.py new file mode 100644 index 00000000..3b77c23b --- /dev/null +++ b/lib/aci/bd/retention/info.py @@ -0,0 +1,19 @@ +# https://www.kareemccie.com/2021/12/what-is-endpoint-retention-policy-in-aci.html + + +class BridgeDomainRetentionInfo(): + def __init__(self): + pass + + def get_bridge_domain_retention_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['tenant'] = managed_object['tDn'].split('/')[1].split('tn-')[1] + info['name'] = managed_object['tnFvEpRetPolName'] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + return info diff --git a/lib/aci/bd/retention/main.py b/lib/aci/bd/retention/main.py new file mode 100644 index 00000000..543a0515 --- /dev/null +++ b/lib/aci/bd/retention/main.py @@ -0,0 +1,6 @@ +from lib.aci.bd.retention.info import BridgeDomainRetentionInfo + + +class BridgeDomainRetention(BridgeDomainRetentionInfo): + def __init__(self): + BridgeDomainRetentionInfo.__init__(self) diff --git a/lib/aci/bd/subnet/__init__.py b/lib/aci/bd/subnet/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/subnet/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/subnet/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5002ab87 Binary files /dev/null and b/lib/aci/bd/subnet/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/subnet/__pycache__/info.cpython-310.pyc b/lib/aci/bd/subnet/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e9ad3e12 Binary files /dev/null and b/lib/aci/bd/subnet/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/subnet/__pycache__/main.cpython-310.pyc b/lib/aci/bd/subnet/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6a277e85 Binary files /dev/null and b/lib/aci/bd/subnet/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/subnet/info.py b/lib/aci/bd/subnet/info.py new file mode 100644 index 00000000..d80c42ff --- /dev/null +++ b/lib/aci/bd/subnet/info.py @@ -0,0 +1,96 @@ +from lib import ip_helper + + +# Scope +# Public : This means that ACI will automatically advertise this subnet outside the fabric. Users are not longer required to create route-maps or distributing routes. ACI will automate this for you +# Private: This means this subnet will stay within the Tenant. This is the default setting for subnets within a BD. +# Shared: This means that the subnet can be shared with other VRF within the same Tenant. It is important to note if you enable this knob to users different subnets. + + +class BridgeDomainSubnetInfo(): + def __init__(self): + pass + + def get_subnet_usage(self, bridge_domain_subnets, endpoints): + for subnet in bridge_domain_subnets: + subnet['endpoints'] = 1 + if endpoints is not None: + for endpoint in endpoints: + for endpoint_ip in endpoint['fvIp']: + if ip_helper.is_ipv4_in_cidr(endpoint_ip['addr'], subnet['network']): + subnet['endpoints'] = subnet['endpoints'] + 1 + + subnet['usage'] = '%s/%s' % ( + subnet['endpoints'], + subnet['size'] + ) + + subnet['available'] = None + if subnet['size'] is not None: + subnet['available'] = subnet['size'] - subnet['endpoints'] + + return bridge_domain_subnets + + def get_bridge_domain_subnet_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "configIssues": "", + # "ctrl": "", + # "debugMessage": "", + # "descr": "", + # "extMngdBy": "", + # "ip": "/24", + # "ipDPLearning": "enabled", + # "lcOwn": "local", + # "modTs": "2021-10-27T15:21:50.404+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "name": "", + # "nameAlias": "", + # "preferred": "no", + # "rn": "subnet-[/24]", + # "scope": "private", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:", + # "virtual": "no" + info = {} + info['__Output'] = {} + + keys = [ + 'ip', + 'ipDPLearning', + 'preferred', + 'rn', + 'scope', + 'virtual' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['preferred'] == 'yes': + info['__Output']['preferred'] = 'Green' + info['preferredTick'] = '\u2713' + else: + info['preferredTick'] = '\u2717' + + if info['virtual'] == 'yes': + info['virtualTick'] = '\u2713' + else: + info['virtualTick'] = '\u2717' + + if info['ipDPLearning'] == 'enabled': + info['ipDPLearningTick'] = '\u2713' + else: + info['ipDPLearningTick'] = '\u2717' + + info['network'] = '%s/%s' % ( + ip_helper.get_network_ipv4_in_cidr(info['ip']), + info['ip'].split('/')[1] + ) + info['gateway'] = info['ip'].split('/')[0] + info['size'] = ip_helper.get_ipv4_cidr_size(info['ip']) + + return info diff --git a/lib/aci/bd/subnet/main.py b/lib/aci/bd/subnet/main.py new file mode 100644 index 00000000..7377b02f --- /dev/null +++ b/lib/aci/bd/subnet/main.py @@ -0,0 +1,6 @@ +from lib.aci.bd.subnet.info import BridgeDomainSubnetInfo + + +class BridgeDomainSubnet(BridgeDomainSubnetInfo): + def __init__(self): + BridgeDomainSubnetInfo.__init__(self) diff --git a/lib/aci/bd/vrf/__init__.py b/lib/aci/bd/vrf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/bd/vrf/__pycache__/__init__.cpython-310.pyc b/lib/aci/bd/vrf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0f771ed6 Binary files /dev/null and b/lib/aci/bd/vrf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/bd/vrf/__pycache__/info.cpython-310.pyc b/lib/aci/bd/vrf/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..433ee46b Binary files /dev/null and b/lib/aci/bd/vrf/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/bd/vrf/__pycache__/main.cpython-310.pyc b/lib/aci/bd/vrf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f721650e Binary files /dev/null and b/lib/aci/bd/vrf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/bd/vrf/info.py b/lib/aci/bd/vrf/info.py new file mode 100644 index 00000000..24f9fad8 --- /dev/null +++ b/lib/aci/bd/vrf/info.py @@ -0,0 +1,27 @@ +class BridgeDomainVrfInfo(): + def __init__(self): + pass + + def get_bridge_domain_vrf_info(self, managed_object): + info = {} + info['__Output'] = {} + + if managed_object['state'] == 'formed': + info['dn'] = managed_object['tDn'] + info['state'] = managed_object['state'] + info['tenant'] = managed_object['tDn'].split('/')[1].split('tn-')[1] + info['name'] = managed_object['tnFvCtxName'] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + if managed_object['state'] != 'formed': + info['dn'] = managed_object['tDn'] + info['state'] = managed_object['state'] + info['tenant'] = None + info['name'] = managed_object['tnFvCtxName'] + info['nameTenant'] = info['name'] + info['__Output']['nameTenant'] = 'Red' + + return info diff --git a/lib/aci/bd/vrf/main.py b/lib/aci/bd/vrf/main.py new file mode 100644 index 00000000..05fca712 --- /dev/null +++ b/lib/aci/bd/vrf/main.py @@ -0,0 +1,6 @@ +from lib.aci.bd.vrf.info import BridgeDomainVrfInfo + + +class BridgeDomainVrf(BridgeDomainVrfInfo): + def __init__(self): + BridgeDomainVrfInfo.__init__(self) diff --git a/lib/aci/bot_output.py b/lib/aci/bot_output.py new file mode 100644 index 00000000..ea2d353d --- /dev/null +++ b/lib/aci/bot_output.py @@ -0,0 +1,111 @@ +from lib import output_helper + +from lib.aci.endpoint.bot_output import EndpointBotOutput +from lib.aci.node.bot_output import NodeBotOutput +from lib.aci.proto.bot_output import ProtocolBotOutput + + +class ApicBotOutput( + EndpointBotOutput, + NodeBotOutput, + ProtocolBotOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.is_apic = True + + EndpointBotOutput.__init__(self) + NodeBotOutput.__init__(self) + ProtocolBotOutput.__init__(self) + + def print_apic_controllers(self, controllers, title=False): + self.my_output.clear_output() + + controllers = sorted( + controllers, + key=lambda i: i['name'] + ) + + for controller in controllers: + controller['__Output'] = {} + + if controller['online']: + controller['onlineTick'] = '\u2713' + controller['__Output']['onlineTick'] = 'Green' + else: + controller['onlineTick'] = '\u2717' + controller['__Output']['onlineTick'] = 'Red' + + if controller['cache']['enabled']: + controller['cache']['enabledTick'] = '\u2713' + controller['__Output']['cache.enabledTick'] = 'Green' + else: + controller['cache']['enabledTick'] = '\u2717' + controller['__Output']['cache.enabledTick'] = 'Red' + + if controller['cache']['enabled']: + if len(controller['cache']['object']): + controller['cache']['objectTick'] = '\u2713' + controller['__Output']['cache.objectTick'] = 'Green' + else: + controller['cache']['objectTick'] = '\u2717' + controller['__Output']['cache.objectTick'] = 'Red' + + if not controller['cache']['enabled']: + controller['cache']['ttlT'] = '--' + controller['cache']['objectTick'] = '--' + + if title: + self.my_output.my_print( + 'APIC [#%s]' % (len(controllers)), + underline=True, + before_newline=True + ) + + order = [ + 'name', + 'ip', + 'port', + 'username', + 'domain', + 'cache.enabledTick', + 'cache.ttlT' + ] + + headers = [ + 'Name', + 'IP', + 'Port', + 'Username', + 'Domain', + 'Cache', + 'TTL' + ] + + self.my_output.my_table( + controllers, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + controllers, + order, + headers, + title='APIC' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/aci/cache.py b/lib/aci/cache.py new file mode 100644 index 00000000..6acef3e0 --- /dev/null +++ b/lib/aci/cache.py @@ -0,0 +1,272 @@ +import time +from datetime import timedelta +import os +import json + +from progress.bar import Bar + +from lib.aci import settings + + +class Cache(): + def __init__(self, apic_name, no_cache=False): + if apic_name is None: + self.cache_enabled = False + self.cache_write_enabled = False + return + + settings_handler = settings.ApicSettings() + + self.cache_directory = os.path.join( + settings_handler.get_apic_cache_base_directory(), + apic_name + ) + self.apic_online_mode = settings_handler.is_apic_online( + apic_name + ) + + if not self.apic_online_mode: + self.cache_enabled = True + self.cache_write_enabled = False + self.cache_settings = settings_handler.get_apic_offline_cache_settings() + if self.cache_enabled: + self.import_logs_to_cache() + return + + self.cache_settings = settings_handler.get_apic_cache_settings( + apic_name + ) + self.cache_enabled = self.cache_settings['enabled'] + self.cache_write_enabled = True + if no_cache: + self.cache_enabled = False + + if self.cache_enabled: + self.import_logs_to_cache() + + def import_logs_to_cache(self): + logs_directory = os.path.join( + self.cache_directory, + 'log' + ) + + if not os.path.isdir(logs_directory): + return + + for name in os.listdir(logs_directory): + object_name = name[8:].split('.')[0] + object_selector = None + if len(name[8:].split('.')) > 1: + object_selector = '.'.join(name[8:].split('.')[1:]) + + filename = os.path.join( + logs_directory, + name + ) + + if not name.startswith('apic.mo.'): + print('Remove non apic.mo. file: %s' % (filename)) + os.remove(filename) + continue + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + print('Remove file on failed json load: %s' % (filename)) + os.remove(filename) + continue + + print('Import cache: %s from file %s' % (object_name, filename)) + success = self.set_object_cache( + object_name, + content, + object_selector=object_selector, + enforce=True + ) + + if not success: + print('Import failed') + + os.remove(filename) + + def is_cache_enabled(self): + return self.cache_enabled + + def is_object_cache_enabled(self, object_name): + if not self.is_cache_enabled(): + return False + + if object_name not in self.cache_settings['object']: + return True + + return self.cache_settings['object'][object_name]['enabled'] + + def get_object_cache_filename(self, object_name): + filename = os.path.join( + self.cache_directory, + object_name + ) + return filename + + def get_object_cache_ttl(self, object_name): + if object_name in self.cache_settings['object']: + return self.cache_settings['object'][object_name]['ttl'] + + return self.cache_settings['ttl'] + + def get_object_cache(self, object_name, object_selector=None): + if not self.is_cache_enabled(): + return None + + filename = self.get_object_cache_filename(object_name) + if filename is None: + return None + + if object_selector is not None: + filename = '%s.%s' % (filename, object_selector) + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + return None + + ttl = self.get_object_cache_ttl(object_name) + age = int(time.time()) - content['timestamp'] + if ttl > 0: + if age > ttl: + return None + + self.log.cache_hit( + 'aci', + self.apic_name, + object_name, + filename, + ttl, + age + ) + + return content['cache'] + + def set_object_cache(self, object_name, cache, object_selector=None, enforce=False): + if not self.cache_write_enabled: + if not enforce: + return False + + filename = self.get_object_cache_filename(object_name) + if filename is None: + return False + + if not os.path.isdir(self.cache_directory): + os.makedirs(self.cache_directory, exist_ok=True) + + content = {} + content['object'] = object_name + content['selector'] = object_selector + content['timestamp'] = int(time.time()) + content['cache'] = cache + + if object_selector is not None: + object_selector = object_selector.replace('/', '_') + filename = '%s.%s' % (filename, object_selector) + + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(content, indent=4)) + + except BaseException: + self.log.error( + 'apic.set_object_cache', + 'Set cache failed: %s %s %s %s' % ( + self.apic_name, + object_name, + object_selector, + filename + ) + ) + return False + + return True + + def get_cache_stats(self): + info = [] + + if not os.path.isdir(self.cache_directory): + return info + + for name in os.listdir(self.cache_directory): + filename = os.path.join( + self.cache_directory, name + ) + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + cache_item = {} + cache_item['__Output'] = {} + cache_item['object'] = content['object'] + cache_item['selector'] = content['selector'] + if cache_item['selector'] is None: + cache_item['selector'] = '' + + cache_item['ttl'] = self.get_object_cache_ttl( + content['object'] + ) + if cache_item['ttl'] <= 0: + cache_item['ttlT'] = '--' + else: + cache_item['ttlT'] = '{}'.format(str(timedelta(seconds=cache_item['ttl']))) + + cache_item['age'] = int(time.time()) - content['timestamp'] + cache_item['ageT'] = '{}'.format(str(timedelta(seconds=cache_item['age']))) + + cache_item['valid'] = True + cache_item['validTick'] = '\u2713' + cache_item['__Output']['validTick'] = 'Green' + if cache_item['ttl'] > 0: + if cache_item['age'] > cache_item['ttl']: + cache_item['valid'] = False + cache_item['validTick'] = '\u2717' + cache_item['__Output']['validTick'] = 'Red' + + info.append( + cache_item + ) + + except BaseException: + pass + + info = sorted( + info, + key=lambda i: ( + i['object'], + i['selector'] + ) + ) + + return info + + def clear_cache(self, bar_enabled=False): + if not os.path.isdir(self.cache_directory): + return True + + names = os.listdir(self.cache_directory) + if bar_enabled: + bar_handler = Bar('Cache Files', max=len(names)) + + for name in names: + filename = os.path.join( + self.cache_directory, name + ) + os.remove(filename) + if bar_enabled: + bar_handler.next() + + if bar_enabled: + bar_handler.finish() + + return True diff --git a/lib/aci/common.py b/lib/aci/common.py new file mode 100644 index 00000000..760935b2 --- /dev/null +++ b/lib/aci/common.py @@ -0,0 +1,85 @@ +class Common(): + def __init__(self): + pass + + def get_health_info(self, value): + try: + ivalue = int(value) + except BaseException: + return None, value + + if ivalue >= 75: + return 'Green', value + + if ivalue >= 50: + return 'Magenta', value + + return 'Red', value + + def is_any_fault(self, faults): + for key in ['crit', 'maj', 'minor', 'warn']: + if faults[key] != '0': + return True + return False + + def get_faults_info(self, faults): + # "childAction": "", + # "crit": "0", + # "critAcked": "0", + # "critAckedandDelegated": "0", + # "critDelegated": "0", + # "maj": "0", + # "majAcked": "0", + # "majAckedandDelegated": "0", + # "majDelegated": "0", + # "minor": "0", + # "minorAcked": "0", + # "minorAckedandDelegated": "0", + # "minorDelegated": "0", + # "rn": "fltCnts", + # "status": "", + # "warn": "0", + # "warnAcked": "0", + # "warnAckedandDelegated": "0", + # "warnDelegated": "0" + + info = '' + color = ':' + + info = '%s%s' % ( + info, + faults['crit'] + ) + color = '%s%s' % ( + color, + ''.rjust(len(str(faults['crit'])), 'R') + ) + + info = '%s %s' % ( + info, + faults['maj'] + ) + color = '%s.%s' % ( + color, + ''.rjust(len(str(faults['maj'])), 'M') + ) + + info = '%s %s' % ( + info, + faults['minor'] + ) + color = '%s.%s' % ( + color, + ''.rjust(len(str(faults['minor'])), 'Y') + ) + + info = '%s %s' % ( + info, + faults['warn'] + ) + color = '%s.%s' % ( + color, + ''.rjust(len(str(faults['warn'])), 'G') + ) + + return color, info diff --git a/lib/aci/context.py b/lib/aci/context.py new file mode 100644 index 00000000..c5cc4367 --- /dev/null +++ b/lib/aci/context.py @@ -0,0 +1,45 @@ +class Context(): + def __init__(self): + pass + + def get_context_server_connectivity_interface(self, servers_connectivity_info): + interfaces = [] + + for server_connectivity_info in servers_connectivity_info: + if 'MacAddressInfo' not in server_connectivity_info: + continue + + for mac_address_info in server_connectivity_info['MacAddressInfo']: + if mac_address_info['endpoint'] is not None: + for fabric_info in mac_address_info['endpoint']['fabric']: + interface_label = 'aci:%s:pod-%s:node-%s:%s' % ( + mac_address_info['endpoint']['apic'], + fabric_info['pod_id'], + fabric_info['node_id'], + fabric_info['port_id'] + ) + if interface_label not in interfaces: + interfaces.append(interface_label) + + if mac_address_info['lacp'] is not None: + for lacp_info in mac_address_info['lacp']: + interface_label = 'aci:%s:pod-%s:node-%s:%s' % ( + lacp_info['apic'], + lacp_info['podId'], + lacp_info['nodeId'], + lacp_info['id'] + ) + if interface_label not in interfaces: + interfaces.append(interface_label) + + if mac_address_info['adjacency'] is not None: + interface_label = 'aci:%s:%s:%s:%s' % ( + mac_address_info['adjacency']['apic'], + mac_address_info['adjacency']['pod_id'], + mac_address_info['adjacency']['node_id'], + mac_address_info['adjacency']['interface_id'] + ) + if interface_label not in interfaces: + interfaces.append(interface_label) + + return interfaces diff --git a/lib/aci/contract/__init__.py b/lib/aci/contract/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/__pycache__/__init__.cpython-310.pyc b/lib/aci/contract/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..eb6c3410 Binary files /dev/null and b/lib/aci/contract/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/contract/__pycache__/api.cpython-310.pyc b/lib/aci/contract/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..ba6113e7 Binary files /dev/null and b/lib/aci/contract/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/contract/__pycache__/info.cpython-310.pyc b/lib/aci/contract/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ca06b964 Binary files /dev/null and b/lib/aci/contract/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/contract/__pycache__/main.cpython-310.pyc b/lib/aci/contract/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c07d558f Binary files /dev/null and b/lib/aci/contract/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/contract/__pycache__/output.cpython-310.pyc b/lib/aci/contract/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..94c24d23 Binary files /dev/null and b/lib/aci/contract/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/contract/filter/__init__.py b/lib/aci/contract/filter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/filter/__pycache__/__init__.cpython-310.pyc b/lib/aci/contract/filter/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..eb6c3410 Binary files /dev/null and b/lib/aci/contract/filter/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/contract/filter/__pycache__/api.cpython-310.pyc b/lib/aci/contract/filter/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c5c76cb5 Binary files /dev/null and b/lib/aci/contract/filter/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/contract/filter/__pycache__/info.cpython-310.pyc b/lib/aci/contract/filter/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..bd1778a4 Binary files /dev/null and b/lib/aci/contract/filter/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/contract/filter/__pycache__/main.cpython-310.pyc b/lib/aci/contract/filter/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..981251c5 Binary files /dev/null and b/lib/aci/contract/filter/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/contract/filter/__pycache__/output.cpython-310.pyc b/lib/aci/contract/filter/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..f36459cf Binary files /dev/null and b/lib/aci/contract/filter/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/contract/filter/api.py b/lib/aci/contract/filter/api.py new file mode 100644 index 00000000..e79dff8b --- /dev/null +++ b/lib/aci/contract/filter/api.py @@ -0,0 +1,60 @@ +class ContractFilterApi(): + def __init__(self): + self.contract_filter_mo = None + + def get_contract_filters_mo(self): + if self.contract_filter_mo is not None: + return self.contract_filter_mo + + cache = self.get_object_cache( + 'vzFilter' + ) + if cache is not None: + self.contract_filter_mo = cache + self.log.apic_mo( + 'vzFilter', + self.contract_filter_mo + ) + return self.contract_filter_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=vzEntry' + managed_objects = self.get_class( + 'vzFilter', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_contract_filters_mo', + 'API failed' + ) + return None + + self.contract_filter_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vzFilter']['attributes'] + attributes['vzEntry'] = self.get_mo_children_attributes( + 'vzFilter', + managed_object, + 'vzEntry' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vzFilter', + managed_object, + 'faultCounts' + ) + self.contract_filter_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzFilter', + self.contract_filter_mo + ) + + self.set_object_cache( + 'vzFilter', + self.contract_filter_mo + ) + + return self.contract_filter_mo diff --git a/lib/aci/contract/filter/audit/__init__.py b/lib/aci/contract/filter/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/filter/audit/api.py b/lib/aci/contract/filter/audit/api.py new file mode 100644 index 00000000..e81d4224 --- /dev/null +++ b/lib/aci/contract/filter/audit/api.py @@ -0,0 +1,48 @@ +class ContractFilterAuditApi(): + def __init__(self): + self.filter_contract_audit_mo = None + + def get_filter_contract_audit_mo(self): + cache = self.get_object_cache( + 'vzFilter.audit' + ) + if cache is not None: + self.filter_contract_audit_mo = cache + self.log.apic_mo( + 'vzFilter.audit', + self.filter_contract_audit_mo + ) + return self.filter_contract_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'vzFilter', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_filter_contract_audit_mo', + 'API failed' + ) + return None + + self.filter_contract_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.filter_contract_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzFilter.audit', + self.filter_contract_audit_mo + ) + + self.set_object_cache( + 'vzFilter.audit', + self.filter_contract_audit_mo + ) + + return self.filter_contract_audit_mo diff --git a/lib/aci/contract/filter/audit/info.py b/lib/aci/contract/filter/audit/info.py new file mode 100644 index 00000000..218a3b45 --- /dev/null +++ b/lib/aci/contract/filter/audit/info.py @@ -0,0 +1,110 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractFilterAuditInfo(): + def __init__(self): + self.filter_contract_audit = None + + def get_filter_contract_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['filterName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/filter-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/flt-' in info['affected']: + info['filterName'] = info['affected'].split('/flt-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['filterName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['filterName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_filter_contract_audit(self): + if self.filter_contract_audit is not None: + return self.filter_contract_audit + + managed_objects = self.get_filter_contract_audit_mo() + if managed_objects is None: + return None + + self.filter_contract_audit = [] + for managed_object in managed_objects: + audit_info = self.get_filter_contract_audit_info( + managed_object + ) + self.filter_contract_audit.append( + audit_info + ) + + self.log.apic_mo( + 'vzFilter.auditRecord.info', + self.filter_contract_audit + ) + + return self.filter_contract_audit + + def get_filter_contract_id_audit(self, tenant_name, filter_name, audit_filter=None): + audits = [] + + all_audits = self.get_filter_contract_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['filterName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['filterName'] == filter_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/contract/filter/audit/main.py b/lib/aci/contract/filter/audit/main.py new file mode 100644 index 00000000..576579dc --- /dev/null +++ b/lib/aci/contract/filter/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.filter.audit.api import ContractFilterAuditApi +from lib.aci.contract.filter.audit.info import ContractFilterAuditInfo + + +class ContractFilterAudit(ContractFilterAuditApi, ContractFilterAuditInfo): + def __init__(self): + ContractFilterAuditApi.__init__(self) + ContractFilterAuditInfo.__init__(self) diff --git a/lib/aci/contract/filter/event/__init__.py b/lib/aci/contract/filter/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/filter/event/api.py b/lib/aci/contract/filter/event/api.py new file mode 100644 index 00000000..9224f980 --- /dev/null +++ b/lib/aci/contract/filter/event/api.py @@ -0,0 +1,51 @@ +class ContractFilterEventApi(): + def __init__(self): + self.filter_contract_event_mo = None + + def get_filter_contract_event_mo(self): + if self.filter_contract_event_mo is not None: + return self.filter_contract_event_mo + + cache = self.get_object_cache( + 'vzFilter.eventLog' + ) + if cache is not None: + self.filter_contract_event_mo = cache + self.log.apic_mo( + 'vzFilter.eventLog', + self.filter_contract_event_mo + ) + return self.filter_contract_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'vzFilter', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_filter_contract_event_mo', + 'API failed' + ) + return None + + self.filter_contract_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.filter_contract_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzFilter.eventLog', + self.filter_contract_event_mo + ) + + self.set_object_cache( + 'vzFilter.eventLog', + self.filter_contract_event_mo + ) + + return self.filter_contract_event_mo diff --git a/lib/aci/contract/filter/event/info.py b/lib/aci/contract/filter/event/info.py new file mode 100644 index 00000000..b83a367f --- /dev/null +++ b/lib/aci/contract/filter/event/info.py @@ -0,0 +1,124 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractFilterEventInfo(): + def __init__(self): + self.filter_contract_event = None + + def get_filter_contract_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['filterName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/flt-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/flt-' in info['affected']: + info['filterName'] = info['affected'].split('/flt-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/flt-BT-Demo + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/flt-' in info['dn']: + info['filterName'] = info['dn'].split('/flt-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['filterName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['filterName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_filter_contract_event(self, deduplicate=True): + if self.filter_contract_event is not None: + return self.filter_contract_event + + managed_objects = self.get_filter_contract_event_mo() + if managed_objects is None: + return None + + self.filter_contract_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_filter_contract_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.filter_contract_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'vzFilter.eventLog.info', + self.filter_contract_event + ) + + return self.filter_contract_event + + def get_filter_contract_id_event(self, tenant_name, filter_name, event_filter=None): + events = [] + + all_events = self.get_filter_contract_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['filterName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['filterName'] == filter_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/contract/filter/event/main.py b/lib/aci/contract/filter/event/main.py new file mode 100644 index 00000000..e1fe22f1 --- /dev/null +++ b/lib/aci/contract/filter/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.filter.event.api import ContractFilterEventApi +from lib.aci.contract.filter.event.info import ContractFilterEventInfo + + +class ContractFilterEvent(ContractFilterEventApi, ContractFilterEventInfo): + def __init__(self): + ContractFilterEventApi.__init__(self) + ContractFilterEventInfo.__init__(self) diff --git a/lib/aci/contract/filter/fault/__init__.py b/lib/aci/contract/filter/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/filter/fault/api.py b/lib/aci/contract/filter/fault/api.py new file mode 100644 index 00000000..094034fb --- /dev/null +++ b/lib/aci/contract/filter/fault/api.py @@ -0,0 +1,118 @@ +class ContractFilterFaultApi(): + def __init__(self): + self.filter_contract_fault_mo = None + self.filter_contract_fault_record_mo = None + + def get_filter_contract_fault_mo(self): + cache = self.get_object_cache( + 'vzFilter.fault' + ) + if cache is not None: + self.filter_contract_fault_mo = cache + self.log.apic_mo( + 'vzFilter.fault', + self.filter_contract_fault_mo + ) + return self.filter_contract_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'vzFilter', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_filter_contract_fault_mo', + 'API failed' + ) + return None + + self.filter_contract_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.filter_contract_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.filter_contract_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzFilter.fault', + self.filter_contract_fault_mo + ) + + self.set_object_cache( + 'vzFilter.fault', + self.filter_contract_fault_mo + ) + + return self.filter_contract_fault_mo + + def get_filter_contract_fault_record_mo(self): + cache = self.get_object_cache( + 'vzFilter.faultRecord' + ) + if cache is not None: + self.filter_contract_fault_record_mo = cache + self.log.apic_mo( + 'vzFilter.faultRecord', + self.filter_contract_fault_record_mo + ) + return self.filter_contract_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'vzFilter', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_filter_contract_fault_record_mo', + 'API failed' + ) + return None + + self.filter_contract_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.filter_contract_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.filter_contract_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzFilter.faultRecord', + self.filter_contract_fault_record_mo + ) + + self.set_object_cache( + 'vzFilter.faultRecord', + self.filter_contract_fault_record_mo + ) + + return self.filter_contract_fault_record_mo diff --git a/lib/aci/contract/filter/fault/info.py b/lib/aci/contract/filter/fault/info.py new file mode 100644 index 00000000..c8092407 --- /dev/null +++ b/lib/aci/contract/filter/fault/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractFilterFaultInfo(): + def __init__(self): + self.filter_contract_fault = None + self.filter_contract_fault_record = None + + def get_filter_contract_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['filterName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/flt-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/flt-' in info['affected']: + info['filterName'] = info['affected'].split('/flt-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/flt-BT-Demo + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/flt-' in info['dn']: + info['filterName'] = info['dn'].split('/flt-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['filterName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['filterName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_filter_contract_fault(self): + if self.filter_contract_fault is not None: + return self.filter_contract_fault + + managed_objects = self.get_filter_contract_fault_mo() + if managed_objects is None: + return None + + self.filter_contract_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_filter_contract_fault_info( + managed_object + ) + self.filter_contract_fault.append( + fault_info + ) + + self.log.apic_mo( + 'vzFilter.fault.info', + self.filter_contract_fault + ) + + return self.filter_contract_fault + + def get_filter_contract_fault_record(self, deduplicate=True): + if self.filter_contract_fault_record is not None: + return self.filter_contract_fault_record + + managed_objects = self.get_filter_contract_fault_record_mo() + if managed_objects is None: + return None + + self.filter_contract_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_filter_contract_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.filter_contract_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'vzFilter.faultRecord.info', + self.filter_contract_fault_record + ) + + return self.filter_contract_fault_record + + def get_filter_contract_id_fault(self, tenant_name, filter_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_filter_contract_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_filter_contract_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['filterName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['filterName'] == filter_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/contract/filter/fault/main.py b/lib/aci/contract/filter/fault/main.py new file mode 100644 index 00000000..e87ae43c --- /dev/null +++ b/lib/aci/contract/filter/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.filter.fault.api import ContractFilterFaultApi +from lib.aci.contract.filter.fault.info import ContractFilterFaultInfo + + +class ContractFilterFault(ContractFilterFaultApi, ContractFilterFaultInfo): + def __init__(self): + ContractFilterFaultApi.__init__(self) + ContractFilterFaultInfo.__init__(self) diff --git a/lib/aci/contract/filter/info.py b/lib/aci/contract/filter/info.py new file mode 100644 index 00000000..d9609f84 --- /dev/null +++ b/lib/aci/contract/filter/info.py @@ -0,0 +1,270 @@ +from lib import filter_helper + + +class ContractFilterInfo(): + def __init__(self): + self.contract_filter = None + + def get_contract_filter_count(self, tenant_name=None): + filter_filter = None + if tenant_name is not None: + filter_filter = ['tenant:%s' % (tenant_name)] + + filters = self.get_contract_filters( + filter_filter=filter_filter + ) + return len(filters) + + def get_contract_filter(self, tenant, name): + filter_filter = [] + filter_filter.append( + 'tenant:%s' % (tenant) + ) + filter_filter.append( + 'name:%s' % (name) + ) + + filters = self.get_contract_filters( + filter_filter=filter_filter + ) + + if len(filters) == 1: + return filters[0] + + return None + + def get_contract_filter_entry_info(self, managed_object): + keys = [ + 'applyToFrag', + 'arpOpc', + 'dFromPort', + 'dToPort', + 'descr', + 'etherT', + 'icmpv4T', + 'icmpv6T', + 'matchDscp', + 'name', + 'prot', + 'sFromPort', + 'sToPort', + 'stateful', + 'status', + 'tcpRules' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['source'] = '' + if info['sFromPort'] != 'unspecified' and info['sToPort'] != 'unspecified': + info['source'] = '%s - %s' % ( + info['sFromPort'], + info['sToPort'] + ) + + info['destination'] = '' + if info['dFromPort'] != 'unspecified' and info['dToPort'] != 'unspecified': + info['destination'] = '%s - %s' % ( + info['dFromPort'], + info['dToPort'] + ) + + for key in ['etherT', 'arpOpc', 'prot']: + if info[key] == 'unspecified': + info[key] = '' + + return info + + def get_contract_filter_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + info['vzEntry'] = [] + for entry_mo in managed_object['vzEntry']: + info['vzEntry'].append( + self.get_contract_filter_entry_info( + entry_mo + ) + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_contract_filters_info(self): + if self.contract_filter is None: + self.contract_filter = [] + + filters = self.get_contract_filters_mo() + if filters is not None: + for managed_object in filters: + self.contract_filter.append( + self.get_contract_filter_info( + managed_object + ) + ) + + return self.contract_filter + + def match_contract_filter(self, filter_info, filter_filter): + if filter_filter is None or len(filter_filter) == 0: + return True + + for filter_rule in filter_filter: + (key, value) = filter_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, filter_info['nameTenant']): + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, filter_info['tenant']): + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not filter_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_contract_filter', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_contract_filter', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_contract_filter_usage_info(self, filter_info): + filter_filter = ['filter:%s' % (filter_info['nameTenant'])] + + filter_info['taboo'] = [] + + contracts = self.get_contract_filters( + filter_filter=filter_filter + ) + if contracts is not None: + for contract in contracts: + filter_info['taboo'].append( + contract['nameTenant'] + ) + + filter_info['contract'] = [] + + contracts = self.get_standard_contracts( + contract_filter=filter_filter + ) + if contracts is not None: + for contract in contracts: + filter_info['contract'].append( + contract['nameTenant'] + ) + + return filter_info + + def get_contract_filters( + self, + filter_filter=None, + usage_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_filters = self.get_contract_filters_info() + if all_filters is None: + return None + + filters = [] + + for filter_info in all_filters: + if not self.match_contract_filter(filter_info, filter_filter): + continue + + if usage_info: + filter_info = self.get_contract_filter_usage_info(filter_info) + + if fault_info: + filter_info['faultInst'] = self.get_filter_contract_id_fault( + filter_info['tenant'], + filter_info['name'], + 'faultInst' + ) + + if hfault_info: + filter_info['faultRecord'] = self.get_filter_contract_id_fault( + filter_info['tenant'], + filter_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + filter_info['eventLog'] = self.get_filter_contract_id_event( + filter_info['tenant'], + filter_info['name'], + event_filter=event_filter + ) + + if audit_info: + filter_info['auditLog'] = self.get_filter_contract_id_audit( + filter_info['tenant'], + filter_info['name'], + audit_filter=audit_filter + ) + + filters.append(filter_info) + + filters = sorted( + filters, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'vzFilter.info', + filters + ) + + return filters diff --git a/lib/aci/contract/filter/main.py b/lib/aci/contract/filter/main.py new file mode 100644 index 00000000..05f4028b --- /dev/null +++ b/lib/aci/contract/filter/main.py @@ -0,0 +1,20 @@ +from lib.aci.contract.filter.api import ContractFilterApi +from lib.aci.contract.filter.info import ContractFilterInfo +from lib.aci.contract.filter.audit.main import ContractFilterAudit +from lib.aci.contract.filter.event.main import ContractFilterEvent +from lib.aci.contract.filter.fault.main import ContractFilterFault + + +class ContractFilter( + ContractFilterApi, + ContractFilterInfo, + ContractFilterAudit, + ContractFilterEvent, + ContractFilterFault + ): + def __init__(self): + ContractFilterApi.__init__(self) + ContractFilterInfo.__init__(self) + ContractFilterAudit.__init__(self) + ContractFilterEvent.__init__(self) + ContractFilterFault.__init__(self) diff --git a/lib/aci/contract/filter/output.py b/lib/aci/contract/filter/output.py new file mode 100644 index 00000000..02fdcbc2 --- /dev/null +++ b/lib/aci/contract/filter/output.py @@ -0,0 +1,304 @@ +class ContractFilterOutput(): + def __init__(self): + pass + + def print_contract_filters(self, info, title=False): + if title: + self.my_output.default( + 'Contract Filter [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'vzEntry.name', + 'vzEntry.etherT', + 'vzEntry.arpOpc', + 'vzEntry.prot', + 'vzEntry.applyToFrag', + 'vzEntry.stateful', + 'vzEntry.source', + 'vzEntry.destination', + 'vzEntry.tcpRules' + ] + + headers = [ + 'Faults', + 'Filter', + 'Entry', + 'Ether', + 'ARP Flag', + 'Proto', + 'Fragments', + 'Stateful', + 'Source', + 'Destination', + 'Rules' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vzEntry'] + ), + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + def print_contract_filters_usage(self, info, title=False): + if title: + self.my_output.default( + 'Contract Filter - Usage [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'contract', + 'taboo' + ] + + headers = [ + 'Faults', + 'Filter', + 'Contract', + 'Taboo' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['contract', 'taboo'] + ), + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + def print_contract_filters_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Contract Filter - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Contract Filter - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Contract Filter', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_contract_filters_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Contract Filter - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Contract Filter', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_contract_filters_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Contract Filter - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Contract Filter - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Contract Filter', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_contract_filters_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Contract Filter - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Contract Filter - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Contract Filter', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/contract/main.py b/lib/aci/contract/main.py new file mode 100644 index 00000000..aca2798a --- /dev/null +++ b/lib/aci/contract/main.py @@ -0,0 +1,14 @@ +from lib.aci.contract.standard.main import ContractStandard +from lib.aci.contract.filter.main import ContractFilter +from lib.aci.contract.taboo.main import ContractTaboo + + +class Contract( + ContractStandard, + ContractFilter, + ContractTaboo, + ): + def __init__(self): + ContractStandard.__init__(self) + ContractFilter.__init__(self) + ContractTaboo.__init__(self) diff --git a/lib/aci/contract/output.py b/lib/aci/contract/output.py new file mode 100644 index 00000000..7f005093 --- /dev/null +++ b/lib/aci/contract/output.py @@ -0,0 +1,10 @@ +from lib.aci.contract.standard.output import ContractStandardOutput +from lib.aci.contract.filter.output import ContractFilterOutput +from lib.aci.contract.taboo.output import ContractTabooOutput + + +class ContractOutput(ContractStandardOutput, ContractFilterOutput, ContractTabooOutput): + def __init__(self): + ContractStandardOutput.__init__(self) + ContractFilterOutput.__init__(self) + ContractTabooOutput.__init__(self) diff --git a/lib/aci/contract/standard/__init__.py b/lib/aci/contract/standard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/standard/api.py b/lib/aci/contract/standard/api.py new file mode 100644 index 00000000..f469aaa1 --- /dev/null +++ b/lib/aci/contract/standard/api.py @@ -0,0 +1,70 @@ +class ContractStandardApi(): + def __init__(self): + self.standard_contract_mo = None + + def get_standard_contract_mo(self): + if self.standard_contract_mo is not None: + return self.standard_contract_mo + + cache = self.get_object_cache( + 'vzBrCP' + ) + if cache is not None: + self.standard_contract_mo = cache + self.log.apic_mo( + 'vzBrCP', + self.standard_contract_mo + ) + return self.standard_contract_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=vzSubj,vzRtCons,vzRtProv' + managed_objects = self.get_class( + 'vzBrCP', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_standard_contract_mo', + 'API failed' + ) + return None + + self.standard_contract_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vzBrCP']['attributes'] + attributes['vzSubj'] = self.get_mo_children_attributes( + 'vzBrCP', + managed_object, + 'vzSubj' + ) + attributes['vzRtCons'] = self.get_mo_children_attributes( + 'vzBrCP', + managed_object, + 'vzRtCons' + ) + attributes['vzRtProv'] = self.get_mo_children_attributes( + 'vzBrCP', + managed_object, + 'vzRtProv' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vzBrCP', + managed_object, + 'faultCounts' + ) + self.standard_contract_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzBrCP', + self.standard_contract_mo + ) + + self.set_object_cache( + 'vzBrCP', + self.standard_contract_mo + ) + + return self.standard_contract_mo diff --git a/lib/aci/contract/standard/audit/__init__.py b/lib/aci/contract/standard/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/standard/audit/api.py b/lib/aci/contract/standard/audit/api.py new file mode 100644 index 00000000..826da5d4 --- /dev/null +++ b/lib/aci/contract/standard/audit/api.py @@ -0,0 +1,48 @@ +class ContractStandardAuditApi(): + def __init__(self): + self.standard_contract_audit_mo = None + + def get_standard_contract_audit_mo(self): + cache = self.get_object_cache( + 'vzBrCP.audit' + ) + if cache is not None: + self.standard_contract_audit_mo = cache + self.log.apic_mo( + 'vzBrCP.audit', + self.standard_contract_audit_mo + ) + return self.standard_contract_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'vzBrCP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_standard_contract_audit_mo', + 'API failed' + ) + return None + + self.standard_contract_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.standard_contract_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzBrCP.audit', + self.standard_contract_audit_mo + ) + + self.set_object_cache( + 'vzBrCP.audit', + self.standard_contract_audit_mo + ) + + return self.standard_contract_audit_mo diff --git a/lib/aci/contract/standard/audit/info.py b/lib/aci/contract/standard/audit/info.py new file mode 100644 index 00000000..1d113977 --- /dev/null +++ b/lib/aci/contract/standard/audit/info.py @@ -0,0 +1,110 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractStandardAuditInfo(): + def __init__(self): + self.standard_contract_audit = None + + def get_standard_contract_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['contractName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/brc-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/brc-' in info['affected']: + info['contractName'] = info['affected'].split('/brc-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['contractName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['contractName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_standard_contract_audit(self): + if self.standard_contract_audit is not None: + return self.standard_contract_audit + + managed_objects = self.get_standard_contract_audit_mo() + if managed_objects is None: + return None + + self.standard_contract_audit = [] + for managed_object in managed_objects: + audit_info = self.get_standard_contract_audit_info( + managed_object + ) + self.standard_contract_audit.append( + audit_info + ) + + self.log.apic_mo( + 'vzBrCP.auditRecord.info', + self.standard_contract_audit + ) + + return self.standard_contract_audit + + def get_standard_contract_id_audit(self, tenant_name, contract_name, audit_filter=None): + audits = [] + + all_audits = self.get_standard_contract_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['contractName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['contractName'] == contract_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/contract/standard/audit/main.py b/lib/aci/contract/standard/audit/main.py new file mode 100644 index 00000000..6c01a115 --- /dev/null +++ b/lib/aci/contract/standard/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.standard.audit.api import ContractStandardAuditApi +from lib.aci.contract.standard.audit.info import ContractStandardAuditInfo + + +class ContractStandardAudit(ContractStandardAuditApi, ContractStandardAuditInfo): + def __init__(self): + ContractStandardAuditApi.__init__(self) + ContractStandardAuditInfo.__init__(self) diff --git a/lib/aci/contract/standard/event/__init__.py b/lib/aci/contract/standard/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/standard/event/api.py b/lib/aci/contract/standard/event/api.py new file mode 100644 index 00000000..5b48dae8 --- /dev/null +++ b/lib/aci/contract/standard/event/api.py @@ -0,0 +1,51 @@ +class ContractStandardEventApi(): + def __init__(self): + self.standard_contract_event_mo = None + + def get_standard_contract_event_mo(self): + if self.standard_contract_event_mo is not None: + return self.standard_contract_event_mo + + cache = self.get_object_cache( + 'vzBrCP.eventLog' + ) + if cache is not None: + self.standard_contract_event_mo = cache + self.log.apic_mo( + 'vzBrCP.eventLog', + self.standard_contract_event_mo + ) + return self.standard_contract_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'vzBrCP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_standard_contract_event_mo', + 'API failed' + ) + return None + + self.standard_contract_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.standard_contract_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzBrCP.eventLog', + self.standard_contract_event_mo + ) + + self.set_object_cache( + 'vzBrCP.eventLog', + self.standard_contract_event_mo + ) + + return self.standard_contract_event_mo diff --git a/lib/aci/contract/standard/event/info.py b/lib/aci/contract/standard/event/info.py new file mode 100644 index 00000000..3f4afe7e --- /dev/null +++ b/lib/aci/contract/standard/event/info.py @@ -0,0 +1,124 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractStandardEventInfo(): + def __init__(self): + self.standard_contract_event = None + + def get_standard_contract_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['contractName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/brc-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/brc-' in info['affected']: + info['contractName'] = info['affected'].split('/brc-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/brc-BT-Demo + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/brc-' in info['dn']: + info['contractName'] = info['dn'].split('/brc-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['contractName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['contractName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_standard_contract_event(self, deduplicate=True): + if self.standard_contract_event is not None: + return self.standard_contract_event + + managed_objects = self.get_standard_contract_event_mo() + if managed_objects is None: + return None + + self.standard_contract_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_standard_contract_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.standard_contract_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'vzBrCP.eventLog.info', + self.standard_contract_event + ) + + return self.standard_contract_event + + def get_standard_contract_id_event(self, tenant_name, contract_name, event_filter=None): + events = [] + + all_events = self.get_standard_contract_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['contractName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['contractName'] == contract_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/contract/standard/event/main.py b/lib/aci/contract/standard/event/main.py new file mode 100644 index 00000000..a58a4b22 --- /dev/null +++ b/lib/aci/contract/standard/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.standard.event.api import ContractStandardEventApi +from lib.aci.contract.standard.event.info import ContractStandardEventInfo + + +class ContractStandardEvent(ContractStandardEventApi, ContractStandardEventInfo): + def __init__(self): + ContractStandardEventApi.__init__(self) + ContractStandardEventInfo.__init__(self) diff --git a/lib/aci/contract/standard/fault/__init__.py b/lib/aci/contract/standard/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/standard/fault/api.py b/lib/aci/contract/standard/fault/api.py new file mode 100644 index 00000000..479da925 --- /dev/null +++ b/lib/aci/contract/standard/fault/api.py @@ -0,0 +1,118 @@ +class ContractStandardFaultApi(): + def __init__(self): + self.standard_contract_fault_mo = None + self.standard_contract_fault_record_mo = None + + def get_standard_contract_fault_mo(self): + cache = self.get_object_cache( + 'vzBrCP.fault' + ) + if cache is not None: + self.standard_contract_fault_mo = cache + self.log.apic_mo( + 'vzBrCP.fault', + self.standard_contract_fault_mo + ) + return self.standard_contract_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'vzBrCP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_standard_contract_fault_mo', + 'API failed' + ) + return None + + self.standard_contract_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.standard_contract_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.standard_contract_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzBrCP.fault', + self.standard_contract_fault_mo + ) + + self.set_object_cache( + 'vzBrCP.fault', + self.standard_contract_fault_mo + ) + + return self.standard_contract_fault_mo + + def get_standard_contract_fault_record_mo(self): + cache = self.get_object_cache( + 'vzBrCP.faultRecord' + ) + if cache is not None: + self.standard_contract_fault_record_mo = cache + self.log.apic_mo( + 'vzBrCP.faultRecord', + self.standard_contract_fault_record_mo + ) + return self.standard_contract_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'vzBrCP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_standard_contract_fault_record_mo', + 'API failed' + ) + return None + + self.standard_contract_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.standard_contract_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.standard_contract_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzBrCP.faultRecord', + self.standard_contract_fault_record_mo + ) + + self.set_object_cache( + 'vzBrCP.faultRecord', + self.standard_contract_fault_record_mo + ) + + return self.standard_contract_fault_record_mo diff --git a/lib/aci/contract/standard/fault/info.py b/lib/aci/contract/standard/fault/info.py new file mode 100644 index 00000000..f6712848 --- /dev/null +++ b/lib/aci/contract/standard/fault/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractStandardFaultInfo(): + def __init__(self): + self.standard_contract_fault = None + self.standard_contract_fault_record = None + + def get_standard_contract_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['contractName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/brc-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/brc-' in info['affected']: + info['contractName'] = info['affected'].split('/brc-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/brc-BT-Demo + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/brc-' in info['dn']: + info['contractName'] = info['dn'].split('/brc-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['contractName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['contractName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_standard_contract_fault(self): + if self.standard_contract_fault is not None: + return self.standard_contract_fault + + managed_objects = self.get_standard_contract_fault_mo() + if managed_objects is None: + return None + + self.standard_contract_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_standard_contract_fault_info( + managed_object + ) + self.standard_contract_fault.append( + fault_info + ) + + self.log.apic_mo( + 'vzBrCP.fault.info', + self.standard_contract_fault + ) + + return self.standard_contract_fault + + def get_standard_contract_fault_record(self, deduplicate=True): + if self.standard_contract_fault_record is not None: + return self.standard_contract_fault_record + + managed_objects = self.get_standard_contract_fault_record_mo() + if managed_objects is None: + return None + + self.standard_contract_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_standard_contract_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.standard_contract_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'vzBrCP.faultRecord.info', + self.standard_contract_fault_record + ) + + return self.standard_contract_fault_record + + def get_standard_contract_id_fault(self, tenant_name, contract_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_standard_contract_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_standard_contract_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['contractName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['contractName'] == contract_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/contract/standard/fault/main.py b/lib/aci/contract/standard/fault/main.py new file mode 100644 index 00000000..db1373e8 --- /dev/null +++ b/lib/aci/contract/standard/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.standard.fault.api import ContractStandardFaultApi +from lib.aci.contract.standard.fault.info import ContractStandardFaultInfo + + +class ContractStandardFault(ContractStandardFaultApi, ContractStandardFaultInfo): + def __init__(self): + ContractStandardFaultApi.__init__(self) + ContractStandardFaultInfo.__init__(self) diff --git a/lib/aci/contract/standard/info.py b/lib/aci/contract/standard/info.py new file mode 100644 index 00000000..60d842e6 --- /dev/null +++ b/lib/aci/contract/standard/info.py @@ -0,0 +1,361 @@ +from lib import filter_helper + + +class ContractStandardInfo(): + def __init__(self): + self.standard_contract = None + + def get_standard_contract_count(self, tenant_name=None): + contract_filter = None + if tenant_name is not None: + contract_filter = ['tenant:%s' % (tenant_name)] + + contracts = self.get_standard_contracts( + contract_filter=contract_filter + ) + return len(contracts) + + def get_standard_contract(self, tenant, name): + contract_filter = [] + contract_filter.append( + 'tenant:%s' % (tenant) + ) + contract_filter.append( + 'name:%s' % (name) + ) + + contracts = self.get_standard_contracts( + contract_filter=contract_filter + ) + + if len(contracts) == 1: + return contracts[0] + + return None + + def get_standard_contract_epg_info(self, managed_object): + if managed_object['tCl'] not in ['fvAEPg', 'l2extInstP', 'l3extInstP', 'mgmtInB']: + self.log.error( + 'get_contract_epg_info', + 'Unsupported object class: %s' % (managed_object) + ) + return None + + if managed_object['tCl'] == 'fvAEPg': + # "tDn": "uni/tn-mgmt/ap-EU-SPDC_ANP/epg-EU-SPDC-MGMT" + info = {} + info['class'] = 'fvAEPg' + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['application_profile'] = managed_object['tDn'].split('/')[2][3:] + info['name'] = managed_object['tDn'].split('/')[3][4:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + info['nameLong'] = '%s/%s/%s' % ( + info['tenant'], + info['application_profile'], + info['name'] + ) + + if managed_object['tCl'] == 'l3extInstP': + # "tDn": "uni/tn-common/out-Infra_privIP_L3out/instP-Infra_privIP_ExtEPG" + info = {} + info['class'] = 'l3extInstP' + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['l3out'] = managed_object['tDn'].split('/')[2][4:] + info['name'] = managed_object['tDn'].split('/')[3][6:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + info['nameLong'] = '%s/%s/%s' % ( + info['tenant'], + info['l3out'], + info['name'] + ) + + if managed_object['tCl'] == 'l2extInstP': + # "tDn": "uni/tn-common/l2out-VNF-mgmt_L2out/instP-VNF-mgmt_L2ext" + info = {} + info['class'] = 'l2extInstP' + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['l3out'] = managed_object['tDn'].split('/')[2][4:] + info['name'] = managed_object['tDn'].split('/')[3][6:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + info['nameLong'] = '%s/%s/%s' % ( + info['tenant'], + info['l3out'], + info['name'] + ) + + if managed_object['tCl'] == 'mgmtInB': + # "tDn": "uni/tn-mgmt/mgmtp-default/inb-default" + info = {} + info['class'] = 'mgmtInB' + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['mgmt'] = managed_object['tDn'].split('/')[2][6:] + info['name'] = managed_object['tDn'].split('/')[3][4:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + info['nameLong'] = '%s/%s/%s' % ( + info['tenant'], + info['mgmt'], + info['name'] + ) + + return info + + def get_standard_contract_filters_info(self, managed_object): + info = [] + for item in managed_object['vzSubj']: + subject_name = item['name'] + subject_tenant = managed_object['dn'].split('/')[1][3:] + subject_info = self.get_subject( + subject_tenant, + subject_name + ) + if subject_info is None: + continue + + for filter_item in subject_info['vzFilter']: + filter_tenant = filter_item['tenant'] + if len(filter_tenant) == 0: + filter_tenant = subject_tenant + + filter_info = self.get_contract_filter( + filter_tenant, + filter_item['name'] + ) + if filter_info is None: + self.log.error( + 'get_standard_contract_filters_info', + 'Filter not found: %s/%s' % ( + filter_tenant, + filter_item['name'] + ) + ) + self.log.error( + 'get_standard_contract_filters_info', + subject_info + ) + self.log.error( + 'get_standard_contract_filters_info', + managed_object + ) + continue + + filter_info['subjectName'] = subject_name + filter_info['subjectTenant'] = subject_tenant + filter_info['subjectNameTenant'] = '%s/%s' % ( + subject_tenant, + subject_name + ) + info.append( + filter_info + ) + + return info + + def get_standard_contract_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'intent', + 'name', + 'scope', + 'targetDscp', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + info['vzFilter'] = self.get_standard_contract_filters_info( + managed_object + ) + + info['consumerEpg'] = [] + for item in managed_object['vzRtCons']: + contract_epg_info = self.get_standard_contract_epg_info( + item + ) + if contract_epg_info is not None: + info['consumerEpg'].append( + contract_epg_info + ) + + info['providerEpg'] = [] + for item in managed_object['vzRtProv']: + contract_epg_info = self.get_standard_contract_epg_info( + item + ) + if contract_epg_info is not None: + info['providerEpg'].append( + contract_epg_info + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_standard_contracts_info(self): + if self.standard_contract is None: + self.standard_contract = [] + + contracts = self.get_standard_contract_mo() + if contracts is not None: + for managed_object in contracts: + self.standard_contract.append( + self.get_standard_contract_info( + managed_object + ) + ) + + return self.standard_contract + + def match_standard_contract(self, contract_info, contract_filter): + if contract_filter is None or len(contract_filter) == 0: + return True + + for contract_rule in contract_filter: + (key, value) = contract_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, contract_info['nameTenant']): + return False + + if key == 'names': + key_found = True + found = False + for name in value.split(','): + if filter_helper.match_tenant_name(name, contract_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, contract_info['tenant']): + return False + + if key == 'filter': + key_found = True + found = False + for filter_info in contract_info['vzFilter']: + if filter_helper.match_tenant_name(value, filter_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not contract_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_standard_contract', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_standard_contract', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_standard_contracts( + self, + contract_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_contracts = self.get_standard_contracts_info() + if all_contracts is None: + return None + + contracts = [] + + for contract_info in all_contracts: + if not self.match_standard_contract(contract_info, contract_filter): + continue + + if fault_info: + contract_info['faultInst'] = self.get_standard_contract_id_fault( + contract_info['tenant'], + contract_info['name'], + 'faultInst' + ) + + if hfault_info: + contract_info['faultRecord'] = self.get_standard_contract_id_fault( + contract_info['tenant'], + contract_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + contract_info['eventLog'] = self.get_standard_contract_id_event( + contract_info['tenant'], + contract_info['name'], + event_filter=event_filter + ) + + if audit_info: + contract_info['auditLog'] = self.get_standard_contract_id_audit( + contract_info['tenant'], + contract_info['name'], + audit_filter=audit_filter + ) + + contracts.append(contract_info) + + contracts = sorted( + contracts, + key=lambda i: i['nameTenant'].lower() + ) + + self.log.apic_mo( + 'vzBrCP.info', + contracts + ) + + return contracts diff --git a/lib/aci/contract/standard/main.py b/lib/aci/contract/standard/main.py new file mode 100644 index 00000000..b15dc829 --- /dev/null +++ b/lib/aci/contract/standard/main.py @@ -0,0 +1,23 @@ +from lib.aci.contract.standard.api import ContractStandardApi +from lib.aci.contract.standard.info import ContractStandardInfo +from lib.aci.contract.standard.subject.main import ContractSubject +from lib.aci.contract.standard.audit.main import ContractStandardAudit +from lib.aci.contract.standard.event.main import ContractStandardEvent +from lib.aci.contract.standard.fault.main import ContractStandardFault + + +class ContractStandard( + ContractStandardApi, + ContractStandardInfo, + ContractSubject, + ContractStandardAudit, + ContractStandardEvent, + ContractStandardFault + ): + def __init__(self): + ContractStandardApi.__init__(self) + ContractStandardInfo.__init__(self) + ContractSubject.__init__(self) + ContractStandardAudit.__init__(self) + ContractStandardEvent.__init__(self) + ContractStandardFault.__init__(self) diff --git a/lib/aci/contract/standard/output.py b/lib/aci/contract/standard/output.py new file mode 100644 index 00000000..33ba421b --- /dev/null +++ b/lib/aci/contract/standard/output.py @@ -0,0 +1,316 @@ +import copy + + +class ContractStandardOutput(): + def __init__(self): + pass + + def print_standard_contracts(self, info, show_contract_filters=False, title=False): + if title: + self.my_output.default( + 'Standard Contract [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'scope', + 'intent', + 'targetDscp', + 'vzFilter.subjectNameTenant', + 'vzFilter.nameTenant' + ] + + headers = [ + 'Faults', + 'Contract', + 'Scope', + 'Intent', + 'Target DSCP', + 'Subject', + 'Filter' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vzFilter'] + ), + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + if show_contract_filters: + filters_in_the_list = [] + filters = [] + for contract in info: + for item in contract['vzFilter']: + if item['nameTenant'] not in filters_in_the_list: + filters_in_the_list.append( + item['nameTenant'] + ) + new_entry = copy.deepcopy(item) + filters.append(new_entry) + + self.print_contract_filters( + filters, + title=title + ) + + def print_standard_contracts_usage(self, info, title=False): + if title: + self.my_output.default( + 'Standard Contract - Usage [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'consumerEpg.nameLong', + 'providerEpg.nameLong' + ] + + headers = [ + 'Faults', + 'Contract', + 'Consumer EPG', + 'Provider EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['consumerEpg', 'providerEpg'] + ), + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + def print_standard_contracts_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Standard Contract - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Standard Contract - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Standard Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_standard_contracts_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Standard Contract - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Standard Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_standard_contracts_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Standard Contract - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Standard Contract - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Standard Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_standard_contracts_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Standard Contract - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Standard Contract - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Standard Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/contract/standard/subject/__init__.py b/lib/aci/contract/standard/subject/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/standard/subject/api.py b/lib/aci/contract/standard/subject/api.py new file mode 100644 index 00000000..73024a90 --- /dev/null +++ b/lib/aci/contract/standard/subject/api.py @@ -0,0 +1,60 @@ +class ContractSubjectApi(): + def __init__(self): + self.subjects_mo = None + + def get_subjects_mo(self): + if self.subjects_mo is not None: + return self.subjects_mo + + cache = self.get_object_cache( + 'vzSubj' + ) + if cache is not None: + self.subjects_mo = cache + self.log.apic_mo( + 'vzSubj', + self.subjects_mo + ) + return self.subjects_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=vzRsSubjFiltAtt' + managed_objects = self.get_class( + 'vzSubj', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_subjects_mo', + 'API failed' + ) + return None + + self.subjects_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vzSubj']['attributes'] + attributes['vzRsSubjFiltAtt'] = self.get_mo_children_attributes( + 'vzSubj', + managed_object, + 'vzRsSubjFiltAtt' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vzSubj', + managed_object, + 'faultCounts' + ) + self.subjects_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzSubj', + self.subjects_mo + ) + + self.set_object_cache( + 'vzSubj', + self.subjects_mo + ) + + return self.subjects_mo diff --git a/lib/aci/contract/standard/subject/info.py b/lib/aci/contract/standard/subject/info.py new file mode 100644 index 00000000..74651eda --- /dev/null +++ b/lib/aci/contract/standard/subject/info.py @@ -0,0 +1,99 @@ +class ContractSubjectInfo(): + def __init__(self): + self.subjects = None + + def get_subject_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['tenant'] = info['dn'].split('/')[1][3:] + contract_dn = info['dn'].split('/')[2] + if contract_dn.split('-')[0] == 'brc': + info['contract'] = contract_dn[4:] + if contract_dn.split('-')[0] == 'oobbrc': + info['contract'] = contract_dn[7:] + + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + info['vzFilter'] = [] + for rule_mo in managed_object['vzRsSubjFiltAtt']: + if rule_mo['tCl'] != 'vzFilter': + self.log.error( + 'get_subject_info', + 'Unsupported tCl: %s' % (rule_mo['tCl']) + ) + continue + + filter_info = {} + filter_info['name'] = rule_mo['tnVzFilterName'] + try: + filter_info['tenant'] = rule_mo['tDn'].split('/')[1][3:] + except BaseException: + filter_info['tenant'] = '' + + info['vzFilter'].append( + filter_info + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_subjects_info(self): + if self.subjects is None: + self.subjects = [] + + subjects = self.get_subjects_mo() + if subjects is not None: + for managed_object in subjects: + self.subjects.append( + self.get_subject_info( + managed_object + ) + ) + + self.log.apic_mo( + 'vzSubj.info', + self.subjects + ) + + return self.subjects + + def get_subjects(self, tenant, contract_name): + all_subjects = self.get_subjects_info() + subjects = [] + for subject in all_subjects: + if subject['tenant'] == tenant and subject['contract'] == contract_name: + subjects.append( + subject + ) + + return subjects + + def get_subject(self, tenant, name): + all_subjects = self.get_subjects_info() + for subject in all_subjects: + if subject['tenant'] == tenant and subject['name'] == name: + return subject + + return None diff --git a/lib/aci/contract/standard/subject/main.py b/lib/aci/contract/standard/subject/main.py new file mode 100644 index 00000000..17809317 --- /dev/null +++ b/lib/aci/contract/standard/subject/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.standard.subject.api import ContractSubjectApi +from lib.aci.contract.standard.subject.info import ContractSubjectInfo + + +class ContractSubject(ContractSubjectApi, ContractSubjectInfo): + def __init__(self): + ContractSubjectApi.__init__(self) + ContractSubjectInfo.__init__(self) diff --git a/lib/aci/contract/taboo/__init__.py b/lib/aci/contract/taboo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/taboo/__pycache__/__init__.cpython-310.pyc b/lib/aci/contract/taboo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..eb6c3410 Binary files /dev/null and b/lib/aci/contract/taboo/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/contract/taboo/__pycache__/api.cpython-310.pyc b/lib/aci/contract/taboo/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..64c10a67 Binary files /dev/null and b/lib/aci/contract/taboo/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/contract/taboo/__pycache__/info.cpython-310.pyc b/lib/aci/contract/taboo/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..65e92478 Binary files /dev/null and b/lib/aci/contract/taboo/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/contract/taboo/__pycache__/main.cpython-310.pyc b/lib/aci/contract/taboo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..677985ef Binary files /dev/null and b/lib/aci/contract/taboo/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/contract/taboo/__pycache__/output.cpython-310.pyc b/lib/aci/contract/taboo/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..a5807853 Binary files /dev/null and b/lib/aci/contract/taboo/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/contract/taboo/api.py b/lib/aci/contract/taboo/api.py new file mode 100644 index 00000000..dd375c7b --- /dev/null +++ b/lib/aci/contract/taboo/api.py @@ -0,0 +1,65 @@ +class ContractTabooApi(): + def __init__(self): + self.taboo_contract_mo = None + + def get_taboo_contract_mo(self): + if self.taboo_contract_mo is not None: + return self.taboo_contract_mo + + cache = self.get_object_cache( + 'vzTaboo' + ) + if cache is not None: + self.taboo_contract_mo = cache + self.log.apic_mo( + 'vzTaboo', + self.taboo_contract_mo + ) + return self.taboo_contract_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=vzTSubj,vzRtProtBy' + managed_objects = self.get_class( + 'vzTaboo', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_taboo_contract_mo', + 'API failed' + ) + return None + + self.taboo_contract_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vzTaboo']['attributes'] + attributes['vzTSubj'] = self.get_mo_children_attributes( + 'vzTaboo', + managed_object, + 'vzTSubj' + ) + attributes['vzRtProtBy'] = self.get_mo_children_attributes( + 'vzTaboo', + managed_object, + 'vzRtProtBy' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vzTaboo', + managed_object, + 'faultCounts' + ) + self.taboo_contract_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzTaboo', + self.taboo_contract_mo + ) + + self.set_object_cache( + 'vzTaboo', + self.taboo_contract_mo + ) + + return self.taboo_contract_mo diff --git a/lib/aci/contract/taboo/audit/__init__.py b/lib/aci/contract/taboo/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/taboo/audit/api.py b/lib/aci/contract/taboo/audit/api.py new file mode 100644 index 00000000..79eedaab --- /dev/null +++ b/lib/aci/contract/taboo/audit/api.py @@ -0,0 +1,48 @@ +class ContractTabooAuditApi(): + def __init__(self): + self.taboo_contract_audit_mo = None + + def get_taboo_contract_audit_mo(self): + cache = self.get_object_cache( + 'vzTaboo.audit' + ) + if cache is not None: + self.taboo_contract_audit_mo = cache + self.log.apic_mo( + 'vzTaboo.audit', + self.taboo_contract_audit_mo + ) + return self.taboo_contract_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'vzTaboo', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_taboo_contract_audit_mo', + 'API failed' + ) + return None + + self.taboo_contract_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.taboo_contract_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzTaboo.audit', + self.taboo_contract_audit_mo + ) + + self.set_object_cache( + 'vzTaboo.audit', + self.taboo_contract_audit_mo + ) + + return self.taboo_contract_audit_mo diff --git a/lib/aci/contract/taboo/audit/info.py b/lib/aci/contract/taboo/audit/info.py new file mode 100644 index 00000000..6acdef3e --- /dev/null +++ b/lib/aci/contract/taboo/audit/info.py @@ -0,0 +1,110 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractTabooAuditInfo(): + def __init__(self): + self.taboo_contract_audit = None + + def get_taboo_contract_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['contractName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/taboo-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/taboo-' in info['affected']: + info['contractName'] = info['affected'].split('/taboo-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['contractName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['contractName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_taboo_contract_audit(self): + if self.taboo_contract_audit is not None: + return self.taboo_contract_audit + + managed_objects = self.get_taboo_contract_audit_mo() + if managed_objects is None: + return None + + self.taboo_contract_audit = [] + for managed_object in managed_objects: + audit_info = self.get_taboo_contract_audit_info( + managed_object + ) + self.taboo_contract_audit.append( + audit_info + ) + + self.log.apic_mo( + 'vzTaboo.auditRecord.info', + self.taboo_contract_audit + ) + + return self.taboo_contract_audit + + def get_taboo_contract_id_audit(self, tenant_name, contract_name, audit_filter=None): + audits = [] + + all_audits = self.get_taboo_contract_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['contractName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['contractName'] == contract_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/contract/taboo/audit/main.py b/lib/aci/contract/taboo/audit/main.py new file mode 100644 index 00000000..d6e68fa4 --- /dev/null +++ b/lib/aci/contract/taboo/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.taboo.audit.api import ContractTabooAuditApi +from lib.aci.contract.taboo.audit.info import ContractTabooAuditInfo + + +class ContractTabooAudit(ContractTabooAuditApi, ContractTabooAuditInfo): + def __init__(self): + ContractTabooAuditApi.__init__(self) + ContractTabooAuditInfo.__init__(self) diff --git a/lib/aci/contract/taboo/event/__init__.py b/lib/aci/contract/taboo/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/taboo/event/api.py b/lib/aci/contract/taboo/event/api.py new file mode 100644 index 00000000..1d72411c --- /dev/null +++ b/lib/aci/contract/taboo/event/api.py @@ -0,0 +1,51 @@ +class ContractTabooEventApi(): + def __init__(self): + self.taboo_contract_event_mo = None + + def get_taboo_contract_event_mo(self): + if self.taboo_contract_event_mo is not None: + return self.taboo_contract_event_mo + + cache = self.get_object_cache( + 'vzTaboo.eventLog' + ) + if cache is not None: + self.taboo_contract_event_mo = cache + self.log.apic_mo( + 'vzTaboo.eventLog', + self.taboo_contract_event_mo + ) + return self.taboo_contract_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'vzTaboo', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_taboo_contract_event_mo', + 'API failed' + ) + return None + + self.taboo_contract_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.taboo_contract_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzTaboo.eventLog', + self.taboo_contract_event_mo + ) + + self.set_object_cache( + 'vzTaboo.eventLog', + self.taboo_contract_event_mo + ) + + return self.taboo_contract_event_mo diff --git a/lib/aci/contract/taboo/event/info.py b/lib/aci/contract/taboo/event/info.py new file mode 100644 index 00000000..01871819 --- /dev/null +++ b/lib/aci/contract/taboo/event/info.py @@ -0,0 +1,124 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractTabooEventInfo(): + def __init__(self): + self.taboo_contract_event = None + + def get_taboo_contract_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['contractName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/taboo-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/taboo-' in info['affected']: + info['contractName'] = info['affected'].split('/taboo-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/taboo-BT-Demo + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/taboo-' in info['dn']: + info['contractName'] = info['dn'].split('/taboo-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['contractName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['contractName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_taboo_contract_event(self, deduplicate=True): + if self.taboo_contract_event is not None: + return self.taboo_contract_event + + managed_objects = self.get_taboo_contract_event_mo() + if managed_objects is None: + return None + + self.taboo_contract_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_taboo_contract_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.taboo_contract_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'vzTaboo.eventLog.info', + self.taboo_contract_event + ) + + return self.taboo_contract_event + + def get_taboo_contract_id_event(self, tenant_name, contract_name, event_filter=None): + events = [] + + all_events = self.get_taboo_contract_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['contractName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['contractName'] == contract_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/contract/taboo/event/main.py b/lib/aci/contract/taboo/event/main.py new file mode 100644 index 00000000..12146730 --- /dev/null +++ b/lib/aci/contract/taboo/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.taboo.event.api import ContractTabooEventApi +from lib.aci.contract.taboo.event.info import ContractTabooEventInfo + + +class ContractTabooEvent(ContractTabooEventApi, ContractTabooEventInfo): + def __init__(self): + ContractTabooEventApi.__init__(self) + ContractTabooEventInfo.__init__(self) diff --git a/lib/aci/contract/taboo/fault/__init__.py b/lib/aci/contract/taboo/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/taboo/fault/api.py b/lib/aci/contract/taboo/fault/api.py new file mode 100644 index 00000000..7975f461 --- /dev/null +++ b/lib/aci/contract/taboo/fault/api.py @@ -0,0 +1,118 @@ +class ContractTabooFaultApi(): + def __init__(self): + self.taboo_contract_fault_mo = None + self.taboo_contract_fault_record_mo = None + + def get_taboo_contract_fault_mo(self): + cache = self.get_object_cache( + 'vzTaboo.fault' + ) + if cache is not None: + self.taboo_contract_fault_mo = cache + self.log.apic_mo( + 'vzTaboo.fault', + self.taboo_contract_fault_mo + ) + return self.taboo_contract_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'vzTaboo', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_taboo_contract_fault_mo', + 'API failed' + ) + return None + + self.taboo_contract_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.taboo_contract_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.taboo_contract_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzTaboo.fault', + self.taboo_contract_fault_mo + ) + + self.set_object_cache( + 'vzTaboo.fault', + self.taboo_contract_fault_mo + ) + + return self.taboo_contract_fault_mo + + def get_taboo_contract_fault_record_mo(self): + cache = self.get_object_cache( + 'vzTaboo.faultRecord' + ) + if cache is not None: + self.taboo_contract_fault_record_mo = cache + self.log.apic_mo( + 'vzTaboo.faultRecord', + self.taboo_contract_fault_record_mo + ) + return self.taboo_contract_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'vzTaboo', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_taboo_contract_fault_record_mo', + 'API failed' + ) + return None + + self.taboo_contract_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.taboo_contract_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.taboo_contract_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzTaboo.faultRecord', + self.taboo_contract_fault_record_mo + ) + + self.set_object_cache( + 'vzTaboo.faultRecord', + self.taboo_contract_fault_record_mo + ) + + return self.taboo_contract_fault_record_mo diff --git a/lib/aci/contract/taboo/fault/info.py b/lib/aci/contract/taboo/fault/info.py new file mode 100644 index 00000000..de3e4bb0 --- /dev/null +++ b/lib/aci/contract/taboo/fault/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ContractTabooFaultInfo(): + def __init__(self): + self.taboo_contract_fault = None + self.taboo_contract_fault_record = None + + def get_taboo_contract_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['contractName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/taboo-BT-Demo + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/taboo-' in info['affected']: + info['contractName'] = info['affected'].split('/taboo-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/taboo-BT-Demo + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/taboo-' in info['dn']: + info['contractName'] = info['dn'].split('/taboo-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['contractName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['contractName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_taboo_contract_fault(self): + if self.taboo_contract_fault is not None: + return self.taboo_contract_fault + + managed_objects = self.get_taboo_contract_fault_mo() + if managed_objects is None: + return None + + self.taboo_contract_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_taboo_contract_fault_info( + managed_object + ) + self.taboo_contract_fault.append( + fault_info + ) + + self.log.apic_mo( + 'vzTaboo.fault.info', + self.taboo_contract_fault + ) + + return self.taboo_contract_fault + + def get_taboo_contract_fault_record(self, deduplicate=True): + if self.taboo_contract_fault_record is not None: + return self.taboo_contract_fault_record + + managed_objects = self.get_taboo_contract_fault_record_mo() + if managed_objects is None: + return None + + self.taboo_contract_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_taboo_contract_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.taboo_contract_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'vzTaboo.faultRecord.info', + self.taboo_contract_fault_record + ) + + return self.taboo_contract_fault_record + + def get_taboo_contract_id_fault(self, tenant_name, contract_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_taboo_contract_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_taboo_contract_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['contractName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['contractName'] == contract_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/contract/taboo/fault/main.py b/lib/aci/contract/taboo/fault/main.py new file mode 100644 index 00000000..77b47f6b --- /dev/null +++ b/lib/aci/contract/taboo/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.taboo.fault.api import ContractTabooFaultApi +from lib.aci.contract.taboo.fault.info import ContractTabooFaultInfo + + +class ContractTabooFault(ContractTabooFaultApi, ContractTabooFaultInfo): + def __init__(self): + ContractTabooFaultApi.__init__(self) + ContractTabooFaultInfo.__init__(self) diff --git a/lib/aci/contract/taboo/info.py b/lib/aci/contract/taboo/info.py new file mode 100644 index 00000000..20c51044 --- /dev/null +++ b/lib/aci/contract/taboo/info.py @@ -0,0 +1,261 @@ +from lib import filter_helper + + +class ContractTabooInfo(): + def __init__(self): + self.taboo_contract = None + + def get_taboo_contract_count(self, tenant_name=None): + taboo_filter = None + if tenant_name is not None: + taboo_filter = ['tenant:%s' % (tenant_name)] + + contracts = self.get_taboo_contracts( + taboo_filter=taboo_filter + ) + return len(contracts) + + def get_taboo_contract(self, tenant, name): + taboo_filter = [] + taboo_filter.append( + 'tenant:%s' % (tenant) + ) + taboo_filter.append( + 'name:%s' % (name) + ) + + taboos = self.get_taboo_contracts( + taboo_filter=taboo_filter + ) + + if len(taboos) == 1: + return taboos[0] + + return None + + def get_taboo_contract_filters_info(self, managed_object): + info = [] + for item in managed_object['vzTSubj']: + taboo_subject_name = item['name'] + taboo_subject_tenant = managed_object['dn'].split('/')[1][3:] + taboo_subject_info = self.get_taboo_contract_subject( + taboo_subject_tenant, + taboo_subject_name + ) + if taboo_subject_info is None: + continue + + for taboo_filter_name in taboo_subject_info['vzFilterName']: + filter_info = self.get_contract_filter( + taboo_subject_tenant, + taboo_filter_name + ) + if filter_info is None: + self.log.error( + 'get_taboo_contract_filters_info', + 'Filter not found: %s/%s' % ( + taboo_subject_tenant, + taboo_filter_name + ) + ) + continue + + filter_info['subjectName'] = taboo_subject_name + filter_info['subjectTenant'] = taboo_subject_tenant + filter_info['subjectNameTenant'] = '%s/%s' % ( + taboo_subject_tenant, + taboo_subject_name + ) + info.append( + filter_info + ) + + return info + + def get_taboo_taboo_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name', + 'reevaluateAll', + 'scope', + 'status', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + info['vzFilter'] = self.get_taboo_contract_filters_info( + managed_object + ) + + info['protectedEpg'] = [] + for item in managed_object['vzRtProtBy']: + contract_epg_info = self.get_standard_contract_epg_info( + item + ) + if contract_epg_info is not None: + info['protectedEpg'].append( + contract_epg_info + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_taboo_contracts_info(self): + if self.taboo_contract is None: + self.taboo_contract = [] + + taboos = self.get_taboo_contract_mo() + if taboos is not None: + for managed_object in taboos: + self.taboo_contract.append( + self.get_taboo_taboo_info( + managed_object + ) + ) + + return self.taboo_contract + + def match_taboo_contract(self, taboo_info, taboo_filter): + if taboo_filter is None or len(taboo_filter) == 0: + return True + + for taboo_rule in taboo_filter: + (key, value) = taboo_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, taboo_info['nameTenant']): + return False + + if key == 'names': + key_found = True + found = False + for name in value.split(','): + if filter_helper.match_tenant_name(name, taboo_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, taboo_info['tenant']): + return False + + if key == 'filter': + key_found = True + found = False + for filter_info in taboo_info['vzFilter']: + if filter_helper.match_tenant_name(value, filter_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not taboo_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_taboo_contract', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_taboo_contract', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_taboo_contracts( + self, + taboo_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_taboos = self.get_taboo_contracts_info() + if all_taboos is None: + return None + + taboos = [] + + for taboo_info in all_taboos: + if not self.match_taboo_contract(taboo_info, taboo_filter): + continue + + if fault_info: + taboo_info['faultInst'] = self.get_taboo_contract_id_fault( + taboo_info['tenant'], + taboo_info['name'], + 'faultInst' + ) + + if hfault_info: + taboo_info['faultRecord'] = self.get_taboo_contract_id_fault( + taboo_info['tenant'], + taboo_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + taboo_info['eventLog'] = self.get_taboo_contract_id_event( + taboo_info['tenant'], + taboo_info['name'], + event_filter=event_filter + ) + + if audit_info: + taboo_info['auditLog'] = self.get_taboo_contract_id_audit( + taboo_info['tenant'], + taboo_info['name'], + audit_filter=audit_filter + ) + + taboos.append(taboo_info) + + taboos = sorted( + taboos, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'vzTaboo.info', + taboos + ) + + return taboos diff --git a/lib/aci/contract/taboo/main.py b/lib/aci/contract/taboo/main.py new file mode 100644 index 00000000..935a4cc2 --- /dev/null +++ b/lib/aci/contract/taboo/main.py @@ -0,0 +1,23 @@ +from lib.aci.contract.taboo.api import ContractTabooApi +from lib.aci.contract.taboo.info import ContractTabooInfo +from lib.aci.contract.taboo.subject.main import ContractTabooSubject +from lib.aci.contract.taboo.audit.main import ContractTabooAudit +from lib.aci.contract.taboo.event.main import ContractTabooEvent +from lib.aci.contract.taboo.fault.main import ContractTabooFault + + +class ContractTaboo( + ContractTabooApi, + ContractTabooInfo, + ContractTabooSubject, + ContractTabooAudit, + ContractTabooEvent, + ContractTabooFault + ): + def __init__(self): + ContractTabooApi.__init__(self) + ContractTabooInfo.__init__(self) + ContractTabooSubject.__init__(self) + ContractTabooAudit.__init__(self) + ContractTabooEvent.__init__(self) + ContractTabooFault.__init__(self) diff --git a/lib/aci/contract/taboo/output.py b/lib/aci/contract/taboo/output.py new file mode 100644 index 00000000..98d76d22 --- /dev/null +++ b/lib/aci/contract/taboo/output.py @@ -0,0 +1,307 @@ +import copy + + +class ContractTabooOutput(): + def __init__(self): + pass + + def print_taboo_contracts(self, info, show_taboo_filters=False, title=False): + if title: + self.my_output.default( + 'Taboo Contract [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'vzFilter.subjectNameTenant', + 'vzFilter.nameTenant' + ] + + headers = [ + 'Faults', + 'Taboo', + 'Subject', + 'Filter' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vzFilter'] + ), + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + if show_taboo_filters: + filters_in_the_list = [] + filters = [] + for taboo in info: + for item in taboo['vzFilter']: + if item['nameTenant'] not in filters_in_the_list: + filters_in_the_list.append( + item['nameTenant'] + ) + new_entry = copy.deepcopy(item) + filters.append(new_entry) + + self.print_contract_filters( + filters, + title=title + ) + + def print_taboo_contracts_usage(self, info, title=False): + if title: + self.my_output.default( + 'Taboo Contract - Usage [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + order = [ + 'faults', + 'nameTenant', + 'protectedEpg.nameLong' + ] + + headers = [ + 'Faults', + 'Taboo', + 'Protected EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['protectedEpg'] + ), + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + def print_taboo_contracts_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Taboo Contract - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Taboo Contract - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Taboo Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_taboo_contracts_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Taboo Contract - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Taboo Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_taboo_contracts_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Taboo Contract - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Taboo Contract - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Taboo Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_taboo_contracts_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Taboo Contract - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Taboo Contract - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Taboo Contract', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/contract/taboo/subject/__init__.py b/lib/aci/contract/taboo/subject/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/contract/taboo/subject/api.py b/lib/aci/contract/taboo/subject/api.py new file mode 100644 index 00000000..88c2ed1d --- /dev/null +++ b/lib/aci/contract/taboo/subject/api.py @@ -0,0 +1,60 @@ +class ContractTabooSubjectApi(): + def __init__(self): + self.taboo_contract_subject_mo = None + + def get_taboo_contract_subject_mo(self): + if self.taboo_contract_subject_mo is not None: + return self.taboo_contract_subject_mo + + cache = self.get_object_cache( + 'vzTSubj' + ) + if cache is not None: + self.taboo_contract_subject_mo = cache + self.log.apic_mo( + 'vzTSubj', + self.taboo_contract_subject_mo + ) + return self.taboo_contract_subject_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=vzRsDenyRule' + managed_objects = self.get_class( + 'vzTSubj', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_taboo_contract_subject_mo', + 'API failed' + ) + return None + + self.taboo_contract_subject_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vzTSubj']['attributes'] + attributes['vzRsDenyRule'] = self.get_mo_children_attributes( + 'vzTSubj', + managed_object, + 'vzRsDenyRule' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vzTSubj', + managed_object, + 'faultCounts' + ) + self.taboo_contract_subject_mo.append( + attributes + ) + + self.log.apic_mo( + 'vzTSubj', + self.taboo_contract_subject_mo + ) + + self.set_object_cache( + 'vzTSubj', + self.taboo_contract_subject_mo + ) + + return self.taboo_contract_subject_mo diff --git a/lib/aci/contract/taboo/subject/info.py b/lib/aci/contract/taboo/subject/info.py new file mode 100644 index 00000000..1f033776 --- /dev/null +++ b/lib/aci/contract/taboo/subject/info.py @@ -0,0 +1,85 @@ +class ContractTabooSubjectInfo(): + def __init__(self): + self.taboo_contract_subject = None + + def get_taboo_contract_subject_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['tenant'] = info['dn'].split('/')[1][3:] + info['taboo'] = info['dn'].split('/')[2][6:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + info['vzFilterName'] = [] + for rule_mo in managed_object['vzRsDenyRule']: + if rule_mo['tCl'] != 'vzFilter': + self.log.error( + 'get_taboo_contract_subject_info', + 'Unsupported tCl: %s' % (rule_mo['tCl']) + ) + continue + + info['vzFilterName'].append( + rule_mo['tnVzFilterName'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_taboo_contract_subjects_info(self): + if self.taboo_contract_subject is None: + self.taboo_contract_subject = [] + + taboo_contract_subject = self.get_taboo_contract_subject_mo() + if taboo_contract_subject is not None: + for managed_object in taboo_contract_subject: + self.taboo_contract_subject.append( + self.get_taboo_contract_subject_info( + managed_object + ) + ) + + self.log.apic_mo( + 'vzTSubj', + self.subjects_mo + ) + + return self.taboo_contract_subject + + def get_taboo_contract_subjects(self, tenant, contract_name): + all_taboo_contract_subjects = self.get_taboo_contract_subjects_info() + taboo_contract_subjects = [] + for taboo_contract_subject in all_taboo_contract_subjects: + if taboo_contract_subject['tenant'] == tenant and taboo_contract_subject['taboo'] == contract_name: + taboo_contract_subject.append( + taboo_contract_subject + ) + return taboo_contract_subjects + + def get_taboo_contract_subject(self, tenant_name, subject_name): + all_taboo_contract_subjects = self.get_taboo_contract_subjects_info() + for taboo_contract_subject in all_taboo_contract_subjects: + if taboo_contract_subject['tenant'] == tenant_name and taboo_contract_subject['name'] == subject_name: + return taboo_contract_subject + return None diff --git a/lib/aci/contract/taboo/subject/main.py b/lib/aci/contract/taboo/subject/main.py new file mode 100644 index 00000000..1b63f793 --- /dev/null +++ b/lib/aci/contract/taboo/subject/main.py @@ -0,0 +1,8 @@ +from lib.aci.contract.taboo.subject.api import ContractTabooSubjectApi +from lib.aci.contract.taboo.subject.info import ContractTabooSubjectInfo + + +class ContractTabooSubject(ContractTabooSubjectApi, ContractTabooSubjectInfo): + def __init__(self): + ContractTabooSubjectApi.__init__(self) + ContractTabooSubjectInfo.__init__(self) diff --git a/lib/aci/domain/__init__.py b/lib/aci/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7e9b50d2 Binary files /dev/null and b/lib/aci/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/__pycache__/main.cpython-310.pyc b/lib/aci/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..163fc5b9 Binary files /dev/null and b/lib/aci/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/__pycache__/output.cpython-310.pyc b/lib/aci/domain/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..851b63ec Binary files /dev/null and b/lib/aci/domain/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/domain/aaa/__init__.py b/lib/aci/domain/aaa/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/aaa/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/aaa/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0213b4bd Binary files /dev/null and b/lib/aci/domain/aaa/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/aaa/__pycache__/api.cpython-310.pyc b/lib/aci/domain/aaa/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..0923e03d Binary files /dev/null and b/lib/aci/domain/aaa/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/domain/aaa/__pycache__/info.cpython-310.pyc b/lib/aci/domain/aaa/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..a47941af Binary files /dev/null and b/lib/aci/domain/aaa/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/domain/aaa/__pycache__/main.cpython-310.pyc b/lib/aci/domain/aaa/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9db8f114 Binary files /dev/null and b/lib/aci/domain/aaa/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/aaa/__pycache__/output.cpython-310.pyc b/lib/aci/domain/aaa/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..6a37a59a Binary files /dev/null and b/lib/aci/domain/aaa/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/domain/aaa/api.py b/lib/aci/domain/aaa/api.py new file mode 100644 index 00000000..cc5aa3a8 --- /dev/null +++ b/lib/aci/domain/aaa/api.py @@ -0,0 +1,52 @@ +class DomainAaaApi(): + def __init__(self): + self.domain_aaa_mo = None + + def get_domain_aaa_mo(self): + if self.domain_aaa_mo is not None: + return self.domain_aaa_mo + + cache = self.get_object_cache( + 'aaaDomain' + ) + if cache is not None: + self.domain_aaa_mo = cache + self.log.apic_mo( + 'aaaDomain', + self.domain_aaa_mo + ) + return self.domain_aaa_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count' + managed_objects = self.get_class( + 'aaaDomain', + query=query, + node_class=True + ) + + if managed_objects is None: + return None + + self.domain_aaa_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaDomain']['attributes'] + attributes['faultCounts'] = self.get_mo_child_attributes( + 'aaaDomain', + managed_object, + 'faultCounts' + ) + self.domain_aaa_mo.append( + attributes + ) + + self.log.apic_mo( + 'aaaDomain', + self.domain_aaa_mo + ) + + self.set_object_cache( + 'aaaDomain', + self.domain_aaa_mo + ) + + return self.domain_aaa_mo diff --git a/lib/aci/domain/aaa/info.py b/lib/aci/domain/aaa/info.py new file mode 100644 index 00000000..b6c20432 --- /dev/null +++ b/lib/aci/domain/aaa/info.py @@ -0,0 +1,111 @@ +from lib import filter_helper + + +class DomainAaaInfo(): + def __init__(self): + pass + + def get_domain_aaa_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name', + 'restrictedRbacDomain', + 'status' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def match_domain_aaa(self, domain_info, domain_filter): + if domain_filter is None or len(domain_filter) == 0: + return True + + for aepg_rule in domain_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, domain_info['name']): + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, domain_info['dn']): + return False + + if key == 'system': + key_found = True + keys = ['mgmt', 'all', 'common'] + if value == 'true': + if domain_info['name'] not in keys: + return False + + if value == 'false': + if domain_info['name'] in keys: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not domain_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_domain_aaa', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_domain_aaa', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_domains_aaa(self, domain_filter=None): + all_domains = self.get_domain_aaa_mo() + if all_domains is None: + return None + + domain_aaa = [] + + for managed_object in all_domains: + domain_info = self.get_domain_aaa_info( + managed_object + ) + + if not self.match_domain_aaa(domain_info, domain_filter): + continue + + domain_aaa.append(domain_info) + + domain_aaa = sorted( + domain_aaa, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'aaaDomain.info', + domain_aaa + ) + + return domain_aaa diff --git a/lib/aci/domain/aaa/main.py b/lib/aci/domain/aaa/main.py new file mode 100644 index 00000000..33823945 --- /dev/null +++ b/lib/aci/domain/aaa/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.aaa.api import DomainAaaApi +from lib.aci.domain.aaa.info import DomainAaaInfo + + +class DomainAaa(DomainAaaApi, DomainAaaInfo): + def __init__(self): + DomainAaaApi.__init__(self) + DomainAaaInfo.__init__(self) diff --git a/lib/aci/domain/aaa/output.py b/lib/aci/domain/aaa/output.py new file mode 100644 index 00000000..6f5282e4 --- /dev/null +++ b/lib/aci/domain/aaa/output.py @@ -0,0 +1,28 @@ +class DomainAaaOutput(): + def __init__(self): + pass + + def print_domains_aaa(self, domain_aaa): + if len(domain_aaa) == 0: + self.my_output.default('No aaa domain found') + return + + order = [ + 'faults', + 'name' + ] + + headers = [ + 'Faults', + 'AAA Domain Name' + ] + + self.my_output.my_table( + domain_aaa, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/aci/domain/l2/__init__.py b/lib/aci/domain/l2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l2/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/l2/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0213b4bd Binary files /dev/null and b/lib/aci/domain/l2/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/l2/__pycache__/api.cpython-310.pyc b/lib/aci/domain/l2/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c945b0bb Binary files /dev/null and b/lib/aci/domain/l2/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/domain/l2/__pycache__/info.cpython-310.pyc b/lib/aci/domain/l2/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..477a2809 Binary files /dev/null and b/lib/aci/domain/l2/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/domain/l2/__pycache__/main.cpython-310.pyc b/lib/aci/domain/l2/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9e50c454 Binary files /dev/null and b/lib/aci/domain/l2/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/l2/__pycache__/output.cpython-310.pyc b/lib/aci/domain/l2/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..d0a93f6b Binary files /dev/null and b/lib/aci/domain/l2/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/domain/l2/api.py b/lib/aci/domain/l2/api.py new file mode 100644 index 00000000..d2398fc7 --- /dev/null +++ b/lib/aci/domain/l2/api.py @@ -0,0 +1,78 @@ +class DomainL2Api(): + def __init__(self): + self.domain_l2_mo = None + + def get_domain_l2_mo(self): + if self.domain_l2_mo is not None: + return self.domain_l2_mo + + cache = self.get_object_cache( + 'l2extDomP' + ) + if cache is not None: + self.domain_l2_mo = cache + self.log.apic_mo( + 'l2extDomP', + self.domain_l2_mo + ) + return self.domain_l2_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=infraRsVlanNs,infraRtDomP,l2extRtL2DomAtt,aaaDomainRef' + managed_objects = self.get_class( + 'l2extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l2_mo', + 'API failed' + ) + return None + + self.domain_l2_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2extDomP']['attributes'] + attributes['infraRsVlanNs'] = self.get_mo_child_attributes( + 'l2extDomP', + managed_object, + 'infraRsVlanNs' + ) + attributes['infraRtDomP'] = self.get_mo_children_attributes( + 'l2extDomP', + managed_object, + 'infraRtDomP' + ) + attributes['l2extRtL2DomAtt'] = self.get_mo_children_attributes( + 'l2extDomP', + managed_object, + 'l2extRtL2DomAtt' + ) + attributes['aaaDomainRef'] = self.get_mo_children_attributes( + 'l2extDomP', + managed_object, + 'aaaDomainRef' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l2extDomP', + managed_object, + 'faultCounts' + ) + + self.domain_l2_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extDomP', + self.domain_l2_mo + ) + + self.set_object_cache( + 'l2extDomP', + self.domain_l2_mo + ) + + return self.domain_l2_mo diff --git a/lib/aci/domain/l2/audit/__init__.py b/lib/aci/domain/l2/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l2/audit/api.py b/lib/aci/domain/l2/audit/api.py new file mode 100644 index 00000000..fc2d30e6 --- /dev/null +++ b/lib/aci/domain/l2/audit/api.py @@ -0,0 +1,48 @@ +class DomainL2AuditApi(): + def __init__(self): + self.domain_l2_audit_mo = None + + def get_domain_l2_audit_mo(self): + cache = self.get_object_cache( + 'l2extDomP.audit' + ) + if cache is not None: + self.domain_l2_audit_mo = cache + self.log.apic_mo( + 'l2extDomP.audit', + self.domain_l2_audit_mo + ) + return self.domain_l2_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'l2extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l2_audit_mo', + 'API failed' + ) + return None + + self.domain_l2_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.domain_l2_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extDomP.audit', + self.domain_l2_audit_mo + ) + + self.set_object_cache( + 'l2extDomP.audit', + self.domain_l2_audit_mo + ) + + return self.domain_l2_audit_mo diff --git a/lib/aci/domain/l2/audit/info.py b/lib/aci/domain/l2/audit/info.py new file mode 100644 index 00000000..c94da139 --- /dev/null +++ b/lib/aci/domain/l2/audit/info.py @@ -0,0 +1,97 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainL2AuditInfo(): + def __init__(self): + self.domain_l2_audit = None + + def get_domain_l2_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'uni/l2dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/l2dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_l2_audit(self): + if self.domain_l2_audit is not None: + return self.domain_l2_audit + + managed_objects = self.get_domain_l2_audit_mo() + if managed_objects is None: + return None + + self.domain_l2_audit = [] + for managed_object in managed_objects: + audit_info = self.get_domain_l2_audit_info( + managed_object + ) + self.domain_l2_audit.append( + audit_info + ) + + self.log.apic_mo( + 'l2extDomP.auditRecord.info', + self.domain_l2_audit + ) + + return self.domain_l2_audit + + def get_domain_l2_id_audit(self, domain_name, audit_filter=None): + audits = [] + + all_audits = self.get_domain_l2_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['domainName'] is not None: + if audit_info['domainName'] == domain_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/domain/l2/audit/main.py b/lib/aci/domain/l2/audit/main.py new file mode 100644 index 00000000..226968cc --- /dev/null +++ b/lib/aci/domain/l2/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l2.audit.api import DomainL2AuditApi +from lib.aci.domain.l2.audit.info import DomainL2AuditInfo + + +class DomainL2Audit(DomainL2AuditApi, DomainL2AuditInfo): + def __init__(self): + DomainL2AuditApi.__init__(self) + DomainL2AuditInfo.__init__(self) diff --git a/lib/aci/domain/l2/event/__init__.py b/lib/aci/domain/l2/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l2/event/api.py b/lib/aci/domain/l2/event/api.py new file mode 100644 index 00000000..54ebc0ec --- /dev/null +++ b/lib/aci/domain/l2/event/api.py @@ -0,0 +1,51 @@ +class DomainL2EventApi(): + def __init__(self): + self.domain_l2_event_mo = None + + def get_domain_l2_event_mo(self): + if self.domain_l2_event_mo is not None: + return self.domain_l2_event_mo + + cache = self.get_object_cache( + 'l2extDomP.eventLog' + ) + if cache is not None: + self.domain_l2_event_mo = cache + self.log.apic_mo( + 'l2extDomP.eventLog', + self.domain_l2_event_mo + ) + return self.domain_l2_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'l2extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l2_event_mo', + 'API failed' + ) + return None + + self.domain_l2_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.domain_l2_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extDomP.eventLog', + self.domain_l2_event_mo + ) + + self.set_object_cache( + 'l2extDomP.eventLog', + self.domain_l2_event_mo + ) + + return self.domain_l2_event_mo diff --git a/lib/aci/domain/l2/event/info.py b/lib/aci/domain/l2/event/info.py new file mode 100644 index 00000000..b85933a0 --- /dev/null +++ b/lib/aci/domain/l2/event/info.py @@ -0,0 +1,107 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainL2EventInfo(): + def __init__(self): + self.domain_l2_event = None + + def get_domain_l2_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'affected' in info: + if 'uni/l2dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/l2dom-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/l2dom-' in info['dn']: + info['domainName'] = info['dn'].split('uni/l2dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T12:22:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_l2_event(self, deduplicate=True): + if self.domain_l2_event is not None: + return self.domain_l2_event + + managed_objects = self.get_domain_l2_event_mo() + if managed_objects is None: + return None + + self.domain_l2_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_domain_l2_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.domain_l2_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l2extDomP.eventLog.info', + self.domain_l2_event + ) + + return self.domain_l2_event + + def get_domain_l2_id_event(self, domain_name, event_filter=None): + events = [] + + all_events = self.get_domain_l2_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['domainName'] is not None: + if event_info['domainName'] == domain_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/domain/l2/event/main.py b/lib/aci/domain/l2/event/main.py new file mode 100644 index 00000000..0b3f0992 --- /dev/null +++ b/lib/aci/domain/l2/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l2.event.api import DomainL2EventApi +from lib.aci.domain.l2.event.info import DomainL2EventInfo + + +class DomainL2Event(DomainL2EventApi, DomainL2EventInfo): + def __init__(self): + DomainL2EventApi.__init__(self) + DomainL2EventInfo.__init__(self) diff --git a/lib/aci/domain/l2/fault/__init__.py b/lib/aci/domain/l2/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l2/fault/api.py b/lib/aci/domain/l2/fault/api.py new file mode 100644 index 00000000..ed8ae726 --- /dev/null +++ b/lib/aci/domain/l2/fault/api.py @@ -0,0 +1,112 @@ +class DomainL2FaultApi(): + def __init__(self): + self.domain_l2_fault_mo = None + self.domain_l2_fault_record_mo = None + + def get_domain_l2_fault_mo(self): + cache = self.get_object_cache( + 'l2extDomP.fault' + ) + if cache is not None: + self.domain_l2_fault_mo = cache + self.log.apic_mo( + 'l2extDomP.fault', + self.domain_l2_fault_mo + ) + return self.domain_l2_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'l2extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l2_fault_mo', + 'API failed' + ) + return None + + self.domain_l2_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.domain_l2_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extDomP.fault', + self.domain_l2_fault_mo + ) + + self.set_object_cache( + 'l2extDomP.fault', + self.domain_l2_fault_mo + ) + + return self.domain_l2_fault_mo + + def get_domain_l2_fault_record_mo(self): + cache = self.get_object_cache( + 'l2extDomP.faultRecord' + ) + if cache is not None: + self.domain_l2_fault_record_mo = cache + self.log.apic_mo( + 'l2extDomP.faultRecord', + self.domain_l2_fault_record_mo + ) + return self.domain_l2_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'l2extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l2_fault_record_mo', + 'API failed' + ) + return None + + self.domain_l2_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.domain_l2_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extDomP.faultRecord', + self.domain_l2_fault_record_mo + ) + + self.set_object_cache( + 'l2extDomP.faultRecord', + self.domain_l2_fault_record_mo + ) + + return self.domain_l2_fault_record_mo diff --git a/lib/aci/domain/l2/fault/info.py b/lib/aci/domain/l2/fault/info.py new file mode 100644 index 00000000..c4a26dea --- /dev/null +++ b/lib/aci/domain/l2/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainL2FaultInfo(): + def __init__(self): + self.domain_l2_fault = None + self.domain_l2_fault_record = None + + def get_domain_l2_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/l2dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/l2dom-')[1].split('/')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/lb-[lo0]" + if info['domainName'] is None: + if 'uni/l2dom-' in info['dn']: + info['domainName'] = info['dn'].split('uni/l2dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T12:22:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_l2_fault(self): + if self.domain_l2_fault is not None: + return self.domain_l2_fault + + managed_objects = self.get_domain_l2_fault_mo() + if managed_objects is None: + return None + + self.domain_l2_fault = [] + for managed_object in managed_objects: + fault_info = self.get_domain_l2_fault_info( + managed_object + ) + self.domain_l2_fault.append( + fault_info + ) + + self.log.apic_mo( + 'l2extDomP.fault.info', + self.domain_l2_fault + ) + + return self.domain_l2_fault + + def get_domain_l2_fault_record(self, deduplicate=True): + if self.domain_l2_fault_record is not None: + return self.domain_l2_fault_record + + managed_objects = self.get_domain_l2_fault_record_mo() + if managed_objects is None: + return None + + self.domain_l2_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_domain_l2_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.domain_l2_fault.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l2extDomP.faultRecord.info', + self.domain_l2_fault_record + ) + + return self.domain_l2_fault_record + + def get_domain_l2_id_fault(self, domain_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_domain_l2_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_domain_l2_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['domainName'] is not None: + if fault_info['domainName'] == domain_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/domain/l2/fault/main.py b/lib/aci/domain/l2/fault/main.py new file mode 100644 index 00000000..e3ffa5c8 --- /dev/null +++ b/lib/aci/domain/l2/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l2.fault.api import DomainL2FaultApi +from lib.aci.domain.l2.fault.info import DomainL2FaultInfo + + +class DomainL2Fault(DomainL2FaultApi, DomainL2FaultInfo): + def __init__(self): + DomainL2FaultApi.__init__(self) + DomainL2FaultInfo.__init__(self) diff --git a/lib/aci/domain/l2/info.py b/lib/aci/domain/l2/info.py new file mode 100644 index 00000000..f834a050 --- /dev/null +++ b/lib/aci/domain/l2/info.py @@ -0,0 +1,316 @@ +from lib import filter_helper + + +class DomainL2Info(): + def __init__(self): + self.domain_l2 = None + + def get_domain_l2_info(self, managed_object): + keys = [ + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['aaep_names'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R2DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + info['aaep_names'].append( + item['tDn'].split('/')[2][8:] + ) + + info['reln'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'AAEP' + reln_info['name'] = item['tDn'].split('/')[2][8:] + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_l2_info', + 'Unsupported infraRtDomP tCl: %s' % (item['tCl']) + ) + + if 'l2extRtL2DomAtt' in managed_object: + if managed_object['l2extRtL2DomAtt'] is not None: + for item in managed_object['l2extRtL2DomAtt']: + # "tCl": "l2extOut", + # "tDn": "uni/tn-k8s/l2out-Test" + if item['tCl'] == 'l2extOut': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'L2 Out' + reln_info['name'] = self.get_l2out_name_from_dn( + item['tDn'] + ) + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_l2_info', + 'Unsupported extnwRtL3DomAtt tCl: %s' % (item['tCl']) + ) + + info['vlan'] = None + if 'infraRsVlanNs' in managed_object: + if managed_object['infraRsVlanNs'] is not None: + if managed_object['infraRsVlanNs']['tCl'] == 'fvnsVlanInstP': + info['vlan'] = managed_object['infraRsVlanNs']['tDn'].split('vlanns-[')[1].split(']')[0] + + info['aaaDomain'] = [] + for item in managed_object['aaaDomainRef']: + info['aaaDomain'].append( + item['name'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_domains_l2_info(self): + if self.domain_l2 is not None: + return self.domain_l2 + + domains_mo = self.get_domain_l2_mo() + if domains_mo is None: + return None + + self.domain_l2 = [] + for managed_object in domains_mo: + self.domain_l2.append( + self.get_domain_l2_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l2extDomP.info', + self.domain_l2 + ) + + return self.domain_l2 + + def match_domain_l2(self, domain_info, domain_filter): + if domain_filter is None or len(domain_filter) == 0: + return True + + for aepg_rule in domain_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, domain_info['name']): + return False + + if key == 'aaep': + key_found = True + found = False + for aaep_name in domain_info['aaep_names']: + if filter_helper.match_string(value, aaep_name): + found = True + + if not found: + return False + + if key == 'pool': + key_found = True + if not filter_helper.match_string(value, domain_info['vlan']): + return False + + if key == 'vlan': + key_found = True + if 'vlan_block' in domain_info: + found = False + for vlan_block in domain_info['vlan_block']: + if filter_helper.match_integer(vlan_block, value): + found = True + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not domain_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_domain_l2', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_domain_l2', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_domains_l2( + self, + domain_filter=None, + vlan_info=False, + vlan_usage_info=False, + node_info=False, + intf_vlan_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_domains = self.get_domains_l2_info() + + domains = [] + + for domain_info in all_domains: + if not self.match_domain_l2(domain_info, domain_filter): + continue + + if vlan_info: + domain_info['vlan_info'] = None + domain_info['vlan_block'] = [] + if domain_info['vlan'] is not None: + domain_info['vlan_info'] = self.get_pool_vlan( + domain_info['vlan'], + vlan_usage_info=vlan_usage_info, + domain_name=domain_info['name'] + ) + if domain_info['vlan_info'] is None: + self.log.error( + 'get_domains_l2', + 'Vlan pool not found: %s' % (domain_info['vlan']) + ) + if domain_info['vlan_info'] is not None: + for vlan_block in domain_info['vlan_info']['fvnsEncapBlk']: + domain_info['vlan_block'].append( + '%s-%s' % ( + vlan_block['fromVlan'], + vlan_block['toVlan'] + ) + ) + + if not self.match_domain_phy(domain_info, domain_filter): + continue + + if node_info: + domain_node_info = self.get_domain_l2_node( + domain_info['name'] + ) + domain_info['node'] = None + domain_info['interface'] = None + if domain_node_info is not None: + domain_info['node'] = domain_node_info['node'] + domain_info['interface'] = domain_node_info['interface'] + + if intf_vlan_info: + if domain_info['interface'] is not None: + for interface in domain_info['interface']: + interface['vlan'] = [] + interface['operSt'] = '--' + interface['operMode'] = '--' + + if interface['intf_type'] == 'l1PhysIf': + interface_info = self.get_interface_phy( + interface['pod_id'], + interface['node_id'], + interface['intf_name'], + epg_stats_info=True + ) + if interface_info is not None: + interface['operSt'] = interface_info['stats']['operSt'] + interface['__Output']['operSt'] = interface_info['stats']['__Output']['operSt'] + interface['operMode'] = interface_info['stats']['operMode'] + for intf_epg_stats in interface_info['epg_stats']: + if intf_epg_stats['vlan'] is not None: + if intf_epg_stats['vlan']['evlan'] not in interface['vlan']: + interface['vlan'].append( + intf_epg_stats['vlan']['evlan'] + ) + + interface['vlan'] = sorted( + interface['vlan'] + ) + interface['vlans'] = filter_helper.get_range_from_values( + interface['vlan'] + ) + + if fault_info: + domain_info['faultInst'] = self.get_domain_l2_id_fault( + domain_info['name'], + 'faultInst' + ) + + if hfault_info: + domain_info['faultRecord'] = self.get_domain_l2_id_fault( + domain_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + domain_info['eventLog'] = self.get_domain_l2_id_event( + domain_info['name'], + event_filter=event_filter + ) + + if audit_info: + domain_info['auditLog'] = self.get_domain_l2_id_audit( + domain_info['name'], + audit_filter=audit_filter + ) + + domains.append(domain_info) + + domains = sorted( + domains, + key=lambda i: i['name'].lower() + ) + + return domains + + def get_domain_l2(self, domain_name, vlan_info=False, vlan_usage_info=False): + domain_filter = ['name:%s' % (domain_name)] + domains = self.get_domains_l2( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info + ) + if domains is None or len(domains) != 1: + return None + return domains[0] diff --git a/lib/aci/domain/l2/main.py b/lib/aci/domain/l2/main.py new file mode 100644 index 00000000..c120f3da --- /dev/null +++ b/lib/aci/domain/l2/main.py @@ -0,0 +1,23 @@ +from lib.aci.domain.l2.api import DomainL2Api +from lib.aci.domain.l2.info import DomainL2Info +from lib.aci.domain.l2.audit.main import DomainL2Audit +from lib.aci.domain.l2.event.main import DomainL2Event +from lib.aci.domain.l2.fault.main import DomainL2Fault +from lib.aci.domain.l2.node.main import DomainL2Node + + +class DomainL2( + DomainL2Api, + DomainL2Info, + DomainL2Audit, + DomainL2Event, + DomainL2Fault, + DomainL2Node + ): + def __init__(self): + DomainL2Api.__init__(self) + DomainL2Info.__init__(self) + DomainL2Audit.__init__(self) + DomainL2Event.__init__(self) + DomainL2Fault.__init__(self) + DomainL2Node.__init__(self) diff --git a/lib/aci/domain/l2/node/__init__.py b/lib/aci/domain/l2/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l2/node/api.py b/lib/aci/domain/l2/node/api.py new file mode 100644 index 00000000..6cfc2d18 --- /dev/null +++ b/lib/aci/domain/l2/node/api.py @@ -0,0 +1,61 @@ +class DomainL2NodeApi(): + def __init__(self): + self.domain_l2_node_mo = {} + + def get_domain_l2_node_mo(self, domain_name): + if domain_name in self.domain_l2_node_mo: + return self.domain_l2_node_mo[domain_name] + + key = domain_name + cache = self.get_object_cache( + 'l2extDomP.%s' % (key) + ) + if cache is not None: + self.domain_l2_node_mo[key] = cache + self.log.apic_mo( + 'l2extDomP.%s' % (key), + self.domain_l2_node_mo[key] + ) + return self.domain_l2_node_mo[key] + + distinguished_name = 'uni/l2dom-%s' % (domain_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=ADomPToEthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l2_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_domain_l2_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2extDomP']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'l2extDomP', + managed_object + ) + self.domain_l2_node_mo[key] = attributes + + self.log.apic_mo( + 'l2extDomP.%s' % (key), + self.domain_l2_node_mo[key] + ) + + self.set_object_cache( + 'l2extDomP.%s' % (key), + self.domain_l2_node_mo[key] + ) + + return self.domain_l2_node_mo[key] diff --git a/lib/aci/domain/l2/node/info.py b/lib/aci/domain/l2/node/info.py new file mode 100644 index 00000000..b9f71642 --- /dev/null +++ b/lib/aci/domain/l2/node/info.py @@ -0,0 +1,81 @@ +class DomainL2NodeInfo(): + def __init__(self): + self.domain_l2_node = {} + + def get_domain_l2_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/l2s-[eth1/42]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_domain_l2_node(self, domain_name): + if domain_name in self.domain_l2_node: + return self.domain_l2_node[domain_name] + + # one object or None value is expected + domain_nodes_mo = self.get_domain_l2_node_mo(domain_name) + if domain_nodes_mo is None: + return None + + self.domain_l2_node[domain_name] = self.get_domain_l2_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'l2extDomP.%s.info' % (domain_name), + self.domain_l2_node[domain_name] + ) + + return self.domain_l2_node[domain_name] diff --git a/lib/aci/domain/l2/node/main.py b/lib/aci/domain/l2/node/main.py new file mode 100644 index 00000000..8d253aaa --- /dev/null +++ b/lib/aci/domain/l2/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l2.node.api import DomainL2NodeApi +from lib.aci.domain.l2.node.info import DomainL2NodeInfo + + +class DomainL2Node(DomainL2NodeApi, DomainL2NodeInfo): + def __init__(self): + DomainL2NodeApi.__init__(self) + DomainL2NodeInfo.__init__(self) diff --git a/lib/aci/domain/l2/output.py b/lib/aci/domain/l2/output.py new file mode 100644 index 00000000..13427712 --- /dev/null +++ b/lib/aci/domain/l2/output.py @@ -0,0 +1,455 @@ +class DomainL2Output(): + def __init__(self): + pass + + def print_domains_l2(self, info, title=False): + if title: + self.my_output.default( + 'L2 Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + for item in info: + if len(item['aaaDomain']) == 0: + item['aaaDomain'].append('--') + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'vlan_info.allocMode', + 'fvnsEncapBlk.blockInfo', + 'aaaDomain' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Mode', + 'Encapsulation Block', + 'Sec Domain' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'fvnsEncapBlk', 'aaaDomain'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l2_node(self, info, title=False): + if title: + self.my_output.default( + 'L2 Domain - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l2_interface(self, info, title=False): + if title: + self.my_output.default( + 'L2 Domain - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l2_vlan(self, info, title=False): + if title: + self.my_output.default( + 'L2 Domain - Interfaces VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'fvnsEncapBlk.blockInfo', + 'interface.node_name', + 'interface.intf_name', + 'interface.operSt', + 'interface.operMode', + 'interface.vlans' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Encapsulation Block', + 'Node', + 'Interface', + 'State', + 'Mode', + 'VLANs' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface', 'fvnsEncapBlk'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l2_reln(self, info, title=False): + if title: + self.my_output.default( + 'L2 Domain - Policy Relationships [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'reln.type', + 'reln.name' + ] + + headers = [ + 'Faults', + 'Domain', + 'Policy Type', + 'Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['reln'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l2_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L2 Domain - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L2 Domain - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_domains_l2_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'L2 Domain - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_l2_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L2 Domain - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L2 Domain - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_l2_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L2 Domain - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L2 Domain - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/domain/l3/__init__.py b/lib/aci/domain/l3/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l3/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/l3/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0213b4bd Binary files /dev/null and b/lib/aci/domain/l3/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/l3/__pycache__/api.cpython-310.pyc b/lib/aci/domain/l3/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..9b8733bf Binary files /dev/null and b/lib/aci/domain/l3/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/domain/l3/__pycache__/info.cpython-310.pyc b/lib/aci/domain/l3/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..00f307d9 Binary files /dev/null and b/lib/aci/domain/l3/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/domain/l3/__pycache__/main.cpython-310.pyc b/lib/aci/domain/l3/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c4e397ec Binary files /dev/null and b/lib/aci/domain/l3/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/l3/__pycache__/output.cpython-310.pyc b/lib/aci/domain/l3/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e7ade81b Binary files /dev/null and b/lib/aci/domain/l3/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/domain/l3/api.py b/lib/aci/domain/l3/api.py new file mode 100644 index 00000000..389240d5 --- /dev/null +++ b/lib/aci/domain/l3/api.py @@ -0,0 +1,78 @@ +class DomainL3Api(): + def __init__(self): + self.domain_l3_mo = None + + def get_domain_l3_mo(self): + if self.domain_l3_mo is not None: + return self.domain_l3_mo + + cache = self.get_object_cache( + 'l3extDomP' + ) + if cache is not None: + self.domain_l3_mo = cache + self.log.apic_mo( + 'l3extDomP', + self.domain_l3_mo + ) + return self.domain_l3_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=infraRsVlanNs,infraRtDomP,extnwRtL3DomAtt,aaaDomainRef' + managed_objects = self.get_class( + 'l3extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l3_mo', + 'API failed' + ) + return None + + self.domain_l3_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3extDomP']['attributes'] + attributes['infraRsVlanNs'] = self.get_mo_child_attributes( + 'l3extDomP', + managed_object, + 'infraRsVlanNs' + ) + attributes['infraRtDomP'] = self.get_mo_children_attributes( + 'l3extDomP', + managed_object, + 'infraRtDomP' + ) + attributes['extnwRtL3DomAtt'] = self.get_mo_children_attributes( + 'l3extDomP', + managed_object, + 'extnwRtL3DomAtt' + ) + attributes['aaaDomainRef'] = self.get_mo_children_attributes( + 'l3extDomP', + managed_object, + 'aaaDomainRef' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l3extDomP', + managed_object, + 'faultCounts' + ) + + self.domain_l3_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extDomP', + self.domain_l3_mo + ) + + self.set_object_cache( + 'l3extDomP', + self.domain_l3_mo + ) + + return self.domain_l3_mo diff --git a/lib/aci/domain/l3/audit/__init__.py b/lib/aci/domain/l3/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l3/audit/api.py b/lib/aci/domain/l3/audit/api.py new file mode 100644 index 00000000..d6e1bb11 --- /dev/null +++ b/lib/aci/domain/l3/audit/api.py @@ -0,0 +1,48 @@ +class DomainL3AuditApi(): + def __init__(self): + self.domain_l3_audit_mo = None + + def get_domain_l3_audit_mo(self): + cache = self.get_object_cache( + 'l3extDomP.audit' + ) + if cache is not None: + self.domain_l3_audit_mo = cache + self.log.apic_mo( + 'l3extDomP.audit', + self.domain_l3_audit_mo + ) + return self.domain_l3_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'l3extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l3_audit_mo', + 'API failed' + ) + return None + + self.domain_l3_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.domain_l3_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extDomP.audit', + self.domain_l3_audit_mo + ) + + self.set_object_cache( + 'l3extDomP.audit', + self.domain_l3_audit_mo + ) + + return self.domain_l3_audit_mo diff --git a/lib/aci/domain/l3/audit/info.py b/lib/aci/domain/l3/audit/info.py new file mode 100644 index 00000000..912f51c8 --- /dev/null +++ b/lib/aci/domain/l3/audit/info.py @@ -0,0 +1,97 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainL3AuditInfo(): + def __init__(self): + self.domain_l3_audit = None + + def get_domain_l3_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'uni/l3dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/l3dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_l3_audit(self): + if self.domain_l3_audit is not None: + return self.domain_l3_audit + + managed_objects = self.get_domain_l3_audit_mo() + if managed_objects is None: + return None + + self.domain_l3_audit = [] + for managed_object in managed_objects: + audit_info = self.get_domain_l3_audit_info( + managed_object + ) + self.domain_l3_audit.append( + audit_info + ) + + self.log.apic_mo( + 'l3extDomP.auditRecord.info', + self.domain_l3_audit + ) + + return self.domain_l3_audit + + def get_domain_l3_id_audit(self, domain_name, audit_filter=None): + audits = [] + + all_audits = self.get_domain_l3_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['domainName'] is not None: + if audit_info['domainName'] == domain_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/domain/l3/audit/main.py b/lib/aci/domain/l3/audit/main.py new file mode 100644 index 00000000..0eaef74d --- /dev/null +++ b/lib/aci/domain/l3/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l3.audit.api import DomainL3AuditApi +from lib.aci.domain.l3.audit.info import DomainL3AuditInfo + + +class DomainL3Audit(DomainL3AuditApi, DomainL3AuditInfo): + def __init__(self): + DomainL3AuditApi.__init__(self) + DomainL3AuditInfo.__init__(self) diff --git a/lib/aci/domain/l3/event/__init__.py b/lib/aci/domain/l3/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l3/event/api.py b/lib/aci/domain/l3/event/api.py new file mode 100644 index 00000000..c59ee8ec --- /dev/null +++ b/lib/aci/domain/l3/event/api.py @@ -0,0 +1,51 @@ +class DomainL3EventApi(): + def __init__(self): + self.domain_l3_event_mo = None + + def get_domain_l3_event_mo(self): + if self.domain_l3_event_mo is not None: + return self.domain_l3_event_mo + + cache = self.get_object_cache( + 'l3extDomP.eventLog' + ) + if cache is not None: + self.domain_l3_event_mo = cache + self.log.apic_mo( + 'l3extDomP.eventLog', + self.domain_l3_event_mo + ) + return self.domain_l3_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'l3extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l3_event_mo', + 'API failed' + ) + return None + + self.domain_l3_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.domain_l3_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extDomP.eventLog', + self.domain_l3_event_mo + ) + + self.set_object_cache( + 'l3extDomP.eventLog', + self.domain_l3_event_mo + ) + + return self.domain_l3_event_mo diff --git a/lib/aci/domain/l3/event/info.py b/lib/aci/domain/l3/event/info.py new file mode 100644 index 00000000..d876bcfd --- /dev/null +++ b/lib/aci/domain/l3/event/info.py @@ -0,0 +1,107 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainL3EventInfo(): + def __init__(self): + self.domain_l3_event = None + + def get_domain_l3_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'affected' in info: + if 'uni/l3dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/l3dom-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/l3dom-' in info['dn']: + info['domainName'] = info['dn'].split('uni/l3dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_l3_event(self, deduplicate=True): + if self.domain_l3_event is not None: + return self.domain_l3_event + + managed_objects = self.get_domain_l3_event_mo() + if managed_objects is None: + return None + + self.domain_l3_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_domain_l3_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.domain_l3_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l3extDomP.eventLog.info', + self.domain_l3_event + ) + + return self.domain_l3_event + + def get_domain_l3_id_event(self, domain_name, event_filter=None): + events = [] + + all_events = self.get_domain_l3_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['domainName'] is not None: + if event_info['domainName'] == domain_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/domain/l3/event/main.py b/lib/aci/domain/l3/event/main.py new file mode 100644 index 00000000..55471d32 --- /dev/null +++ b/lib/aci/domain/l3/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l3.event.api import DomainL3EventApi +from lib.aci.domain.l3.event.info import DomainL3EventInfo + + +class DomainL3Event(DomainL3EventApi, DomainL3EventInfo): + def __init__(self): + DomainL3EventApi.__init__(self) + DomainL3EventInfo.__init__(self) diff --git a/lib/aci/domain/l3/fault/__init__.py b/lib/aci/domain/l3/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l3/fault/api.py b/lib/aci/domain/l3/fault/api.py new file mode 100644 index 00000000..15eff883 --- /dev/null +++ b/lib/aci/domain/l3/fault/api.py @@ -0,0 +1,112 @@ +class DomainL3FaultApi(): + def __init__(self): + self.domain_l3_fault_mo = None + self.domain_l3_fault_record_mo = None + + def get_domain_l3_fault_mo(self): + cache = self.get_object_cache( + 'l3extDomP.fault' + ) + if cache is not None: + self.domain_l3_fault_mo = cache + self.log.apic_mo( + 'l3extDomP.fault', + self.domain_l3_fault_mo + ) + return self.domain_l3_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'l3extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l3_fault_mo', + 'API failed' + ) + return None + + self.domain_l3_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.domain_l3_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extDomP.fault', + self.domain_l3_fault_mo + ) + + self.set_object_cache( + 'l3extDomP.fault', + self.domain_l3_fault_mo + ) + + return self.domain_l3_fault_mo + + def get_domain_l3_fault_record_mo(self): + cache = self.get_object_cache( + 'l3extDomP.faultRecord' + ) + if cache is not None: + self.domain_l3_fault_record_mo = cache + self.log.apic_mo( + 'l3extDomP.faultRecord', + self.domain_l3_fault_record_mo + ) + return self.domain_l3_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'l3extDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l3_fault_record_mo', + 'API failed' + ) + return None + + self.domain_l3_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.domain_l3_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extDomP.faultRecord', + self.domain_l3_fault_record_mo + ) + + self.set_object_cache( + 'l3extDomP.faultRecord', + self.domain_l3_fault_record_mo + ) + + return self.domain_l3_fault_record_mo diff --git a/lib/aci/domain/l3/fault/info.py b/lib/aci/domain/l3/fault/info.py new file mode 100644 index 00000000..11ba60ce --- /dev/null +++ b/lib/aci/domain/l3/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainL3FaultInfo(): + def __init__(self): + self.domain_l3_fault = None + self.domain_l3_fault_record = None + + def get_domain_l3_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/l3dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/l3dom-')[1].split('/')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/lb-[lo0]" + if info['domainName'] is None: + if 'uni/l3dom-' in info['dn']: + info['domainName'] = info['dn'].split('uni/l3dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_l3_fault(self): + if self.domain_l3_fault is not None: + return self.domain_l3_fault + + managed_objects = self.get_domain_l3_fault_mo() + if managed_objects is None: + return None + + self.domain_l3_fault = [] + for managed_object in managed_objects: + fault_info = self.get_domain_l3_fault_info( + managed_object + ) + self.domain_l3_fault.append( + fault_info + ) + + self.log.apic_mo( + 'l3extDomP.fault.info', + self.domain_l3_fault + ) + + return self.domain_l3_fault + + def get_domain_l3_fault_record(self, deduplicate=True): + if self.domain_l3_fault_record is not None: + return self.domain_l3_fault_record + + managed_objects = self.get_domain_l3_fault_record_mo() + if managed_objects is None: + return None + + self.domain_l3_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_domain_l3_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.domain_l3_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l3extDomP.faultRecord.info', + self.domain_l3_fault_record + ) + + return self.domain_l3_fault_record + + def get_domain_l3_id_fault(self, domain_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_domain_l3_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_domain_l3_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['domainName'] is not None: + if fault_info['domainName'] == domain_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/domain/l3/fault/main.py b/lib/aci/domain/l3/fault/main.py new file mode 100644 index 00000000..4e864cb2 --- /dev/null +++ b/lib/aci/domain/l3/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l3.fault.api import DomainL3FaultApi +from lib.aci.domain.l3.fault.info import DomainL3FaultInfo + + +class DomainL3Fault(DomainL3FaultApi, DomainL3FaultInfo): + def __init__(self): + DomainL3FaultApi.__init__(self) + DomainL3FaultInfo.__init__(self) diff --git a/lib/aci/domain/l3/info.py b/lib/aci/domain/l3/info.py new file mode 100644 index 00000000..b64178d3 --- /dev/null +++ b/lib/aci/domain/l3/info.py @@ -0,0 +1,311 @@ +from lib import filter_helper + + +class DomainL3Info(): + def __init__(self): + self.domain_l3 = None + + def get_domain_l3_info(self, managed_object): + keys = [ + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['aaep_names'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + info['aaep_names'].append( + item['tDn'].split('/')[2][8:] + ) + + info['reln'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'AAEP' + reln_info['name'] = item['tDn'].split('/')[2][8:] + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_l3_info', + 'Unsupported infraRtDomP tCl: %s' % (item['tCl']) + ) + + if 'extnwRtL3DomAtt' in managed_object: + if managed_object['extnwRtL3DomAtt'] is not None: + for item in managed_object['extnwRtL3DomAtt']: + # "tCl": "l3extOut", + # "tDn": "uni/tn-k8s/out-bml3_k8s" + if item['tCl'] == 'l3extOut': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'L3 Out' + reln_info['name'] = self.get_l3out_name_from_dn( + item['tDn'] + ) + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_l3_info', + 'Unsupported extnwRtL3DomAtt tCl: %s' % (item['tCl']) + ) + + info['vlan'] = None + if 'infraRsVlanNs' in managed_object: + if managed_object['infraRsVlanNs'] is not None: + if managed_object['infraRsVlanNs']['tCl'] == 'fvnsVlanInstP': + info['vlan'] = managed_object['infraRsVlanNs']['tDn'].split('vlanns-[')[1].split(']')[0] + + info['aaaDomain'] = [] + for item in managed_object['aaaDomainRef']: + info['aaaDomain'].append( + item['name'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_domains_l3_info(self): + if self.domain_l3 is not None: + return self.domain_l3 + + domains_mo = self.get_domain_l3_mo() + if domains_mo is None: + return None + + self.domain_l3 = [] + for managed_object in domains_mo: + self.domain_l3.append( + self.get_domain_l3_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l3extDomP.info', + self.domain_l3 + ) + + return self.domain_l3 + + def match_domain_l3(self, domain_info, domain_filter): + if domain_filter is None or len(domain_filter) == 0: + return True + + for aepg_rule in domain_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, domain_info['name']): + return False + + if key == 'aaep': + key_found = True + found = False + for aaep_name in domain_info['aaep_names']: + if filter_helper.match_string(value, aaep_name): + found = True + + if not found: + return False + + if key == 'pool': + key_found = True + if not filter_helper.match_string(value, domain_info['vlan']): + return False + + if key == 'vlan': + key_found = True + if 'vlan_block' in domain_info: + found = False + for vlan_block in domain_info['vlan_block']: + if filter_helper.match_integer(vlan_block, value): + found = True + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not domain_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_domain_l3', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_domain_l3', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_domains_l3( + self, + domain_filter=None, + vlan_info=False, + vlan_usage_info=False, + node_info=False, + intf_vlan_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_domains = self.get_domains_l3_info() + + domains = [] + + for domain_info in all_domains: + if not self.match_domain_l3(domain_info, domain_filter): + continue + + if vlan_info: + domain_info['vlan_info'] = None + domain_info['vlan_block'] = [] + if domain_info['vlan'] is not None: + domain_info['vlan_info'] = self.get_pool_vlan( + domain_info['vlan'], + vlan_usage_info=vlan_usage_info, + domain_name=domain_info['name'] + ) + if domain_info['vlan_info'] is not None: + for vlan_block in domain_info['vlan_info']['fvnsEncapBlk']: + domain_info['vlan_block'].append( + '%s-%s' % ( + vlan_block['fromVlan'], + vlan_block['toVlan'] + ) + ) + + if not self.match_domain_phy(domain_info, domain_filter): + continue + + if node_info: + domain_node_info = self.get_domain_l3_node( + domain_info['name'] + ) + domain_info['node'] = None + domain_info['interface'] = None + if domain_node_info is not None: + domain_info['node'] = domain_node_info['node'] + domain_info['interface'] = domain_node_info['interface'] + + if intf_vlan_info: + if domain_info['interface'] is not None: + for interface in domain_info['interface']: + interface['vlan'] = [] + interface['operSt'] = '--' + interface['operMode'] = '--' + + if interface['intf_type'] == 'l1PhysIf': + interface_info = self.get_interface_phy( + interface['pod_id'], + interface['node_id'], + interface['intf_name'], + epg_stats_info=True + ) + if interface_info is not None: + interface['operSt'] = interface_info['stats']['operSt'] + interface['__Output']['operSt'] = interface_info['stats']['__Output']['operSt'] + interface['operMode'] = interface_info['stats']['operMode'] + for intf_epg_stats in interface_info['epg_stats']: + if intf_epg_stats['vlan'] is not None: + if intf_epg_stats['vlan']['evlan'] not in interface['vlan']: + interface['vlan'].append( + intf_epg_stats['vlan']['evlan'] + ) + + interface['vlan'] = sorted( + interface['vlan'] + ) + interface['vlans'] = filter_helper.get_range_from_values( + interface['vlan'] + ) + + if fault_info: + domain_info['faultInst'] = self.get_domain_l3_id_fault( + domain_info['name'], + 'faultInst' + ) + + if hfault_info: + domain_info['faultRecord'] = self.get_domain_l3_id_fault( + domain_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + domain_info['eventLog'] = self.get_domain_l3_id_event( + domain_info['name'], + event_filter=event_filter + ) + + if audit_info: + domain_info['auditLog'] = self.get_domain_l3_id_audit( + domain_info['name'], + audit_filter=audit_filter + ) + + domains.append(domain_info) + + domains = sorted( + domains, + key=lambda i: i['name'].lower() + ) + + return domains + + def get_domain_l3(self, domain_name, vlan_info=False, vlan_usage_info=False): + domain_filter = ['name:%s' % (domain_name)] + domains = self.get_domains_l3( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info + ) + if domains is None or len(domains) != 1: + return None + return domains[0] diff --git a/lib/aci/domain/l3/main.py b/lib/aci/domain/l3/main.py new file mode 100644 index 00000000..68946a27 --- /dev/null +++ b/lib/aci/domain/l3/main.py @@ -0,0 +1,23 @@ +from lib.aci.domain.l3.api import DomainL3Api +from lib.aci.domain.l3.info import DomainL3Info +from lib.aci.domain.l3.audit.main import DomainL3Audit +from lib.aci.domain.l3.event.main import DomainL3Event +from lib.aci.domain.l3.fault.main import DomainL3Fault +from lib.aci.domain.l3.node.main import DomainL3Node + + +class DomainL3( + DomainL3Api, + DomainL3Info, + DomainL3Audit, + DomainL3Event, + DomainL3Fault, + DomainL3Node + ): + def __init__(self): + DomainL3Api.__init__(self) + DomainL3Info.__init__(self) + DomainL3Audit.__init__(self) + DomainL3Event.__init__(self) + DomainL3Fault.__init__(self) + DomainL3Node.__init__(self) diff --git a/lib/aci/domain/l3/node/__init__.py b/lib/aci/domain/l3/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/l3/node/api.py b/lib/aci/domain/l3/node/api.py new file mode 100644 index 00000000..93d5ea3d --- /dev/null +++ b/lib/aci/domain/l3/node/api.py @@ -0,0 +1,61 @@ +class DomainL3NodeApi(): + def __init__(self): + self.domain_l3_node_mo = {} + + def get_domain_l3_node_mo(self, domain_name): + if domain_name in self.domain_l3_node_mo: + return self.domain_l3_node_mo[domain_name] + + key = domain_name + cache = self.get_object_cache( + 'l3extDomP.%s' % (key) + ) + if cache is not None: + self.domain_l3_node_mo[key] = cache + self.log.apic_mo( + 'l3extDomP.%s' % (key), + self.domain_l3_node_mo[key] + ) + return self.domain_l3_node_mo[key] + + distinguished_name = 'uni/l3dom-%s' % (domain_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=ADomPToEthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_l3_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_domain_l3_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3extDomP']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'l3extDomP', + managed_object + ) + self.domain_l3_node_mo[key] = attributes + + self.log.apic_mo( + 'l3extDomP.%s' % (key), + self.domain_l3_node_mo[key] + ) + + self.set_object_cache( + 'l3extDomP.%s' % (key), + self.domain_l3_node_mo[key] + ) + + return self.domain_l3_node_mo[key] diff --git a/lib/aci/domain/l3/node/info.py b/lib/aci/domain/l3/node/info.py new file mode 100644 index 00000000..4c0b94c0 --- /dev/null +++ b/lib/aci/domain/l3/node/info.py @@ -0,0 +1,81 @@ +class DomainL3NodeInfo(): + def __init__(self): + self.domain_l3_node = {} + + def get_domain_l3_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/l3s-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_domain_l3_node(self, domain_name): + if domain_name in self.domain_l3_node: + return self.domain_l3_node[domain_name] + + # one object or None value is expected + domain_nodes_mo = self.get_domain_l3_node_mo(domain_name) + if domain_nodes_mo is None: + return None + + self.domain_l3_node[domain_name] = self.get_domain_l3_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'l3extDomP.%s.info' % (domain_name), + self.domain_l3_node[domain_name] + ) + + return self.domain_l3_node[domain_name] diff --git a/lib/aci/domain/l3/node/main.py b/lib/aci/domain/l3/node/main.py new file mode 100644 index 00000000..c98bdd04 --- /dev/null +++ b/lib/aci/domain/l3/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.l3.node.api import DomainL3NodeApi +from lib.aci.domain.l3.node.info import DomainL3NodeInfo + + +class DomainL3Node(DomainL3NodeApi, DomainL3NodeInfo): + def __init__(self): + DomainL3NodeApi.__init__(self) + DomainL3NodeInfo.__init__(self) diff --git a/lib/aci/domain/l3/output.py b/lib/aci/domain/l3/output.py new file mode 100644 index 00000000..30894115 --- /dev/null +++ b/lib/aci/domain/l3/output.py @@ -0,0 +1,455 @@ +class DomainL3Output(): + def __init__(self): + pass + + def print_domains_l3(self, info, title=False): + if title: + self.my_output.default( + 'L3 Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + for item in info: + if len(item['aaaDomain']) == 0: + item['aaaDomain'].append('--') + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'vlan_info.allocMode', + 'fvnsEncapBlk.blockInfo', + 'aaaDomain' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Mode', + 'Encapsulation Block', + 'Sec Domain' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'fvnsEncapBlk', 'aaaDomain'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l3_node(self, info, title=False): + if title: + self.my_output.default( + 'L3 Domain - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l3_interface(self, info, title=False): + if title: + self.my_output.default( + 'L3 Domain - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l3_vlan(self, info, title=False): + if title: + self.my_output.default( + 'L3 Domain - Interfaces VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'fvnsEncapBlk.blockInfo', + 'interface.node_name', + 'interface.intf_name', + 'interface.operSt', + 'interface.operMode', + 'interface.vlans' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Encapsulation Block', + 'Node', + 'Interface', + 'State', + 'Mode', + 'VLANs' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface', 'fvnsEncapBlk'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l3_reln(self, info, title=False): + if title: + self.my_output.default( + 'L3 Domain - Policy Relationships [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'reln.type', + 'reln.name' + ] + + headers = [ + 'Faults', + 'Domain', + 'Policy Type', + 'Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['reln'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_l3_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L3 Domain - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L3 Domain - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_domains_l3_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'L3 Domain - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_l3_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L3 Domain - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L3 Domain - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_l3_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L3 Domain - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L3 Domain - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/domain/main.py b/lib/aci/domain/main.py new file mode 100644 index 00000000..bef52a33 --- /dev/null +++ b/lib/aci/domain/main.py @@ -0,0 +1,32 @@ +from lib.aci.domain.aaa.main import DomainAaa +from lib.aci.domain.l2.main import DomainL2 +from lib.aci.domain.l3.main import DomainL3 +from lib.aci.domain.phy.main import DomainPhy +from lib.aci.domain.vmm.main import DomainVmm + + +class Domain( + DomainAaa, + DomainL2, + DomainL3, + DomainPhy, + DomainVmm + ): + def __init__(self): + DomainAaa.__init__(self) + DomainL2.__init__(self) + DomainL3.__init__(self) + DomainPhy.__init__(self) + DomainVmm.__init__(self) + + def get_domain_type_from_tcl(self, domain_type): + mapping = {} + mapping['l3extDomP'] = 'L3' + mapping['physDomP'] = 'Physical' + mapping['l2extDomP'] = 'L2' + mapping['vmmDomP'] = 'VMM' + + if domain_type in mapping: + return mapping[domain_type] + + return domain_type diff --git a/lib/aci/domain/output.py b/lib/aci/domain/output.py new file mode 100644 index 00000000..ac12e700 --- /dev/null +++ b/lib/aci/domain/output.py @@ -0,0 +1,14 @@ +from lib.aci.domain.aaa.output import DomainAaaOutput +from lib.aci.domain.l2.output import DomainL2Output +from lib.aci.domain.l3.output import DomainL3Output +from lib.aci.domain.phy.output import DomainPhyOutput +from lib.aci.domain.vmm.output import DomainVmmOutput + + +class DomainOutput(DomainAaaOutput, DomainL2Output, DomainL3Output, DomainPhyOutput, DomainVmmOutput): + def __init__(self): + DomainAaaOutput.__init__(self) + DomainL2Output.__init__(self) + DomainL3Output.__init__(self) + DomainPhyOutput.__init__(self) + DomainVmmOutput.__init__(self) diff --git a/lib/aci/domain/phy/TODO.md b/lib/aci/domain/phy/TODO.md new file mode 100644 index 00000000..4f6b61ad --- /dev/null +++ b/lib/aci/domain/phy/TODO.md @@ -0,0 +1,8 @@ +Domain Physical +--------------- + +- context for vlan pool +- context for aaep +- context for node +- context for intf +- context for epg \ No newline at end of file diff --git a/lib/aci/domain/phy/__init__.py b/lib/aci/domain/phy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/phy/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/phy/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0213b4bd Binary files /dev/null and b/lib/aci/domain/phy/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/phy/__pycache__/api.cpython-310.pyc b/lib/aci/domain/phy/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..30de154e Binary files /dev/null and b/lib/aci/domain/phy/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/domain/phy/__pycache__/info.cpython-310.pyc b/lib/aci/domain/phy/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..fcf2c3a0 Binary files /dev/null and b/lib/aci/domain/phy/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/domain/phy/__pycache__/main.cpython-310.pyc b/lib/aci/domain/phy/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..cdabbd8a Binary files /dev/null and b/lib/aci/domain/phy/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/phy/__pycache__/output.cpython-310.pyc b/lib/aci/domain/phy/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..870b1dd4 Binary files /dev/null and b/lib/aci/domain/phy/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/domain/phy/api.py b/lib/aci/domain/phy/api.py new file mode 100644 index 00000000..b52ea3b2 --- /dev/null +++ b/lib/aci/domain/phy/api.py @@ -0,0 +1,78 @@ +class DomainPhyApi(): + def __init__(self): + self.domain_phy_mo = None + + def get_domain_phy_mo(self): + if self.domain_phy_mo is not None: + return self.domain_phy_mo + + cache = self.get_object_cache( + 'physDomP' + ) + if cache is not None: + self.domain_phy_mo = cache + self.log.apic_mo( + 'physDomP', + self.domain_phy_mo + ) + return self.domain_phy_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=infraRsVlanNs,infraRtDomP,infraRtDomAtt,aaaDomainRef' + managed_objects = self.get_class( + 'physDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_phy_mo', + 'API failed' + ) + return None + + self.domain_phy_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['physDomP']['attributes'] + attributes['infraRsVlanNs'] = self.get_mo_child_attributes( + 'physDomP', + managed_object, + 'infraRsVlanNs' + ) + attributes['infraRtDomP'] = self.get_mo_children_attributes( + 'physDomP', + managed_object, + 'infraRtDomP' + ) + attributes['infraRtDomAtt'] = self.get_mo_children_attributes( + 'physDomP', + managed_object, + 'infraRtDomAtt' + ) + attributes['aaaDomainRef'] = self.get_mo_children_attributes( + 'physDomP', + managed_object, + 'aaaDomainRef' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'physDomP', + managed_object, + 'faultCounts' + ) + + self.domain_phy_mo.append( + attributes + ) + + self.log.apic_mo( + 'physDomP', + self.domain_phy_mo + ) + + self.set_object_cache( + 'physDomP', + self.domain_phy_mo + ) + + return self.domain_phy_mo diff --git a/lib/aci/domain/phy/audit/__init__.py b/lib/aci/domain/phy/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/phy/audit/api.py b/lib/aci/domain/phy/audit/api.py new file mode 100644 index 00000000..8cb16419 --- /dev/null +++ b/lib/aci/domain/phy/audit/api.py @@ -0,0 +1,48 @@ +class DomainPhyAuditApi(): + def __init__(self): + self.domain_phy_audit_mo = None + + def get_domain_phy_audit_mo(self): + cache = self.get_object_cache( + 'physDomP.audit' + ) + if cache is not None: + self.domain_phy_audit_mo = cache + self.log.apic_mo( + 'physDomP.audit', + self.domain_phy_audit_mo + ) + return self.domain_phy_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'physDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_phy_audit_mo', + 'API failed' + ) + return None + + self.domain_phy_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.domain_phy_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'physDomP.audit', + self.domain_phy_audit_mo + ) + + self.set_object_cache( + 'physDomP.audit', + self.domain_phy_audit_mo + ) + + return self.domain_phy_audit_mo diff --git a/lib/aci/domain/phy/audit/info.py b/lib/aci/domain/phy/audit/info.py new file mode 100644 index 00000000..928547ab --- /dev/null +++ b/lib/aci/domain/phy/audit/info.py @@ -0,0 +1,97 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainPhyAuditInfo(): + def __init__(self): + self.domain_phy_audit = None + + def get_domain_phy_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'uni/phys-' in info['affected']: + info['domainName'] = info['affected'].split('uni/phys-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_phy_audit(self): + if self.domain_phy_audit is not None: + return self.domain_phy_audit + + managed_objects = self.get_domain_phy_audit_mo() + if managed_objects is None: + return None + + self.domain_phy_audit = [] + for managed_object in managed_objects: + audit_info = self.get_domain_phy_audit_info( + managed_object + ) + self.domain_phy_audit.append( + audit_info + ) + + self.log.apic_mo( + 'physDomP.auditRecord.info', + self.domain_phy_audit + ) + + return self.domain_phy_audit + + def get_domain_phy_id_audit(self, domain_name, audit_filter=None): + audits = [] + + all_audits = self.get_domain_phy_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['domainName'] is not None: + if audit_info['domainName'] == domain_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/domain/phy/audit/main.py b/lib/aci/domain/phy/audit/main.py new file mode 100644 index 00000000..0f0ea2b9 --- /dev/null +++ b/lib/aci/domain/phy/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.phy.audit.api import DomainPhyAuditApi +from lib.aci.domain.phy.audit.info import DomainPhyAuditInfo + + +class DomainPhyAudit(DomainPhyAuditApi, DomainPhyAuditInfo): + def __init__(self): + DomainPhyAuditApi.__init__(self) + DomainPhyAuditInfo.__init__(self) diff --git a/lib/aci/domain/phy/event/__init__.py b/lib/aci/domain/phy/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/phy/event/api.py b/lib/aci/domain/phy/event/api.py new file mode 100644 index 00000000..8539cf00 --- /dev/null +++ b/lib/aci/domain/phy/event/api.py @@ -0,0 +1,51 @@ +class DomainPhyEventApi(): + def __init__(self): + self.domain_phy_event_mo = None + + def get_domain_phy_event_mo(self): + if self.domain_phy_event_mo is not None: + return self.domain_phy_event_mo + + cache = self.get_object_cache( + 'physDomP.eventLog' + ) + if cache is not None: + self.domain_phy_event_mo = cache + self.log.apic_mo( + 'physDomP.eventLog', + self.domain_phy_event_mo + ) + return self.domain_phy_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'physDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_phy_event_mo', + 'API failed' + ) + return None + + self.domain_phy_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.domain_phy_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'physDomP.eventLog', + self.domain_phy_event_mo + ) + + self.set_object_cache( + 'physDomP.eventLog', + self.domain_phy_event_mo + ) + + return self.domain_phy_event_mo diff --git a/lib/aci/domain/phy/event/info.py b/lib/aci/domain/phy/event/info.py new file mode 100644 index 00000000..662eca37 --- /dev/null +++ b/lib/aci/domain/phy/event/info.py @@ -0,0 +1,107 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainPhyEventInfo(): + def __init__(self): + self.domain_phy_event = None + + def get_domain_phy_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'affected' in info: + if 'uni/phys-' in info['affected']: + info['domainName'] = info['affected'].split('uni/phys-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/phys-' in info['dn']: + info['domainName'] = info['dn'].split('uni/phys-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_phy_event(self, deduplicate=True): + if self.domain_phy_event is not None: + return self.domain_phy_event + + managed_objects = self.get_domain_phy_event_mo() + if managed_objects is None: + return None + + self.domain_phy_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_domain_phy_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.domain_phy_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'physDomP.eventLog.info', + self.domain_phy_event + ) + + return self.domain_phy_event + + def get_domain_phy_id_event(self, domain_name, event_filter=None): + events = [] + + all_events = self.get_domain_phy_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['domainName'] is not None: + if event_info['domainName'] == domain_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/domain/phy/event/main.py b/lib/aci/domain/phy/event/main.py new file mode 100644 index 00000000..1c8ac988 --- /dev/null +++ b/lib/aci/domain/phy/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.phy.event.api import DomainPhyEventApi +from lib.aci.domain.phy.event.info import DomainPhyEventInfo + + +class DomainPhyEvent(DomainPhyEventApi, DomainPhyEventInfo): + def __init__(self): + DomainPhyEventApi.__init__(self) + DomainPhyEventInfo.__init__(self) diff --git a/lib/aci/domain/phy/fault/__init__.py b/lib/aci/domain/phy/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/phy/fault/api.py b/lib/aci/domain/phy/fault/api.py new file mode 100644 index 00000000..a85b7e88 --- /dev/null +++ b/lib/aci/domain/phy/fault/api.py @@ -0,0 +1,112 @@ +class DomainPhyFaultApi(): + def __init__(self): + self.domain_phy_fault_mo = None + self.domain_phy_fault_record_mo = None + + def get_domain_phy_fault_mo(self): + cache = self.get_object_cache( + 'physDomP.fault' + ) + if cache is not None: + self.domain_phy_fault_mo = cache + self.log.apic_mo( + 'physDomP.fault', + self.domain_phy_fault_mo + ) + return self.domain_phy_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'physDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_phy_fault_mo', + 'API failed' + ) + return None + + self.domain_phy_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.domain_phy_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'physDomP.fault', + self.domain_phy_fault_mo + ) + + self.set_object_cache( + 'physDomP.fault', + self.domain_phy_fault_mo + ) + + return self.domain_phy_fault_mo + + def get_domain_phy_fault_record_mo(self): + cache = self.get_object_cache( + 'physDomP.faultRecord' + ) + if cache is not None: + self.domain_phy_fault_record_mo = cache + self.log.apic_mo( + 'physDomP.faultRecord', + self.domain_phy_fault_record_mo + ) + return self.domain_phy_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'physDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_phy_fault_record_mo', + 'API failed' + ) + return None + + self.domain_phy_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.domain_phy_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'physDomP.faultRecord', + self.domain_phy_fault_record_mo + ) + + self.set_object_cache( + 'physDomP.faultRecord', + self.domain_phy_fault_record_mo + ) + + return self.domain_phy_fault_record_mo diff --git a/lib/aci/domain/phy/fault/info.py b/lib/aci/domain/phy/fault/info.py new file mode 100644 index 00000000..849c91fc --- /dev/null +++ b/lib/aci/domain/phy/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainPhyFaultInfo(): + def __init__(self): + self.domain_phy_fault = None + self.domain_phy_fault_record = None + + def get_domain_phy_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/phys-' in info['affected']: + info['domainName'] = info['affected'].split('uni/phys-')[1].split('/')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/lb-[lo0]" + if info['domainName'] is None: + if 'uni/phys-' in info['dn']: + info['domainName'] = info['dn'].split('uni/phys-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_phy_fault(self): + if self.domain_phy_fault is not None: + return self.domain_phy_fault + + managed_objects = self.get_domain_phy_fault_mo() + if managed_objects is None: + return None + + self.domain_phy_fault = [] + for managed_object in managed_objects: + fault_info = self.get_domain_phy_fault_info( + managed_object + ) + self.domain_phy_fault.append( + fault_info + ) + + self.log.apic_mo( + 'physDomP.fault.info', + self.domain_phy_fault + ) + + return self.domain_phy_fault + + def get_domain_phy_fault_record(self, deduplicate=True): + if self.domain_phy_fault_record is not None: + return self.domain_phy_fault_record + + managed_objects = self.get_domain_phy_fault_record_mo() + if managed_objects is None: + return None + + self.domain_phy_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_domain_phy_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.domain_phy_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'physDomP.faultRecord.info', + self.domain_phy_fault_record + ) + + return self.domain_phy_fault_record + + def get_domain_phy_id_fault(self, domain_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_domain_phy_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_domain_phy_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['domainName'] is not None: + if fault_info['domainName'] == domain_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/domain/phy/fault/main.py b/lib/aci/domain/phy/fault/main.py new file mode 100644 index 00000000..8e621eaf --- /dev/null +++ b/lib/aci/domain/phy/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.phy.fault.api import DomainPhyFaultApi +from lib.aci.domain.phy.fault.info import DomainPhyFaultInfo + + +class DomainPhyFault(DomainPhyFaultApi, DomainPhyFaultInfo): + def __init__(self): + DomainPhyFaultApi.__init__(self) + DomainPhyFaultInfo.__init__(self) diff --git a/lib/aci/domain/phy/info.py b/lib/aci/domain/phy/info.py new file mode 100644 index 00000000..abc28bf2 --- /dev/null +++ b/lib/aci/domain/phy/info.py @@ -0,0 +1,319 @@ +from lib import filter_helper + + +class DomainPhyInfo(): + def __init__(self): + self.domain_phy = None + + def get_domain_phy_info(self, managed_object): + keys = [ + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['aaep_names'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + info['aaep_names'].append( + item['tDn'].split('/')[2][8:] + ) + + info['reln'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'AAEP' + reln_info['name'] = item['tDn'].split('/')[2][8:] + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_phy_info', + 'Unsupported infraRtDomP tCl: %s' % (item['tCl']) + ) + + if 'infraRtDomAtt' in managed_object: + if managed_object['infraRtDomAtt'] is not None: + for item in managed_object['infraRtDomAtt']: + # "tCl": "fvAEPg", + # "tDn": "uni/tn-k8s/ap-k8s_ANP/epg-site1_pe" + if item['tCl'] == 'fvAEPg': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'Application EPG' + reln_info['name'] = self.get_epg_name_from_dn( + item['tDn'] + ) + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_phy_info', + 'Unsupported infraRtDomAtt tCl: %s' % (item['tCl']) + ) + + info['reln'] = sorted( + info['reln'], + key=lambda i: ( + i['tCl'], + i['tDn'] + ) + ) + + info['vlan'] = None + if 'infraRsVlanNs' in managed_object: + if managed_object['infraRsVlanNs'] is not None: + if managed_object['infraRsVlanNs']['tCl'] == 'fvnsVlanInstP': + info['vlan'] = managed_object['infraRsVlanNs']['tDn'].split('vlanns-[')[1].split(']')[0] + + info['aaaDomain'] = [] + for item in managed_object['aaaDomainRef']: + info['aaaDomain'].append( + item['name'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_domains_phy_info(self): + if self.domain_phy is not None: + return self.domain_phy + + domains_mo = self.get_domain_phy_mo() + if domains_mo is None: + return None + + self.domain_phy = [] + for managed_object in domains_mo: + self.domain_phy.append( + self.get_domain_phy_info( + managed_object + ) + ) + + self.log.apic_mo( + 'physDomP.info', + self.domain_phy + ) + + return self.domain_phy + + def match_domain_phy(self, domain_info, domain_filter): + if domain_filter is None or len(domain_filter) == 0: + return True + + for aepg_rule in domain_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, domain_info['name']): + return False + + if key == 'aaep': + key_found = True + found = False + for aaep_name in domain_info['aaep_names']: + if filter_helper.match_string(value, aaep_name): + found = True + + if not found: + return False + + if key == 'pool': + key_found = True + if not filter_helper.match_string(value, domain_info['vlan']): + return False + + if key == 'vlan': + key_found = True + if 'vlan_block' in domain_info: + found = False + for vlan_block in domain_info['vlan_block']: + if filter_helper.match_integer(vlan_block, value): + found = True + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not domain_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_domain_phy', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_domain_phy', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_domains_phy( + self, + domain_filter=None, + vlan_info=False, + vlan_usage_info=False, + node_info=False, + intf_vlan_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_domains = self.get_domains_phy_info() + + domains = [] + + for domain_info in all_domains: + if not self.match_domain_phy(domain_info, domain_filter): + continue + + if vlan_info: + domain_info['vlan_info'] = None + domain_info['vlan_block'] = [] + if domain_info['vlan'] is not None: + domain_info['vlan_info'] = self.get_pool_vlan( + domain_info['vlan'], + vlan_usage_info=vlan_usage_info, + domain_name=domain_info['name'] + ) + if domain_info['vlan_info'] is not None: + for vlan_block in domain_info['vlan_info']['fvnsEncapBlk']: + domain_info['vlan_block'].append( + '%s-%s' % ( + vlan_block['fromVlan'], + vlan_block['toVlan'] + ) + ) + + if not self.match_domain_phy(domain_info, domain_filter): + continue + + if node_info: + domain_node_info = self.get_domain_phy_node( + domain_info['name'] + ) + domain_info['node'] = None + domain_info['interface'] = None + if domain_node_info is not None: + domain_info['node'] = domain_node_info['node'] + domain_info['interface'] = domain_node_info['interface'] + + if intf_vlan_info: + if domain_info['interface'] is not None: + for interface in domain_info['interface']: + interface['vlan'] = [] + interface['operSt'] = '--' + interface['operMode'] = '--' + + if interface['intf_type'] == 'l1PhysIf': + interface_info = self.get_interface_phy( + interface['pod_id'], + interface['node_id'], + interface['intf_name'], + epg_stats_info=True + ) + if interface_info is not None: + interface['operSt'] = interface_info['stats']['operSt'] + interface['__Output']['operSt'] = interface_info['stats']['__Output']['operSt'] + interface['operMode'] = interface_info['stats']['operMode'] + for intf_epg_stats in interface_info['epg_stats']: + if intf_epg_stats['vlan'] is not None: + if intf_epg_stats['vlan']['evlan'] not in interface['vlan']: + interface['vlan'].append( + intf_epg_stats['vlan']['evlan'] + ) + + interface['vlan'] = sorted( + interface['vlan'] + ) + interface['vlans'] = filter_helper.get_range_from_values( + interface['vlan'] + ) + + if fault_info: + domain_info['faultInst'] = self.get_domain_phy_id_fault( + domain_info['name'], + 'faultInst' + ) + + if hfault_info: + domain_info['faultRecord'] = self.get_domain_phy_id_fault( + domain_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + domain_info['eventLog'] = self.get_domain_phy_id_event( + domain_info['name'], + event_filter=event_filter + ) + + if audit_info: + domain_info['auditLog'] = self.get_domain_phy_id_audit( + domain_info['name'], + audit_filter=audit_filter + ) + + domains.append(domain_info) + + domains = sorted( + domains, + key=lambda i: i['name'].lower() + ) + + return domains + + def get_domain_phy(self, domain_name, vlan_info=False, vlan_usage_info=False): + domain_filter = ['name:%s' % (domain_name)] + domains = self.get_domains_phy( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info + ) + if domains is None or len(domains) != 1: + return None + return domains[0] diff --git a/lib/aci/domain/phy/main.py b/lib/aci/domain/phy/main.py new file mode 100644 index 00000000..a3c88730 --- /dev/null +++ b/lib/aci/domain/phy/main.py @@ -0,0 +1,23 @@ +from lib.aci.domain.phy.api import DomainPhyApi +from lib.aci.domain.phy.info import DomainPhyInfo +from lib.aci.domain.phy.audit.main import DomainPhyAudit +from lib.aci.domain.phy.event.main import DomainPhyEvent +from lib.aci.domain.phy.fault.main import DomainPhyFault +from lib.aci.domain.phy.node.main import DomainPhyNode + + +class DomainPhy( + DomainPhyApi, + DomainPhyInfo, + DomainPhyAudit, + DomainPhyEvent, + DomainPhyFault, + DomainPhyNode + ): + def __init__(self): + DomainPhyApi.__init__(self) + DomainPhyInfo.__init__(self) + DomainPhyAudit.__init__(self) + DomainPhyEvent.__init__(self) + DomainPhyFault.__init__(self) + DomainPhyNode.__init__(self) diff --git a/lib/aci/domain/phy/node/__init__.py b/lib/aci/domain/phy/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/phy/node/api.py b/lib/aci/domain/phy/node/api.py new file mode 100644 index 00000000..28a78ec0 --- /dev/null +++ b/lib/aci/domain/phy/node/api.py @@ -0,0 +1,61 @@ +class DomainPhyNodeApi(): + def __init__(self): + self.domain_phy_node_mo = {} + + def get_domain_phy_node_mo(self, domain_name): + if domain_name in self.domain_phy_node_mo: + return self.domain_phy_node_mo[domain_name] + + key = domain_name + cache = self.get_object_cache( + 'physDomP.%s' % (key) + ) + if cache is not None: + self.domain_phy_node_mo[key] = cache + self.log.apic_mo( + 'physDomP.%s' % (key), + self.domain_phy_node_mo[key] + ) + return self.domain_phy_node_mo[key] + + distinguished_name = 'uni/phys-%s' % (domain_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=ADomPToEthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_phy_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_domain_phy_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['physDomP']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'physDomP', + managed_object + ) + self.domain_phy_node_mo[key] = attributes + + self.log.apic_mo( + 'physDomP.%s' % (key), + self.domain_phy_node_mo[key] + ) + + self.set_object_cache( + 'physDomP.%s' % (key), + self.domain_phy_node_mo[key] + ) + + return self.domain_phy_node_mo[key] diff --git a/lib/aci/domain/phy/node/info.py b/lib/aci/domain/phy/node/info.py new file mode 100644 index 00000000..c3768710 --- /dev/null +++ b/lib/aci/domain/phy/node/info.py @@ -0,0 +1,81 @@ +class DomainPhyNodeInfo(): + def __init__(self): + self.domain_phy_node = {} + + def get_domain_phy_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/phys-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_domain_phy_node(self, domain_name): + if domain_name in self.domain_phy_node: + return self.domain_phy_node[domain_name] + + # one object or None value is expected + domain_nodes_mo = self.get_domain_phy_node_mo(domain_name) + if domain_nodes_mo is None: + return None + + self.domain_phy_node[domain_name] = self.get_domain_phy_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'physDomP.%s.info' % (domain_name), + self.domain_phy_node[domain_name] + ) + + return self.domain_phy_node[domain_name] diff --git a/lib/aci/domain/phy/node/main.py b/lib/aci/domain/phy/node/main.py new file mode 100644 index 00000000..55e1fea2 --- /dev/null +++ b/lib/aci/domain/phy/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.phy.node.api import DomainPhyNodeApi +from lib.aci.domain.phy.node.info import DomainPhyNodeInfo + + +class DomainPhyNode(DomainPhyNodeApi, DomainPhyNodeInfo): + def __init__(self): + DomainPhyNodeApi.__init__(self) + DomainPhyNodeInfo.__init__(self) diff --git a/lib/aci/domain/phy/output.py b/lib/aci/domain/phy/output.py new file mode 100644 index 00000000..a5a9bfef --- /dev/null +++ b/lib/aci/domain/phy/output.py @@ -0,0 +1,455 @@ +class DomainPhyOutput(): + def __init__(self): + pass + + def print_domains_phy(self, info, title=False): + if title: + self.my_output.default( + 'Physical Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + for item in info: + if len(item['aaaDomain']) == 0: + item['aaaDomain'].append('--') + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'vlan_info.allocMode', + 'fvnsEncapBlk.blockInfo', + 'aaaDomain' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Mode', + 'Encapsulation Block', + 'Sec Domain' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'fvnsEncapBlk', 'aaaDomain'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_phy_node(self, info, title=False): + if title: + self.my_output.default( + 'Physical Domain - Node [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_phy_interface(self, info, title=False): + if title: + self.my_output.default( + 'Physical Domain - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_phy_vlan(self, info, title=False): + if title: + self.my_output.default( + 'Physical Domain - Interfaces VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'fvnsEncapBlk.blockInfo', + 'interface.node_name', + 'interface.intf_name', + 'interface.operSt', + 'interface.operMode', + 'interface.vlans' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Encapsulation Block', + 'Node', + 'Interface', + 'State', + 'Mode', + 'VLANs' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface', 'fvnsEncapBlk'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_phy_reln(self, info, title=False): + if title: + self.my_output.default( + 'Physical Domain - Policy Relationships [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'reln.type', + 'reln.name' + ] + + headers = [ + 'Faults', + 'Domain', + 'Policy Type', + 'Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['reln'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_phy_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Physical Domain - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Physical Domain - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_domains_phy_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Physical Domain - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_phy_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Physical Domain - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Physical Domain - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_phy_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Physical Domain - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Physical Domain - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/domain/vmm/__init__.py b/lib/aci/domain/vmm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/vmm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0213b4bd Binary files /dev/null and b/lib/aci/domain/vmm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/__pycache__/api.cpython-310.pyc b/lib/aci/domain/vmm/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5c85773e Binary files /dev/null and b/lib/aci/domain/vmm/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/__pycache__/info.cpython-310.pyc b/lib/aci/domain/vmm/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e7515434 Binary files /dev/null and b/lib/aci/domain/vmm/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/__pycache__/main.cpython-310.pyc b/lib/aci/domain/vmm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..fa45aa85 Binary files /dev/null and b/lib/aci/domain/vmm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/__pycache__/output.cpython-310.pyc b/lib/aci/domain/vmm/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..0f80ead0 Binary files /dev/null and b/lib/aci/domain/vmm/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/api.py b/lib/aci/domain/vmm/api.py new file mode 100644 index 00000000..9dbfed52 --- /dev/null +++ b/lib/aci/domain/vmm/api.py @@ -0,0 +1,97 @@ +class DomainVmmApi(): + def __init__(self): + self.domain_vmm_mo = None + + def get_domain_vmm_mo(self): + if self.domain_vmm_mo is not None: + return self.domain_vmm_mo + + cache = self.get_object_cache( + 'vmmDomP' + ) + if cache is not None: + self.domain_vmm_mo = cache + self.log.apic_mo( + 'vmmDomP', + self.domain_vmm_mo + ) + return self.domain_vmm_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=infraRtDomP,vmmUplinkPCont,infraRsVlanNs,vmmUsrAccP,vmmCtrlrP,vmmVSwitchPolicyCont,aaaDomainRef,vmmEpPD' + managed_objects = self.get_class( + 'vmmDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_mo', + 'API failed' + ) + return None + + self.domain_vmm_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['vmmDomP']['attributes'] + attributes['vmmVSwitchPolicyCont'] = self.get_mo_child_attributes( + 'vmmDomP', + managed_object, + 'vmmVSwitchPolicyCont' + ) + attributes['vmmUsrAccP'] = self.get_mo_children_attributes( + 'vmmDomP', + managed_object, + 'vmmUsrAccP' + ) + attributes['vmmUplinkPCont'] = self.get_mo_child_attributes( + 'vmmDomP', + managed_object, + 'vmmUplinkPCont' + ) + attributes['infraRtDomP'] = self.get_mo_children_attributes( + 'vmmDomP', + managed_object, + 'infraRtDomP' + ) + attributes['vmmCtrlrP'] = self.get_mo_children_attributes( + 'vmmDomP', + managed_object, + 'vmmCtrlrP' + ) + attributes['infraRsVlanNs'] = self.get_mo_child_attributes( + 'vmmDomP', + managed_object, + 'infraRsVlanNs' + ) + attributes['aaaDomainRef'] = self.get_mo_children_attributes( + 'vmmDomP', + managed_object, + 'aaaDomainRef' + ) + attributes['vmmEpPD'] = self.get_mo_children_attributes( + 'vmmDomP', + managed_object, + 'vmmEpPD' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vmmDomP', + managed_object, + 'faultCounts' + ) + self.domain_vmm_mo.append( + attributes + ) + + self.log.apic_mo( + 'vmmDomP', + self.domain_vmm_mo + ) + + self.set_object_cache( + 'vmmDomP', + self.domain_vmm_mo + ) + + return self.domain_vmm_mo diff --git a/lib/aci/domain/vmm/audit/__init__.py b/lib/aci/domain/vmm/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/audit/api.py b/lib/aci/domain/vmm/audit/api.py new file mode 100644 index 00000000..9b049574 --- /dev/null +++ b/lib/aci/domain/vmm/audit/api.py @@ -0,0 +1,48 @@ +class DomainVmmAuditApi(): + def __init__(self): + self.domain_vmm_audit_mo = None + + def get_domain_vmm_audit_mo(self): + cache = self.get_object_cache( + 'vmmDomP.audit' + ) + if cache is not None: + self.domain_vmm_audit_mo = cache + self.log.apic_mo( + 'vmmDomP.audit', + self.domain_vmm_audit_mo + ) + return self.domain_vmm_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'vmmDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_audit_mo', + 'API failed' + ) + return None + + self.domain_vmm_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.domain_vmm_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'vmmDomP.audit', + self.domain_vmm_audit_mo + ) + + self.set_object_cache( + 'vmmDomP.audit', + self.domain_vmm_audit_mo + ) + + return self.domain_vmm_audit_mo diff --git a/lib/aci/domain/vmm/audit/info.py b/lib/aci/domain/vmm/audit/info.py new file mode 100644 index 00000000..2393bdd7 --- /dev/null +++ b/lib/aci/domain/vmm/audit/info.py @@ -0,0 +1,97 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainVmmAuditInfo(): + def __init__(self): + self.domain_vmm_audit = None + + def get_domain_vmm_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'uni/vmmp-VMware/dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/vmmp-VMware/dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_vmm_audit(self): + if self.domain_vmm_audit is not None: + return self.domain_vmm_audit + + managed_objects = self.get_domain_vmm_audit_mo() + if managed_objects is None: + return None + + self.domain_vmm_audit = [] + for managed_object in managed_objects: + audit_info = self.get_domain_vmm_audit_info( + managed_object + ) + self.domain_vmm_audit.append( + audit_info + ) + + self.log.apic_mo( + 'vmmDomP.auditRecord.info', + self.domain_vmm_audit + ) + + return self.domain_vmm_audit + + def get_domain_vmm_id_audit(self, domain_name, audit_filter=None): + audits = [] + + all_audits = self.get_domain_vmm_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['domainName'] is not None: + if audit_info['domainName'] == domain_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/domain/vmm/audit/main.py b/lib/aci/domain/vmm/audit/main.py new file mode 100644 index 00000000..5a2de8e4 --- /dev/null +++ b/lib/aci/domain/vmm/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.vmm.audit.api import DomainVmmAuditApi +from lib.aci.domain.vmm.audit.info import DomainVmmAuditInfo + + +class DomainVmmAudit(DomainVmmAuditApi, DomainVmmAuditInfo): + def __init__(self): + DomainVmmAuditApi.__init__(self) + DomainVmmAuditInfo.__init__(self) diff --git a/lib/aci/domain/vmm/controller/__init__.py b/lib/aci/domain/vmm/controller/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/controller/api.py b/lib/aci/domain/vmm/controller/api.py new file mode 100644 index 00000000..2b42baff --- /dev/null +++ b/lib/aci/domain/vmm/controller/api.py @@ -0,0 +1,66 @@ +class DomainVmmControllerApi(): + def __init__(self): + self.domain_vmm_controller_mo = None + + def get_domain_vmm_controller_mo(self): + if self.domain_vmm_controller_mo is not None: + return self.domain_vmm_controller_mo + + cache = self.get_object_cache( + 'compCtrlr' + ) + if cache is not None: + self.domain_vmm_controller_mo = cache + self.log.apic_mo( + 'compCtrlr', + self.domain_vmm_controller_mo + ) + return self.domain_vmm_controller_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=compHv,compVm' + managed_objects = self.get_class( + 'compCtrlr', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_controller_mo', + 'API failed' + ) + return None + + self.domain_vmm_controller_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['compCtrlr']['attributes'] + attributes['compHv'] = self.get_mo_children_attributes( + 'compCtrlr', + managed_object, + 'compHv' + ) + attributes['compVm'] = self.get_mo_children_attributes( + 'compCtrlr', + managed_object, + 'compVm' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'compCtrlr', + managed_object, + 'faultCounts' + ) + self.domain_vmm_controller_mo.append( + attributes + ) + + self.log.apic_mo( + 'compCtrlr', + self.domain_vmm_controller_mo + ) + + self.set_object_cache( + 'compCtrlr', + self.domain_vmm_controller_mo + ) + + return self.domain_vmm_controller_mo diff --git a/lib/aci/domain/vmm/controller/info.py b/lib/aci/domain/vmm/controller/info.py new file mode 100644 index 00000000..35bac4a5 --- /dev/null +++ b/lib/aci/domain/vmm/controller/info.py @@ -0,0 +1,218 @@ +from lib import filter_helper + + +class DomainVmmControllerInfo(): + def __init__(self): + self.domain_vmm_controller = None + + def get_domain_vmm_controller_hv_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'countUplink', + 'guid', + 'mgmtIp', + 'name', + 'oid', + 'rn', + 'state', + 'type' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['state'] == 'poweredOn': + info['powerTick'] = '\u2713' + info['__Output']['powerTick'] = 'Green' + else: + info['powerTick'] = '\u2717' + info['__Output']['powerTick'] = 'Red' + + return info + + def get_domain_vmm_controller_vm_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'cfgdOs', + 'guid', + 'name', + 'oid', + 'os', + 'rn', + 'state', + 'template', + 'type', + 'uuid' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['state'] == 'poweredOn': + info['powerTick'] = '\u2713' + info['__Output']['powerTick'] = 'Green' + else: + info['powerTick'] = '\u2717' + info['__Output']['powerTick'] = 'Red' + + return info + + def get_domain_vmm_controller_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'accessMode', + 'apiVer', + 'aveSwitchingActive', + 'aveTimeOut', + 'ctrlKnob', + 'ctrlrPKey', + 'dn', + 'domName', + 'dvsVersion', + 'enableAVE', + 'enableTag', + 'enableVmFolder', + 'epRetTime', + 'hostOrIp', + 'id', + 'key', + 'lagPolicyName', + 'lastEventCollectorId', + 'maxWorkerQSize', + 'mode', + 'model', + 'name', + 'operSt', + 'port', + 'rev', + 'rootContName', + 'scope', + 'ser', + 'usr', + 'vendor', + 'vspherePHA', + 'vsphereTag', + 'vxlanDeplPref' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['operSt'] == 'online': + info['operStTick'] = '\u2713' + info['__Output']['operStTick'] = 'Green' + else: + info['operStTick'] = '\u2717' + info['__Output']['operStTick'] = 'Red' + + info['serialShort'] = info['ser'].split('-')[0] + + info['compHv'] = [] + if managed_object['compHv'] is not None: + for hv_mo in managed_object['compHv']: + info['compHv'].append( + self.get_domain_vmm_controller_hv_info( + hv_mo + ) + ) + + info['compHv'] = sorted( + info['compHv'], + key=lambda i: i['name'] + ) + info['hvCount'] = len( + info['compHv'] + ) + + info['compVm'] = [] + if managed_object['compVm'] is not None: + for vm_mo in managed_object['compVm']: + info['compVm'].append( + self.get_domain_vmm_controller_vm_info( + vm_mo + ) + ) + + info['compVm'] = sorted( + info['compVm'], + key=lambda i: i['name'] + ) + info['vmCount'] = len( + info['compVm'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_domain_vmm_controller_infos(self): + if self.domain_vmm_controller is not None: + return self.domain_vmm_controller + + managed_objects = self.get_domain_vmm_controller_mo() + if managed_objects is None: + return None + + self.domain_vmm_controller = [] + for managed_object in managed_objects: + self.domain_vmm_controller.append( + self.get_domain_vmm_controller_info( + managed_object + ) + ) + + self.log.apic_mo( + 'compCtrlr.info', + self.domain_vmm_controller + ) + + return self.domain_vmm_controller + + def match_domain_vmm_controller(self, domain_vmm_controller_info, domain_vmm_controller_filter): + if domain_vmm_controller_filter is None or len(domain_vmm_controller_filter) == 0: + return True + + for aepg_rule in domain_vmm_controller_filter: + (key, value) = aepg_rule.split(':') + if key == 'domain': + if not filter_helper.match_string(value, domain_vmm_controller_info['domName']): + return False + + return True + + def get_domain_vmm_controllers(self, domain_vmm_controller_filter=None): + all_controllers = self.get_domain_vmm_controller_infos() + if all_controllers is None: + return None + + controllers = [] + + for domain_vmm_controller_info in all_controllers: + if not self.match_domain_vmm_controller(domain_vmm_controller_info, domain_vmm_controller_filter): + continue + + controllers.append(domain_vmm_controller_info) + + controllers = sorted( + controllers, + key=lambda i: i['name'] + ) + + return controllers diff --git a/lib/aci/domain/vmm/controller/main.py b/lib/aci/domain/vmm/controller/main.py new file mode 100644 index 00000000..81aa4173 --- /dev/null +++ b/lib/aci/domain/vmm/controller/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.vmm.controller.api import DomainVmmControllerApi +from lib.aci.domain.vmm.controller.info import DomainVmmControllerInfo + + +class DomainVmmController(DomainVmmControllerApi, DomainVmmControllerInfo): + def __init__(self): + DomainVmmControllerApi.__init__(self) + DomainVmmControllerInfo.__init__(self) diff --git a/lib/aci/domain/vmm/epg/__init__.py b/lib/aci/domain/vmm/epg/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/epg/__pycache__/__init__.cpython-310.pyc b/lib/aci/domain/vmm/epg/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..98132b59 Binary files /dev/null and b/lib/aci/domain/vmm/epg/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/epg/__pycache__/api.cpython-310.pyc b/lib/aci/domain/vmm/epg/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4be93618 Binary files /dev/null and b/lib/aci/domain/vmm/epg/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/epg/__pycache__/info.cpython-310.pyc b/lib/aci/domain/vmm/epg/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..73f13f53 Binary files /dev/null and b/lib/aci/domain/vmm/epg/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/epg/__pycache__/main.cpython-310.pyc b/lib/aci/domain/vmm/epg/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..76fbb3eb Binary files /dev/null and b/lib/aci/domain/vmm/epg/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/domain/vmm/epg/api.py b/lib/aci/domain/vmm/epg/api.py new file mode 100644 index 00000000..179197a9 --- /dev/null +++ b/lib/aci/domain/vmm/epg/api.py @@ -0,0 +1,49 @@ +class DomainVmmEpgApi(): + def __init__(self): + self.domain_vmm_epg_mo = None + + def get_domain_vmm_epg_mo(self): + if self.domain_vmm_epg_mo is not None: + return self.domain_vmm_epg_mo + + cache = self.get_object_cache( + 'vmmEpPD' + ) + if cache is not None: + self.domain_vmm_epg_mo = cache + self.log.apic_mo( + 'vmmEpPD', + self.domain_vmm_epg_mo + ) + return self.domain_vmm_epg_mo + + managed_objects = self.get_class( + 'vmmEpPD', + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_epg_mo', + 'API failed' + ) + return None + + self.domain_vmm_epg_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vmmEpPD']['attributes'] + self.domain_vmm_epg_mo.append( + attributes + ) + + self.log.apic_mo( + 'vmmEpPD', + self.domain_vmm_epg_mo + ) + + self.set_object_cache( + 'vmmEpPD', + self.domain_vmm_epg_mo + ) + + return self.domain_vmm_epg_mo diff --git a/lib/aci/domain/vmm/epg/info.py b/lib/aci/domain/vmm/epg/info.py new file mode 100644 index 00000000..88e593df --- /dev/null +++ b/lib/aci/domain/vmm/epg/info.py @@ -0,0 +1,117 @@ +from lib import filter_helper + + +class DomainVmmEpgInfo(): + def __init__(self): + self.domain_vmm_epg = None + + def get_domain_vmm_epg_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['vlanId'] = int(info['encap'][5:]) + + if info['allocMode'] == 'dynamic': + info['tenant'] = info['encapAllocKey'].split('/')[1][3:] + info['appName'] = info['encapAllocKey'].split('/')[2][3:] + info['epgName'] = info['encapAllocKey'].split('/')[3][4:] + info['tenantAppEpg'] = '%s/%s/%s' % ( + info['tenant'], + info['appName'], + info['epgName'] + ) + + if info['allocMode'] == 'static': + info['tenant'] = '' + info['appName'] = '' + info['epgName'] = '' + info['tenantAppEpg'] = 'static allocation' + + info['domainType'] = 'VMM Domain' + info['domainName'] = None + + if info['domainName'] is None and 'dn' in info: + info['domainName'] = '%s/%s' % ( + info['dn'].split('/')[1][5:], + info['dn'].split('/')[2][4:] + ) + + if info['domainName'] is None and 'idConsumerDn' in info: + if len(info['idConsumerDn']) > 0: + info['domainName'] = '%s/%s' % ( + info['idConsumerDn'].split('/')[1][5:], + info['idConsumerDn'].split('/')[2][4:] + ) + + return info + + def get_domain_vmm_epg_infos(self): + if self.domain_vmm_epg is not None: + return self.domain_vmm_epg + + managed_objects = self.get_domain_vmm_epg_mo() + if managed_objects is None: + return None + + self.domain_vmm_epg = [] + for managed_object in managed_objects: + self.domain_vmm_epg.append( + self.get_domain_vmm_epg_info( + managed_object + ) + ) + + self.log.apic_mo( + 'vmmEpPD.info', + self.domain_vmm_epg + ) + + return self.domain_vmm_epg + + def match_domain_vmm_epg(self, domain_vmm_epg_info, domain_vmm_epg_filter): + if domain_vmm_epg_filter is None or len(domain_vmm_epg_filter) == 0: + return True + + range_defined = False + range_match = False + + for aepg_rule in domain_vmm_epg_filter: + (key, value) = aepg_rule.split(':') + if key == 'pool': + if not filter_helper.match_string(value, domain_vmm_epg_info['encapCtx']): + return False + + if key == 'range': + range_defined = True + (vlan_from, vlan_to) = value.split(',') + vlan_id = domain_vmm_epg_info['encap'][5:] + if int(vlan_from) <= int(vlan_id) <= int(vlan_to): + range_match = True + + if range_defined and not range_match: + return False + + return True + + def get_domain_vmm_epgs(self, domain_vmm_epg_filter=None): + all_epgs = self.get_domain_vmm_epg_infos() + if all_epgs is None: + return None + + epgs = [] + + for domain_vmm_epg_info in all_epgs: + if not self.match_domain_vmm_epg(domain_vmm_epg_info, domain_vmm_epg_filter): + continue + + epgs.append(domain_vmm_epg_info) + + epgs = sorted( + epgs, + key=lambda i: i['vlanId'] + ) + + return epgs diff --git a/lib/aci/domain/vmm/epg/main.py b/lib/aci/domain/vmm/epg/main.py new file mode 100644 index 00000000..1fbe558d --- /dev/null +++ b/lib/aci/domain/vmm/epg/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.vmm.epg.api import DomainVmmEpgApi +from lib.aci.domain.vmm.epg.info import DomainVmmEpgInfo + + +class DomainVmmEpg(DomainVmmEpgApi, DomainVmmEpgInfo): + def __init__(self): + DomainVmmEpgApi.__init__(self) + DomainVmmEpgInfo.__init__(self) diff --git a/lib/aci/domain/vmm/event/__init__.py b/lib/aci/domain/vmm/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/event/api.py b/lib/aci/domain/vmm/event/api.py new file mode 100644 index 00000000..4e680c9d --- /dev/null +++ b/lib/aci/domain/vmm/event/api.py @@ -0,0 +1,51 @@ +class DomainVmmEventApi(): + def __init__(self): + self.domain_vmm_event_mo = None + + def get_domain_vmm_event_mo(self): + if self.domain_vmm_event_mo is not None: + return self.domain_vmm_event_mo + + cache = self.get_object_cache( + 'vmmDomP.eventLog' + ) + if cache is not None: + self.domain_vmm_event_mo = cache + self.log.apic_mo( + 'vmmDomP.eventLog', + self.domain_vmm_event_mo + ) + return self.domain_vmm_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'vmmDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_event_mo', + 'API failed' + ) + return None + + self.domain_vmm_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.domain_vmm_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'vmmDomP.eventLog', + self.domain_vmm_event_mo + ) + + self.set_object_cache( + 'vmmDomP.eventLog', + self.domain_vmm_event_mo + ) + + return self.domain_vmm_event_mo diff --git a/lib/aci/domain/vmm/event/info.py b/lib/aci/domain/vmm/event/info.py new file mode 100644 index 00000000..bf698c98 --- /dev/null +++ b/lib/aci/domain/vmm/event/info.py @@ -0,0 +1,107 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainVmmEventInfo(): + def __init__(self): + self.domain_vmm_event = None + + def get_domain_vmm_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + if 'affected' in info: + if 'uni/vmmp-VMware/dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/vmmp-VMware/dom-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/vmmp-VMware/dom-' in info['dn']: + info['domainName'] = info['dn'].split('uni/vmmp-VMware/dom-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_vmm_event(self, deduplicate=True): + if self.domain_vmm_event is not None: + return self.domain_vmm_event + + managed_objects = self.get_domain_vmm_event_mo() + if managed_objects is None: + return None + + self.domain_vmm_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_domain_vmm_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.domain_vmm_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'vmmDomP.eventLog.info', + self.domain_vmm_event + ) + + return self.domain_vmm_event + + def get_domain_vmm_id_event(self, domain_name, event_filter=None): + events = [] + + all_events = self.get_domain_vmm_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['domainName'] is not None: + if event_info['domainName'] == domain_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/domain/vmm/event/main.py b/lib/aci/domain/vmm/event/main.py new file mode 100644 index 00000000..d4e606d9 --- /dev/null +++ b/lib/aci/domain/vmm/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.vmm.event.api import DomainVmmEventApi +from lib.aci.domain.vmm.event.info import DomainVmmEventInfo + + +class DomainVmmEvent(DomainVmmEventApi, DomainVmmEventInfo): + def __init__(self): + DomainVmmEventApi.__init__(self) + DomainVmmEventInfo.__init__(self) diff --git a/lib/aci/domain/vmm/fault/__init__.py b/lib/aci/domain/vmm/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/fault/api.py b/lib/aci/domain/vmm/fault/api.py new file mode 100644 index 00000000..8fc1ab95 --- /dev/null +++ b/lib/aci/domain/vmm/fault/api.py @@ -0,0 +1,112 @@ +class DomainVmmFaultApi(): + def __init__(self): + self.domain_vmm_fault_mo = None + self.domain_vmm_fault_record_mo = None + + def get_domain_vmm_fault_mo(self): + cache = self.get_object_cache( + 'vmmDomP.fault' + ) + if cache is not None: + self.domain_vmm_fault_mo = cache + self.log.apic_mo( + 'vmmDomP.fault', + self.domain_vmm_fault_mo + ) + return self.domain_vmm_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'vmmDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_fault_mo', + 'API failed' + ) + return None + + self.domain_vmm_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.domain_vmm_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'vmmDomP.fault', + self.domain_vmm_fault_mo + ) + + self.set_object_cache( + 'vmmDomP.fault', + self.domain_vmm_fault_mo + ) + + return self.domain_vmm_fault_mo + + def get_domain_vmm_fault_record_mo(self): + cache = self.get_object_cache( + 'vmmDomP.faultRecord' + ) + if cache is not None: + self.domain_vmm_fault_record_mo = cache + self.log.apic_mo( + 'vmmDomP.faultRecord', + self.domain_vmm_fault_record_mo + ) + return self.domain_vmm_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'vmmDomP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_fault_record_mo', + 'API failed' + ) + return None + + self.domain_vmm_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.domain_vmm_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'vmmDomP.faultRecord', + self.domain_vmm_fault_record_mo + ) + + self.set_object_cache( + 'vmmDomP.faultRecord', + self.domain_vmm_fault_record_mo + ) + + return self.domain_vmm_fault_record_mo diff --git a/lib/aci/domain/vmm/fault/info.py b/lib/aci/domain/vmm/fault/info.py new file mode 100644 index 00000000..d16110fd --- /dev/null +++ b/lib/aci/domain/vmm/fault/info.py @@ -0,0 +1,144 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class DomainVmmFaultInfo(): + def __init__(self): + self.domain_vmm_fault = None + self.domain_vmm_fault_record = None + + def get_domain_vmm_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = None + info['controllerName'] = None + + if not managed_object['delegated']: + # "uni/vmmp-VMware/dom-EU-SPDC-CDC-22/ctrlr-EU-SPDC-CDC-22" + if 'affected' in info: + if 'uni/vmmp-VMware/dom-' in info['affected']: + info['domainName'] = info['affected'].split('uni/vmmp-VMware/dom-')[1].split('/')[0] + if len(info['affected'].split('/')) == 4: + info['controllerName'] = info['affected'].split('uni/vmmp-VMware/dom-')[1].split('/')[1][6:] + + # "dn": "uni/vmmp-VMware/dom-EU-SPDC-CDC-22/ctrlr-EU-SPDC-CDC-22/fd-[comp/prov-VMware/ctrlr-[EU-SPDC-CDC-22]-EU-SPDC-CDC-22/hv-host-3381]-fault-F2840" + if info['domainName'] is None: + if 'uni/vmmp-VMware/dom-' in info['dn']: + info['domainName'] = info['dn'].split('uni/vmmp-VMware/dom-')[1].split('/')[0] + info['controllerName'] = info['dn'].split('uni/vmmp-VMware/dom-')[1].split('/')[1][6:] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_domain_vmm_fault(self): + if self.domain_vmm_fault is not None: + return self.domain_vmm_fault + + managed_objects = self.get_domain_vmm_fault_mo() + if managed_objects is None: + return None + + self.domain_vmm_fault = [] + for managed_object in managed_objects: + fault_info = self.get_domain_vmm_fault_info( + managed_object + ) + self.domain_vmm_fault.append( + fault_info + ) + + self.log.apic_mo( + 'vmmDomP.fault.info', + self.domain_vmm_fault + ) + + return self.domain_vmm_fault + + def get_domain_vmm_fault_record(self, deduplicate=True): + if self.domain_vmm_fault_record is not None: + return self.domain_vmm_fault_record + + managed_objects = self.get_domain_vmm_fault_record_mo() + if managed_objects is None: + return None + + self.domain_vmm_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_domain_vmm_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.domain_vmm_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'vmmDomP.faultRecord.info', + self.domain_vmm_fault_record + ) + + return self.domain_vmm_fault_record + + def get_domain_vmm_id_fault(self, domain_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_domain_vmm_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_domain_vmm_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['domainName'] is not None: + if fault_info['domainName'] == domain_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/domain/vmm/fault/main.py b/lib/aci/domain/vmm/fault/main.py new file mode 100644 index 00000000..bd3b7de1 --- /dev/null +++ b/lib/aci/domain/vmm/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.vmm.fault.api import DomainVmmFaultApi +from lib.aci.domain.vmm.fault.info import DomainVmmFaultInfo + + +class DomainVmmFault(DomainVmmFaultApi, DomainVmmFaultInfo): + def __init__(self): + DomainVmmFaultApi.__init__(self) + DomainVmmFaultInfo.__init__(self) diff --git a/lib/aci/domain/vmm/info.py b/lib/aci/domain/vmm/info.py new file mode 100644 index 00000000..711defe9 --- /dev/null +++ b/lib/aci/domain/vmm/info.py @@ -0,0 +1,380 @@ +from lib import filter_helper + + +class DomainVmmInfo(): + def __init__(self): + self.domain_vmm = None + + def get_domain_vmm_info(self, managed_object): + keys = [ + 'accessMode', + 'aveTimeOut', + 'configInfraPg', + 'ctrlKnob', + 'dn', + 'enableAVE', + 'enableTag', + 'enableVmFolder', + 'encapMode', + 'epInventoryType', + 'epRetTime', + 'hvAvailMonitor', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # No clue why I get unknown value while APIC UI gets vlan value... + if info['encapMode'] == 'unknown': + info['encapMode'] = 'vlan' + + info['accessModeT'] = '--' + if info['accessMode'] == 'read-write': + info['accessModeT'] = 'RW' + if info['accessMode'] == 'read-only': + info['accessModeT'] = 'RO' + + info['vmmVSwitchPolicyContRn'] = None + if 'vmmVSwitchPolicyCont' in managed_object: + if managed_object['vmmVSwitchPolicyCont'] is not None: + info['vmmVSwitchPolicyCont'] = managed_object['vmmVSwitchPolicyCont']['rn'] + + info['vmmCtrlrP'] = [] + if 'vmmCtrlrP' in managed_object: + if managed_object['vmmCtrlrP'] is not None: + for item in managed_object['vmmCtrlrP']: + vc_info = {} + vc_info['name'] = item['name'] + vc_info['rootContName'] = item['rootContName'] + vc_info['hostOrIp'] = item['hostOrIp'] + vc_info['usr'] = '' + if 'vmmUsrAccP' in managed_object: + if managed_object['vmmUsrAccP'] is not None: + for user_item in managed_object['vmmUsrAccP']: + cred_name = '%s_cred' % (item['name']) + if user_item['name'].lower() == cred_name.lower(): + vc_info['usr'] = user_item['usr'] + + info['vmmCtrlrP'].append( + vc_info + ) + + info['numOfUplinks'] = None + if 'vmmUplinkPCont' in managed_object: + if managed_object['vmmUplinkPCont'] is not None: + info['numOfUplinks'] = managed_object['vmmUplinkPCont']['numOfUplinks'] + + info['aaep_names'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + info['aaep_names'].append( + item['tDn'].split('/')[2][8:] + ) + + info['vlan'] = None + if 'infraRsVlanNs' in managed_object: + if managed_object['infraRsVlanNs'] is not None: + if managed_object['infraRsVlanNs']['tCl'] == 'fvnsVlanInstP': + info['vlan'] = managed_object['infraRsVlanNs']['tDn'].split('vlanns-[')[1].split(']')[0] + + info['aaaDomain'] = [] + for item in managed_object['aaaDomainRef']: + info['aaaDomain'].append( + item['name'] + ) + + info['vmmEpPD'] = [] + for epg_mo in managed_object['vmmEpPD']: + info['vmmEpPD'].append( + self.get_domain_vmm_epg_info( + epg_mo + ) + ) + + info['epgCount'] = len( + info['vmmEpPD'] + ) + + info['reln'] = [] + if 'infraRtDomP' in managed_object: + if managed_object['infraRtDomP'] is not None: + for item in managed_object['infraRtDomP']: + # "tCl": "infraAttEntityP", + # "tDn": "uni/infra/attentp-UCSB1-R3DC_AAEP" + if item['tCl'] == 'infraAttEntityP': + reln_info = {} + reln_info['tCl'] = item['tCl'] + reln_info['tDn'] = item['tDn'] + reln_info['type'] = 'AAEP' + reln_info['name'] = item['tDn'].split('/')[2][8:] + info['reln'].append( + reln_info + ) + continue + + self.log.error( + 'get_domain_phy_info', + 'Unsupported infraRtDomP tCl: %s' % (item['tCl']) + ) + + if 'vmmEpPD' in managed_object: + if managed_object['vmmEpPD'] is not None: + for item in managed_object['vmmEpPD']: + reln_info = {} + reln_info['tCl'] = 'fvAEPg' + reln_info['tDn'] = item['encapAllocKey'] + reln_info['type'] = 'Application EPG' + reln_info['name'] = self.get_epg_name_from_dn( + reln_info['tDn'] + ) + info['reln'].append( + reln_info + ) + + info['reln'] = sorted( + info['reln'], + key=lambda i: ( + i['tCl'], + i['tDn'] + ) + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_domains_vmm_info(self): + if self.domain_vmm is not None: + return self.domain_vmm + + domains_mo = self.get_domain_vmm_mo() + if domains_mo is None: + return None + + self.domain_vmm = [] + for managed_object in domains_mo: + self.domain_vmm.append( + self.get_domain_vmm_info( + managed_object + ) + ) + + self.log.apic_mo( + 'vmmDomP.info', + self.domain_vmm + ) + + return self.domain_vmm + + def match_domain_vmm(self, domain_info, domain_filter): + if domain_filter is None or len(domain_filter) == 0: + return True + + for aepg_rule in domain_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, domain_info['name']): + return False + + if key == 'aaep': + key_found = True + found = False + for aaep_name in domain_info['aaep_names']: + if filter_helper.match_string(value, aaep_name): + found = True + + if not found: + return False + + if key == 'pool': + key_found = True + if not filter_helper.match_string(value, domain_info['vlan']): + return False + + if key == 'vlan': + key_found = True + if 'vlan_block' in domain_info: + found = False + for vlan_block in domain_info['vlan_block']: + if filter_helper.match_integer(vlan_block, value): + found = True + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not domain_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_domain_vmm', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_domain_vmm', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_domains_vmm( + self, + domain_filter=None, + vlan_info=False, + vlan_usage_info=False, + node_info=False, + intf_vlan_info=False, + controller_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_domains = self.get_domains_vmm_info() + + domains = [] + + self.get_domain_vmm_controller_mo() + for domain_info in all_domains: + if not self.match_domain_vmm(domain_info, domain_filter): + continue + + if vlan_info: + domain_info['vlan_info'] = None + domain_info['vlan_block'] = [] + if domain_info['vlan'] is not None: + domain_info['vlan_info'] = self.get_pool_vlan( + domain_info['vlan'], + vlan_usage_info=vlan_usage_info, + domain_name=domain_info['name'] + ) + if domain_info['vlan_info'] is not None: + for vlan_block in domain_info['vlan_info']['fvnsEncapBlk']: + domain_info['vlan_block'].append( + '%s-%s' % ( + vlan_block['fromVlan'], + vlan_block['toVlan'] + ) + ) + + if not self.match_domain_vmm(domain_info, domain_filter): + continue + + if node_info: + domain_node_info = self.get_domain_vmm_node( + domain_info['name'] + ) + domain_info['node'] = None + domain_info['interface'] = None + if domain_node_info is not None: + domain_info['node'] = domain_node_info['node'] + domain_info['interface'] = domain_node_info['interface'] + + if intf_vlan_info: + if domain_info['interface'] is not None: + for interface in domain_info['interface']: + interface['vlan'] = [] + interface['operSt'] = '--' + interface['operMode'] = '--' + + if interface['intf_type'] == 'l1PhysIf': + interface_info = self.get_interface_phy( + interface['pod_id'], + interface['node_id'], + interface['intf_name'], + epg_stats_info=True + ) + if interface_info is not None: + interface['operSt'] = interface_info['stats']['operSt'] + interface['__Output']['operSt'] = interface_info['stats']['__Output']['operSt'] + interface['operMode'] = interface_info['stats']['operMode'] + for intf_epg_stats in interface_info['epg_stats']: + if intf_epg_stats['vlan'] is not None: + if intf_epg_stats['vlan']['evlan'] not in interface['vlan']: + interface['vlan'].append( + intf_epg_stats['vlan']['evlan'] + ) + + interface['vlan'] = sorted( + interface['vlan'] + ) + interface['vlans'] = filter_helper.get_range_from_values( + interface['vlan'] + ) + + if controller_info: + domain_info['controller'] = self.get_domain_vmm_controllers( + domain_vmm_controller_filter=['domain:%s' % (domain_info['name'])] + ) + + if fault_info: + domain_info['faultInst'] = self.get_domain_vmm_id_fault( + domain_info['name'], + 'faultInst' + ) + + if hfault_info: + domain_info['faultRecord'] = self.get_domain_vmm_id_fault( + domain_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + domain_info['eventLog'] = self.get_domain_vmm_id_event( + domain_info['name'], + event_filter=event_filter + ) + + if audit_info: + domain_info['auditLog'] = self.get_domain_vmm_id_audit( + domain_info['name'], + audit_filter=audit_filter + ) + + domains.append(domain_info) + + domains = sorted( + domains, + key=lambda i: i['name'].lower() + ) + + return domains + + def get_domain_vmm(self, domain_name, vlan_info=False, vlan_usage_info=False): + domain_filter = ['name:%s' % (domain_name)] + domains = self.get_domains_vmm( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info + ) + if domains is None or len(domains) != 1: + return None + return domains[0] diff --git a/lib/aci/domain/vmm/main.py b/lib/aci/domain/vmm/main.py new file mode 100644 index 00000000..a03dfcdc --- /dev/null +++ b/lib/aci/domain/vmm/main.py @@ -0,0 +1,29 @@ +from lib.aci.domain.vmm.api import DomainVmmApi +from lib.aci.domain.vmm.info import DomainVmmInfo +from lib.aci.domain.vmm.audit.main import DomainVmmAudit +from lib.aci.domain.vmm.controller.main import DomainVmmController +from lib.aci.domain.vmm.epg.main import DomainVmmEpg +from lib.aci.domain.vmm.event.main import DomainVmmEvent +from lib.aci.domain.vmm.fault.main import DomainVmmFault +from lib.aci.domain.vmm.node.main import DomainVmmNode + + +class DomainVmm( + DomainVmmApi, + DomainVmmInfo, + DomainVmmAudit, + DomainVmmController, + DomainVmmEpg, + DomainVmmEvent, + DomainVmmFault, + DomainVmmNode + ): + def __init__(self): + DomainVmmApi.__init__(self) + DomainVmmInfo.__init__(self) + DomainVmmAudit.__init__(self) + DomainVmmController.__init__(self) + DomainVmmEpg.__init__(self) + DomainVmmEvent.__init__(self) + DomainVmmFault.__init__(self) + DomainVmmNode.__init__(self) diff --git a/lib/aci/domain/vmm/node/__init__.py b/lib/aci/domain/vmm/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/domain/vmm/node/api.py b/lib/aci/domain/vmm/node/api.py new file mode 100644 index 00000000..f0f3ad2b --- /dev/null +++ b/lib/aci/domain/vmm/node/api.py @@ -0,0 +1,61 @@ +class DomainVmmNodeApi(): + def __init__(self): + self.domain_vmm_node_mo = {} + + def get_domain_vmm_node_mo(self, domain_name): + if domain_name in self.domain_vmm_node_mo: + return self.domain_vmm_node_mo[domain_name] + + key = domain_name + cache = self.get_object_cache( + 'vmmDomP.%s' % (key) + ) + if cache is not None: + self.domain_vmm_node_mo[key] = cache + self.log.apic_mo( + 'vmmDomP.%s' % (key), + self.domain_vmm_node_mo[key] + ) + return self.domain_vmm_node_mo[key] + + distinguished_name = 'uni/vmmp-VMware/dom-%s' % (domain_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=ADomPToEthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_domain_vmm_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_domain_vmm_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['vmmDomP']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'vmmDomP', + managed_object + ) + self.domain_vmm_node_mo[key] = attributes + + self.log.apic_mo( + 'vmmDomP.%s' % (key), + self.domain_vmm_node_mo[key] + ) + + self.set_object_cache( + 'vmmDomP.%s' % (key), + self.domain_vmm_node_mo[key] + ) + + return self.domain_vmm_node_mo[key] diff --git a/lib/aci/domain/vmm/node/info.py b/lib/aci/domain/vmm/node/info.py new file mode 100644 index 00000000..323749e5 --- /dev/null +++ b/lib/aci/domain/vmm/node/info.py @@ -0,0 +1,81 @@ +class DomainVmmNodeInfo(): + def __init__(self): + self.domain_vmm_node = {} + + def get_domain_vmm_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_domain_vmm_node(self, domain_name): + if domain_name in self.domain_vmm_node: + return self.domain_vmm_node[domain_name] + + # one object or None value is expected + domain_nodes_mo = self.get_domain_vmm_node_mo(domain_name) + if domain_nodes_mo is None: + return None + + self.domain_vmm_node[domain_name] = self.get_domain_vmm_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'vmmDomP.%s.info' % (domain_name), + self.domain_vmm_node[domain_name] + ) + + return self.domain_vmm_node[domain_name] diff --git a/lib/aci/domain/vmm/node/main.py b/lib/aci/domain/vmm/node/main.py new file mode 100644 index 00000000..9e8b68b6 --- /dev/null +++ b/lib/aci/domain/vmm/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.domain.vmm.node.api import DomainVmmNodeApi +from lib.aci.domain.vmm.node.info import DomainVmmNodeInfo + + +class DomainVmmNode(DomainVmmNodeApi, DomainVmmNodeInfo): + def __init__(self): + DomainVmmNodeApi.__init__(self) + DomainVmmNodeInfo.__init__(self) diff --git a/lib/aci/domain/vmm/output.py b/lib/aci/domain/vmm/output.py new file mode 100644 index 00000000..0e2b7c1c --- /dev/null +++ b/lib/aci/domain/vmm/output.py @@ -0,0 +1,624 @@ +class DomainVmmOutput(): + def __init__(self): + pass + + def print_domains_vmm(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + for item in info: + if len(item['aaaDomain']) == 0: + item['aaaDomain'].append('--') + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'vlan_info.allocMode', + 'fvnsEncapBlk.blockInfo', + 'epgCount', + 'aaaDomain' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Mode', + 'Encapsulation Block', + 'EPG', + 'Sec Domain' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'fvnsEncapBlk', 'aaaDomain'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_prop(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'name', + 'encapMode', + 'accessModeT', + 'configInfraPg', + 'enableTag', + 'enableVmFolder', + 'epInventoryType', + 'epRetTime', + 'numOfUplinks' + ] + + headers = [ + 'Domain Name', + 'Encap', + 'Access Mode', + 'Cfg Infra PGs', + 'Tag Collection', + 'VM Folder Data', + 'Ep Inventory', + 'Ep Retention Time', + 'Uplinks' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_vcenter(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - vCenter [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'controller.faults', + 'controller.name', + 'controller.hostOrIp', + 'controller.usr', + 'controller.operStTick', + 'controller.model', + 'controller.serialShort', + 'controller.rev', + 'controller.rootContName', + 'controller.hvCount', + 'controller.vmCount' + ] + + headers = [ + 'Faults', + 'Domain Name', + 'Controller Faults', + 'Controller Name', + 'IP', + 'Username', + 'Online', + 'Model', + 'Serial', + 'Rev', + 'Datacenter', + 'HV', + 'VM' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['controller'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_epg(self, info, title=False): + epg = [] + for item in info: + for epg_info in item['vmmEpPD']: + epg_info['domainName'] = item['name'] + epg.append( + epg_info + ) + + epg = sorted( + epg, + key=lambda i: ( + i['domainName'], + i['tenantAppEpg'] + ) + ) + + if title: + self.my_output.default( + 'VMM Domain - Associated EPG [#%s]' % (len(epg)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'tenantAppEpg', + 'encapCtx', + 'allocMode', + 'vlanId', + 'instrImedcy', + 'resImedcy', + 'switchingMode' + ] + + headers = [ + 'Domain Name', + 'EPG', + 'VLAN Pool', + 'Alloc Mode', + 'VLAN', + 'Deployment', + 'Resolution', + 'Switching' + ] + + self.my_output.my_table( + epg, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_node(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_interface(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_vlan(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - Interfaces VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['fvnsEncapBlk'] = [] + if item['vlan_info'] is not None: + item['fvnsEncapBlk'] = item['vlan_info']['fvnsEncapBlk'] + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'fvnsEncapBlk.blockInfo', + 'interface.node_name', + 'interface.intf_name', + 'interface.operSt', + 'interface.operMode', + 'interface.vlans' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Encapsulation Block', + 'Node', + 'Interface', + 'State', + 'Mode', + 'VLANs' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface', 'fvnsEncapBlk'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_reln(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - Policy Relationships [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'reln.type', + 'reln.name' + ] + + headers = [ + 'Faults', + 'Domain', + 'Policy Type', + 'Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['reln'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_domains_vmm_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'VMM Domain - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'VMM Domain - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_domains_vmm_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'VMM Domain - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_vmm_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'VMM Domain - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'VMM Domain - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_domains_vmm_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'VMM Domain - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'VMM Domain - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'domainName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Domain', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/endpoint/__init__.py b/lib/aci/endpoint/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c15d795b Binary files /dev/null and b/lib/aci/endpoint/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/api.cpython-310.pyc b/lib/aci/endpoint/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..00e3d968 Binary files /dev/null and b/lib/aci/endpoint/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/hv.cpython-310.pyc b/lib/aci/endpoint/__pycache__/hv.cpython-310.pyc new file mode 100644 index 00000000..7e6ba7b6 Binary files /dev/null and b/lib/aci/endpoint/__pycache__/hv.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..6762e651 Binary files /dev/null and b/lib/aci/endpoint/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/ip.cpython-310.pyc b/lib/aci/endpoint/__pycache__/ip.cpython-310.pyc new file mode 100644 index 00000000..9f7f42a4 Binary files /dev/null and b/lib/aci/endpoint/__pycache__/ip.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..29602a9f Binary files /dev/null and b/lib/aci/endpoint/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/output.cpython-310.pyc b/lib/aci/endpoint/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..dcd104fb Binary files /dev/null and b/lib/aci/endpoint/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/vm.cpython-310.pyc b/lib/aci/endpoint/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..98fa4129 Binary files /dev/null and b/lib/aci/endpoint/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/aci/endpoint/__pycache__/vmm.cpython-310.pyc b/lib/aci/endpoint/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..4c81a9ff Binary files /dev/null and b/lib/aci/endpoint/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/endpoint/api.py b/lib/aci/endpoint/api.py new file mode 100644 index 00000000..8102a802 --- /dev/null +++ b/lib/aci/endpoint/api.py @@ -0,0 +1,91 @@ +class EndpointApi(): + def __init__(self): + self.endpoints_mo = None + + def get_endpoints_mo(self): + if self.endpoints_mo is not None: + return self.endpoints_mo + + cache = self.get_object_cache( + 'fvCEp' + ) + if cache is not None: + self.endpoints_mo = cache + self.log.apic_mo( + 'fvCEp', + self.endpoints_mo + ) + return self.endpoints_mo + + query = 'rsp-subtree-include=health,fault-count&rsp-subtree=children' + children = [ + 'fvIp', + 'fvRsCEpToPathEp', + 'fvRsToVm', + 'fvRsHyper', + 'fvRsToNic' + ] + for child in children: + query = '%s&rsp-subtree-class=%s' % (query, child) + + managed_objects = self.get_class( + 'fvCEp', + query=query + ) + if managed_objects is None: + self.log.error( + 'get_endpoint_mo', + 'API failed' + ) + return None + + self.endpoints_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvCEp']['attributes'] + + attributes['fvIp'] = self.get_mo_children_attributes( + 'fvCEp', + managed_object, + 'fvIp' + ) + + attributes['fvRsCEpToPathEp'] = self.get_mo_child_attributes( + 'fvCEp', + managed_object, + 'fvRsCEpToPathEp' + ) + + attributes['fvRsToVm'] = self.get_mo_child_attributes( + 'fvCEp', + managed_object, + 'fvRsToVm' + ) + + attributes['fvRsHyper'] = self.get_mo_child_attributes( + 'fvCEp', + managed_object, + 'fvRsHyper' + ) + + attributes['fvRsToNic'] = self.get_mo_child_attributes( + 'fvCEp', + managed_object, + 'fvRsToNic' + ) + + self.endpoints_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvCEp', + self.endpoints_mo + ) + + self.set_object_cache( + 'fvCEp', + self.endpoints_mo + ) + + return self.endpoints_mo diff --git a/lib/aci/endpoint/bot_output.py b/lib/aci/endpoint/bot_output.py new file mode 100644 index 00000000..971ffdd0 --- /dev/null +++ b/lib/aci/endpoint/bot_output.py @@ -0,0 +1,72 @@ +class EndpointBotOutput(): + def __init__(self): + pass + + def print_endpoints(self, endpoints, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Endpoint [#%s]' % (len(endpoints)), + underline=True, + before_newline=True + ) + + if len(endpoints) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'apic', + 'flags', + 'mac', + 'fvIp.addr', + 'epgNameApTenant', + 'encapT', + 'bdNameTenant', + 'vrfNameTenant', + 'fabric.ep' + ] + + headers = [ + 'APIC', + 'SF', + 'MAC Address', + 'IP Address', + 'EPG', + 'Encap', + 'BD', + 'VRF', + 'Fabric' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + endpoints, + order, + ['fvIp', 'fabric'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + endpoints, + order, + headers, + title='Endpoint' + ) + + html_output = self.my_output.get_output() + + return output, html_output \ No newline at end of file diff --git a/lib/aci/endpoint/hv/__init__.py b/lib/aci/endpoint/hv/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/hv/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/hv/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b6c6fe8d Binary files /dev/null and b/lib/aci/endpoint/hv/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/hv/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/hv/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f1c75ed5 Binary files /dev/null and b/lib/aci/endpoint/hv/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/hv/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/hv/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..501457a4 Binary files /dev/null and b/lib/aci/endpoint/hv/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/hv/info.py b/lib/aci/endpoint/hv/info.py new file mode 100644 index 00000000..b89fafee --- /dev/null +++ b/lib/aci/endpoint/hv/info.py @@ -0,0 +1,34 @@ +class EndpointHvInfo(): + def __init__(self): + pass + + def get_endpoint_hv_info(self, managed_object): + # "childAction": "", + # "forceResolve": "yes", + # "isBootstrapUpd": "attach", + # "lcOwn": "local", + # "modTs": "2022-09-22T15:10:06.162+01:00", + # "rType": "mo", + # "rn": "rshyper-[comp/prov-VMware/ctrlr-[EU-SPDC-CDC-22]-EU-SPDC-CDC-22/hv-host-2842]", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "compHv", + # "tDn": "comp/prov-VMware/ctrlr-[EU-SPDC-CDC-22]-EU-SPDC-CDC-22/hv-host-2842", + # "tType": "mo" + info = {} + info['__Output'] = {} + + keys = [ + 'rn', + 'state', + 'tCl', + 'tDn', + 'tType' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/endpoint/hv/main.py b/lib/aci/endpoint/hv/main.py new file mode 100644 index 00000000..1506909a --- /dev/null +++ b/lib/aci/endpoint/hv/main.py @@ -0,0 +1,6 @@ +from lib.aci.endpoint.hv.info import EndpointHvInfo + + +class EndpointHv(EndpointHvInfo): + def __init__(self): + EndpointHvInfo.__init__(self) diff --git a/lib/aci/endpoint/info.py b/lib/aci/endpoint/info.py new file mode 100644 index 00000000..c52a906c --- /dev/null +++ b/lib/aci/endpoint/info.py @@ -0,0 +1,348 @@ +from lib import ip_helper +from lib import filter_helper + + +class EndpointInfo(): + def __init__(self): + self.endpoints = None + + def get_endpoint_count(self, tenant_name=None): + endpoint_filter = [] + if tenant_name is not None: + endpoint_filter.append( + 'tenant:%s' % (tenant_name) + ) + + endpoints = self.get_endpoints( + endpoint_filter=endpoint_filter + ) + return len(endpoints) + + def get_endpoint_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'bdDn', + 'dn', + 'encap', + 'fabricPathDn', + 'lcC', + 'lcOwn', + 'mac', + 'name', + 'userdom', + 'vrfDn' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['flags'] = '' + if 'learned' in managed_object['lcC'].split(','): + info['flags'] = '%sL' % (info['flags']) + if 'vmm' in managed_object['lcC'].split(','): + info['flags'] = '%sV' % (info['flags']) + + info['encapT'] = info['encap'] + info['encapVlan'] = info['encap'] + if info['encap'].startswith('vlan-'): + info['encapVlan'] = info['encap'].split('vlan-')[1] + + # Dn format + # [0]: uni/tn-{name}/ap-{name}/esg-{name}/cep-{name} + # [1]: uni/tn-{name}/Tnlepg-{name}/cep-{name} + # [2]: uni/ldev-[{priKey}]-ctx-[{ctxDn}]-bd-[{bdDn}]/cep-{name} + # [3]: uni/tn-{name}/LDevInst-[{priKey}]-ctx-{ctxName}/G-{graphRn}-N-{nodeRn}-C-{connRn}/cep-{name} + # [4]: uni/vDev-[{priKey}]-tn-[{tnDn}]-ctx-{ctxName}/rndrInfo/eppContr/G-{graphRn}-N-{nodeRn}-C-{connRn}/cep-{name} + # [5]: uni/tn-{name}/ctx-{name}/cep-{name} + # [6]: uni/tn-{name}/ap-{name}/epg-{name}/cep-{name} + # [7]: uni/tn-{name}/l2out-{name}/instP-{name}/cep-{name} + + info['apic'] = self.apic_name + info['tenant'] = '' + info['vrfTenant'] = '' + info['vrfName'] = '' + info['vrfNameTenant'] = '' + info['bdTenant'] = '' + info['bdName'] = '' + info['bdNameTenant'] = '' + info['epgName'] = '' + info['apName'] = '' + info['epgNameApTenant'] = '' + + if info['bdDn'] is not None and len(info['bdDn']) > 0: + info['bdTenant'] = info['bdDn'].split('/')[1].split('tn-')[1] + info['bdName'] = info['bdDn'].split('/')[2].split('BD-')[1] + info['bdNameTenant'] = '%s/%s' % ( + info['bdTenant'], + info['bdName'] + ) + + if info['vrfDn'] is not None and len(info['vrfDn']) > 0: + info['vrfTenant'] = info['vrfDn'].split('/')[1].split('tn-')[1] + info['vrfName'] = info['vrfDn'].split('/')[2].split('ctx-')[1] + info['vrfNameTenant'] = '%s/%s' % ( + info['vrfTenant'], + info['vrfName'] + ) + + if info['dn'].startswith('uni/tn-'): + info['tenant'] = info['dn'].split('/')[1][3:] + + if info['dn'].startswith('uni/tn-') and '/ap-' in info['dn']: + info['epgName'] = info['dn'].split('/')[3][4:] + info['apName'] = info['dn'].split('/')[2][3:] + info['epgNameApTenant'] = '%s/%s/%s' % ( + info['tenant'], + info['apName'], + info['epgName'] + ) + + info['fvIp'] = [] + address = [] + for ip_managed_object in managed_object['fvIp']: + ip_info = self.get_endpoint_ip_info( + ip_managed_object + ) + info['fvIp'].append( + ip_info + ) + address.append(ip_info['addr']) + + info['ip'] = ','.join(address) + + info['fvRsToVm'] = None + if 'fvRsToVm' in managed_object and managed_object['fvRsToVm'] is not None: + info['fvRsToVm'] = self.get_endpoint_vm_info( + managed_object['fvRsToVm'] + ) + + info['fvRsHyper'] = None + if 'fvRsHyper' in managed_object and managed_object['fvRsHyper'] is not None: + info['fvRsHyper'] = self.get_endpoint_hv_info( + managed_object['fvRsHyper'] + ) + + if len(info['fabricPathDn']) == 0: + if managed_object['fvRsCEpToPathEp'] is not None: + if 'tDn' in managed_object['fvRsCEpToPathEp']: + info['fabricPathDn'] = managed_object['fvRsCEpToPathEp']['tDn'] + + return info + + def get_endpoints_info(self): + if self.endpoints is not None: + return self.endpoints + + managed_objects = self.get_endpoints_mo() + if managed_objects is None: + return None + + self.endpoints = [] + for managed_object in managed_objects: + self.endpoints.append( + self.get_endpoint_info( + managed_object + ) + ) + + self.log.apic_mo( + 'fvCEp.info', + self.endpoints + ) + + return self.endpoints + + def match_endpoint(self, endpoint_info, endpoint_filter): + if endpoint_filter is None or len(endpoint_filter) == 0: + return True + + # support multiple mac: filtering with 'or' logic + + mac_filtering = False + mac_match = False + for rule in endpoint_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + if key == 'mac': + mac_filtering = True + if ip_helper.is_mac_match(value, endpoint_info['mac']): + mac_match = True + + if mac_filtering and not mac_match: + return False + + for rule in endpoint_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + key_found = False + + if key == 'mac': + key_found = True + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, endpoint_info['tenant']): + return False + + if key == 'bd': + key_found = True + if not filter_helper.match_tenant_name(value, endpoint_info['bdNameTenant']): + return False + + if key == 'epg': + key_found = True + if not filter_helper.match_tenant_ap_name(value, endpoint_info['epgNameApTenant']): + return False + + if key == 'ap': + key_found = True + if not filter_helper.match_string(value, endpoint_info['apName']): + return False + + if key == 'vrf': + key_found = True + if not filter_helper.match_tenant_name(value, endpoint_info['vrfNameTenant']): + return False + + if key == 'bdDn': + key_found = True + if not filter_helper.match(value, endpoint_info['bdDn']): + return False + + if key == 'vlan': + key_found = True + if not filter_helper.match_integer(value, endpoint_info['encapVlan']): + return False + + if key == 'ip': + key_found = True + found = False + for ip_address in endpoint_info['fvIp']: + if value == ip_address['addr']: + found = True + break + + if not found: + return False + + if key == 'subnet': + key_found = True + found = False + for ip_address in endpoint_info['fvIp']: + if ip_helper.is_ipv4_in_cidr(ip_address['addr'], value): + found = True + break + + if not found: + return False + + if key == 'vm-info': + key_found = True + if value not in ['enabled']: + self.log.error( + 'match_endpoint', + 'Unsupported key:value %s:%s' % (key, value) + ) + + if value == 'enabled': + if endpoint_info['fvRsToVm'] is None: + return False + + if key == 'vmm': + key_found = True + if 'vm' in endpoint_info: + if not filter_helper.match_string(value, endpoint_info['vm']['vmm']): + return False + + if key == 'hv': + key_found = True + if 'hv' in endpoint_info: + if not filter_helper.match_string(value, endpoint_info['hv']['name']): + return False + + if key == 'vm': + key_found = True + if 'vm' in endpoint_info: + if not filter_helper.match_string(value, endpoint_info['vm']['name']): + return False + + if key == 'node': + key_found = True + nodes = value.split(',') + if 'fabric' in endpoint_info: + node_match = False + for fabric in endpoint_info['fabric']: + if fabric['node_id'] in nodes: + node_match = True + break + + if not node_match: + return False + + if not key_found: + self.log.error( + 'match_endpoint', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_endpoints(self, endpoint_filter=None, vm_info=False, fabric_info=False): + all_endpoints = self.get_endpoints_info() + if all_endpoints is None: + return None + + endpoints = [] + + for endpoint_info in all_endpoints: + if not self.match_endpoint(endpoint_info, endpoint_filter): + continue + + if vm_info: + if 'fvRsToVm' in endpoint_info and endpoint_info['fvRsToVm'] is not None: + vm_dn = endpoint_info['fvRsToVm']['tDn'] + vm_mac = endpoint_info['mac'] + hv_dn = endpoint_info['fvRsHyper']['tDn'] + + endpoint_info['vm'] = self.get_endpoint_vmm_vm( + vm_filter=['dn:%s' % (vm_dn)], + expected_single=True + ) + + endpoint_info['vnic'] = self.get_endpoint_vmm_vnic( + vm_filter=[ + 'dn:%s' % (vm_dn), + 'mac:%s' % (vm_mac) + ], + expected_single=True + ) + + endpoint_info['hv'] = self.get_endpoint_vmm_hv( + vm_filter=['dn:%s' % (hv_dn)], + expected_single=True + ) + + if not self.match_endpoint(endpoint_info, endpoint_filter): + continue + + if fabric_info: + endpoint_info['fabric'] = self.get_fabric_path_ports( + endpoint_info['fabricPathDn'], + resolve=True + ) + if not self.match_endpoint(endpoint_info, endpoint_filter): + continue + + endpoints.append(endpoint_info) + + endpoints = sorted( + endpoints, + key=lambda i: i['mac'] + ) + + return endpoints diff --git a/lib/aci/endpoint/ip/__init__.py b/lib/aci/endpoint/ip/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/ip/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/ip/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a619d7f8 Binary files /dev/null and b/lib/aci/endpoint/ip/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/ip/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/ip/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..3fa708fd Binary files /dev/null and b/lib/aci/endpoint/ip/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/ip/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/ip/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9b62eae1 Binary files /dev/null and b/lib/aci/endpoint/ip/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/ip/info.py b/lib/aci/endpoint/ip/info.py new file mode 100644 index 00000000..cd55e520 --- /dev/null +++ b/lib/aci/endpoint/ip/info.py @@ -0,0 +1,38 @@ +class EndpointIpInfo(): + def __init__(self): + pass + + def get_endpoint_ip_info(self, managed_object): + # "addr": "", + # "annotation": "", + # "baseEpgDn": "", + # "bdDn": "", + # "childAction": "", + # "createTs": "2022-09-14T22:56:47.772+01:00", + # "debugMACMessage": "", + # "esgUsegDn": "", + # "extMngdBy": "", + # "fabricPathDn": "topology/pod-1/paths-2205/pathep-[eth1/25]", + # "flags": "", + # "lcOwn": "local", + # "modTs": "2022-09-14T22:57:01.829+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "rn": "ip-[]", + # "status": "", + # "uid": "0", + # "userdom": "all", + # "vrfDn": "uni/tn-common/ctx-Infra_VRF" + info = {} + info['__Output'] = {} + + keys = [ + 'addr', + 'baseEpgDn', + 'vrfDn' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/endpoint/ip/main.py b/lib/aci/endpoint/ip/main.py new file mode 100644 index 00000000..76041a82 --- /dev/null +++ b/lib/aci/endpoint/ip/main.py @@ -0,0 +1,6 @@ +from lib.aci.endpoint.ip.info import EndpointIpInfo + + +class EndpointIp(EndpointIpInfo): + def __init__(self): + EndpointIpInfo.__init__(self) diff --git a/lib/aci/endpoint/main.py b/lib/aci/endpoint/main.py new file mode 100644 index 00000000..526c69d7 --- /dev/null +++ b/lib/aci/endpoint/main.py @@ -0,0 +1,16 @@ +from lib.aci.endpoint.api import EndpointApi +from lib.aci.endpoint.info import EndpointInfo +from lib.aci.endpoint.ip.main import EndpointIp +from lib.aci.endpoint.hv.main import EndpointHv +from lib.aci.endpoint.vm.main import EndpointVm +from lib.aci.endpoint.vmm.main import EndpointVmm + + +class Endpoint(EndpointApi, EndpointInfo, EndpointIp, EndpointHv, EndpointVm, EndpointVmm): + def __init__(self): + EndpointApi.__init__(self) + EndpointInfo.__init__(self) + EndpointIp.__init__(self) + EndpointHv.__init__(self) + EndpointVm.__init__(self) + EndpointVmm.__init__(self) diff --git a/lib/aci/endpoint/output.py b/lib/aci/endpoint/output.py new file mode 100644 index 00000000..036b5b54 --- /dev/null +++ b/lib/aci/endpoint/output.py @@ -0,0 +1,128 @@ +class EndpointOutput(): + def __init__(self): + pass + + def print_endpoints_apic(self, endpoints): + if not self.is_apic: + return False + + if len(endpoints) == 0: + return False + + if 'apic' not in endpoints[0]: + return False + + return True + + def print_endpoints(self, endpoints, bridge_domain_name=True, stream='default', title=False): + if title: + self.my_output.default( + 'Endpoint [#%s]' % (len(endpoints)), + underline=True, + before_newline=True + ) + + if len(endpoints) == 0: + self.my_output.default('None') + return + + is_apic = self.print_endpoints_apic(endpoints) + order = [] + if is_apic: + order = ['apic'] + + order = order + [ + 'flags', + 'mac', + 'fvIp.addr', + 'epgNameApTenant', + 'encapT', + 'bdNameTenant', + 'vrfNameTenant', + 'fabric.ep' + ] + + headers = [] + if is_apic: + headers = ['Apic'] + + headers = headers + [ + 'SF', + 'MAC Address', + 'IP Address', + 'EPG', + 'Encap', + 'BD', + 'VRF', + 'Fabric' + ] + + if not bridge_domain_name: + order.remove('bdNameTenant') + headers.remove('BD') + + self.my_output.my_table( + self.my_output.expand_lists( + endpoints, + order, + ['fvIp', 'fabric'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=True, + table=True, + stream=stream + ) + + def print_endpoints_vmm(self, endpoints): + order = [] + + is_apic = self.print_endpoints_apic(endpoints) + if is_apic: + order = ['apic'] + + order = order + [ + 'flags', + 'mac', + 'fvIp.addr', + 'vm.vmm', + 'hv.name', + 'vm.name', + 'vm.state', + 'vnic.name', + 'vnic.operSt' + ] + + headers = [] + if is_apic: + headers = ['Apic'] + + headers = headers + [ + 'SF', + 'MAC Address', + 'IP Address', + 'VMM', + 'Hypervisor', + 'VM Name', + 'VM State', + 'vNIC Name', + 'vNIC State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + endpoints, + order, + ['fvIp'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/endpoint/vm/__init__.py b/lib/aci/endpoint/vm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/vm/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/vm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ec82bbaa Binary files /dev/null and b/lib/aci/endpoint/vm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vm/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/vm/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..33c2ee16 Binary files /dev/null and b/lib/aci/endpoint/vm/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vm/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/vm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1a5c7be5 Binary files /dev/null and b/lib/aci/endpoint/vm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vm/info.py b/lib/aci/endpoint/vm/info.py new file mode 100644 index 00000000..01ffb027 --- /dev/null +++ b/lib/aci/endpoint/vm/info.py @@ -0,0 +1,34 @@ +class EndpointVmInfo(): + def __init__(self): + pass + + def get_endpoint_vm_info(self, managed_object): + # "childAction": "", + # "forceResolve": "yes", + # "isBootstrapUpd": "attach", + # "lcOwn": "local", + # "modTs": "2022-12-16T15:57:06.305+01:00", + # "rType": "mo", + # "rn": "rstoVm-[comp/prov-VMware/ctrlr-[EU-SPDC-POD2B]-EU-SPDC-POD2B/vm-vm-12062]", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "compVm", + # "tDn": "comp/prov-VMware/ctrlr-[EU-SPDC-POD2B]-EU-SPDC-POD2B/vm-vm-12062", + # "tType": "mo" + info = {} + info['__Output'] = {} + + keys = [ + 'rn', + 'state', + 'tCl', + 'tDn', + 'tType' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/endpoint/vm/main.py b/lib/aci/endpoint/vm/main.py new file mode 100644 index 00000000..f5fcc8f3 --- /dev/null +++ b/lib/aci/endpoint/vm/main.py @@ -0,0 +1,6 @@ +from lib.aci.endpoint.vm.info import EndpointVmInfo + + +class EndpointVm(EndpointVmInfo): + def __init__(self): + EndpointVmInfo.__init__(self) diff --git a/lib/aci/endpoint/vmm/__init__.py b/lib/aci/endpoint/vmm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/vmm/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/vmm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..fcc43ad0 Binary files /dev/null and b/lib/aci/endpoint/vmm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/__pycache__/hv.cpython-310.pyc b/lib/aci/endpoint/vmm/__pycache__/hv.cpython-310.pyc new file mode 100644 index 00000000..1d53c335 Binary files /dev/null and b/lib/aci/endpoint/vmm/__pycache__/hv.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/vmm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..432c94e3 Binary files /dev/null and b/lib/aci/endpoint/vmm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/__pycache__/vm.cpython-310.pyc b/lib/aci/endpoint/vmm/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..7cf92ed2 Binary files /dev/null and b/lib/aci/endpoint/vmm/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/__pycache__/vnic.cpython-310.pyc b/lib/aci/endpoint/vmm/__pycache__/vnic.cpython-310.pyc new file mode 100644 index 00000000..f0465d94 Binary files /dev/null and b/lib/aci/endpoint/vmm/__pycache__/vnic.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/hv/__init__.py b/lib/aci/endpoint/vmm/hv/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/vmm/hv/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/vmm/hv/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..940a44f7 Binary files /dev/null and b/lib/aci/endpoint/vmm/hv/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/hv/__pycache__/api.cpython-310.pyc b/lib/aci/endpoint/vmm/hv/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..a732771f Binary files /dev/null and b/lib/aci/endpoint/vmm/hv/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/hv/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/vmm/hv/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..731193d0 Binary files /dev/null and b/lib/aci/endpoint/vmm/hv/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/hv/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/vmm/hv/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..702f5bc7 Binary files /dev/null and b/lib/aci/endpoint/vmm/hv/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/hv/api.py b/lib/aci/endpoint/vmm/hv/api.py new file mode 100644 index 00000000..292223a1 --- /dev/null +++ b/lib/aci/endpoint/vmm/hv/api.py @@ -0,0 +1,48 @@ +class EndpointVmmHvApi(): + def __init__(self): + self.endpoint_vmm_hv_mo = None + + def get_endpoint_vmm_hv_mo(self): + if self.endpoint_vmm_hv_mo is not None: + return self.endpoint_vmm_hv_mo + + cache = self.get_object_cache( + 'compHv' + ) + if cache is not None: + self.endpoint_vmm_hv_mo = cache + self.log.apic_mo( + 'compHv', + self.endpoint_vmm_hv_mo + ) + return self.endpoint_vmm_hv_mo + + managed_objects = self.get_class( + 'compHv' + ) + if managed_objects is None: + self.log.error( + 'get_endpoint_vmm_hv_mo', + 'API failed' + ) + return None + + self.endpoint_vmm_hv_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['compHv']['attributes'] + self.endpoint_vmm_hv_mo.append( + attributes + ) + + self.log.apic_mo( + 'compHv', + self.endpoint_vmm_hv_mo + ) + + self.set_object_cache( + 'compHv', + self.endpoint_vmm_hv_mo + ) + + return self.endpoint_vmm_hv_mo diff --git a/lib/aci/endpoint/vmm/hv/info.py b/lib/aci/endpoint/vmm/hv/info.py new file mode 100644 index 00000000..fe4aaad0 --- /dev/null +++ b/lib/aci/endpoint/vmm/hv/info.py @@ -0,0 +1,92 @@ +from lib import filter_helper + + +class EndpointVmmHvInfo(): + def __init__(self): + self.endpoint_vmm_hv = None + + def get_endpoint_vmm_hv_info(self, managed_object): + info = {} + info['__Output'] = {} + keys = [ + 'availAdminSt', + 'availOperSt', + 'countUplink', + 'dn', + 'enteringMaintenance', + 'mgmtIp', + 'name', + 'oid', + 'state' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['vmm'] = info['dn'].split('[')[1].split(']')[0] + + return info + + def get_endpoints_vmm_hv_info(self): + if self.endpoint_vmm_hv is not None: + return self.endpoint_vmm_hv + + managed_objects = self.get_endpoint_vmm_hv_mo() + if managed_objects is None: + return None + + self.endpoint_vmm_hv = [] + for managed_object in managed_objects: + self.endpoint_vmm_hv.append( + self.get_endpoint_vmm_hv_info( + managed_object + ) + ) + + self.log.apic_mo( + 'compHv.info', + self.endpoint_vmm_hv + ) + + return self.endpoint_vmm_hv + + def match_endpoint_vmm_hv(self, vm_info, vm_filter): + if vm_filter is None or len(vm_filter) == 0: + return True + + for rule in vm_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + if key == 'dn': + if not filter_helper.match_string(value, vm_info['dn']): + return False + + return True + + def get_endpoint_vmm_hv(self, vm_filter=None, expected_single=False): + all_vms = self.get_endpoints_vmm_hv_info() + + vms = [] + + for vm_info in all_vms: + if self.match_endpoint_vmm_hv(vm_info, vm_filter): + vms.append( + vm_info + ) + + if expected_single: + if len(vms) == 0: + return None + + if len(vms) == 1: + return vms[0] + + self.log.error( + 'get_endpoint_vmm_hv', + 'Expected single result' + ) + return None + + return vms diff --git a/lib/aci/endpoint/vmm/hv/main.py b/lib/aci/endpoint/vmm/hv/main.py new file mode 100644 index 00000000..3c082e0e --- /dev/null +++ b/lib/aci/endpoint/vmm/hv/main.py @@ -0,0 +1,8 @@ +from lib.aci.endpoint.vmm.hv.api import EndpointVmmHvApi +from lib.aci.endpoint.vmm.hv.info import EndpointVmmHvInfo + + +class EndpointVmmHv(EndpointVmmHvApi, EndpointVmmHvInfo): + def __init__(self): + EndpointVmmHvApi.__init__(self) + EndpointVmmHvInfo.__init__(self) diff --git a/lib/aci/endpoint/vmm/main.py b/lib/aci/endpoint/vmm/main.py new file mode 100644 index 00000000..463646f6 --- /dev/null +++ b/lib/aci/endpoint/vmm/main.py @@ -0,0 +1,10 @@ +from lib.aci.endpoint.vmm.hv.main import EndpointVmmHv +from lib.aci.endpoint.vmm.vm.main import EndpointVmmVm +from lib.aci.endpoint.vmm.vnic.main import EndpointVmmVnic + + +class EndpointVmm(EndpointVmmHv, EndpointVmmVm, EndpointVmmVnic): + def __init__(self, log_id=None): + EndpointVmmHv.__init__(self) + EndpointVmmVm.__init__(self) + EndpointVmmVnic.__init__(self) diff --git a/lib/aci/endpoint/vmm/vm/__init__.py b/lib/aci/endpoint/vmm/vm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/vmm/vm/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/vmm/vm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9936fa5f Binary files /dev/null and b/lib/aci/endpoint/vmm/vm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vm/__pycache__/api.cpython-310.pyc b/lib/aci/endpoint/vmm/vm/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e05c6176 Binary files /dev/null and b/lib/aci/endpoint/vmm/vm/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vm/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/vmm/vm/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..a9113637 Binary files /dev/null and b/lib/aci/endpoint/vmm/vm/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vm/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/vmm/vm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f266bc57 Binary files /dev/null and b/lib/aci/endpoint/vmm/vm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vm/api.py b/lib/aci/endpoint/vmm/vm/api.py new file mode 100644 index 00000000..3d06f99b --- /dev/null +++ b/lib/aci/endpoint/vmm/vm/api.py @@ -0,0 +1,48 @@ +class EndpointVmmVmApi(): + def __init__(self): + self.endpoint_vmm_vm_mo = None + + def get_endpoint_vmm_vm_mo(self): + if self.endpoint_vmm_vm_mo is not None: + return self.endpoint_vmm_vm_mo + + cache = self.get_object_cache( + 'compVm' + ) + if cache is not None: + self.endpoint_vmm_vm_mo = cache + self.log.apic_mo( + 'compVm', + self.endpoint_vmm_vm_mo + ) + return self.endpoint_vmm_vm_mo + + managed_objects = self.get_class( + 'compVm' + ) + if managed_objects is None: + self.log.error( + 'get_endpoint_vmm_vm_mo', + 'API failed' + ) + return None + + self.endpoint_vmm_vm_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['compVm']['attributes'] + self.endpoint_vmm_vm_mo.append( + attributes + ) + + self.log.apic_mo( + 'compVm', + self.endpoint_vmm_vm_mo + ) + + self.set_object_cache( + 'compVm', + self.endpoint_vmm_vm_mo + ) + + return self.endpoint_vmm_vm_mo diff --git a/lib/aci/endpoint/vmm/vm/info.py b/lib/aci/endpoint/vmm/vm/info.py new file mode 100644 index 00000000..312e81e9 --- /dev/null +++ b/lib/aci/endpoint/vmm/vm/info.py @@ -0,0 +1,115 @@ +from lib import filter_helper + + +class EndpointVmmVmInfo(): + def __init__(self): + self.endpoint_vmm_vm = None + + def get_endpoint_vmm_vm_info(self, managed_object): + # "cfgdOs": "Red Hat Enterprise Linux 8 (64-bit)", + # "childAction": "", + # "descr": "", + # "dn": "comp/prov-VMware/ctrlr-[EU-SPDC-POD2B]-EU-SPDC-POD2B/vm-vm-12127", + # "ftRole": "unset", + # "guid": "5034b867-282f-2aff-9024-d4d063029325", + # "id": "0", + # "issues": "", + # "lcOwn": "local", + # "modTs": "2023-01-16T21:15:07.545+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "name": "cluster-6csrc-rhcos", + # "nameAlias": "", + # "oid": "vm-12127", + # "os": "", + # "state": "poweredOff", + # "status": "", + # "template": "yes", + # "type": "virt", + # "uuid": "4234e811-d953-f70b-d555-fa5d1b947709" + info = {} + info['__Output'] = {} + + keys = [ + 'cfgdOs', + 'dn', + 'name', + 'oid', + 'os', + 'state' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['vmm'] = info['dn'].split('[')[1].split(']')[0] + + if info['state'] == 'poweredOn': + info['__Output']['state'] = 'Green' + else: + info['__Output']['state'] = 'Red' + + return info + + def get_endpoints_vmm_vm_info(self): + if self.endpoint_vmm_vm is not None: + return self.endpoint_vmm_vm + + managed_objects = self.get_endpoint_vmm_vm_mo() + if managed_objects is None: + return None + + self.endpoint_vmm_vm = [] + for managed_object in managed_objects: + self.endpoint_vmm_vm.append( + self.get_endpoint_vmm_vm_info( + managed_object + ) + ) + + self.log.apic_mo( + 'compVm.info', + self.endpoint_vmm_vm + ) + + return self.endpoint_vmm_vm + + def match_endpoint_vmm_vm(self, vm_info, vm_filter): + if vm_filter is None or len(vm_filter) == 0: + return True + + for rule in vm_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + if key == 'dn': + if not filter_helper.match_string(value, vm_info['dn']): + return False + + return True + + def get_endpoint_vmm_vm(self, vm_filter=None, expected_single=False): + all_vms = self.get_endpoints_vmm_vm_info() + + vms = [] + + for vm_info in all_vms: + if self.match_endpoint_vmm_vm(vm_info, vm_filter): + vms.append( + vm_info + ) + + if expected_single: + if len(vms) == 0: + return None + + if len(vms) == 1: + return vms[0] + + self.log.error( + 'get_endpoint_vmm_vm', + 'Expected single result' + ) + return None + + return vms diff --git a/lib/aci/endpoint/vmm/vm/main.py b/lib/aci/endpoint/vmm/vm/main.py new file mode 100644 index 00000000..91eb120b --- /dev/null +++ b/lib/aci/endpoint/vmm/vm/main.py @@ -0,0 +1,8 @@ +from lib.aci.endpoint.vmm.vm.api import EndpointVmmVmApi +from lib.aci.endpoint.vmm.vm.info import EndpointVmmVmInfo + + +class EndpointVmmVm(EndpointVmmVmApi, EndpointVmmVmInfo): + def __init__(self): + EndpointVmmVmApi.__init__(self) + EndpointVmmVmInfo.__init__(self) diff --git a/lib/aci/endpoint/vmm/vnic/__init__.py b/lib/aci/endpoint/vmm/vnic/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/endpoint/vmm/vnic/__pycache__/__init__.cpython-310.pyc b/lib/aci/endpoint/vmm/vnic/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ec34fad5 Binary files /dev/null and b/lib/aci/endpoint/vmm/vnic/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vnic/__pycache__/api.cpython-310.pyc b/lib/aci/endpoint/vmm/vnic/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..593f8259 Binary files /dev/null and b/lib/aci/endpoint/vmm/vnic/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vnic/__pycache__/info.cpython-310.pyc b/lib/aci/endpoint/vmm/vnic/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..bb4ae255 Binary files /dev/null and b/lib/aci/endpoint/vmm/vnic/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vnic/__pycache__/main.cpython-310.pyc b/lib/aci/endpoint/vmm/vnic/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e664a6e5 Binary files /dev/null and b/lib/aci/endpoint/vmm/vnic/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/endpoint/vmm/vnic/api.py b/lib/aci/endpoint/vmm/vnic/api.py new file mode 100644 index 00000000..f42d0a98 --- /dev/null +++ b/lib/aci/endpoint/vmm/vnic/api.py @@ -0,0 +1,48 @@ +class EndpointVmmVnicApi(): + def __init__(self): + self.endpoint_vmm_vnic_mo = None + + def get_endpoint_vmm_vnic_mo(self): + if self.endpoint_vmm_vnic_mo is not None: + return self.endpoint_vmm_vnic_mo + + cache = self.get_object_cache( + 'compVNic' + ) + if cache is not None: + self.endpoint_vmm_vnic_mo = cache + self.log.apic_mo( + 'compVNic', + self.endpoint_vmm_vnic_mo + ) + return self.endpoint_vmm_vnic_mo + + managed_objects = self.get_class( + 'compVNic' + ) + if managed_objects is None: + self.log.error( + 'get_endpoint_vmm_vnic_mo', + 'API failed' + ) + return None + + self.endpoint_vmm_vnic_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['compVNic']['attributes'] + self.endpoint_vmm_vnic_mo.append( + attributes + ) + + self.log.apic_mo( + 'compVNic', + self.endpoint_vmm_vnic_mo + ) + + self.set_object_cache( + 'compVNic', + self.endpoint_vmm_vnic_mo + ) + + return self.endpoint_vmm_vnic_mo diff --git a/lib/aci/endpoint/vmm/vnic/info.py b/lib/aci/endpoint/vmm/vnic/info.py new file mode 100644 index 00000000..21ba622e --- /dev/null +++ b/lib/aci/endpoint/vmm/vnic/info.py @@ -0,0 +1,116 @@ +from lib import filter_helper + + +class EndpointVmmVnicInfo(): + def __init__(self): + self.endpoint_vmm_vnic = None + + def get_endpoint_vmm_vnic_info(self, managed_object): + # "adapterType": "Vmxnet3", + # "addressType": "assigned", + # "childAction": "", + # "descr": "", + # "dn": "comp/prov-VMware/ctrlr-[EU-SPDC-POD2B]-EU-SPDC-POD2B/vm-vm-12127/vnic-00:50:56:B4:16:6D", + # "guid": "241", + # "id": "0", + # "ip": "", + # "issues": "", + # "lcOwn": "local", + # "mac": "00:50:56:B4:16:6D", + # "modTs": "2023-01-16T20:52:58.626+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "name": "Network adapter 1", + # "nameAlias": "", + # "oid": "4000", + # "operSt": "down", + # "status": "", + # "type": "virt", + # "uuid": "", + # "vmName": "" + info = {} + info['__Output'] = {} + + keys = [ + 'dn', + 'name', + 'operSt', + 'adapterType' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_endpoints_vmm_vnic_info(self): + if self.endpoint_vmm_vnic is not None: + return self.endpoint_vmm_vnic + + managed_objects = self.get_endpoint_vmm_vnic_mo() + if managed_objects is None: + return None + + self.endpoint_vmm_vnic = [] + for managed_object in managed_objects: + self.endpoint_vmm_vnic.append( + self.get_endpoint_vmm_vnic_info( + managed_object + ) + ) + + self.log.apic_mo( + 'compVNic.info', + self.endpoint_vmm_vnic + ) + + return self.endpoint_vmm_vnic + + def match_endpoint_vmm_vnic(self, vm_info, vm_filter): + if vm_filter is None or len(vm_filter) == 0: + return True + + for rule in vm_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + if key == 'dn': + if not filter_helper.match_string('%s/*' % (value), vm_info['dn']): + return False + + if key == 'mac': + if not filter_helper.match_string('*/vnic-%s' % (value), vm_info['dn']): + return False + + return True + + def get_endpoint_vmm_vnic(self, vm_filter=None, expected_single=False): + all_vms = self.get_endpoints_vmm_vnic_info() + + vms = [] + + for vm_info in all_vms: + if self.match_endpoint_vmm_vnic(vm_info, vm_filter): + vms.append( + vm_info + ) + + if expected_single: + if len(vms) == 0: + return None + + if len(vms) == 1: + return vms[0] + + self.log.error( + 'get_endpoint_vmm_vnic', + 'Expected single result' + ) + return None + + return vms diff --git a/lib/aci/endpoint/vmm/vnic/main.py b/lib/aci/endpoint/vmm/vnic/main.py new file mode 100644 index 00000000..2eb5008c --- /dev/null +++ b/lib/aci/endpoint/vmm/vnic/main.py @@ -0,0 +1,8 @@ +from lib.aci.endpoint.vmm.vnic.api import EndpointVmmVnicApi +from lib.aci.endpoint.vmm.vnic.info import EndpointVmmVnicInfo + + +class EndpointVmmVnic(EndpointVmmVnicApi, EndpointVmmVnicInfo): + def __init__(self): + EndpointVmmVnicApi.__init__(self) + EndpointVmmVnicInfo.__init__(self) diff --git a/lib/aci/epg/__init__.py b/lib/aci/epg/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/__pycache__/__init__.cpython-310.pyc b/lib/aci/epg/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..503e1c6c Binary files /dev/null and b/lib/aci/epg/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/epg/__pycache__/api.cpython-310.pyc b/lib/aci/epg/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..63fd62c0 Binary files /dev/null and b/lib/aci/epg/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/epg/__pycache__/info.cpython-310.pyc b/lib/aci/epg/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f0dc1dbb Binary files /dev/null and b/lib/aci/epg/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/epg/__pycache__/main.cpython-310.pyc b/lib/aci/epg/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..dd53b6d7 Binary files /dev/null and b/lib/aci/epg/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/epg/__pycache__/output.cpython-310.pyc b/lib/aci/epg/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..163d6fa0 Binary files /dev/null and b/lib/aci/epg/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/epg/api.py b/lib/aci/epg/api.py new file mode 100644 index 00000000..c7574276 --- /dev/null +++ b/lib/aci/epg/api.py @@ -0,0 +1,95 @@ +class EpgApi(): + def __init__(self): + self.epg_mo = None + + def get_epg_mo(self): + if self.epg_mo is not None: + return self.epg_mo + + cache = self.get_object_cache( + 'fvAEPg' + ) + if cache is not None: + self.epg_mo = cache + self.log.apic_mo( + 'fvAEPg', + self.epg_mo + ) + return self.epg_mo + + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count&rsp-subtree-class=fvRsBd,fvRsCons,fvRsProv,fvRsProtBy,fvRtMatchEPg,fvRsPathAtt,fvRsDomAtt' + managed_objects = self.get_class( + 'fvAEPg', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_epgs_mo', + 'API failed' + ) + return None + + self.epg_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvAEPg']['attributes'] + attributes['fvBD'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRsBd' + ) + attributes['fvRsCons'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRsCons' + ) + attributes['fvRsProv'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRsProv' + ) + attributes['fvRsProtBy'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRsProtBy' + ) + attributes['fvMatchEPg'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRtMatchEPg' + ) + attributes['fvRsPathAtt'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRsPathAtt' + ) + attributes['fvRsDomAtt'] = self.get_mo_children_attributes( + 'fvAEPg', + managed_object, + 'fvRsDomAtt' + ) + attributes['healthInst'] = self.get_mo_child_attributes( + 'fvAEPg', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'fvAEPg', + managed_object, + 'faultCounts' + ) + self.epg_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAEPg', + self.epg_mo + ) + + self.set_object_cache( + 'fvAEPg', + self.epg_mo + ) + + return self.epg_mo diff --git a/lib/aci/epg/audit/__init__.py b/lib/aci/epg/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/audit/api.py b/lib/aci/epg/audit/api.py new file mode 100644 index 00000000..7c1025d7 --- /dev/null +++ b/lib/aci/epg/audit/api.py @@ -0,0 +1,48 @@ +class EpgAuditApi(): + def __init__(self): + self.epg_audit_mo = None + + def get_epg_audit_mo(self): + cache = self.get_object_cache( + 'fvAEPg.audit' + ) + if cache is not None: + self.epg_audit_mo = cache + self.log.apic_mo( + 'fvAEPg.audit', + self.epg_audit_mo + ) + return self.epg_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'fvAEPg', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_epg_audit_mo', + 'API failed' + ) + return None + + self.epg_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.epg_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAEPg.audit', + self.epg_audit_mo + ) + + self.set_object_cache( + 'fvAEPg.audit', + self.epg_audit_mo + ) + + return self.epg_audit_mo diff --git a/lib/aci/epg/audit/info.py b/lib/aci/epg/audit/info.py new file mode 100644 index 00000000..057598a2 --- /dev/null +++ b/lib/aci/epg/audit/info.py @@ -0,0 +1,115 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class EpgAuditInfo(): + def __init__(self): + self.epg_audit = None + + def get_epg_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['apName'] = None + info['epgName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-bmk8s_prov + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['affected']: + info['apName'] = info['affected'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['affected']: + info['epgName'] = info['affected'].split('/epg-')[1].split('/')[0] + + info['nameApTenant'] = '--' + if info['tenantName'] is not None and info['apName'] is not None and info['epgName'] is not None: + info['nameApTenant'] = '%s/%s/%s' % ( + info['tenantName'], + info['apName'], + info['epgName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_epg_audit(self): + if self.epg_audit is not None: + return self.epg_audit + + managed_objects = self.get_epg_audit_mo() + if managed_objects is None: + return None + + self.epg_audit = [] + for managed_object in managed_objects: + audit_info = self.get_epg_audit_info( + managed_object + ) + self.epg_audit.append( + audit_info + ) + + self.log.apic_mo( + 'fvAEPg.auditRecord.info', + self.epg_audit + ) + + return self.epg_audit + + def get_epg_id_audit(self, tenant_name, ap_name, epg_name, audit_filter=None): + audits = [] + + all_audits = self.get_epg_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['apName'] is not None and audit_info['epgName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['apName'] == ap_name and audit_info['epgName'] == epg_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/epg/audit/main.py b/lib/aci/epg/audit/main.py new file mode 100644 index 00000000..92360a7e --- /dev/null +++ b/lib/aci/epg/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.epg.audit.api import EpgAuditApi +from lib.aci.epg.audit.info import EpgAuditInfo + + +class EpgAudit(EpgAuditApi, EpgAuditInfo): + def __init__(self): + EpgAuditApi.__init__(self) + EpgAuditInfo.__init__(self) diff --git a/lib/aci/epg/event/__init__.py b/lib/aci/epg/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/event/api.py b/lib/aci/epg/event/api.py new file mode 100644 index 00000000..9f7299d8 --- /dev/null +++ b/lib/aci/epg/event/api.py @@ -0,0 +1,51 @@ +class EpgEventApi(): + def __init__(self): + self.epg_event_mo = None + + def get_epg_event_mo(self): + if self.epg_event_mo is not None: + return self.epg_event_mo + + cache = self.get_object_cache( + 'fvAEPg.eventLog' + ) + if cache is not None: + self.epg_event_mo = cache + self.log.apic_mo( + 'fvAEPg.eventLog', + self.epg_event_mo + ) + return self.epg_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'fvAEPg', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_epg_event_mo', + 'API failed' + ) + return None + + self.epg_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.epg_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAEPg.eventLog', + self.epg_event_mo + ) + + self.set_object_cache( + 'fvAEPg.eventLog', + self.epg_event_mo + ) + + return self.epg_event_mo diff --git a/lib/aci/epg/event/info.py b/lib/aci/epg/event/info.py new file mode 100644 index 00000000..0a4be535 --- /dev/null +++ b/lib/aci/epg/event/info.py @@ -0,0 +1,132 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class EpgEventInfo(): + def __init__(self): + self.epg_event = None + + def get_epg_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['apName'] = None + info['epgName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-bmk8s_prov + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['affected']: + info['apName'] = info['affected'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['affected']: + info['epgName'] = info['affected'].split('/epg-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/ap-k8s_ANP/epg-bmk8s_prov + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['dn']: + info['apName'] = info['dn'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['dn']: + info['epgName'] = info['dn'].split('/epg-')[1].split('/')[0] + + info['nameApTenant'] = '--' + if info['tenantName'] is not None and info['apName'] is not None and info['epgName'] is not None: + info['nameApTenant'] = '%s/%s/%s' % ( + info['tenantName'], + info['apName'], + info['epgName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_epg_event(self, deduplicate=True): + if self.epg_event is not None: + return self.epg_event + + managed_objects = self.get_epg_event_mo() + if managed_objects is None: + return None + + self.epg_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_epg_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.epg_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'fvAEPg.eventLog.info', + self.epg_event + ) + + return self.epg_event + + def get_epg_id_event(self, tenant_name, ap_name, epg_name, event_filter=None): + events = [] + + all_events = self.get_epg_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['apName'] is not None and event_info['epgName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['apName'] == ap_name and event_info['epgName'] == epg_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/epg/event/main.py b/lib/aci/epg/event/main.py new file mode 100644 index 00000000..a2d794ce --- /dev/null +++ b/lib/aci/epg/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.epg.event.api import EpgEventApi +from lib.aci.epg.event.info import EpgEventInfo + + +class EpgEvent(EpgEventApi, EpgEventInfo): + def __init__(self): + EpgEventApi.__init__(self) + EpgEventInfo.__init__(self) diff --git a/lib/aci/epg/fault/__init__.py b/lib/aci/epg/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/fault/api.py b/lib/aci/epg/fault/api.py new file mode 100644 index 00000000..b6bb714b --- /dev/null +++ b/lib/aci/epg/fault/api.py @@ -0,0 +1,118 @@ +class EpgFaultApi(): + def __init__(self): + self.epg_fault_mo = None + self.epg_fault_record_mo = None + + def get_epg_fault_mo(self): + cache = self.get_object_cache( + 'fvAEPg.fault' + ) + if cache is not None: + self.epg_fault_mo = cache + self.log.apic_mo( + 'fvAEPg.fault', + self.epg_fault_mo + ) + return self.epg_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'fvAEPg', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_epg_fault_mo', + 'API failed' + ) + return None + + self.epg_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.epg_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.epg_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAEPg.fault', + self.epg_fault_mo + ) + + self.set_object_cache( + 'fvAEPg.fault', + self.epg_fault_mo + ) + + return self.epg_fault_mo + + def get_epg_fault_record_mo(self): + cache = self.get_object_cache( + 'fvAEPg.faultRecord' + ) + if cache is not None: + self.epg_fault_record_mo = cache + self.log.apic_mo( + 'fvAEPg.faultRecord', + self.epg_fault_record_mo + ) + return self.epg_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'fvAEPg', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_epg_fault_record_mo', + 'API failed' + ) + return None + + self.epg_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.epg_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.epg_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvAEPg.faultRecord', + self.epg_fault_record_mo + ) + + self.set_object_cache( + 'fvAEPg.faultRecord', + self.epg_fault_record_mo + ) + + return self.epg_fault_record_mo diff --git a/lib/aci/epg/fault/info.py b/lib/aci/epg/fault/info.py new file mode 100644 index 00000000..4abaf5d2 --- /dev/null +++ b/lib/aci/epg/fault/info.py @@ -0,0 +1,163 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class EpgFaultInfo(): + def __init__(self): + self.epg_fault = None + self.epg_fault_record = None + + def get_epg_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['apName'] = None + info['epgName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-bmk8s_prov + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['affected']: + info['apName'] = info['affected'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['affected']: + info['epgName'] = info['affected'].split('/epg-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/ap-k8s_ANP/epg-bmk8s_prov + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/ap-' in info['dn']: + info['apName'] = info['dn'].split('/ap-')[1].split('/')[0] + + if '/epg-' in info['dn']: + info['epgName'] = info['dn'].split('/epg-')[1].split('/')[0] + + info['nameApTenant'] = '--' + if info['tenantName'] is not None and info['apName'] is not None and info['epgName'] is not None: + info['nameApTenant'] = '%s/%s/%s' % ( + info['tenantName'], + info['apName'], + info['epgName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_epg_fault(self): + if self.epg_fault is not None: + return self.epg_fault + + managed_objects = self.get_epg_fault_mo() + if managed_objects is None: + return None + + self.epg_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_epg_fault_info( + managed_object + ) + self.epg_fault.append( + fault_info + ) + + self.log.apic_mo( + 'fvAEPg.fault.info', + self.epg_fault + ) + + return self.epg_fault + + def get_epg_fault_record(self, deduplicate=True): + if self.epg_fault_record is not None: + return self.epg_fault_record + + managed_objects = self.get_epg_fault_record_mo() + if managed_objects is None: + return None + + self.epg_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_epg_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.epg_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'fvAEPg.faultRecord.info', + self.epg_fault_record + ) + + return self.epg_fault_record + + def get_epg_id_fault(self, tenant_name, ap_name, epg_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_epg_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_epg_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['apName'] is not None and fault_info['epgName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['apName'] == ap_name and fault_info['epgName'] == epg_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/epg/fault/main.py b/lib/aci/epg/fault/main.py new file mode 100644 index 00000000..eafe0e99 --- /dev/null +++ b/lib/aci/epg/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.epg.fault.api import EpgFaultApi +from lib.aci.epg.fault.info import EpgFaultInfo + + +class EpgFault(EpgFaultApi, EpgFaultInfo): + def __init__(self): + EpgFaultApi.__init__(self) + EpgFaultInfo.__init__(self) diff --git a/lib/aci/epg/ifconn/__init__.py b/lib/aci/epg/ifconn/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/ifconn/__pycache__/__init__.cpython-310.pyc b/lib/aci/epg/ifconn/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..32767593 Binary files /dev/null and b/lib/aci/epg/ifconn/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/epg/ifconn/__pycache__/api.cpython-310.pyc b/lib/aci/epg/ifconn/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..09c9a8e4 Binary files /dev/null and b/lib/aci/epg/ifconn/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/epg/ifconn/__pycache__/info.cpython-310.pyc b/lib/aci/epg/ifconn/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..38d66a32 Binary files /dev/null and b/lib/aci/epg/ifconn/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/epg/ifconn/__pycache__/main.cpython-310.pyc b/lib/aci/epg/ifconn/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..75cc1b78 Binary files /dev/null and b/lib/aci/epg/ifconn/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/epg/ifconn/api.py b/lib/aci/epg/ifconn/api.py new file mode 100644 index 00000000..2494b40f --- /dev/null +++ b/lib/aci/epg/ifconn/api.py @@ -0,0 +1,48 @@ +class EpgIfConnApi(): + def __init__(self): + self.epg_ifconn_mo = None + + def get_epg_ifconn_mo(self): + if self.epg_ifconn_mo is not None: + return self.epg_ifconn_mo + + cache = self.get_object_cache( + 'fvIfConn' + ) + if cache is not None: + self.epg_ifconn_mo = cache + self.log.apic_mo( + 'fvIfConn', + self.epg_ifconn_mo + ) + return self.epg_ifconn_mo + + managed_objects = self.get_class( + 'fvIfConn' + ) + + if managed_objects is None: + self.log.error( + 'epg_ifconn_mo', + 'API failed' + ) + return None + + self.epg_ifconn_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvIfConn']['attributes'] + self.epg_ifconn_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvIfConn', + self.epg_ifconn_mo + ) + + self.set_object_cache( + 'fvIfConn', + self.epg_ifconn_mo + ) + + return self.epg_ifconn_mo diff --git a/lib/aci/epg/ifconn/dn.md b/lib/aci/epg/ifconn/dn.md new file mode 100644 index 00000000..1a7f9e6b --- /dev/null +++ b/lib/aci/epg/ifconn/dn.md @@ -0,0 +1,122 @@ +# https://pubhub.devnetcloud.com/media/model-doc-521/docs/doc/jsonmeta/fv/IfConn.json + +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "resPolCont/rtdOutCont/rtdOutDef-[{outDn}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/sec-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/sec-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/cld-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/cld-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/tnlp-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/instp-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/instp-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/vns-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/vns-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/inb-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/inb-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/oob-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/oob-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/fv-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/fv-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/rtd-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/rtd-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/br-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/br-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + +# "uni/epp/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", +# "uni/epp/node-{id}/conndef/conn-[{encap}]-[{addr}]", diff --git a/lib/aci/epg/ifconn/info.py b/lib/aci/epg/ifconn/info.py new file mode 100644 index 00000000..1a6fffe1 --- /dev/null +++ b/lib/aci/epg/ifconn/info.py @@ -0,0 +1,514 @@ +from lib import filter_helper + + +class EpgIfConnInfo(): + def __init__(self): + self.epg_ifconn = None + self.epg_ifconn_dns = [ + 'uni/epp/br', + 'uni/epp/cld', + 'uni/epp/fv', + 'uni/epp/inb', + 'uni/epp/instp', + 'uni/epp/node', + 'uni/epp/oob', + 'uni/epp/rtd', + 'uni/epp/sec', + 'uni/epp/tnlp', + 'uni/epp/vns', + 'resPolCont/rtdOutCont/rtdOutDef' + ] + + self.epg_ifconn_fv_types = [ + 'phynodeatt', + 'stnodeatt', + 'vnodeatt', + 'dyatt', + 'extstpathatt', + 'stpathatt', + 'attEntitypathatt' + ] + + self.epg_ifconn_unsupported_dn = [] + + def get_epg_ifconn_summary(self, ifconns): + info = {} + + for supported_dns in self.epg_ifconn_dns: + dns_name = supported_dns.rsplit('/', maxsplit=1)[-1] + info[dns_name] = {} + for supported_type in self.epg_ifconn_fv_types: + info[dns_name][supported_type] = 0 + + for ifconn in ifconns: + for supported_dns in self.epg_ifconn_dns: + dns_name = supported_dns.rsplit('/', maxsplit=1)[-1] + if ifconn['typeDn'] == supported_dns: + if ifconn['type'] in self.epg_ifconn_fv_types: + info[dns_name][ifconn['type']] = info[dns_name][ifconn['type']] + 1 + + return info + + def get_epg_ifconn_epg_pkey_info(self, pkey): + if len(pkey.split('/')) != 3 and len(pkey.split('/')) != 4: + return None + + if len(pkey.split('/')) == 3: + (key1, key2, key3) = pkey.split('/') + key4 = None + + if len(pkey.split('/')) == 4: + (key1, key2, key3, key4) = pkey.split('/') + + if key1 != 'uni': + return None + + if not key2.startswith('tn-'): + return None + + # uni/tn-infra/out-RL-L3Out/instP-ipnInstP + if key3.startswith('out-'): + if key4 is None: + info = {} + info['epgType'] = 'l3rtdout' + info['epgTenant'] = key2[3:] + info['epgL3out'] = key3[4:] + info['epgFullName'] = '%s/%s' % ( + info['epgTenant'], + info['epgL3out'] + ) + return info + + if not key4.startswith('instP-'): + self.log.error( + 'get_epg_ifconn_epg_pkey_info', + 'Expected epgPKey uni/out/instP: %s' % (pkey) + ) + return None + + info = {} + info['epgType'] = 'l3out' + info['epgTenant'] = key2[3:] + info['epgL3out'] = key3[4:] + info['epgName'] = key4[6:] + info['epgFullName'] = '%s/%s/%s' % ( + info['epgTenant'], + info['epgL3out'], + info['epgName'] + ) + + return info + + # uni/tn-k8s/l2out-Test/instP-L2Out-ext-epg + if key3.startswith('l2out-'): + if not key4.startswith('instP-'): + self.log.error( + 'get_epg_ifconn_epg_pkey_info', + 'Expected epgPKey uni/l2out/instP: %s' % (pkey) + ) + return None + + info = {} + info['epgType'] = 'l2out' + info['epgTenant'] = key2[3:] + info['epgL2out'] = key3[6:] + info['epgName'] = key4[6:] + info['epgFullName'] = '%s/%s/%s' % ( + info['epgTenant'], + info['epgL2out'], + info['epgName'] + ) + + return info + + # uni/tn-mgmt/mgmtp-default/inb-default + # uni/tn-mgmt/mgmtp-default/oob-default + if key3.startswith('mgmtp-'): + if not key4.startswith('inb-') and not key4.startswith('oob-'): + self.log.error( + 'get_epg_ifconn_epg_pkey_info', + 'Expected epgPKey uni/mgmtp/inb|oob: %s' % (pkey) + ) + return None + + info = {} + + if key4.startswith('inb-'): + info['epgType'] = 'inb' + + if key4.startswith('oob-'): + info['epgType'] = 'oob' + + info['epgTenant'] = key2[3:] + info['epgMgmt'] = key3[6:] + info['epgName'] = key4[4:] + info['epgFullName'] = '%s/%s/%s' % ( + info['epgTenant'], + info['epgMgmt'], + info['epgName'] + ) + + return info + + # uni/tn-common/ap-privIP_TEST/epg-privIP_TEST + if key3.startswith('ap-'): + if not key4.startswith('epg-'): + self.log.error( + 'get_epg_ifconn_epg_pkey_info', + 'Expected epgPKey uni/ap/epg: %s' % (pkey) + ) + return None + + info = {} + info['epgType'] = 'application' + info['epgTenant'] = key2[3:] + info['epgAp'] = key3[3:] + info['epgName'] = key4[4:] + info['epgFullName'] = '%s/%s/%s' % ( + info['epgTenant'], + info['epgAp'], + info['epgName'] + ) + + return info + + self.log.error( + 'get_epg_ifconn_epg_pkey_info', + 'Unsupported pkey: %s' % (pkey) + ) + return None + + def get_epg_ifconn_targetdn_info(self, target_dn): + info = {} + info['pathType'] = '' + info['podId'] = '' + info['pathNode'] = '' + info['pathNodeName'] = [] + info['pathNodeT'] = '' + info['pathName'] = '' + + if target_dn.split('/')[2].startswith('protpaths-'): + # "topology/pod-1/protpaths-2207-2208/pathep-[k8s_ocp_bm_1_PolGrp]" + info['pathType'] = 'Policy Group' + info['podId'] = target_dn.split('/')[1][4:] + info['pathNode'] = target_dn.split('/')[2][10:] + info['pathNodeT'] = 'node-%s' % (info['pathNode']) + for node_id in info['pathNode'].split('-'): + info['pathNodeName'].append( + 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + node_id + ) + ) + ) + info['pathName'] = target_dn.split('[')[1].split(']')[0] + + if target_dn.split('/')[2].startswith('paths-'): + # "topology/pod-1/paths-2207/pathep-[eth1/3/1]" + info['pathType'] = 'Intf' + info['podId'] = target_dn.split('/')[1][4:] + info['pathNode'] = target_dn.split('/')[2][6:] + info['pathNodeT'] = 'node-%s' % (info['pathNode']) + for node_id in info['pathNode'].split('-'): + info['pathNodeName'].append( + 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + node_id + ) + ) + ) + info['pathName'] = target_dn.split('[')[1].split(']')[0] + + if target_dn.split('/')[2].startswith('node-') and target_dn.split('/')[3] == 'sys': + info['pathType'] = 'LsNode' + info['podId'] = target_dn.split('/')[1][4:] + info['pathNode'] = target_dn.split('/')[2][6:] + info['pathNodeT'] = 'node-%s' % (info['pathNode']) + for node_id in info['pathNode'].split('-'): + info['pathNodeName'].append( + 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + node_id + ) + ) + ) + info['pathName'] = target_dn.split('/sys/lsnode-')[1] + + return info + + def get_epg_ifconn_type_info(self, info): + # Step 1: epgPKey + + info['epgPKey'] = info['dn'].split('%s-[' % (info['typeDn']))[1].split(']')[0] + epg_info = self.get_epg_ifconn_epg_pkey_info(info['epgPKey']) + if epg_info is None: + self.log.error( + 'get_epg_ifconn_type_info', + 'Unsupported epgPKey: %s' % (info['epgPKey']) + ) + return None + info.update(epg_info) + + # Step 2: node-{id} + + new_dn = info['dn'].replace('%s-[%s]/' % (info['typeDn'], info['epgPKey']), '') + if not new_dn.startswith('node-'): + self.log.error( + 'get_epg_ifconn_type_info', + 'Missing node-id: %s' % (info['dn']) + ) + return None + + info['nodeId'] = new_dn.split('/')[0].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'] + ) + if info['nodeName'] is None: + info['nodeName'] = 'Node id: %s' % (info['nodeId']) + + # Step 3: type + + new_dn = '/'.join(new_dn.split('/')[1:]) + info['pathName'] = '' + + if new_dn.startswith('phynodeatt'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/phynodeatt/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'phynodeatt' + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('stnodeatt'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/stnodeatt/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'stnodeatt' + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('dynodeatt'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/dynodeatt/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'dynodeatt' + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('vnodeatt'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/vnodeatt/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'vnodeatt' + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('conndef'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'conndef' + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('dyatt-'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/dyatt-[{targetDn}]/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'dyatt' + info['memberType'] = 'dynamic' + info['targetDn'] = new_dn.split(']/conndef/conn', maxsplit=1)[0].split('dyatt-[')[1] + info.update( + self.get_epg_ifconn_targetdn_info( + info['targetDn'] + ) + ) + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('extstpathatt-'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/extstpathatt-[{pathName}]-extchid-{extChId}/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'extstpathatt' + info['member'] = 'static' + info['pathName'] = new_dn.split(']-extchid-', maxsplit=1)[0].split('extstpathatt-[')[1] + info['extChId'] = new_dn.split('-extchid-')[1].split('/')[0] + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('stpathatt-'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/stpathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'stpathatt' + info['memberType'] = 'static' + info['pathName'] = new_dn.split(']/conndef/conn-[', maxsplit=1)[0].split('stpathatt-[')[1] + if info['pathName'].startswith('eth') and len(info['pathName'][3:].split('/')) > 1: + info['pathType'] = 'Intf' + else: + info['pathType'] = 'Policy Group' + + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + if new_dn.startswith('attEntitypathatt-'): + # "uni/epp/fv-[{epgPKey}]/node-{id}/attEntitypathatt-[{pathName}]/conndef/conn-[{encap}]-[{addr}]", + info['type'] = 'attEntitypathatt' + info['pathName'] = new_dn.split(']/conndef/conn-[', maxsplit=1)[0].split('attEntitypathatt-[')[1] + info['encap'] = new_dn.split('conndef/conn-[')[1].split(']')[0] + return info + + self.log.error( + 'get_epg_ifconn_type_info', + 'Unsupported dn type: %s' % (info['dn']) + ) + + return None + + def get_epg_ifconn_info(self, managed_object): + # "addr": "", + # "auto": "no", + # "autostate": "disabled", + # "bcastP": "", + # "childAction": "", + # "classPref": "encap", + # "descr": "", + # "dn": "uni/epp/fv-[uni/tn-k8s/ap-k8s_ANP/epg-vk8s_4]/node-2207/dyatt-[topology/pod-1/protpaths-2207-2208/pathep-[k8s_esx72_PolGrp]]/conndef/conn-[vlan-1368]-[]", + # "encap": "vlan-1368", + # "extEncap": "unknown", + # "gw": "", + # "ifInstT": "l3-port", + # "ipv6Dad": "enabled", + # "isMultiPodDirect": "no", + # "lcOwn": "local", + # "llAddr": "", + # "mac": "00:00:00:00:00:00", + # "mcastAddr": "", + # "modTs": "2022-12-16T16:55:06.272+02:00", + # "mode": "regular", + # "monPolDn": "uni/tn-common/monepg-default", + # "mtu": "inherit", + # "name": "", + # "nameAlias": "", + # "resImedcy": "immediate", + # "status": "", + # "validState": "not-validated" + keys = [ + 'addr', + 'auto', + 'autostate', + 'classPref', + 'dn', + 'encap', + 'extEncap', + 'gw', + 'ifInstT', + 'mac', + 'mode', + 'mtu', + 'resImedcy' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + is_supported_dn = False + for supported_dn in self.epg_ifconn_dns: + if info['dn'].startswith('%s-' % (supported_dn)): + info['type'] = supported_dn.rsplit('/', maxsplit=1)[-1] + info['typeDn'] = '%s' % (supported_dn) + is_supported_dn = True + break + + if not is_supported_dn: + self.log.error( + 'get_epg_ifconn_info', + 'Unsupported dn: %s' % (info['dn']) + ) + return None + + is_supported_dn = True + unsupported_dns = [ + '/LDevInst-[' + ] + for unsupported_dn in unsupported_dns: + if unsupported_dn in info['dn']: + # Avoid log debug of every unsupported dn + if unsupported_dn not in self.epg_ifconn_unsupported_dn: + self.epg_ifconn_unsupported_dn.append( + unsupported_dn + ) + self.log.debug( + 'get_epg_ifconn_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return None + + info = self.get_epg_ifconn_type_info( + info + ) + + return info + + def get_epgs_ifconn_info(self): + if self.epg_ifconn is not None: + return self.epg_ifconn + + epgs_ifconn_mo = self.get_epg_ifconn_mo() + if epgs_ifconn_mo is None: + return None + + self.epg_ifconn = [] + for epg_ifconn_mo in epgs_ifconn_mo: + epg_ifconn_info = self.get_epg_ifconn_info( + epg_ifconn_mo + ) + if epg_ifconn_info is not None: + self.epg_ifconn.append( + epg_ifconn_info + ) + + self.epg_ifconn = sorted( + self.epg_ifconn, + key=lambda i: ( + i['nodeName'], + i['pathName'] + ) + ) + + self.log.apic_mo( + 'fvIfConn.info', + self.epg_ifconn + ) + + return self.epg_ifconn + + def match_epg_ifconn(self, epg_ifconn_info, epg_ifconn_filter): + if epg_ifconn_filter is None or len(epg_ifconn_filter) == 0: + return True + + for aepg_rule in epg_ifconn_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_ap_name(value, epg_ifconn_info['epgFullName']): + return False + + if not key_found: + self.log.error( + 'match_epg_ifconn', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_epg_ifconn(self, epg_ifconn_filter=None): + all_epg_ifconn = self.get_epgs_ifconn_info() + if all_epg_ifconn is None: + return None + + epg_ifconn = [] + + for epg_ifconn_info in all_epg_ifconn: + if not self.match_epg_ifconn(epg_ifconn_info, epg_ifconn_filter): + continue + + epg_ifconn.append(epg_ifconn_info) + + return epg_ifconn diff --git a/lib/aci/epg/ifconn/main.py b/lib/aci/epg/ifconn/main.py new file mode 100644 index 00000000..9edc1347 --- /dev/null +++ b/lib/aci/epg/ifconn/main.py @@ -0,0 +1,8 @@ +from lib.aci.epg.ifconn.api import EpgIfConnApi +from lib.aci.epg.ifconn.info import EpgIfConnInfo + + +class EpgIfConn(EpgIfConnApi, EpgIfConnInfo): + def __init__(self): + EpgIfConnApi.__init__(self) + EpgIfConnInfo.__init__(self) diff --git a/lib/aci/epg/info.py b/lib/aci/epg/info.py new file mode 100644 index 00000000..5842eb5b --- /dev/null +++ b/lib/aci/epg/info.py @@ -0,0 +1,973 @@ +import copy +import json + +from lib import filter_helper +from lib import ip_helper + + +class EpgInfo(): + def __init__(self): + self.epg = None + + def get_epg_count(self, tenant_name=None): + epg_filter = None + if tenant_name is not None: + epg_filter = ['tenant:%s' % (tenant_name)] + + aepgs = self.get_epgs( + epg_filter=epg_filter + ) + return len(aepgs) + + def get_epg(self, epg_distinguished_name): + epg_filter = ['dn:%s' % (epg_distinguished_name)] + aepgs = self.get_epgs( + epg_filter=epg_filter + ) + + if len(aepgs) == 1: + return aepgs[0] + + return None + + def get_epg_contract_info(self, managed_object, info): + info['contractConsumed'] = [] + for item in managed_object['fvRsCons']: + if item['tCl'] == 'vzBrCP': + if item['state'] == 'formed': + contract = {} + contract['dn'] = item['tDn'] + contract['tenant'] = item['tDn'].split('/')[1][3:] + contract['name'] = item['tDn'].split('/')[2][4:] + contract['nameTenant'] = '%s/%s' % ( + contract['tenant'], + contract['name'] + ) + info['contractConsumed'].append(contract) + + if item['state'] != 'formed': + contract = {} + contract['__Output'] = {} + contract['__Output']['nameTenant'] = 'Red' + contract['dn'] = item['tDn'] + contract['tenant'] = None + contract['name'] = item['tnVzBrCPName'] + contract['nameTenant'] = item['tnVzBrCPName'] + info['contractConsumed'].append(contract) + + info['contractProvided'] = [] + for item in managed_object['fvRsProv']: + if item['tCl'] == 'vzBrCP': + if item['state'] == 'formed': + contract = {} + contract['dn'] = item['tDn'] + contract['tenant'] = item['tDn'].split('/')[1][3:] + contract['name'] = item['tDn'].split('/')[2][4:] + contract['nameTenant'] = '%s/%s' % ( + contract['tenant'], + contract['name'] + ) + info['contractProvided'].append(contract) + + if item['state'] != 'formed': + contract = {} + contract['__Output'] = {} + contract['__Output']['nameTenant'] = 'Red' + contract['dn'] = item['tDn'] + contract['tenant'] = None + contract['name'] = item['tnVzBrCPName'] + contract['nameTenant'] = item['tnVzBrCPName'] + info['contractProvided'].append(contract) + + info['contractTaboo'] = [] + for item in managed_object['fvRsProtBy']: + if item['tCl'] == 'vzTaboo': + if item['state'] == 'formed': + contract = {} + contract['dn'] = item['tDn'] + contract['tenant'] = item['tDn'].split('/')[1][3:] + contract['name'] = item['tDn'].split('/')[2][6:] + contract['nameTenant'] = '%s/%s' % ( + contract['tenant'], + contract['name'] + ) + info['contractTaboo'].append(contract) + + if item['state'] != 'formed': + contract = {} + contract['__Output'] = {} + contract['__Output']['nameTenant'] = 'Red' + contract['dn'] = item['tDn'] + contract['tenant'] = None + contract['name'] = item['tnVzTabooName'] + contract['nameTenant'] = item['tnVzTabooName'] + info['contractTaboo'].append(contract) + + info['contractCount'] = len(info['contractConsumed']) + len(info['contractProvided']) + len(info['contractTaboo']) + info['contractTick'] = '' + if info['contractCount'] > 0: + info['contractTick'] = '\u2713' + info['__Output']['contractTick'] = 'Green' + + return info + + def get_epg_bd_info(self, managed_object, info): + if len(managed_object['fvBD']) != 1: + self.log.error( + 'get_epg_bd_info', + 'Unexpected fvBD count: %s' % (managed_object) + ) + return None + + bd_mo = managed_object['fvBD'][0] + if bd_mo['state'] == 'formed': + info['bd_tenant_name'] = managed_object['fvBD'][0]['tDn'].split('/')[1][3:] + info['bd_name'] = managed_object['fvBD'][0]['tDn'].split('/')[2][3:] + info['bd_state'] = bd_mo['state'] + + if bd_mo['state'] != 'formed': + info['bd_tenant_name'] = bd_mo['tnFvBDName'] + info['bd_name'] = bd_mo['tnFvBDName'] + info['bd_state'] = bd_mo['state'] + info['__Output']['bd_tenant_name'] = 'Red' + + return info + + def get_epg_static_ports_info(self, managed_object, info): + # "annotation": "", + # "childAction": "", + # "descr": "", + # "encap": "vlan-3000", + # "extMngdBy": "", + # "forceResolve": "yes", + # "instrImedcy": "lazy", + # "lcC": "", + # "lcOwn": "local", + # "modTs": "2023-03-06T21:44:13.066+02:00", + # "mode": "regular", + # "monPolDn": "uni/tn-common/monepg-default", + # "primaryEncap": "unknown", + # "rType": "mo", + # "rn": "rspathAtt-[topology/pod-1/paths-2702/pathep-[eth1/19]]", + # "state": "unformed", + # "stateQual": "none", + # "status": "", + # "tCl": "fabricPathEp", + # "tDn": "topology/pod-1/paths-2702/pathep-[eth1/19]", + # "tType": "mo", + # "uid": "15374", + # "userdom": ":all:common:" + info['staticPort'] = [] + + for item in managed_object['fvRsPathAtt']: + keys = [ + 'encap', + 'forceResolve', + 'instrImedcy', + 'mode', + 'primaryEncap', + 'state', + 'rn', + 'tCl', + 'tDn' + ] + port_info = {} + port_info['__Output'] = {} + + for key in keys: + port_info[key] = None + if key in item: + port_info[key] = item[key] + + port_info['modeT'] = port_info['mode'] + if port_info['mode'] == 'regular': + port_info['modeT'] = 'Trunk' + + if port_info['tCl'] != 'fabricPathEp': + self.log.error( + 'get_epg_static_ports_info', + 'Unsupported tCl: %s' % (port_info['tCl']) + ) + + port_info['pathNode'] = '' + port_info['pathNodeName'] = [] + port_info['pathType'] = '' + port_info['pathEp'] = '' + if port_info['tCl'] == 'fabricPathEp': + if port_info['tDn'].split('/')[2].startswith('protpaths-'): + # "topology/pod-1/protpaths-2207-2208/pathep-[k8s_ocp_bm_1_PolGrp]" + port_info['pathType'] = 'PG' + port_info['podId'] = port_info['tDn'].split('/')[1][4:] + port_info['pathNode'] = port_info['tDn'].split('/')[2][10:] + port_info['pathNodeT'] = 'node-%s' % (port_info['pathNode']) + for node_id in port_info['pathNode'].split('-'): + port_info['pathNodeName'].append( + 'pod-%s/%s' % ( + port_info['podId'], + self.get_node_name( + node_id + ) + ) + ) + port_info['pathEp'] = port_info['tDn'].split('[')[1].split(']')[0] + + if port_info['tDn'].split('/')[2].startswith('paths-'): + # "topology/pod-1/paths-2207/pathep-[eth1/3/1]" + port_info['pathType'] = 'Intf' + port_info['podId'] = port_info['tDn'].split('/')[1][4:] + port_info['pathNode'] = port_info['tDn'].split('/')[2][6:] + port_info['pathNodeT'] = 'node-%s' % (port_info['pathNode']) + for node_id in port_info['pathNode'].split('-'): + port_info['pathNodeName'].append( + 'pod-%s/%s' % ( + port_info['podId'], + self.get_node_name( + node_id + ) + ) + ) + port_info['pathEp'] = port_info['tDn'].split('[')[1].split(']')[0] + + info['staticPort'].append( + port_info + ) + + info['staticPort'] = sorted( + info['staticPort'], + key=lambda i: ( + i['pathNode'], + i['pathEp'] + ) + ) + info['staticPortCount'] = len(info['staticPort']) + + return info + + def get_epg_domain_info(self, managed_object, info): + # "annotation": "orchestrator:terraform", + # "bindingType": "none", + # "childAction": "", + # "classPref": "encap", + # "configIssues": "", + # "customEpgName": "", + # "delimiter": "", + # "encap": "unknown", + # "encapMode": "auto", + # "epgCos": "Cos0", + # "epgCosPref": "disabled", + # "extMngdBy": "", + # "forceResolve": "yes", + # "instrImedcy": "lazy", + # "lagPolicyName": "", + # "lcOwn": "local", + # "modTs": "2023-04-05T21:31:58.171+02:00", + # "mode": "default", + # "monPolDn": "uni/tn-common/monepg-default", + # "netflowDir": "both", + # "netflowPref": "disabled", + # "numPorts": "0", + # "portAllocation": "none", + # "primaryEncap": "unknown", + # "primaryEncapInner": "unknown", + # "rType": "mo", + # "resImedcy": "lazy", + # "rn": "rsdomAtt-[uni/phys-k8s_phys_PhysDom]", + # "secondaryEncapInner": "unknown", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "switchingMode": "native", + # "tCl": "physDomP", + # "tDn": "uni/phys-k8s_phys_PhysDom", + # "tType": "mo", + # "triggerSt": "not_triggerable", + # "txId": "7493989779975624787", + # "uid": "15374", + # "untagged": "no", + # "userdom": ":all:common:", + # "vnetOnly": "no" + info['domain'] = [] + + for item in managed_object['fvRsDomAtt']: + domain_info = {} + domain_info['__Output'] = {} + + for key in item: + domain_info[key] = item[key] + + if domain_info['tCl'] not in ['physDomP', 'vmmDomP', 'infraDomP']: + self.log.error( + 'get_epg_domain_info', + 'Unsupported epg domain type: %s' % (domain_info['tCl']) + ) + self.log.error( + 'get_epg_domain_info', + json.dumps(domain_info, indent=4) + ) + return None + + domain_info['type'] = domain_info['tCl'] + if domain_info['type'] == 'physDomP': + # "tDn": "uni/phys-k8s_phys_PhysDom" + domain_info['typeT'] = 'Physical' + domain_info['name'] = domain_info['tDn'].split('/')[1][5:] + + if domain_info['type'] == 'infraDomP': + # "tDn": "uni/phys-all-physical-devices" + domain_info['typeT'] = 'Infra' + domain_info['name'] = domain_info['tDn'].split('/')[1][5:] + + if domain_info['type'] == 'vmmDomP': + # "tDn": "uni/vmmp-VMware/dom-EU-SPDC-POD2B" + domain_info['typeT'] = 'VMM' + domain_info['vmmType'] = domain_info['tDn'].split('/')[1][5:] + domain_info['vmmName'] = domain_info['tDn'].split('/')[2][4:] + domain_info['name'] = '%s/%s' % ( + domain_info['vmmType'], + domain_info['vmmName'] + ) + + info['domain'].append( + domain_info + ) + + info['domain'] = sorted( + info['domain'], + key=lambda i: i['name'] + ) + + info['domainCount'] = len(info['domain']) + + return info + + def get_epg_name_from_dn(self, epg_dn): + # [0]: uni/tn-{name}/ap-{name}/epg-{name} + if len(epg_dn) == 0: + return '' + + tenant = epg_dn.split('/')[1][3:] + application_profile = epg_dn.split('/')[2][3:] + name = epg_dn.split('/')[3][4:] + epg_name = '%s/%s/%s' % ( + tenant, + application_profile, + name + ) + return epg_name + + def get_epg_info(self, managed_object): + keys = [ + 'annotation', + 'configSt', + 'descr', + 'dn', + 'exceptionTag', + 'floodOnEncap', + 'hasMcastSource', + 'isAttrBasedEPg', + 'matchT', + 'name', + 'nameAlias', + 'pcEnfPref', + 'pcTag', + 'prefGrMemb', + 'prio', + 'shutdown' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # state + if info['shutdown'] == 'no': + info['adminUp'] = True + info['adminUpTick'] = '\u2713' + info['__Output']['adminUpTick'] = 'Green' + else: + info['adminUp'] = False + info['adminUpTick'] = '\u2717' + info['__Output']['adminUpTick'] = 'Red' + + if info['configSt'] == 'applied': + info['__Output']['configSt'] = 'Green' + else: + info['__Output']['configSt'] = 'Red' + + # pcTag Number Ranges + # System Reserved pcTag – This pcTag is used for system internal rules (1-15). + # Globally scoped pcTag – This pcTag is used for shared service (16-16385). + # Locally scoped pcTag – This pcTag is locally used per VRF (range from 16386-65535). + info['pcTagT'] = info['pcTag'] + if 15 < int(info['pcTag']) < 16386: + info['pcTagT'] = '%s (global)' % (info['pcTag']) + info['__Output']['pcTagT'] = 'Red' + + if int(info['pcTag']) < 16: + info['pcTagT'] = '%s (system)' % (info['pcTag']) + info['__Output']['pcTagT'] = 'Red' + + # Dn format + # [0]: uni/tn-{name}/ap-{name}/epg-{name} + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + info['application_profile'] = info['dn'].split('/')[2][3:] + info['nameApTenant'] = '%s/%s/%s' % ( + info['tenant'], + info['application_profile'], + info['name'] + ) + + info = self.get_epg_contract_info( + managed_object, + info + ) + if info is None: + return None + + info = self.get_epg_bd_info( + managed_object, + info + ) + if info is None: + return None + + info = self.get_epg_static_ports_info( + managed_object, + info + ) + if info is None: + return None + + info = self.get_epg_domain_info( + managed_object, + info + ) + if info is None: + return None + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_epgs_info(self): + if self.epg is not None: + return self.epg + + epgs_mo = self.get_epg_mo() + if epgs_mo is None: + return None + + self.epg = [] + for epg_mo in epgs_mo: + epg_info = self.get_epg_info( + epg_mo + ) + if epg_info is None: + continue + + self.epg.append( + epg_info + ) + + self.log.apic_mo( + 'fvAEPg.info', + self.epg + ) + + return self.epg + + def match_epg_member(self, epg_member_info, epg_filter): + if epg_filter is None or len(epg_filter) == 0: + return True + + for aepg_rule in epg_filter: + (key, value) = aepg_rule.split(':') + + if key == 'pg': + if epg_member_info['pathType'] != 'Policy Group': + return False + + if not filter_helper.match_string(value, epg_member_info['pathName']): + return False + + return True + + def match_epg(self, epg_info, epg_filter): + if epg_filter is None or len(epg_filter) == 0: + return True + + for aepg_rule in epg_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, epg_info['tenant']): + return False + + if key == 'profile': + key_found = True + if not filter_helper.match_string(value, epg_info['application_profile']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_ap_name(value, epg_info['nameApTenant']): + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, epg_info['dn']): + return False + + if key == 'node': + key_found = True + if 'fabricNode' in epg_info: + found = False + + for node_info in epg_info['fabricNode']: + if filter_helper.match_string(value, node_info['name']): + found = True + break + + if not found: + return False + + if key == 'contract': + key_found = True + found = False + + for contract in epg_info['contractConsumed']: + if filter_helper.match_tenant_name(value, contract['nameTenant']): + found = True + break + + for contract in epg_info['contractProvided']: + if filter_helper.match_tenant_name(value, contract['nameTenant']): + found = True + break + + for contract in epg_info['contractTaboo']: + if filter_helper.match_tenant_name(value, contract['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'bd': + key_found = True + if 'fvBD' in epg_info: + if epg_info['fvBD'] is None: + return False + + if not filter_helper.match_tenant_name(value, epg_info['fvBD']['nameTenant']): + return False + + if key == 'subnet': + key_found = True + if 'fvBD' in epg_info: + if epg_info['fvBD'] is None: + return False + + found = False + for bd_subnet in epg_info['fvBD']['fvSubnet']: + if ip_helper.is_subnet_in_subnet(value, bd_subnet['network']): + found = True + break + + if not found: + return False + + if key == 'ip': + key_found = True + if 'fvBD' in epg_info: + if epg_info['fvBD'] is None: + return False + + found = False + for bd_subnet in epg_info['fvBD']['fvSubnet']: + if ip_helper.is_ipv4_in_cidr(value, bd_subnet['network']): + found = True + break + + if not found: + return False + + if key == 'pctag': + key_found = True + if value == 'global': + if int(epg_info['pcTag']) >= 16386: + return False + + if value == 'system': + if int(epg_info['pcTag']) >= 16: + return False + + if value not in ['global', 'system']: + if not filter_helper.match_integer(value, epg_info['pcTag']): + return False + + if key == 'domain': + key_found = True + if 'domain' in epg_info: + found = False + + for domain_info in epg_info['domain']: + if filter_helper.match_string(value, domain_info['name']): + found = True + break + + if not found: + return False + + if key == 'pg': + key_found = True + if 'member' in epg_info: + found = False + + for member_info in epg_info['member']: + if member_info['pathType'] == 'Policy Group': + if filter_helper.match_string(value, member_info['pathName']): + found = True + break + + if not found: + return False + + if key == 'member_type': + key_found = True + if 'member' in epg_info: + found = False + + for member_info in epg_info['member']: + if member_info['memberType'] == 'dynamic' and value == 'dyn': + found = True + break + + if member_info['memberType'] == 'static' and value == 'st': + found = True + break + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not epg_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_epg', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_epg', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_epg_contract_filter(self, epg_contracts): + contracts = [] + for contract in epg_contracts: + contracts.append( + contract['nameTenant'] + ) + + contract_filter = '' + if len(contracts) > 0: + contract_filter = ['names:%s' % (','.join(contracts))] + + return contract_filter + + def get_epgs_contract_filter(self, epgs_info): + contracts = [] + for epg in epgs_info: + for contract in epg['contractConsumed']: + if contract['nameTenant'] not in contracts: + contracts.append( + contract['nameTenant'] + ) + + for contract in epg['contractProvided']: + if contract['nameTenant'] not in contracts: + contracts.append( + contract['nameTenant'] + ) + + contract_filter = '' + if len(contracts) > 0: + contract_filter = ['names:%s' % (','.join(contracts))] + + return contract_filter + + def get_epgs_taboo_filter(self, epgs_info): + contracts = [] + for epg in epgs_info: + for contract in epg['contractTaboo']: + if contract['nameTenant'] not in contracts: + contracts.append( + contract['nameTenant'] + ) + + contract_filter = '' + if len(contracts) > 0: + contract_filter = ['names:%s' % (','.join(contracts))] + + return contract_filter + + def get_epg_l3out_filter(self, epg_info): + l3outs = [] + for l3out in epg_info['fvBD']['fvRsBDToOut']: + l3outs.append( + l3out['nameTenant'] + ) + + l3out_filter = '' + if len(l3outs) > 0: + l3out_filter = ['names:%s' % (','.join(l3outs))] + + return l3out_filter + + def get_epgs( + self, + epg_filter=None, + bd_info=False, + locale_info=False, + ifconn_info=False, + endpoint_info=False, + endpoint_vm_info=False, + endpoint_fabric_info=False, + contract_info=False, + vrf_info=False, + l3out_info=False, + node_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_epgs = self.get_epgs_info() + if all_epgs is None: + return None + + epgs = [] + + for epg_info in all_epgs: + if not self.match_epg(epg_info, epg_filter): + continue + + if ifconn_info: + epg_info['ifconn'] = self.get_epg_ifconn( + epg_ifconn_filter=['name:%s' % (epg_info['nameApTenant'])] + ) + + epg_info['ifconnSummary'] = self.get_epg_ifconn_summary( + epg_info['ifconn'] + ) + + epg_info['member'] = [] + for ifconn in epg_info['ifconn']: + if ifconn['type'] in ['stpathatt', 'dyatt']: + if self.match_epg_member(ifconn, epg_filter): + epg_info['member'].append( + ifconn + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if locale_info: + epg_info['locale'] = self.get_epg_locale( + epg_locale_filter=['name:%s' % (epg_info['nameApTenant'])] + ) + + epg_info['fabricNode'] = self.get_epg_locale_node( + epg_info['locale'] + ) + + epg_info['nodeCount'] = 0 + if epg_info['fabricNode'] is not None: + epg_info['nodeCount'] = len( + epg_info['fabricNode'] + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if bd_info: + epg_info['fvBD'] = self.get_bridge_domain( + epg_info['bd_tenant_name'], + epg_info['bd_name'] + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if endpoint_info: + endpoint_filter = ['epg:%s' % (epg_info['name'])] + epg_info['fvCEp'] = self.get_endpoints( + endpoint_filter=endpoint_filter, + vm_info=endpoint_vm_info, + fabric_info=endpoint_fabric_info + ) + + epg_info['endpointCount'] = 0 + if epg_info['fvCEp'] is not None: + epg_info['endpointCount'] = len( + epg_info['fvCEp'] + ) + + if epg_info['fvBD'] is not None: + epg_info['fvBD']['fvSubnet'] = self.get_subnet_usage( + epg_info['fvBD']['fvSubnet'], + epg_info['fvCEp'] + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if contract_info: + epg_info['contractConsumedInfo'] = [] + contract_filter = self.get_epg_contract_filter( + epg_info['contractConsumed'] + ) + if len(contract_filter) > 0: + epg_info['contractConsumedInfo'] = copy.deepcopy( + self.get_standard_contracts( + contract_filter=contract_filter + ) + ) + + epg_info['contractProvidedInfo'] = [] + contract_filter = self.get_epg_contract_filter( + epg_info['contractProvided'] + ) + if len(contract_filter) > 0: + epg_info['contractProvidedInfo'] = copy.deepcopy( + self.get_standard_contracts( + contract_filter=contract_filter + ) + ) + + epg_info['contractTabooInfo'] = [] + contract_filter = self.get_epg_contract_filter( + epg_info['contractTaboo'] + ) + if len(contract_filter) > 0: + epg_info['contractTabooInfo'] = copy.deepcopy( + self.get_taboo_contracts( + taboo_filter=contract_filter + ) + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if vrf_info: + if epg_info['fvBD'] is not None: + vrf_dn = epg_info['fvBD']['fvRsCtx']['dn'] + epg_info['fvBD']['fvCtxInfo'] = copy.deepcopy( + self.get_vrf( + vrf_dn + ) + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if l3out_info: + if epg_info['fvBD'] is not None: + epg_info['fvBD']['l3extOutInfo'] = [] + l3out_filter = self.get_epg_l3out_filter( + epg_info + ) + if len(l3out_filter) > 0: + epg_info['fvBD']['l3extOutInfo'] = copy.deepcopy( + self.get_l3outs( + l3out_filter=l3out_filter + ) + ) + + if not self.match_epg(epg_info, epg_filter): + continue + + if node_info: + ap_node_info = self.get_bridge_domain_node( + epg_info['tenant'], + epg_info['application_profile'], + epg_info['name'] + ) + epg_info['node'] = None + epg_info['interface'] = None + if ap_node_info is not None: + epg_info['node'] = ap_node_info['node'] + epg_info['interface'] = ap_node_info['interface'] + + if fault_info: + epg_info['faultInst'] = self.get_epg_id_fault( + epg_info['tenant'], + epg_info['application_profile'], + epg_info['name'], + 'faultInst' + ) + + if hfault_info: + epg_info['faultRecord'] = self.get_epg_id_fault( + epg_info['tenant'], + epg_info['application_profile'], + epg_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + epg_info['eventLog'] = self.get_epg_id_event( + epg_info['tenant'], + epg_info['application_profile'], + epg_info['name'], + event_filter=event_filter + ) + + if audit_info: + epg_info['auditLog'] = self.get_epg_id_audit( + epg_info['tenant'], + epg_info['application_profile'], + epg_info['name'], + audit_filter=audit_filter + ) + + epgs.append(epg_info) + + epgs = sorted( + epgs, + key=lambda i: i['nameApTenant'].lower() + ) + + return epgs diff --git a/lib/aci/epg/locale/__init__.py b/lib/aci/epg/locale/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/locale/__pycache__/__init__.cpython-310.pyc b/lib/aci/epg/locale/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..32767593 Binary files /dev/null and b/lib/aci/epg/locale/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/epg/locale/__pycache__/api.cpython-310.pyc b/lib/aci/epg/locale/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4bfc2673 Binary files /dev/null and b/lib/aci/epg/locale/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/epg/locale/__pycache__/info.cpython-310.pyc b/lib/aci/epg/locale/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e4023419 Binary files /dev/null and b/lib/aci/epg/locale/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/epg/locale/__pycache__/main.cpython-310.pyc b/lib/aci/epg/locale/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8dba4f8c Binary files /dev/null and b/lib/aci/epg/locale/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/epg/locale/api.py b/lib/aci/epg/locale/api.py new file mode 100644 index 00000000..ba871826 --- /dev/null +++ b/lib/aci/epg/locale/api.py @@ -0,0 +1,48 @@ +class EpgLocaleApi(): + def __init__(self): + self.epg_locale_mo = None + + def get_epg_locale_mo(self): + if self.epg_locale_mo is not None: + return self.epg_locale_mo + + cache = self.get_object_cache( + 'fvLocale' + ) + if cache is not None: + self.epg_locale_mo = cache + self.log.apic_mo( + 'fvLocale', + self.epg_locale_mo + ) + return self.epg_locale_mo + + managed_objects = self.get_class( + 'fvLocale' + ) + + if managed_objects is None: + self.log.error( + 'epg_locale_mo', + 'API failed' + ) + return None + + self.epg_locale_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvLocale']['attributes'] + self.epg_locale_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvLocale', + self.epg_locale_mo + ) + + self.set_object_cache( + 'fvLocale', + self.epg_locale_mo + ) + + return self.epg_locale_mo diff --git a/lib/aci/epg/locale/info.py b/lib/aci/epg/locale/info.py new file mode 100644 index 00000000..4d8a7de5 --- /dev/null +++ b/lib/aci/epg/locale/info.py @@ -0,0 +1,275 @@ +from lib import filter_helper + + +class EpgLocaleInfo(): + def __init__(self): + self.epg_locale = None + self.epg_locale_unsupported_dn = [] + + def get_epg_locale_node(self, locales_info): + info = [] + node_ids = [] + + for locale_info in locales_info: + if locale_info['id'] in node_ids: + continue + + node_info = self.get_node( + node_id=locale_info['id'] + ) + if node_info is not None: + info.append( + node_info + ) + + return info + + def get_epg_locale_fv_info(self, info): + # "dn": "uni/epp/fv-[uni/tn-common/ap-privIP_TEST/epg-privIP_TEST]/node-2202" + info['type'] = 'epg' + + epg_dn = info['dn'].split('[')[1].split(']')[0] + info['epgTenant'] = epg_dn.split('/')[1][3:] + info['epgAp'] = epg_dn.split('/')[2][3:] + info['epgName'] = epg_dn.split('/')[3][4:] + info['epgNameApTenant'] = '%s/%s/%s' % ( + info['epgTenant'], + info['epgAp'], + info['epgName'] + ) + + return info + + def get_epg_locale_br_info(self, info): + # uni/epp/br-[uni/tn-k8s/l2out-Test/instP-L2Out-ext-epg]/node-2208 + info['type'] = 'l2out' + + epg_dn = info['dn'].split('[')[1].split(']')[0] + info['l2outTenant'] = epg_dn.split('/')[1][3:] + info['l2outName'] = epg_dn.split('/')[2][6:] + info['epgName'] = epg_dn.split('/')[3][6:] + + return info + + def get_epg_locale_rtd_info(self, info): + # uni/epp/rtd-[uni/tn-Ericsson_PACO/out-RAN/instP-RAN]/node-2208 + info['type'] = 'l3out' + + epg_dn = info['dn'].split('[')[1].split(']')[0] + info['l3outTenant'] = epg_dn.split('/')[1][3:] + info['l3outName'] = epg_dn.split('/')[2][4:] + info['epgName'] = epg_dn.split('/')[3][6:] + + return info + + def get_epg_locale_info(self, managed_object): + # "boostrapTriggered": "no", + # "childAction": "", + # "deployAllPorts": "no", + # "dn": "uni/epp/fv-[uni/tn-common/ap-privIP_TEST/epg-privIP_TEST]/node-2202", + # "fabricExtCtrlPeering": "no", + # "fabricExtIntersiteCtrlPeering": "no", + # "fabricExtIntersitePeering": "no", + # "firstUpdateDeployed": "yes", + # "id": "2202", + # "instrImedcy": "immediate", + # "ipv4LbAddr": "", + # "ipv6LbAddr": "", + # "lcOwn": "local", + # "modTs": "2023-06-12T11:29:17.382+02:00", + # "modeMisconfiguration": "no", + # "monPolDn": "uni/tn-common/monepg-default", + # "operSt": "allocated", + # "rtrId": "", + # "rtrIdLoopBack": "yes", + # "status": "", + # "summaryNeeded": "full" + keys = [ + 'deployAllPorts', + 'dn', + 'fabricExtCtrlPeering', + 'fabricExtIntersiteCtrlPeering', + 'fabricExtIntersitePeering', + 'firstUpdateDeployed', + 'id', + 'instrImedcy', + 'operSt' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['nodeName'] = self.get_node_name( + info['id'] + ) + + # state + if info['operSt'] == 'allocated': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + # Dn format + # "uni/epp/sec-[{epgPKey}]/node-{id}", + # "uni/epp/cld-[{epgPKey}]/node-{id}", + # "uni/epp/tnlp-[{epgPKey}]/node-{id}", + # "uni/epp/instp-[{epgPKey}]/node-{id}", + # "uni/epp/vns-[{epgPKey}]/node-{id}", + # "uni/epp/inb-[{epgPKey}]/node-{id}", + # "uni/epp/oob-[{epgPKey}]/node-{id}", + # "uni/epp/node-{id}", + # "uni/epp/fv-[{epgPKey}]/node-{id}", + # "uni/epp/rtd-[{epgPKey}]/node-{id}", + # "uni/epp/br-[{epgPKey}]/node-{id}", + # "uni/epp/node-{id}", + # "uni/epp/node-{id}" + + supported_dns = [ + 'uni/epp/fv-', + 'uni/epp/br-', + 'uni/epp/rtd-', + 'uni/epp/inb-', + 'uni/epp/oob-' + ] + is_supported_dn = False + for supported_dn in supported_dns: + if info['dn'].startswith(supported_dn): + is_supported_dn = True + + if not is_supported_dn: + self.log.error( + 'get_epg_locale_info', + 'Unsupported dn: %s' % (info['dn']) + ) + return None + + is_supported_dn = True + unsupported_dns = [ + '/LDevInst-[' + ] + for unsupported_dn in unsupported_dns: + if unsupported_dn in info['dn']: + # Avoid log debug of every unsupported dn + if unsupported_dn not in self.epg_locale_unsupported_dn: + self.epg_locale_unsupported_dn.append( + unsupported_dn + ) + self.log.debug( + 'get_epg_locale_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return None + + if info['dn'].startswith('uni/epp/fv-'): + info = self.get_epg_locale_fv_info( + info + ) + + if info['dn'].startswith('uni/epp/br-'): + info = self.get_epg_locale_br_info( + info + ) + + if info['dn'].startswith('uni/epp/rtd-'): + info = self.get_epg_locale_rtd_info( + info + ) + + if info['dn'].startswith('uni/epp/inb-'): + return None + + if info['dn'].startswith('uni/epp/oob-'): + return None + + return info + + def get_epgs_locale_info(self): + if self.epg_locale is not None: + return self.epg_locale + + epgs_locale_mo = self.get_epg_locale_mo() + if epgs_locale_mo is None: + return None + + self.epg_locale = [] + for epg_locale_mo in epgs_locale_mo: + epg_locale_info = self.get_epg_locale_info( + epg_locale_mo + ) + + if epg_locale_info is not None: + self.epg_locale.append( + epg_locale_info + ) + + self.log.apic_mo( + 'fvLocale.info', + self.epg_locale + ) + + return self.epg_locale + + def match_epg_locale(self, epg_locale_info, epg_locale_filter): + if epg_locale_info['type'] != 'epg': + return False + + if epg_locale_filter is None or len(epg_locale_filter) == 0: + return True + + for aepg_rule in epg_locale_filter: + (key, value) = aepg_rule.split(':') + key_found = False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, epg_locale_info['epgTenant']): + return False + + if key == 'profile': + key_found = True + if not filter_helper.match_string(value, epg_locale_info['epgAp']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_ap_name(value, epg_locale_info['epgNameApTenant']): + return False + + if key == 'node_name': + key_found = True + if not filter_helper.match_string(value, epg_locale_info['nodeName']): + return False + + if key == 'node_id': + key_found = True + if not filter_helper.match_string(value, epg_locale_info['id']): + return False + + if not key_found: + self.log.error( + 'match_epg_locale', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_epg_locale(self, epg_locale_filter=None): + all_epg_locale = self.get_epgs_locale_info() + if all_epg_locale is None: + return None + + epg_locale = [] + + for epg_locale_info in all_epg_locale: + if not self.match_epg_locale(epg_locale_info, epg_locale_filter): + continue + + epg_locale.append(epg_locale_info) + + return epg_locale diff --git a/lib/aci/epg/locale/main.py b/lib/aci/epg/locale/main.py new file mode 100644 index 00000000..36ca3801 --- /dev/null +++ b/lib/aci/epg/locale/main.py @@ -0,0 +1,8 @@ +from lib.aci.epg.locale.api import EpgLocaleApi +from lib.aci.epg.locale.info import EpgLocaleInfo + + +class EpgLocale(EpgLocaleApi, EpgLocaleInfo): + def __init__(self): + EpgLocaleApi.__init__(self) + EpgLocaleInfo.__init__(self) diff --git a/lib/aci/epg/main.py b/lib/aci/epg/main.py new file mode 100644 index 00000000..d719f308 --- /dev/null +++ b/lib/aci/epg/main.py @@ -0,0 +1,29 @@ +from lib.aci.epg.api import EpgApi +from lib.aci.epg.info import EpgInfo +from lib.aci.epg.ifconn.main import EpgIfConn +from lib.aci.epg.locale.main import EpgLocale +from lib.aci.epg.audit.main import EpgAudit +from lib.aci.epg.event.main import EpgEvent +from lib.aci.epg.fault.main import EpgFault +from lib.aci.epg.node.main import EpgNode + + +class Epg( + EpgApi, + EpgInfo, + EpgIfConn, + EpgLocale, + EpgAudit, + EpgEvent, + EpgFault, + EpgNode + ): + def __init__(self): + EpgApi.__init__(self) + EpgInfo.__init__(self) + EpgIfConn.__init__(self) + EpgLocale.__init__(self) + EpgAudit.__init__(self) + EpgEvent.__init__(self) + EpgFault.__init__(self) + EpgNode.__init__(self) diff --git a/lib/aci/epg/node/__init__.py b/lib/aci/epg/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/epg/node/api.py b/lib/aci/epg/node/api.py new file mode 100644 index 00000000..03b82813 --- /dev/null +++ b/lib/aci/epg/node/api.py @@ -0,0 +1,61 @@ +class EpgNodeApi(): + def __init__(self): + self.epg_node_mo = {} + + def get_epg_node_mo(self, tenant_name, ap_name, epg_name): + key = '%s.%s.%s' % (tenant_name, ap_name, epg_name) + if key in self.epg_node_mo: + return self.epg_node_mo[key] + + cache = self.get_object_cache( + 'fvAEPg.%s' % (key) + ) + if cache is not None: + self.epg_node_mo[key] = cache + self.log.apic_mo( + 'fvAEPg.%s' % (key), + self.epg_node_mo[key] + ) + return self.epg_node_mo[key] + + distinguished_name = 'uni/tn-%s/ap-%s/epg-%s' % (tenant_name, ap_name, epg_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=EPgToNwIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_epg_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_epg_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvAEPg']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'fvAEPg', + managed_object + ) + self.epg_node_mo[key] = attributes + + self.log.apic_mo( + 'fvAEPg.%s' % (key), + self.epg_node_mo[key] + ) + + self.set_object_cache( + 'fvAEPg.%s' % (key), + self.epg_node_mo[key] + ) + + return self.epg_node_mo[key] diff --git a/lib/aci/epg/node/info.py b/lib/aci/epg/node/info.py new file mode 100644 index 00000000..0b653080 --- /dev/null +++ b/lib/aci/epg/node/info.py @@ -0,0 +1,82 @@ +class EpgNodeInfo(): + def __init__(self): + self.epg_node = {} + + def get_epg_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_epg_node(self, tenant_name, ap_name, epg_name): + key = '%s.%s.%s' % (tenant_name, ap_name, epg_name) + if key in self.epg_node: + return self.epg_node[key] + + # one object or None value is expected + nodes_mo = self.get_epg_node_mo(tenant_name, ap_name, epg_name) + if nodes_mo is None: + return None + + self.epg_node[key] = self.get_epg_node_info( + nodes_mo + ) + + self.log.apic_mo( + 'fvAEPg.%s.info' % (key), + self.epg_node[key] + ) + + return self.epg_node[key] diff --git a/lib/aci/epg/node/main.py b/lib/aci/epg/node/main.py new file mode 100644 index 00000000..a68859f5 --- /dev/null +++ b/lib/aci/epg/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.epg.node.api import EpgNodeApi +from lib.aci.epg.node.info import EpgNodeInfo + + +class EpgNode(EpgNodeApi, EpgNodeInfo): + def __init__(self): + EpgNodeApi.__init__(self) + EpgNodeInfo.__init__(self) diff --git a/lib/aci/epg/output.py b/lib/aci/epg/output.py new file mode 100644 index 00000000..37c85fb8 --- /dev/null +++ b/lib/aci/epg/output.py @@ -0,0 +1,1077 @@ +class EpgOutput(): + def __init__(self): + pass + + def print_epg_properties(self, info): + order = [ + 'health', + 'faults', + 'configSt', + 'name', + 'application_profile', + 'tenant', + 'fvBD.nameTenant', + 'nameAlias', + 'descr', + 'annotation', + 'pcTagT', + 'exceptionTag', + 'prio', + 'pcEnfPref', + 'prefGrMemb', + 'floodOnEncap', + 'isMatch' + ] + + headers = [ + 'Health', + 'Faults', + 'Configuration State', + 'EPG Name', + 'Application Profile', + 'Tenant', + 'Bridge Domain', + 'Alias', + 'Description', + 'Annotations', + 'Class ID', + 'Contract Exception Tag', + 'QoS Class', + 'Intra EPG Isolation', + 'Preferred Group Member', + 'Flood in Encapsulation', + 'ESG Matched' + ] + + self.my_output.dictionary( + info, + title='Application EPG Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_epg_contracts(self, info): + if len(info['contractConsumed']) > 0: + self.my_output.default( + 'Contract Consumed', + underline=True + ) + for contract in info['contractConsumed']: + self.my_output.default( + '- %s' % (contract['nameTenant']) + ) + + if len(info['contractConsumedInfo']) > 0: + self.print_contracts( + info['contractConsumedInfo'], + show_contract_filters=True + ) + + if len(info['contractProvided']) > 0: + self.my_output.default( + 'Contract Provided', + underline=True, + before_newline=True + ) + for contract in info['contractProvided']: + self.my_output.default( + '- %s' % (contract['nameTenant']) + ) + + if len(info['contractProvidedInfo']) > 0: + self.print_contracts( + info['contractProvidedInfo'], + show_contract_filters=True + ) + + if len(info['contractTaboo']) > 0: + self.my_output.default( + 'Contract Taboo', + underline=True, + before_newline=True + ) + for contract in info['contractTaboo']: + self.my_output.default( + '- %s' % (contract['nameTenant']) + ) + + if len(info['contractTabooInfo']) > 0: + self.print_taboos( + info['contractTabooInfo'], + show_taboo_filters=True + ) + + def print_epg_bridge_domain(self, info): + self.print_bridge_domain_properties( + info['fvBD'] + ) + + self.print_bridge_domain_subnets( + info['fvBD']['fvSubnet'] + ) + + def print_epg_vrf(self, info): + self.print_vrf_properties( + info['fvBD']['fvCtxInfo'] + ) + + def print_epg_l3out(self, info): + if len(info['fvBD']['fvRsBDToOut']) > 0: + self.my_output.default( + 'Associated L3 Out', + underline=True, + before_newline=True + ) + + self.print_l3outs( + info['fvBD']['l3extOutInfo'] + ) + + def print_epg_fabric(self, info): + if len(info['fabricNode']) > 0: + self.my_output.default( + 'Deployed Nodes', + underline=True, + before_newline=True + ) + self.print_nodes( + info['fabricNode'] + ) + + def print_epg_endpoints(self, info): + if info['endpointCount'] > 0: + self.my_output.default( + 'EPG Endpoints', + underline=True, + before_newline=True + ) + self.print_endpoints( + info['fvCEp'], + bridge_domain_name=False, + title=True + ) + + def print_epg(self, info): + self.print_epg_properties( + info + ) + + self.print_epg_contracts( + info + ) + + self.print_epg_bridge_domain( + info + ) + + self.print_epg_vrf( + info + ) + + self.print_epg_l3out( + info + ) + + self.print_epg_fabric( + info + ) + + self.print_epg_endpoints( + info + ) + + def print_epgs_properties(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'health', + 'faults', + 'nameApTenant', + 'prefGrMemb', + 'floodOnEncap', + 'pcTagT', + 'prio', + 'pcEnfPref', + 'matchT' + ] + + headers = [ + 'Health', + 'Faults', + 'EPG', + 'Preferred Member', + 'Flood', + 'Class ID', + 'QoS Class', + 'Isolation', + 'Label Match' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + table=True + ) + + def print_epgs_bridge_domain(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Bridge Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['fvSubnet'] = None + item['fvRsBDToOut'] = None + if item['fvBD'] is not None: + item['fvSubnet'] = item['fvBD']['fvSubnet'] + item['fvRsBDToOut'] = item['fvBD']['fvRsBDToOut'] + + order = [ + 'adminUpTick', + 'nameApTenant', + 'fvBD.nameTenant', + 'fvSubnet.ip', + 'fvSubnet.usage', + 'fvBD.fvRsCtx.nameTenant', + 'fvRsBDToOut.nameTenant' + ] + + headers = [ + 'Up', + 'EPG', + 'Bridge Domain', + 'BD Subnets', + 'Usage', + 'VRF', + 'L3Out' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fvSubnet', 'fvRsBDToOut'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_contract(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Contracts [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'adminUpTick', + 'nameApTenant', + 'pcTagT', + 'contractConsumed.nameTenant', + 'contractProvided.nameTenant', + 'contractTaboo.nameTenant' + ] + + headers = [ + 'Up', + 'EPG', + 'Class ID', + 'Contract Consumed', + 'Contract Provided', + 'Contract Taboo' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['contractConsumed', 'contractProvided', 'contractTaboo'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_contract_pivot(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Contracts (pivot view) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + contract_names = [] + contracts = [] + taboo_names = [] + taboos = [] + for epg_info in info: + for contract_info in epg_info['contractConsumed']: + if contract_info['nameTenant'] not in contract_names: + contract_names.append( + contract_info['nameTenant'] + ) + contract_info['type'] = 'Contract' + contract_info['epg'] = [] + contracts.append( + contract_info + ) + + for contract_info in epg_info['contractProvided']: + if contract_info['nameTenant'] not in contract_names: + contract_names.append( + contract_info['nameTenant'] + ) + contract_info['type'] = 'Contract' + contract_info['epg'] = [] + contracts.append( + contract_info + ) + + for contract_info in epg_info['contractTaboo']: + if contract_info['nameTenant'] not in taboo_names: + taboo_names.append( + contract_info['nameTenant'] + ) + contract_info['type'] = 'Taboo' + contract_info['epg'] = [] + taboos.append( + contract_info + ) + + for contract_info in contracts: + for epg_info in info: + for epg_contract_info in epg_info['contractConsumed']: + if epg_contract_info['nameTenant'] == contract_info['nameTenant']: + contract_info['epg'].append( + '%s (Consumed)' % (epg_info['nameApTenant']) + ) + + for epg_contract_info in epg_info['contractProvided']: + if epg_contract_info['nameTenant'] == contract_info['nameTenant']: + contract_info['epg'].append( + '%s (Provided)' % (epg_info['nameApTenant']) + ) + + for taboo_info in taboos: + for epg_info in info: + for epg_contract_info in epg_info['contractTaboo']: + if epg_contract_info['nameTenant'] == taboo_info['nameTenant']: + taboo_info['epg'].append( + epg_info['nameApTenant'] + ) + + all_contracts = contracts + taboos + all_contracts = sorted( + all_contracts, + key=lambda i: i['nameTenant'] + ) + + order = [ + 'nameTenant', + 'type', + 'epg' + ] + + headers = [ + 'Contract', + 'Type', + 'EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + all_contracts, + order, + ['epg'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_node(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Deployed Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'fabricNode.name', + 'fabricNode.address', + 'fabricNode.adSt', + 'fabricNode.fabricSt', + 'fabricNode.model', + 'fabricNode.serial', + 'fabricNode.version' + + ] + + headers = [ + 'EPG', + 'Node Name', + 'IP Address', + 'Admin', + 'Fabric', + 'Model', + 'Serial', + 'Version' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fabricNode'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_node_pivot(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Deployed Nodes (pivot view) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + names = [] + nodes = [] + for epg_info in info: + for node_info in epg_info['fabricNode']: + if node_info['pod_node_name'] not in names: + names.append( + node_info['pod_node_name'] + ) + node_info['epg'] = [] + nodes.append( + node_info + ) + + for node_info in nodes: + for epg_info in info: + for epg_node_info in epg_info['fabricNode']: + if epg_node_info['pod_node_name'] == node_info['pod_node_name']: + node_info['epg'].append( + epg_info['nameApTenant'] + ) + + order = [ + 'name', + 'address', + 'adSt', + 'fabricSt', + 'model', + 'serial', + 'version', + 'epg', + + ] + + headers = [ + 'Node Name', + 'IP Address', + 'Admin', + 'Fabric', + 'Model', + 'Serial', + 'Version', + 'EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + nodes, + order, + ['epg'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_static_port(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Static Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + order = [ + 'nameApTenant', + 'staticPort.pathNodeT', + 'staticPort.pathType', + 'staticPort.pathEp', + 'staticPort.encap', + 'staticPort.modeT', + 'staticPort.instrImedcy', + 'staticPort.state' + ] + + headers = [ + 'EPG', + 'Path', + 'Type', + 'Ep', + 'Encapsulation', + 'Mode', + 'Deployment Immediacy', + 'State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['staticPort'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_domain(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'domain.name', + 'domain.typeT', + 'domain.instrImedcy', + 'domain.resImedcy', + 'domain.switchingMode', + 'domain.encapMode', + 'domain.epgCos' + ] + + headers = [ + 'EPG', + 'Domain Name', + 'Domain Type', + 'Deployment', + 'Resolution', + 'Switching Mode', + 'Encap Mode', + 'CoS' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlan', 'domain', 'domainVlanPool'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_domain_pivot(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Domain (pivot view) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + names = [] + domains = [] + for epg_info in info: + for domain_info in epg_info['domain']: + if domain_info['name'] not in names: + names.append( + domain_info['name'] + ) + domain_info['epg'] = [] + domains.append( + domain_info + ) + + for domain_info in domains: + for epg_info in info: + for epg_domain_info in epg_info['domain']: + if epg_domain_info['name'] == domain_info['name']: + domain_info['epg'].append( + epg_info['nameApTenant'] + ) + + order = [ + 'name', + 'typeT', + 'instrImedcy', + 'resImedcy', + 'switchingMode', + 'encapMode', + 'epgCos', + 'epg', + + ] + + headers = [ + 'Domain Name', + 'Domain Type', + 'Deployment', + 'Resolution', + 'Switching Mode', + 'Encap Mode', + 'CoS', + 'EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + domains, + order, + ['epg'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_member(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Member [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'member.memberType', + 'member.nodeName', + 'member.pathType', + 'member.pathName', + 'member.encap' + ] + + headers = [ + 'EPG', + 'Member Type', + 'Node', + 'Type', + 'ID', + 'VLAN' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['member'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_endpoint(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Endpoints [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'flags', + 'mac', + 'fvIp.addr', + 'epgNameApTenant', + 'encapT', + 'bdNameTenant', + 'vrfNameTenant' + ] + + headers = [ + 'SF', + 'MAC Address', + 'IP Address', + 'EPG', + 'Encap', + 'BD', + 'VRF' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fvIp'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + table=True + ) + + def print_epgs(self, info, title=False): + if title: + self.my_output.default( + 'EPG [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for epg in info: + epg['fvSubnet'] = epg['fvBD']['fvSubnet'] + + order = [ + 'health', + 'faults', + 'adminUpTick', + 'nameApTenant', + 'pcTag', + 'fvBD.nameTenant', + 'fvSubnet.ip', + 'endpointCount', + 'fabricNode.pod_node_name', + 'domain.name', + 'contractCount', + 'staticPortCount', + 'ifconnSummary.fv.stpathatt', + 'ifconnSummary.fv.dyatt' + ] + + headers = [ + 'Health', + 'Faults', + 'Up', + 'EPG', + 'Class ID', + 'BD', + 'BD Subnet', + 'Endpoint', + 'Node', + 'Domain', + 'Contract', + 'StPort', + 'StMember', + 'DynMember' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fvSubnet', 'vlan', 'fabricNode', 'domain'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_epgs_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'EPG - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'EPG - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'EPG', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_epgs_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'EPG - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'EPG', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_epgs_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'EPG - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'EPG - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'EPG', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_epgs_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'EPG - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'EPG - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameApTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'EPG', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/__init__.py b/lib/aci/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..faddc3a7 Binary files /dev/null and b/lib/aci/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/cdp_adj_ep.cpython-310.pyc b/lib/aci/intf/__pycache__/cdp_adj_ep.cpython-310.pyc new file mode 100644 index 00000000..da0dec08 Binary files /dev/null and b/lib/aci/intf/__pycache__/cdp_adj_ep.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/fault_counts.cpython-310.pyc b/lib/aci/intf/__pycache__/fault_counts.cpython-310.pyc new file mode 100644 index 00000000..bc3dbb8a Binary files /dev/null and b/lib/aci/intf/__pycache__/fault_counts.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/interface.cpython-310.pyc b/lib/aci/intf/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..92f28ad3 Binary files /dev/null and b/lib/aci/intf/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/ipv4.cpython-310.pyc b/lib/aci/intf/__pycache__/ipv4.cpython-310.pyc new file mode 100644 index 00000000..e8d64a2b Binary files /dev/null and b/lib/aci/intf/__pycache__/ipv4.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/ipv4_address.cpython-310.pyc b/lib/aci/intf/__pycache__/ipv4_address.cpython-310.pyc new file mode 100644 index 00000000..0d589f48 Binary files /dev/null and b/lib/aci/intf/__pycache__/ipv4_address.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/ipv4_if.cpython-310.pyc b/lib/aci/intf/__pycache__/ipv4_if.cpython-310.pyc new file mode 100644 index 00000000..cdf87a37 Binary files /dev/null and b/lib/aci/intf/__pycache__/ipv4_if.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/ipv6_address.cpython-310.pyc b/lib/aci/intf/__pycache__/ipv6_address.cpython-310.pyc new file mode 100644 index 00000000..91df20dd Binary files /dev/null and b/lib/aci/intf/__pycache__/ipv6_address.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/ipv6_if.cpython-310.pyc b/lib/aci/intf/__pycache__/ipv6_if.cpython-310.pyc new file mode 100644 index 00000000..578fca45 Binary files /dev/null and b/lib/aci/intf/__pycache__/ipv6_if.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/lacp_adj_ep.cpython-310.pyc b/lib/aci/intf/__pycache__/lacp_adj_ep.cpython-310.pyc new file mode 100644 index 00000000..51211313 Binary files /dev/null and b/lib/aci/intf/__pycache__/lacp_adj_ep.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/lacp_if_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/lacp_if_stats.cpython-310.pyc new file mode 100644 index 00000000..dd674f0c Binary files /dev/null and b/lib/aci/intf/__pycache__/lacp_if_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/lacp_instance.cpython-310.pyc b/lib/aci/intf/__pycache__/lacp_instance.cpython-310.pyc new file mode 100644 index 00000000..a753b7ce Binary files /dev/null and b/lib/aci/intf/__pycache__/lacp_instance.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/lldp_adj_ep.cpython-310.pyc b/lib/aci/intf/__pycache__/lldp_adj_ep.cpython-310.pyc new file mode 100644 index 00000000..0dfbbd08 Binary files /dev/null and b/lib/aci/intf/__pycache__/lldp_adj_ep.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/main.cpython-310.pyc b/lib/aci/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ba0e7980 Binary files /dev/null and b/lib/aci/intf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/management.cpython-310.pyc b/lib/aci/intf/__pycache__/management.cpython-310.pyc new file mode 100644 index 00000000..a83b8f0a Binary files /dev/null and b/lib/aci/intf/__pycache__/management.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/management_state.cpython-310.pyc b/lib/aci/intf/__pycache__/management_state.cpython-310.pyc new file mode 100644 index 00000000..d47df0fd Binary files /dev/null and b/lib/aci/intf/__pycache__/management_state.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/management_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/management_stats.cpython-310.pyc new file mode 100644 index 00000000..01650988 Binary files /dev/null and b/lib/aci/intf/__pycache__/management_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/output.cpython-310.pyc b/lib/aci/intf/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..05701ecb Binary files /dev/null and b/lib/aci/intf/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/pc.cpython-310.pyc b/lib/aci/intf/__pycache__/pc.cpython-310.pyc new file mode 100644 index 00000000..9d29c0ab Binary files /dev/null and b/lib/aci/intf/__pycache__/pc.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port.cpython-310.pyc b/lib/aci/intf/__pycache__/port.cpython-310.pyc new file mode 100644 index 00000000..7155c5b4 Binary files /dev/null and b/lib/aci/intf/__pycache__/port.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_channel.cpython-310.pyc b/lib/aci/intf/__pycache__/port_channel.cpython-310.pyc new file mode 100644 index 00000000..7fdbf453 Binary files /dev/null and b/lib/aci/intf/__pycache__/port_channel.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_channel_members.cpython-310.pyc b/lib/aci/intf/__pycache__/port_channel_members.cpython-310.pyc new file mode 100644 index 00000000..a6c21d81 Binary files /dev/null and b/lib/aci/intf/__pycache__/port_channel_members.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_channel_relations.cpython-310.pyc b/lib/aci/intf/__pycache__/port_channel_relations.cpython-310.pyc new file mode 100644 index 00000000..c633678a Binary files /dev/null and b/lib/aci/intf/__pycache__/port_channel_relations.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_epg_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/port_epg_stats.cpython-310.pyc new file mode 100644 index 00000000..a27c44ac Binary files /dev/null and b/lib/aci/intf/__pycache__/port_epg_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_fc_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/port_fc_stats.cpython-310.pyc new file mode 100644 index 00000000..03a252ef Binary files /dev/null and b/lib/aci/intf/__pycache__/port_fc_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_qos_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/port_qos_stats.cpython-310.pyc new file mode 100644 index 00000000..38e3e0ce Binary files /dev/null and b/lib/aci/intf/__pycache__/port_qos_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/port_stats.cpython-310.pyc new file mode 100644 index 00000000..f2549d53 Binary files /dev/null and b/lib/aci/intf/__pycache__/port_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/port_vlan_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/port_vlan_stats.cpython-310.pyc new file mode 100644 index 00000000..bf308dfb Binary files /dev/null and b/lib/aci/intf/__pycache__/port_vlan_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..6c506409 Binary files /dev/null and b/lib/aci/intf/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/virtual_port_channel.cpython-310.pyc b/lib/aci/intf/__pycache__/virtual_port_channel.cpython-310.pyc new file mode 100644 index 00000000..a5064017 Binary files /dev/null and b/lib/aci/intf/__pycache__/virtual_port_channel.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/virtual_port_channel_member.cpython-310.pyc b/lib/aci/intf/__pycache__/virtual_port_channel_member.cpython-310.pyc new file mode 100644 index 00000000..487e5a15 Binary files /dev/null and b/lib/aci/intf/__pycache__/virtual_port_channel_member.cpython-310.pyc differ diff --git a/lib/aci/intf/__pycache__/vlan_stats.cpython-310.pyc b/lib/aci/intf/__pycache__/vlan_stats.cpython-310.pyc new file mode 100644 index 00000000..216876cc Binary files /dev/null and b/lib/aci/intf/__pycache__/vlan_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/__init__.py b/lib/aci/intf/adjacency/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/adjacency/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/adjacency/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..794352d4 Binary files /dev/null and b/lib/aci/intf/adjacency/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/__pycache__/main.cpython-310.pyc b/lib/aci/intf/adjacency/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8d7e9c93 Binary files /dev/null and b/lib/aci/intf/adjacency/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/__pycache__/output.cpython-310.pyc b/lib/aci/intf/adjacency/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..859c3abd Binary files /dev/null and b/lib/aci/intf/adjacency/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/cdp/__init__.py b/lib/aci/intf/adjacency/cdp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/adjacency/cdp/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/adjacency/cdp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..dd3611e3 Binary files /dev/null and b/lib/aci/intf/adjacency/cdp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/cdp/__pycache__/api.cpython-310.pyc b/lib/aci/intf/adjacency/cdp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..81e30ac8 Binary files /dev/null and b/lib/aci/intf/adjacency/cdp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/cdp/__pycache__/info.cpython-310.pyc b/lib/aci/intf/adjacency/cdp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e0b71379 Binary files /dev/null and b/lib/aci/intf/adjacency/cdp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/cdp/__pycache__/main.cpython-310.pyc b/lib/aci/intf/adjacency/cdp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..13280f5b Binary files /dev/null and b/lib/aci/intf/adjacency/cdp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/cdp/api.py b/lib/aci/intf/adjacency/cdp/api.py new file mode 100644 index 00000000..44433d68 --- /dev/null +++ b/lib/aci/intf/adjacency/cdp/api.py @@ -0,0 +1,66 @@ +class InterfaceAdjacencyCdpApi(): + def __init__(self): + self.adjacency_cdp_mo = {} + + def get_adjacency_cdp_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.adjacency_cdp_mo: + return self.adjacency_cdp_mo[key] + + cache = self.get_object_cache( + 'cdpAdjEp', + object_selector=key + ) + if cache is not None: + self.adjacency_cdp_mo[key] = cache + self.log.apic_mo( + 'cdpAdjEp.%s' % (key), + self.adjacency_cdp_mo[key] + ) + return self.adjacency_cdp_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/cdp/inst' % ( + pod_id, + node_id + ) + + query = 'query-target=subtree&target-subtree-class=cdpAdjEp&rsp-subtree-include=fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_adjacency_cdp_mo', + 'API failed' + ) + return None + + self.adjacency_cdp_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['cdpAdjEp']['attributes'] + attributes['faultCounts'] = self.get_mo_child_attributes( + 'cdpAdjEp', + managed_object, + 'faultCounts' + ) + self.adjacency_cdp_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cdpAdjEp.%s' % (key), + self.adjacency_cdp_mo[key] + ) + + self.set_object_cache( + 'cdpAdjEp', + self.adjacency_cdp_mo[key], + object_selector=key + ) + + return self.adjacency_cdp_mo[key] diff --git a/lib/aci/intf/adjacency/cdp/info.py b/lib/aci/intf/adjacency/cdp/info.py new file mode 100644 index 00000000..28cac119 --- /dev/null +++ b/lib/aci/intf/adjacency/cdp/info.py @@ -0,0 +1,68 @@ +class InterfaceAdjacencyCdpInfo(): + def __init__(self): + self.adjacency_cdp = {} + + def get_cdp_adjacency_endpoint_info(self, managed_object): + keys = [ + 'cap', + 'devId', + 'dn', + 'duplex', + 'index', + 'name', + 'nativeVlan', + 'platId', + 'portId', + 'stQual', + 'status', + 'sysName', + 'sysObjIdL', + 'sysObjIdV', + 'ver' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/cdp/inst/if-[eth1/11]/adj-1" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = info['dn'].split('if-[')[1].split(']')[0] + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + return info + + def get_cdp_adjacency_endpoint(self, pod_id, node_id, interface_id, allow_multiple=True): + managed_objects = self.get_adjacency_cdp_mo( + pod_id, + node_id + ) + + if managed_objects is None: + return None + + info = [] + for managed_object in managed_objects: + endpoint_info = self.get_cdp_adjacency_endpoint_info( + managed_object + ) + + if endpoint_info['interface_id'] == interface_id: + info.append( + endpoint_info + ) + + if allow_multiple: + return info + + if len(info) == 0: + return None + + return info[0] diff --git a/lib/aci/intf/adjacency/cdp/main.py b/lib/aci/intf/adjacency/cdp/main.py new file mode 100644 index 00000000..67a5b957 --- /dev/null +++ b/lib/aci/intf/adjacency/cdp/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.adjacency.cdp.api import InterfaceAdjacencyCdpApi +from lib.aci.intf.adjacency.cdp.info import InterfaceAdjacencyCdpInfo + + +class InterfaceAdjacencyCdp(InterfaceAdjacencyCdpApi, InterfaceAdjacencyCdpInfo): + def __init__(self): + InterfaceAdjacencyCdpApi.__init__(self) + InterfaceAdjacencyCdpInfo.__init__(self) diff --git a/lib/aci/intf/adjacency/lacp/__init__.py b/lib/aci/intf/adjacency/lacp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/adjacency/lacp/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/adjacency/lacp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3bbd68dc Binary files /dev/null and b/lib/aci/intf/adjacency/lacp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lacp/__pycache__/api.cpython-310.pyc b/lib/aci/intf/adjacency/lacp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..a1366f8f Binary files /dev/null and b/lib/aci/intf/adjacency/lacp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lacp/__pycache__/info.cpython-310.pyc b/lib/aci/intf/adjacency/lacp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..12a549c2 Binary files /dev/null and b/lib/aci/intf/adjacency/lacp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lacp/__pycache__/main.cpython-310.pyc b/lib/aci/intf/adjacency/lacp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7e619aec Binary files /dev/null and b/lib/aci/intf/adjacency/lacp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lacp/api.py b/lib/aci/intf/adjacency/lacp/api.py new file mode 100644 index 00000000..f96dddec --- /dev/null +++ b/lib/aci/intf/adjacency/lacp/api.py @@ -0,0 +1,66 @@ +class InterfaceAdjacencyLacpApi(): + def __init__(self): + self.adjacency_lacp_mo = {} + + def get_adjacency_lacp_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.adjacency_lacp_mo: + return self.adjacency_lacp_mo[key] + + cache = self.get_object_cache( + 'lacpAdjEp', + object_selector=key + ) + if cache is not None: + self.adjacency_lacp_mo[key] = cache + self.log.apic_mo( + 'lacpAdjEp.%s' % (key), + self.adjacency_lacp_mo[key] + ) + return self.adjacency_lacp_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lacp/inst' % ( + pod_id, + node_id + ) + + query = 'query-target=subtree&target-subtree-class=lacpAdjEp&rsp-subtree-include=fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_adjacency_lacp_mo', + 'API failed' + ) + return None + + self.adjacency_lacp_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['lacpAdjEp']['attributes'] + attributes['faultCounts'] = self.get_mo_child_attributes( + 'lacpAdjEp', + managed_object, + 'faultCounts' + ) + self.adjacency_lacp_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lacpAdjEp.%s' % (key), + self.adjacency_lacp_mo[key] + ) + + self.set_object_cache( + 'lacpAdjEp', + self.adjacency_lacp_mo[key], + object_selector=key + ) + + return self.adjacency_lacp_mo[key] diff --git a/lib/aci/intf/adjacency/lacp/info.py b/lib/aci/intf/adjacency/lacp/info.py new file mode 100644 index 00000000..6700c986 --- /dev/null +++ b/lib/aci/intf/adjacency/lacp/info.py @@ -0,0 +1,80 @@ +class InterfaceAdjacencyLacpInfo(): + def __init__(self): + self.adjacency_lacp = {} + + def get_lacp_adjacency_endpoint_info(self, managed_object): + keys = [ + 'activityFlags', + 'dn', + 'key', + 'name', + 'port', + 'portPrio', + 'status', + 'sysId', + 'sysPrio' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/lacp/inst/if-[eth1/27]/adj" + info['apic'] = self.apic_name + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = info['dn'].split('if-[')[1].split(']')[0] + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + return info + + def get_lacp_adjacency_endpoints_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.adjacency_lacp: + return self.adjacency_lacp[key] + + managed_objects = self.get_adjacency_lacp_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.adjacency_lacp[key] = [] + for managed_object in managed_objects: + self.adjacency_lacp[key].append( + self.get_lacp_adjacency_endpoint_info( + managed_object + ) + ) + + return self.adjacency_lacp[key] + + def get_lacp_adjacency_endpoint(self, pod_id, node_id, interface_id, allow_multiple=True): + endpoints_info = self.get_lacp_adjacency_endpoints_info(pod_id, node_id) + if endpoints_info is None: + return None + + info = [] + for endpoint_info in endpoints_info: + if interface_id == endpoint_info['interface_id']: + info.append( + endpoint_info + ) + + if allow_multiple: + return info + + if len(info) == 0: + return None + + return info[0] diff --git a/lib/aci/intf/adjacency/lacp/main.py b/lib/aci/intf/adjacency/lacp/main.py new file mode 100644 index 00000000..5c49d10a --- /dev/null +++ b/lib/aci/intf/adjacency/lacp/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.adjacency.lacp.api import InterfaceAdjacencyLacpApi +from lib.aci.intf.adjacency.lacp.info import InterfaceAdjacencyLacpInfo + + +class InterfaceAdjacencyLacp(InterfaceAdjacencyLacpApi, InterfaceAdjacencyLacpInfo): + def __init__(self): + InterfaceAdjacencyLacpApi.__init__(self) + InterfaceAdjacencyLacpInfo.__init__(self) diff --git a/lib/aci/intf/adjacency/lldp/__init__.py b/lib/aci/intf/adjacency/lldp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/adjacency/lldp/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/adjacency/lldp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e8e1b29d Binary files /dev/null and b/lib/aci/intf/adjacency/lldp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lldp/__pycache__/api.cpython-310.pyc b/lib/aci/intf/adjacency/lldp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..dbc48a9a Binary files /dev/null and b/lib/aci/intf/adjacency/lldp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lldp/__pycache__/info.cpython-310.pyc b/lib/aci/intf/adjacency/lldp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..31500972 Binary files /dev/null and b/lib/aci/intf/adjacency/lldp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lldp/__pycache__/main.cpython-310.pyc b/lib/aci/intf/adjacency/lldp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..fb62e48f Binary files /dev/null and b/lib/aci/intf/adjacency/lldp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lldp/__pycache__/output.cpython-310.pyc b/lib/aci/intf/adjacency/lldp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..8dd9f6b8 Binary files /dev/null and b/lib/aci/intf/adjacency/lldp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/adjacency/lldp/api.py b/lib/aci/intf/adjacency/lldp/api.py new file mode 100644 index 00000000..29e2f4da --- /dev/null +++ b/lib/aci/intf/adjacency/lldp/api.py @@ -0,0 +1,72 @@ +class InterfaceAdjacencyLldpApi(): + def __init__(self): + self.adjacency_lldp_mo = {} + + def get_adjacency_lldp_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.adjacency_lldp_mo: + return self.adjacency_lldp_mo[key] + + cache = self.get_object_cache( + 'lldpAdjEp', + object_selector=key + ) + if cache is not None: + self.adjacency_lldp_mo[key] = cache + self.log.apic_mo( + 'lldpAdjEp.%s' % (key), + self.adjacency_lldp_mo[key] + ) + return self.adjacency_lldp_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lldp/inst' % ( + pod_id, + node_id + ) + + query = 'query-target=subtree&target-subtree-class=lldpAdjEp&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + + ) + + if managed_objects is None: + self.log.error( + 'get_adjacency_lldp_mo', + 'API failed' + ) + return None + + self.adjacency_lldp_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['lldpAdjEp']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'lldpAdjEp', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'lldpAdjEp', + managed_object, + 'faultCounts' + ) + self.adjacency_lldp_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lldpAdjEp.%s' % (key), + self.adjacency_lldp_mo[key] + ) + + self.set_object_cache( + 'lldpAdjEp', + self.adjacency_lldp_mo[key], + object_selector=key + ) + + return self.adjacency_lldp_mo[key] diff --git a/lib/aci/intf/adjacency/lldp/info.py b/lib/aci/intf/adjacency/lldp/info.py new file mode 100644 index 00000000..5851608c --- /dev/null +++ b/lib/aci/intf/adjacency/lldp/info.py @@ -0,0 +1,134 @@ +from lib import filter_helper +from lib import ip_helper + + +class InterfaceAdjacencyLldpInfo(): + def __init__(self): + self.adjacency_lldp = {} + + def get_lldp_adjacency_endpoint_info(self, managed_object): + keys = [ + 'capability', + 'chassisIdT', + 'chassisIdV', + 'dn', + 'enCap', + 'id', + 'mgmtId', + 'mgmtIp', + 'mgmtPortMac', + 'portDesc', + 'portIdT', + 'portIdV', + 'portVlan', + 'stQual', + 'status', + 'sysDesc', + 'sysName', + 'ttl' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['portVlan'] == 'unspecified': + info['portVlan'] = '' + + # topology/pod-1/node-201/sys/lldp/inst/if-[mgmt0]/adj-1 + info['apic'] = self.apic_name + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = info['dn'].split('if-[')[1].split(']')[0] + + info['pod_node_name'] = '%s/%s' % ( + info['pod_id'], + self.get_node_name( + info['node_id'].split('-')[1] + ) + ) + + info['portId'] = '' + if info['portIdT'] in ['local', 'if-name']: + info['portId'] = info['portIdV'] + + info['mac'] = '' + if info['portIdT'] == 'mac': + info['mac'] = info['portIdV'] + + if info['portIdT'] != 'mac' and ip_helper.is_mac_address(info['chassisIdV']): + info['mac'] = info['chassisIdV'] + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + return info + + def match_lldp_adjacency_endpoint(self, endpoint_info, adjacency_filter): + if adjacency_filter is None or len(adjacency_filter) == 0: + return True + + mac_filtering = False + mac_match = False + for rule in adjacency_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + if key == 'mac': + mac_filtering = True + if ip_helper.is_mac_match(value, endpoint_info['mac']): + mac_match = True + + if mac_filtering and not mac_match: + return False + + for ap_rule in adjacency_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'interface_id': + if not filter_helper.match_string(value, endpoint_info['interface_id']): + return False + + if key == 'device': + if not filter_helper.match_string(value, endpoint_info['sysName']): + return False + + return True + + def get_lldp_adjacency_endpoint(self, pod_id, node_id, adjacency_filter=None, allow_multiple=True): + managed_objects = self.get_adjacency_lldp_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + endpoints = [] + for managed_object in managed_objects: + endpoint_info = self.get_lldp_adjacency_endpoint_info( + managed_object + ) + + if not self.match_lldp_adjacency_endpoint(endpoint_info, adjacency_filter): + continue + + endpoints.append( + endpoint_info + ) + + if allow_multiple: + return endpoints + + if len(endpoints) == 0: + return None + + return endpoints[0] diff --git a/lib/aci/intf/adjacency/lldp/main.py b/lib/aci/intf/adjacency/lldp/main.py new file mode 100644 index 00000000..30b86a8e --- /dev/null +++ b/lib/aci/intf/adjacency/lldp/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.adjacency.lldp.api import InterfaceAdjacencyLldpApi +from lib.aci.intf.adjacency.lldp.info import InterfaceAdjacencyLldpInfo + + +class InterfaceAdjacencyLldp(InterfaceAdjacencyLldpApi, InterfaceAdjacencyLldpInfo): + def __init__(self): + InterfaceAdjacencyLldpApi.__init__(self) + InterfaceAdjacencyLldpInfo.__init__(self) diff --git a/lib/aci/intf/adjacency/lldp/output.py b/lib/aci/intf/adjacency/lldp/output.py new file mode 100644 index 00000000..303ddd1c --- /dev/null +++ b/lib/aci/intf/adjacency/lldp/output.py @@ -0,0 +1,117 @@ +from lib import filter_helper +from lib import ip_helper + + +class InterfaceAdjacencyLldpOutput(): + def __init__(self): + pass + + def print_lldp_adjacency_endpoints(self, info, title=False): + if title: + self.my_output.default( + 'LLDP Adjacency [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['portDescT'] = filter_helper.get_string_chunks( + item['portDesc'], + 30 + ) + + order = [ + 'pod_node_name', + 'health', + 'faults', + 'interface_id', + 'ttl', + 'sysName', + 'mac', + 'portId', + 'portVlan', + 'portDescT', + 'capability' + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'Intf', + 'Hold', + 'Neighbor', + 'MAC', + 'Port', + 'VLAN', + 'Description', + 'Cap' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['portDescT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_lldp_adjacency_interface_endpoints(self, adjacency, interface, title=False): + if title: + self.my_output.default( + 'LLDP Adjacency - Endpoints [#%s]' % (len(interface)), + underline=True, + before_newline=True + ) + + if len(interface) == 0: + if title: + self.my_output.default('None') + return + + for interface_info in interface: + for adjacency_info in adjacency: + if ip_helper.is_mac_equal(interface_info['mac'], adjacency_info['mac']): + for key in adjacency_info: + interface_info[key] = adjacency_info[key] + + order = [ + 'host', + 'mac', + 'pci', + 'interface', + 'model', + 'pod_node_name', + 'interface_id' + ] + + headers = [ + 'Server', + 'MAC', + 'PCI', + 'Interface', + 'Model', + 'LLDP Node', + 'LLDP Interface ID' + ] + + self.my_output.my_table( + interface, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/adjacency/main.py b/lib/aci/intf/adjacency/main.py new file mode 100644 index 00000000..96aa1efa --- /dev/null +++ b/lib/aci/intf/adjacency/main.py @@ -0,0 +1,10 @@ +from lib.aci.intf.adjacency.cdp.main import InterfaceAdjacencyCdp +from lib.aci.intf.adjacency.lacp.main import InterfaceAdjacencyLacp +from lib.aci.intf.adjacency.lldp.main import InterfaceAdjacencyLldp + + +class InterfaceAdjacency(InterfaceAdjacencyCdp, InterfaceAdjacencyLacp, InterfaceAdjacencyLldp): + def __init__(self): + InterfaceAdjacencyCdp.__init__(self) + InterfaceAdjacencyLacp.__init__(self) + InterfaceAdjacencyLldp.__init__(self) diff --git a/lib/aci/intf/adjacency/output.py b/lib/aci/intf/adjacency/output.py new file mode 100644 index 00000000..3c4390b2 --- /dev/null +++ b/lib/aci/intf/adjacency/output.py @@ -0,0 +1,6 @@ +from lib.aci.intf.adjacency.lldp.output import InterfaceAdjacencyLldpOutput + + +class InterfaceAdjecencyOutput(InterfaceAdjacencyLldpOutput): + def __init__(self): + InterfaceAdjacencyLldpOutput.__init__(self) diff --git a/lib/aci/intf/cloudsec/__init__.py b/lib/aci/intf/cloudsec/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/cloudsec/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/cloudsec/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..67b324f7 Binary files /dev/null and b/lib/aci/intf/cloudsec/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/cloudsec/__pycache__/api.cpython-310.pyc b/lib/aci/intf/cloudsec/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..aaa55620 Binary files /dev/null and b/lib/aci/intf/cloudsec/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/cloudsec/__pycache__/info.cpython-310.pyc b/lib/aci/intf/cloudsec/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..35cdce77 Binary files /dev/null and b/lib/aci/intf/cloudsec/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/cloudsec/__pycache__/main.cpython-310.pyc b/lib/aci/intf/cloudsec/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..846c9651 Binary files /dev/null and b/lib/aci/intf/cloudsec/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/cloudsec/__pycache__/output.cpython-310.pyc b/lib/aci/intf/cloudsec/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..335448c6 Binary files /dev/null and b/lib/aci/intf/cloudsec/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/cloudsec/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/cloudsec/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..b67f0449 Binary files /dev/null and b/lib/aci/intf/cloudsec/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/cloudsec/api.py b/lib/aci/intf/cloudsec/api.py new file mode 100644 index 00000000..2c3de144 --- /dev/null +++ b/lib/aci/intf/cloudsec/api.py @@ -0,0 +1,67 @@ +class InterfaceCloudSecApi(): + def __init__(self): + self.interface_cloudsec_mo = {} + + def get_interface_cloudsec_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_cloudsec_mo: + return self.interface_cloudsec_mo[key] + + cache = self.get_object_cache( + 'cloudsecIf', + object_selector=key + ) + if cache is not None: + self.interface_cloudsec_mo[key] = cache + self.log.apic_mo( + 'cloudsecIf.%s' % (key), + self.interface_cloudsec_mo[key] + ) + return self.interface_cloudsec_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s' % (pod_id, node_id) + query = 'query-target=children&target-subtree-class=cloudsecIf&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_cloudsec_mo', + 'API failed' + ) + return None + + self.interface_cloudsec_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['cloudsecIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'cloudsecIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'cloudsecIf', + managed_object, + 'faultCounts' + ) + self.interface_cloudsec_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cloudsecIf.%s' % (key), + self.interface_cloudsec_mo[key] + ) + + self.set_object_cache( + 'cloudsecIf', + self.interface_cloudsec_mo[key], + object_selector=key + ) + + return self.interface_cloudsec_mo[key] diff --git a/lib/aci/intf/cloudsec/audit/__init__.py b/lib/aci/intf/cloudsec/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/cloudsec/audit/api.py b/lib/aci/intf/cloudsec/audit/api.py new file mode 100644 index 00000000..98ee8130 --- /dev/null +++ b/lib/aci/intf/cloudsec/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceCloudSecAuditApi(): + def __init__(self): + self.interface_cloudsec_audit_mo = {} + + def get_interface_cloudsec_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_audit_mo: + return self.interface_cloudsec_audit_mo[key] + + cache = self.get_object_cache( + 'cloudsecIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_cloudsec_audit_mo[key] = cache + self.log.apic_mo( + 'cloudsecIf.audit.%s' % (key), + self.interface_cloudsec_audit_mo[key] + ) + return self.interface_cloudsec_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/cloudsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_cloudsec_audit_mo', + 'API failed' + ) + return None + + self.interface_cloudsec_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_cloudsec_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cloudsecIf.audit.%s' % (key), + self.interface_cloudsec_audit_mo[key] + ) + + self.set_object_cache( + 'cloudsecIf.audit', + self.interface_cloudsec_audit_mo[key], + object_selector=key + ) + + return self.interface_cloudsec_audit_mo[key] diff --git a/lib/aci/intf/cloudsec/audit/info.py b/lib/aci/intf/cloudsec/audit/info.py new file mode 100644 index 00000000..a3e28e96 --- /dev/null +++ b/lib/aci/intf/cloudsec/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceCloudSecAuditInfo(): + def __init__(self): + self.interface_cloudsec_audit = {} + + def get_interface_cloudsec_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/cloudsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/cloudsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_cloudsec_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_audit: + return self.interface_cloudsec_audit[key] + + managed_objects = self.get_interface_cloudsec_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_cloudsec_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_cloudsec_audit_info( + managed_object + ) + self.interface_cloudsec_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'cloudsecIf.auditRecord.info.%s' % (key), + self.interface_cloudsec_audit[key] + ) + + return self.interface_cloudsec_audit[key] + + def get_interface_cloudsec_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_cloudsec_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/cloudsec/audit/main.py b/lib/aci/intf/cloudsec/audit/main.py new file mode 100644 index 00000000..6fd945a4 --- /dev/null +++ b/lib/aci/intf/cloudsec/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.cloudsec.audit.api import InterfaceCloudSecAuditApi +from lib.aci.intf.cloudsec.audit.info import InterfaceCloudSecAuditInfo + + +class InterfaceCloudSecAudit(InterfaceCloudSecAuditApi, InterfaceCloudSecAuditInfo): + def __init__(self): + InterfaceCloudSecAuditApi.__init__(self) + InterfaceCloudSecAuditInfo.__init__(self) diff --git a/lib/aci/intf/cloudsec/event/__init__.py b/lib/aci/intf/cloudsec/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/cloudsec/event/api.py b/lib/aci/intf/cloudsec/event/api.py new file mode 100644 index 00000000..282d38f9 --- /dev/null +++ b/lib/aci/intf/cloudsec/event/api.py @@ -0,0 +1,54 @@ +class InterfaceCloudSecEventApi(): + def __init__(self): + self.interface_cloudsec_event_mo = {} + + def get_interface_cloudsec_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_event_mo: + return self.interface_cloudsec_event_mo[key] + + cache = self.get_object_cache( + 'cloudsecIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_cloudsec_event_mo[key] = cache + self.log.apic_mo( + 'cloudsecIf.eventLog.%s' % (key), + self.interface_cloudsec_event_mo[key] + ) + return self.interface_cloudsec_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/cloudsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_cloudsec_event_mo', + 'API failed' + ) + return None + + self.interface_cloudsec_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_cloudsec_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cloudsecIf.eventLog.%s' % (key), + self.interface_cloudsec_event_mo[key] + ) + + self.set_object_cache( + 'cloudsecIf.eventLog', + self.interface_cloudsec_event_mo[key], + object_selector=key + ) + + return self.interface_cloudsec_event_mo[key] diff --git a/lib/aci/intf/cloudsec/event/info.py b/lib/aci/intf/cloudsec/event/info.py new file mode 100644 index 00000000..cd15e071 --- /dev/null +++ b/lib/aci/intf/cloudsec/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceCloudSecEventInfo(): + def __init__(self): + self.interface_cloudsec_event = {} + + def get_interface_cloudsec_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/cloudsec-[lo0]" + info['interfaceId'] = None + if '/cloudsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/cloudsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_cloudsec_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_event: + return self.interface_cloudsec_event[key] + + managed_objects = self.get_interface_cloudsec_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_cloudsec_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_cloudsec_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_cloudsec_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'cloudsecIf.eventLog.info.%s' % (key), + self.interface_cloudsec_event[key] + ) + + return self.interface_cloudsec_event[key] + + def get_interface_cloudsec_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_cloudsec_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/cloudsec/event/main.py b/lib/aci/intf/cloudsec/event/main.py new file mode 100644 index 00000000..c0116993 --- /dev/null +++ b/lib/aci/intf/cloudsec/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.cloudsec.event.api import InterfaceCloudSecEventApi +from lib.aci.intf.cloudsec.event.info import InterfaceCloudSecEventInfo + + +class InterfaceCloudSecEvent(InterfaceCloudSecEventApi, InterfaceCloudSecEventInfo): + def __init__(self): + InterfaceCloudSecEventApi.__init__(self) + InterfaceCloudSecEventInfo.__init__(self) diff --git a/lib/aci/intf/cloudsec/fault/__init__.py b/lib/aci/intf/cloudsec/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/cloudsec/fault/api.py b/lib/aci/intf/cloudsec/fault/api.py new file mode 100644 index 00000000..cd6c725a --- /dev/null +++ b/lib/aci/intf/cloudsec/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceCloudSecFaultApi(): + def __init__(self): + self.interface_cloudsec_fault_mo = {} + self.interface_cloudsec_fault_record_mo = {} + + def get_interface_cloudsec_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_fault_mo: + return self.interface_cloudsec_fault_mo[key] + + cache = self.get_object_cache( + 'cloudsecIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_cloudsec_fault_mo[key] = cache + self.log.apic_mo( + 'cloudsecIf.fault.%s' % (key), + self.interface_cloudsec_fault_mo[key] + ) + return self.interface_cloudsec_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/cloudsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_cloudsec_fault_mo', + 'API failed' + ) + return None + + self.interface_cloudsec_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_cloudsec_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cloudsecIf.fault.%s' % (key), + self.interface_cloudsec_fault_mo[key] + ) + + self.set_object_cache( + 'cloudsecIf.fault', + self.interface_cloudsec_fault_mo[key], + object_selector=key + ) + + return self.interface_cloudsec_fault_mo[key] + + def get_interface_cloudsec_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_fault_record_mo: + return self.interface_cloudsec_fault_record_mo[key] + + cache = self.get_object_cache( + 'cloudsecIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_cloudsec_fault_record_mo[key] = cache + self.log.apic_mo( + 'cloudsecIf.faultRecord.%s' % (key), + self.interface_cloudsec_fault_record_mo[key] + ) + return self.interface_cloudsec_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/cloudsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_cloudsec_fault_record_mo', + 'API failed' + ) + return None + + self.interface_cloudsec_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_cloudsec_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cloudsecIf.faultRecord.%s' % (key), + self.interface_cloudsec_fault_record_mo[key] + ) + + self.set_object_cache( + 'cloudsecIf.faultRecord', + self.interface_cloudsec_fault_record_mo[key], + object_selector=key + ) + + return self.interface_cloudsec_fault_record_mo[key] diff --git a/lib/aci/intf/cloudsec/fault/info.py b/lib/aci/intf/cloudsec/fault/info.py new file mode 100644 index 00000000..1a65aa39 --- /dev/null +++ b/lib/aci/intf/cloudsec/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceCloudSecFaultInfo(): + def __init__(self): + self.interface_cloudsec_fault = {} + self.interface_cloudsec_fault_record = {} + + def get_interface_cloudsec_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/cloudsec-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/cloudsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/cloudsec-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/cloudsec-[lo0]" + if info['interfaceId'] is None: + if '/cloudsec-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/cloudsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_cloudsec_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_fault: + return self.interface_cloudsec_fault[key] + + managed_objects = self.get_interface_cloudsec_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_cloudsec_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_cloudsec_fault_info( + managed_object + ) + self.interface_cloudsec_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'cloudsecIf.fault.info.%s' % (key), + self.interface_cloudsec_fault[key] + ) + + return self.interface_cloudsec_fault[key] + + def get_interface_cloudsec_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec_fault_record: + return self.interface_cloudsec_fault_record[key] + + managed_objects = self.get_interface_cloudsec_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_cloudsec_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_cloudsec_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_cloudsec_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'cloudsecIf.faultRecord.info.%s' % (key), + self.interface_cloudsec_fault_record[key] + ) + + return self.interface_cloudsec_fault_record[key] + + def get_interface_cloudsec_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_cloudsec_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_cloudsec_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/cloudsec/fault/main.py b/lib/aci/intf/cloudsec/fault/main.py new file mode 100644 index 00000000..69452154 --- /dev/null +++ b/lib/aci/intf/cloudsec/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.cloudsec.fault.api import InterfaceCloudSecFaultApi +from lib.aci.intf.cloudsec.fault.info import InterfaceCloudSecFaultInfo + + +class InterfaceCloudSecFault(InterfaceCloudSecFaultApi, InterfaceCloudSecFaultInfo): + def __init__(self): + InterfaceCloudSecFaultApi.__init__(self) + InterfaceCloudSecFaultInfo.__init__(self) diff --git a/lib/aci/intf/cloudsec/info.py b/lib/aci/intf/cloudsec/info.py new file mode 100644 index 00000000..a806734d --- /dev/null +++ b/lib/aci/intf/cloudsec/info.py @@ -0,0 +1,202 @@ +from lib import filter_helper + + +class InterfaceCloudSecInfo(): + def __init__(self): + self.interface_cloudsec = {} + + def get_interface_cloudsec_summary(self, pod_id, node_id): + ports = self.get_interfaces_cloudsec( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_cloudsec_count(self, pod_id, node_id): + interfaces = self.get_interfaces_cloudsec(pod_id, node_id) + return len(interfaces) + + def get_interface_cloudsec_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + info['up'] = False + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_cloudsec_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_cloudsec: + return self.interface_cloudsec[key] + + interfaces_mo = self.get_interface_cloudsec_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_cloudsec[key] = [] + for interface_mo in interfaces_mo: + self.interface_cloudsec[key].append( + self.get_interface_cloudsec_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'cloudsecIf.info.%s' % (key), + self.interface_cloudsec[key] + ) + + return self.interface_cloudsec[key] + + def match_interface_cloudsec(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_cloudsec', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_cloudsec( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_cloudsec_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_cloudsec(interface_info, interface_filter): + continue + + if fault_info: + interface_info['faultInst'] = self.get_interface_cloudsec_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_cloudsec_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_cloudsec_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_cloudsec_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces + + def get_interface_cloudsec(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_cloudsec( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/cloudsec/main.py b/lib/aci/intf/cloudsec/main.py new file mode 100644 index 00000000..60a3ef08 --- /dev/null +++ b/lib/aci/intf/cloudsec/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.cloudsec.api import InterfaceCloudSecApi +from lib.aci.intf.cloudsec.info import InterfaceCloudSecInfo +from lib.aci.intf.cloudsec.audit.main import InterfaceCloudSecAudit +from lib.aci.intf.cloudsec.event.main import InterfaceCloudSecEvent +from lib.aci.intf.cloudsec.fault.main import InterfaceCloudSecFault + + +class InterfaceCloudSec( + InterfaceCloudSecApi, + InterfaceCloudSecInfo, + InterfaceCloudSecAudit, + InterfaceCloudSecEvent, + InterfaceCloudSecFault + ): + def __init__(self): + InterfaceCloudSecApi.__init__(self) + InterfaceCloudSecInfo.__init__(self) + InterfaceCloudSecAudit.__init__(self) + InterfaceCloudSecEvent.__init__(self) + InterfaceCloudSecFault.__init__(self) diff --git a/lib/aci/intf/cloudsec/output.py b/lib/aci/intf/cloudsec/output.py new file mode 100644 index 00000000..9b793b9b --- /dev/null +++ b/lib/aci/intf/cloudsec/output.py @@ -0,0 +1,263 @@ +class InterfaceCloudSecOutput(): + def __init__(self): + pass + + def print_interfaces_cloudsec_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface CloudSec State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_cloudsec_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface CloudSec - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface CloudSec - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_cloudsec_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface CloudSec - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_cloudsec_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface CloudSec - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface CloudSec - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_cloudsec_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface CloudSec - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface CloudSec - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/encapsulated_routed/__init__.py b/lib/aci/intf/encapsulated_routed/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/encapsulated_routed/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/encapsulated_routed/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c09e56c7 Binary files /dev/null and b/lib/aci/intf/encapsulated_routed/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/encapsulated_routed/__pycache__/api.cpython-310.pyc b/lib/aci/intf/encapsulated_routed/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..1a7538bd Binary files /dev/null and b/lib/aci/intf/encapsulated_routed/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/encapsulated_routed/__pycache__/info.cpython-310.pyc b/lib/aci/intf/encapsulated_routed/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..bed09561 Binary files /dev/null and b/lib/aci/intf/encapsulated_routed/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/encapsulated_routed/__pycache__/main.cpython-310.pyc b/lib/aci/intf/encapsulated_routed/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..26853afd Binary files /dev/null and b/lib/aci/intf/encapsulated_routed/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/encapsulated_routed/__pycache__/output.cpython-310.pyc b/lib/aci/intf/encapsulated_routed/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..2ebaf668 Binary files /dev/null and b/lib/aci/intf/encapsulated_routed/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/encapsulated_routed/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/encapsulated_routed/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..5de80750 Binary files /dev/null and b/lib/aci/intf/encapsulated_routed/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/encapsulated_routed/api.py b/lib/aci/intf/encapsulated_routed/api.py new file mode 100644 index 00000000..36ccb089 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/api.py @@ -0,0 +1,80 @@ +class InterfaceEncapsulatedRoutedApi(): + def __init__(self): + self.interface_encap_routed_mo = {} + + def get_interface_encap_routed_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_encap_routed_mo: + return self.interface_encap_routed_mo[key] + + cache = self.get_object_cache( + 'l3EncRtdIf', + object_selector=key + ) + if cache is not None: + self.interface_encap_routed_mo[key] = cache + self.log.apic_mo( + 'l3EncRtdIf.%s' % (key), + self.interface_encap_routed_mo[key] + ) + return self.interface_encap_routed_mo[key] + + # https:///api/node/class/topology/pod-1/node-201/l3EncRtdIf.json?rsp-subtree=children&rsp-subtree-class=ethpmEncRtdIf&subscription=yes&order-by=l3EncRtdIf.mplsEnable|asc&page=0&page-size=15&_dc=1683801093405 + + class_name = 'topology/pod-%s/node-%s/l3EncRtdIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-class=ethpmEncRtdIf&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_interface_encap_routed_mo', + 'API failed' + ) + return None + + self.log.apic_mo( + 'l3EncRtdIf.mo.%s' % (key), + managed_objects + ) + + self.interface_encap_routed_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3EncRtdIf']['attributes'] + attributes['ethpmEncRtdIf'] = self.get_mo_child_attributes( + 'l3EncRtdIf', + managed_object, + 'ethpmEncRtdIf' + ) + attributes['healthInst'] = self.get_mo_child_attributes( + 'l3EncRtdIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l3EncRtdIf', + managed_object, + 'faultCounts' + ) + self.interface_encap_routed_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3EncRtdIf.%s' % (key), + self.interface_encap_routed_mo[key] + ) + + self.set_object_cache( + 'l3EncRtdIf', + self.interface_encap_routed_mo[key], + object_selector=key + ) + + return self.interface_encap_routed_mo[key] diff --git a/lib/aci/intf/encapsulated_routed/audit/__init__.py b/lib/aci/intf/encapsulated_routed/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/encapsulated_routed/audit/api.py b/lib/aci/intf/encapsulated_routed/audit/api.py new file mode 100644 index 00000000..9a715a39 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceEncapsulatedRoutedAuditApi(): + def __init__(self): + self.interface_encap_routed_audit_mo = {} + + def get_interface_encap_routed_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_audit_mo: + return self.interface_encap_routed_audit_mo[key] + + cache = self.get_object_cache( + 'l3EncRtdIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_encap_routed_audit_mo[key] = cache + self.log.apic_mo( + 'l3EncRtdIf.audit.%s' % (key), + self.interface_encap_routed_audit_mo[key] + ) + return self.interface_encap_routed_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3EncRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_encap_routed_audit_mo', + 'API failed' + ) + return None + + self.interface_encap_routed_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_encap_routed_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3EncRtdIf.audit.%s' % (key), + self.interface_encap_routed_audit_mo[key] + ) + + self.set_object_cache( + 'l3EncRtdIf.audit', + self.interface_encap_routed_audit_mo[key], + object_selector=key + ) + + return self.interface_encap_routed_audit_mo[key] diff --git a/lib/aci/intf/encapsulated_routed/audit/info.py b/lib/aci/intf/encapsulated_routed/audit/info.py new file mode 100644 index 00000000..12cc1306 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceEncapsulatedRoutedAuditInfo(): + def __init__(self): + self.interface_encap_routed_audit = {} + + def get_interface_encap_routed_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/encrtd-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/encrtd-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_encap_routed_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_audit: + return self.interface_encap_routed_audit[key] + + managed_objects = self.get_interface_encap_routed_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_encap_routed_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_encap_routed_audit_info( + managed_object + ) + self.interface_encap_routed_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'l3EncRtdIf.auditRecord.info.%s' % (key), + self.interface_encap_routed_audit[key] + ) + + return self.interface_encap_routed_audit[key] + + def get_interface_encap_routed_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_encap_routed_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/encapsulated_routed/audit/main.py b/lib/aci/intf/encapsulated_routed/audit/main.py new file mode 100644 index 00000000..2064f430 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.encapsulated_routed.audit.api import InterfaceEncapsulatedRoutedAuditApi +from lib.aci.intf.encapsulated_routed.audit.info import InterfaceEncapsulatedRoutedAuditInfo + + +class InterfaceEncapsulatedRoutedAudit(InterfaceEncapsulatedRoutedAuditApi, InterfaceEncapsulatedRoutedAuditInfo): + def __init__(self): + InterfaceEncapsulatedRoutedAuditApi.__init__(self) + InterfaceEncapsulatedRoutedAuditInfo.__init__(self) diff --git a/lib/aci/intf/encapsulated_routed/event/__init__.py b/lib/aci/intf/encapsulated_routed/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/encapsulated_routed/event/api.py b/lib/aci/intf/encapsulated_routed/event/api.py new file mode 100644 index 00000000..1a5ffba0 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/event/api.py @@ -0,0 +1,54 @@ +class InterfaceEncapsulatedRoutedEventApi(): + def __init__(self): + self.interface_encap_routed_event_mo = {} + + def get_interface_encap_routed_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_event_mo: + return self.interface_encap_routed_event_mo[key] + + cache = self.get_object_cache( + 'l3EncRtdIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_encap_routed_event_mo[key] = cache + self.log.apic_mo( + 'l3EncRtdIf.eventLog.%s' % (key), + self.interface_encap_routed_event_mo[key] + ) + return self.interface_encap_routed_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3EncRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_encap_routed_event_mo', + 'API failed' + ) + return None + + self.interface_encap_routed_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_encap_routed_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3EncRtdIf.eventLog.%s' % (key), + self.interface_encap_routed_event_mo[key] + ) + + self.set_object_cache( + 'l3EncRtdIf.eventLog', + self.interface_encap_routed_event_mo[key], + object_selector=key + ) + + return self.interface_encap_routed_event_mo[key] diff --git a/lib/aci/intf/encapsulated_routed/event/info.py b/lib/aci/intf/encapsulated_routed/event/info.py new file mode 100644 index 00000000..b2b81d26 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceEncapsulatedRoutedEventInfo(): + def __init__(self): + self.interface_encap_routed_event = {} + + def get_interface_encap_routed_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/encrtd-[eth1/36.7]" + info['interfaceId'] = None + if '/encrtd-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/encrtd-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_encap_routed_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_event: + return self.interface_encap_routed_event[key] + + managed_objects = self.get_interface_encap_routed_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_encap_routed_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_encap_routed_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_encap_routed_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l3EncRtdIf.eventLog.info.%s' % (key), + self.interface_encap_routed_event[key] + ) + + return self.interface_encap_routed_event[key] + + def get_interface_encap_routed_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_encap_routed_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/encapsulated_routed/event/main.py b/lib/aci/intf/encapsulated_routed/event/main.py new file mode 100644 index 00000000..827d3e6e --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.encapsulated_routed.event.api import InterfaceEncapsulatedRoutedEventApi +from lib.aci.intf.encapsulated_routed.event.info import InterfaceEncapsulatedRoutedEventInfo + + +class InterfaceEncapsulatedRoutedEvent(InterfaceEncapsulatedRoutedEventApi, InterfaceEncapsulatedRoutedEventInfo): + def __init__(self): + InterfaceEncapsulatedRoutedEventApi.__init__(self) + InterfaceEncapsulatedRoutedEventInfo.__init__(self) diff --git a/lib/aci/intf/encapsulated_routed/fault/__init__.py b/lib/aci/intf/encapsulated_routed/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/encapsulated_routed/fault/api.py b/lib/aci/intf/encapsulated_routed/fault/api.py new file mode 100644 index 00000000..bcbd65f5 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceEncapsulatedRoutedFaultApi(): + def __init__(self): + self.interface_encap_routed_fault_mo = {} + self.interface_encap_routed_fault_record_mo = {} + + def get_interface_encap_routed_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_fault_mo: + return self.interface_encap_routed_fault_mo[key] + + cache = self.get_object_cache( + 'l3EncRtdIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_encap_routed_fault_mo[key] = cache + self.log.apic_mo( + 'l3EncRtdIf.fault.%s' % (key), + self.interface_encap_routed_fault_mo[key] + ) + return self.interface_encap_routed_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3EncRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_encap_routed_fault_mo', + 'API failed' + ) + return None + + self.interface_encap_routed_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_encap_routed_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3EncRtdIf.fault.%s' % (key), + self.interface_encap_routed_fault_mo[key] + ) + + self.set_object_cache( + 'l3EncRtdIf.fault', + self.interface_encap_routed_fault_mo[key], + object_selector=key + ) + + return self.interface_encap_routed_fault_mo[key] + + def get_interface_encap_routed_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_fault_record_mo: + return self.interface_encap_routed_fault_record_mo[key] + + cache = self.get_object_cache( + 'l3EncRtdIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_encap_routed_fault_record_mo[key] = cache + self.log.apic_mo( + 'l3EncRtdIf.faultRecord.%s' % (key), + self.interface_encap_routed_fault_record_mo[key] + ) + return self.interface_encap_routed_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3EncRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_encap_routed_fault_record_mo', + 'API failed' + ) + return None + + self.interface_encap_routed_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_encap_routed_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3EncRtdIf.faultRecord.%s' % (key), + self.interface_encap_routed_fault_record_mo[key] + ) + + self.set_object_cache( + 'l3EncRtdIf.faultRecord', + self.interface_encap_routed_fault_record_mo[key], + object_selector=key + ) + + return self.interface_encap_routed_fault_record_mo[key] diff --git a/lib/aci/intf/encapsulated_routed/fault/info.py b/lib/aci/intf/encapsulated_routed/fault/info.py new file mode 100644 index 00000000..0f1c3bf3 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceEncapsulatedRoutedFaultInfo(): + def __init__(self): + self.interface_encap_routed_fault = {} + self.interface_encap_routed_fault_record = {} + + def get_interface_encap_routed_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/encrtd-[eth1/36.7]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/encrtd-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/encrtd-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/encrtd-[eth1/36.7]" + if info['interfaceId'] is None: + if '/encrtd-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/encrtd-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_encap_routed_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_fault: + return self.interface_encap_routed_fault[key] + + managed_objects = self.get_interface_encap_routed_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_encap_routed_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_encap_routed_fault_info( + managed_object + ) + self.interface_encap_routed_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'l3EncRtdIf.fault.info.%s' % (key), + self.interface_encap_routed_fault[key] + ) + + return self.interface_encap_routed_fault[key] + + def get_interface_encap_routed_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed_fault_record: + return self.interface_encap_routed_fault_record[key] + + managed_objects = self.get_interface_encap_routed_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_encap_routed_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_encap_routed_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_encap_routed_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l3EncRtdIf.faultRecord.info.%s' % (key), + self.interface_encap_routed_fault_record[key] + ) + + return self.interface_encap_routed_fault_record[key] + + def get_interface_encap_routed_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_encap_routed_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_encap_routed_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/encapsulated_routed/fault/main.py b/lib/aci/intf/encapsulated_routed/fault/main.py new file mode 100644 index 00000000..7033e5e2 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.encapsulated_routed.fault.api import InterfaceEncapsulatedRoutedFaultApi +from lib.aci.intf.encapsulated_routed.fault.info import InterfaceEncapsulatedRoutedFaultInfo + + +class InterfaceEncapsulatedRoutedFault(InterfaceEncapsulatedRoutedFaultApi, InterfaceEncapsulatedRoutedFaultInfo): + def __init__(self): + InterfaceEncapsulatedRoutedFaultApi.__init__(self) + InterfaceEncapsulatedRoutedFaultInfo.__init__(self) diff --git a/lib/aci/intf/encapsulated_routed/info.py b/lib/aci/intf/encapsulated_routed/info.py new file mode 100644 index 00000000..67cac5f4 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/info.py @@ -0,0 +1,291 @@ +from lib import filter_helper + + +class InterfaceEncapsulatedRoutedInfo(): + def __init__(self): + self.interface_encap_routed = {} + + def get_interface_encap_routed_summary(self, pod_id, node_id): + ports = self.get_interfaces_encap_routed( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_encap_routed_count(self, pod_id, node_id): + interfaces = self.get_interfaces_encap_routed(pod_id, node_id) + return len(interfaces) + + def get_interface_encap_routed_info(self, managed_object): + keys = [ + 'MultiPodDirect', + 'adminSt', + 'delay', + 'dn', + 'encap', + 'ethpmCfgFailedBmp', + 'ethpmCfgFailedTs', + 'ethpmCfgState', + 'id', + 'mplsEnable', + 'mplsMtu', + 'mtu', + 'mtuInherit', + 'pcTag', + 'qosPrio', + 'routerMac', + 'rtdOutDefDn', + 'serviceEnabled' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # topology/pod-1/node-201/sys/inst-overlay-1/encrtd-[eth1/108.7] + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['__Output']['id'] = 'Blue' + + if info['adminSt'] == 'up': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + info['state'] = None + if managed_object['ethpmEncRtdIf'] is not None: + info['state'] = {} + + keys = [ + 'currErrIndex', + 'fsmState', + 'hwBdId', + 'hwResourceId', + 'iod', + 'lastErrors', + 'operBitset', + 'operMtu', + 'operSt', + 'operStQual', + 'siCfgFlags' + ] + + for key in keys: + info['state'][key] = None + if key in managed_object['ethpmEncRtdIf']: + info['state'][key] = managed_object['ethpmEncRtdIf'][key] + + if info['state']['operSt'] == 'up': + info['__Output']['state.operSt'] = 'Green' + if info['state']['operStQual'] == 'none': + info['state']['operStQual'] = '' + else: + info['__Output']['state.operSt'] = 'Red' + + info['donorIf'] = '' + info['__Output']['donorIf'] = 'Yellow' + + info['up'] = False + if info['adminSt'] == 'up' and info['state']['operSt'] == 'up': + info['up'] = True + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_encap_routed_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_encap_routed: + return self.interface_encap_routed[key] + + interfaces_mo = self.get_interface_encap_routed_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_encap_routed[key] = [] + for interface_mo in interfaces_mo: + self.interface_encap_routed[key].append( + self.get_interface_encap_routed_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'l3EncRtdIf.info.%s' % (key), + self.interface_encap_routed[key] + ) + + return self.interface_encap_routed[key] + + def match_interface_encap_routed(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'admin': + if value != 'any': + if not filter_helper.match_string(value, interface_info['adminSt']): + return False + + if key == 'oper': + if value != 'any': + if not filter_helper.match_string(value, interface_info['state']['operSt']): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_encap_routed', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_encap_routed( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_encap_routed_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + ipv4_addresses_info = self.get_node_interface_ipv4( + pod_id, + node_id + ) + + for interface_info in all_interfaces: + if not self.match_interface_encap_routed(interface_info, interface_filter): + continue + + interface_search_pattern = '%s' % (interface_info['id']) + for item in ipv4_addresses_info: + if interface_search_pattern in item['id']: + if item['donorIf'] != 'unspecified': + interface_info['donorIf'] = item['donorIf'] + + if fault_info: + interface_info['faultInst'] = self.get_interface_encap_routed_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_encap_routed_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_encap_routed_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_encap_routed_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces + + def get_interface_encap_routed(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_encap_routed( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/encapsulated_routed/main.py b/lib/aci/intf/encapsulated_routed/main.py new file mode 100644 index 00000000..3d0de04e --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.encapsulated_routed.api import InterfaceEncapsulatedRoutedApi +from lib.aci.intf.encapsulated_routed.info import InterfaceEncapsulatedRoutedInfo +from lib.aci.intf.encapsulated_routed.audit.main import InterfaceEncapsulatedRoutedAudit +from lib.aci.intf.encapsulated_routed.event.main import InterfaceEncapsulatedRoutedEvent +from lib.aci.intf.encapsulated_routed.fault.main import InterfaceEncapsulatedRoutedFault + + +class InterfaceEncapsulatedRouted( + InterfaceEncapsulatedRoutedApi, + InterfaceEncapsulatedRoutedInfo, + InterfaceEncapsulatedRoutedAudit, + InterfaceEncapsulatedRoutedEvent, + InterfaceEncapsulatedRoutedFault + ): + def __init__(self): + InterfaceEncapsulatedRoutedApi.__init__(self) + InterfaceEncapsulatedRoutedInfo.__init__(self) + InterfaceEncapsulatedRoutedAudit.__init__(self) + InterfaceEncapsulatedRoutedEvent.__init__(self) + InterfaceEncapsulatedRoutedFault.__init__(self) diff --git a/lib/aci/intf/encapsulated_routed/output.py b/lib/aci/intf/encapsulated_routed/output.py new file mode 100644 index 00000000..f5434e44 --- /dev/null +++ b/lib/aci/intf/encapsulated_routed/output.py @@ -0,0 +1,281 @@ +class InterfaceEncapsulatedRoutedOutput(): + def __init__(self): + pass + + def print_interfaces_encap_routed_state(self, info, title=False): + if title: + self.my_output.default( + 'Encapsulated Routed Interface - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'adminSt', + 'state.operSt', + 'state.operStQual', + 'encap', + 'mplsEnable', + 'state.operMtu', + 'donorIf', + 'delay', + 'routerMac' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Oper', + 'Reason', + 'Encap', + 'SR-MPLS', + 'MTU', + 'IP Unnumbered Intf', + 'Delay', + 'Router MAC' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_encap_routed_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Encapsulated Routed - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Encapsulated Routed - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_encap_routed_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Encapsulated Routed - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_encap_routed_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Encapsulated Routed - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Encapsulated Routed - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_encap_routed_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Encapsulated Routed - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Encapsulated Routed - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/fault_counts/__init__.py b/lib/aci/intf/fault_counts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fault_counts/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/fault_counts/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..561083dd Binary files /dev/null and b/lib/aci/intf/fault_counts/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/fault_counts/__pycache__/api.cpython-310.pyc b/lib/aci/intf/fault_counts/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..068a0b93 Binary files /dev/null and b/lib/aci/intf/fault_counts/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/fault_counts/__pycache__/info.cpython-310.pyc b/lib/aci/intf/fault_counts/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..5ad4e5f0 Binary files /dev/null and b/lib/aci/intf/fault_counts/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/fault_counts/__pycache__/main.cpython-310.pyc b/lib/aci/intf/fault_counts/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ce9830ba Binary files /dev/null and b/lib/aci/intf/fault_counts/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/fault_counts/api.py b/lib/aci/intf/fault_counts/api.py new file mode 100644 index 00000000..c3ab68a4 --- /dev/null +++ b/lib/aci/intf/fault_counts/api.py @@ -0,0 +1,63 @@ +class InterfaceFaultCountsApi(): + def __init__(self): + self.interface_fault_counts_mo = {} + + def get_interface_fault_counts_mo(self, pod_id, node_id, interface_type, interface_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + interface_id + ) + if key in self.interface_fault_counts_mo: + return self.interface_fault_counts_mo[key] + + cache = self.get_object_cache( + 'fltCnts', + object_selector=key + ) + if cache is not None: + self.interface_fault_counts_mo[key] = cache + self.log.apic_mo( + 'fltCnts.%s' % (key), + self.interface_fault_counts_mo[key] + ) + return self.interface_fault_counts_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/%s-[%s]/fltCnts' % ( + pod_id, + node_id, + interface_type, + interface_id + ) + managed_objects = self.get_managed_object( + distinguished_name + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fault_counts_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_interface_fault_counts_mo', + 'Unexpected object count' + ) + return None + + self.interface_fault_counts_mo[key] = managed_objects['imdata'][0]['faultCounts']['attributes'] + + self.log.apic_mo( + 'fltCnts.%s' % (key), + self.interface_fault_counts_mo[key] + ) + + self.set_object_cache( + 'fltCnts', + self.interface_fault_counts_mo[key], + object_selector=key + ) + + return self.interface_fault_counts_mo[key] diff --git a/lib/aci/intf/fault_counts/info.py b/lib/aci/intf/fault_counts/info.py new file mode 100644 index 00000000..5229eea6 --- /dev/null +++ b/lib/aci/intf/fault_counts/info.py @@ -0,0 +1,35 @@ +class InterfaceFaultCountsInfo(): + def __init__(self): + pass + + def get_interface_fault_counts_info(self, managed_object): + keys = [ + 'crit', + 'critAcked', + 'critAckedandDelegated', + 'critDelegated', + 'maj', + 'majAcked', + 'majAckedandDelegated', + 'majDelegated', + 'minor', + 'minorAcked', + 'minorAckedandDelegated', + 'minorDelegated', + 'warn', + 'warnAckedandDelegated', + 'warnDelegated' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + return info + + def get_interface_fault_counts(self, pod_id, node_id, interface_type, interface_id): + managed_object = self.get_interface_fault_counts_mo(pod_id, node_id, interface_type, interface_id) + if managed_object is None: + return None + + return self.get_interface_fault_counts_info(managed_object) diff --git a/lib/aci/intf/fault_counts/main.py b/lib/aci/intf/fault_counts/main.py new file mode 100644 index 00000000..8b502893 --- /dev/null +++ b/lib/aci/intf/fault_counts/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fault_counts.api import InterfaceFaultCountsApi +from lib.aci.intf.fault_counts.info import InterfaceFaultCountsInfo + + +class InterfaceFaultCounts(InterfaceFaultCountsApi, InterfaceFaultCountsInfo): + def __init__(self): + InterfaceFaultCountsApi.__init__(self) + InterfaceFaultCountsInfo.__init__(self) diff --git a/lib/aci/intf/fc/__init__.py b/lib/aci/intf/fc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fc/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/fc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..dcfa8936 Binary files /dev/null and b/lib/aci/intf/fc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/fc/__pycache__/api.cpython-310.pyc b/lib/aci/intf/fc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..385ffd2b Binary files /dev/null and b/lib/aci/intf/fc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/fc/__pycache__/info.cpython-310.pyc b/lib/aci/intf/fc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f1292a7f Binary files /dev/null and b/lib/aci/intf/fc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/fc/__pycache__/main.cpython-310.pyc b/lib/aci/intf/fc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d2358639 Binary files /dev/null and b/lib/aci/intf/fc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/fc/__pycache__/output.cpython-310.pyc b/lib/aci/intf/fc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e1d01547 Binary files /dev/null and b/lib/aci/intf/fc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/fc/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/fc/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..7557b7e0 Binary files /dev/null and b/lib/aci/intf/fc/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/fc/api.py b/lib/aci/intf/fc/api.py new file mode 100644 index 00000000..628d1f31 --- /dev/null +++ b/lib/aci/intf/fc/api.py @@ -0,0 +1,72 @@ +class InterfaceFcApi(): + def __init__(self): + self.interface_fc_mo = {} + + def get_interface_fc_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_fc_mo: + return self.interface_fc_mo[key] + + cache = self.get_object_cache( + 'l1FcPhysIf', + object_selector=key + ) + if cache is not None: + self.interface_fc_mo[key] = cache + self.log.apic_mo( + 'l1FcPhysIf.%s' % (key), + self.interface_fc_mo[key] + ) + return self.interface_fc_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1FcPhysIf' % (pod_id, node_id) + query = 'query-target=children&target-subtree-class=l1RtFcBrConf&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fc_mo', + 'API failed' + ) + return None + + self.interface_fc_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l1FcPhysIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'l1FcPhysIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l1FcPhysIf', + managed_object, + 'faultCounts' + ) + attributes['ethpmLbRtdIf'] = self.get_mo_child_attributes( + 'l1FcPhysIf', + managed_object, + 'l1RtFcBrConf' + ) + self.interface_fc_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1FcPhysIf.%s' % (key), + self.interface_fc_mo[key] + ) + + self.set_object_cache( + 'l1FcPhysIf', + self.interface_fc_mo[key], + object_selector=key + ) + + return self.interface_fc_mo[key] diff --git a/lib/aci/intf/fc/audit/__init__.py b/lib/aci/intf/fc/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fc/audit/api.py b/lib/aci/intf/fc/audit/api.py new file mode 100644 index 00000000..ef28ef06 --- /dev/null +++ b/lib/aci/intf/fc/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceFcAuditApi(): + def __init__(self): + self.interface_fc_audit_mo = {} + + def get_interface_fc_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_audit_mo: + return self.interface_fc_audit_mo[key] + + cache = self.get_object_cache( + 'l1FcPhysIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_fc_audit_mo[key] = cache + self.log.apic_mo( + 'l1FcPhysIf.audit.%s' % (key), + self.interface_fc_audit_mo[key] + ) + return self.interface_fc_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1FcPhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fc_audit_mo', + 'API failed' + ) + return None + + self.interface_fc_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_fc_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1FcPhysIf.audit.%s' % (key), + self.interface_fc_audit_mo[key] + ) + + self.set_object_cache( + 'l1FcPhysIf.audit', + self.interface_fc_audit_mo[key], + object_selector=key + ) + + return self.interface_fc_audit_mo[key] diff --git a/lib/aci/intf/fc/audit/info.py b/lib/aci/intf/fc/audit/info.py new file mode 100644 index 00000000..770b4349 --- /dev/null +++ b/lib/aci/intf/fc/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceFcAuditInfo(): + def __init__(self): + self.interface_fc_audit = {} + + def get_interface_fc_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/cloudsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/cloudsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_fc_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_audit: + return self.interface_fc_audit[key] + + managed_objects = self.get_interface_fc_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_fc_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_fc_audit_info( + managed_object + ) + self.interface_fc_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'l1FcPhysIf.auditRecord.info.%s' % (key), + self.interface_fc_audit[key] + ) + + return self.interface_fc_audit[key] + + def get_interface_fc_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_fc_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/fc/audit/main.py b/lib/aci/intf/fc/audit/main.py new file mode 100644 index 00000000..87e404dc --- /dev/null +++ b/lib/aci/intf/fc/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fc.audit.api import InterfaceFcAuditApi +from lib.aci.intf.fc.audit.info import InterfaceFcAuditInfo + + +class InterfaceFcAudit(InterfaceFcAuditApi, InterfaceFcAuditInfo): + def __init__(self): + InterfaceFcAuditApi.__init__(self) + InterfaceFcAuditInfo.__init__(self) diff --git a/lib/aci/intf/fc/event/__init__.py b/lib/aci/intf/fc/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fc/event/api.py b/lib/aci/intf/fc/event/api.py new file mode 100644 index 00000000..0719976a --- /dev/null +++ b/lib/aci/intf/fc/event/api.py @@ -0,0 +1,54 @@ +class InterfaceFcEventApi(): + def __init__(self): + self.interface_fc_event_mo = {} + + def get_interface_fc_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_event_mo: + return self.interface_fc_event_mo[key] + + cache = self.get_object_cache( + 'l1FcPhysIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_fc_event_mo[key] = cache + self.log.apic_mo( + 'l1FcPhysIf.eventLog.%s' % (key), + self.interface_fc_event_mo[key] + ) + return self.interface_fc_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1FcPhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fc_event_mo', + 'API failed' + ) + return None + + self.interface_fc_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_fc_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1FcPhysIf.eventLog.%s' % (key), + self.interface_fc_event_mo[key] + ) + + self.set_object_cache( + 'l1FcPhysIf.eventLog', + self.interface_fc_event_mo[key], + object_selector=key + ) + + return self.interface_fc_event_mo[key] diff --git a/lib/aci/intf/fc/event/info.py b/lib/aci/intf/fc/event/info.py new file mode 100644 index 00000000..2e11b001 --- /dev/null +++ b/lib/aci/intf/fc/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceFcEventInfo(): + def __init__(self): + self.interface_fc_event = {} + + def get_interface_fc_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/fc-[lo0]" + info['interfaceId'] = None + if '/fc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/fc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_fc_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_event: + return self.interface_fc_event[key] + + managed_objects = self.get_interface_fc_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_fc_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_fc_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_fc_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l1FcPhysIf.eventLog.info.%s' % (key), + self.interface_fc_event[key] + ) + + return self.interface_fc_event[key] + + def get_interface_fc_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_fc_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/fc/event/main.py b/lib/aci/intf/fc/event/main.py new file mode 100644 index 00000000..7d172e7e --- /dev/null +++ b/lib/aci/intf/fc/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fc.event.api import InterfaceFcEventApi +from lib.aci.intf.fc.event.info import InterfaceFcEventInfo + + +class InterfaceFcEvent(InterfaceFcEventApi, InterfaceFcEventInfo): + def __init__(self): + InterfaceFcEventApi.__init__(self) + InterfaceFcEventInfo.__init__(self) diff --git a/lib/aci/intf/fc/fault/__init__.py b/lib/aci/intf/fc/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fc/fault/api.py b/lib/aci/intf/fc/fault/api.py new file mode 100644 index 00000000..f38a60ff --- /dev/null +++ b/lib/aci/intf/fc/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceFcFaultApi(): + def __init__(self): + self.interface_fc_fault_mo = {} + self.interface_fc_fault_record_mo = {} + + def get_interface_fc_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_fault_mo: + return self.interface_fc_fault_mo[key] + + cache = self.get_object_cache( + 'l1FcPhysIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_fc_fault_mo[key] = cache + self.log.apic_mo( + 'l1FcPhysIf.fault.%s' % (key), + self.interface_fc_fault_mo[key] + ) + return self.interface_fc_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1FcPhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fc_fault_mo', + 'API failed' + ) + return None + + self.interface_fc_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_fc_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1FcPhysIf.fault.%s' % (key), + self.interface_fc_fault_mo[key] + ) + + self.set_object_cache( + 'l1FcPhysIf.fault', + self.interface_fc_fault_mo[key], + object_selector=key + ) + + return self.interface_fc_fault_mo[key] + + def get_interface_fc_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_fault_record_mo: + return self.interface_fc_fault_record_mo[key] + + cache = self.get_object_cache( + 'l1FcPhysIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_fc_fault_record_mo[key] = cache + self.log.apic_mo( + 'l1FcPhysIf.faultRecord.%s' % (key), + self.interface_fc_fault_record_mo[key] + ) + return self.interface_fc_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1FcPhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fc_fault_record_mo', + 'API failed' + ) + return None + + self.interface_fc_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_fc_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1FcPhysIf.faultRecord.%s' % (key), + self.interface_fc_fault_record_mo[key] + ) + + self.set_object_cache( + 'l1FcPhysIf.faultRecord', + self.interface_fc_fault_record_mo[key], + object_selector=key + ) + + return self.interface_fc_fault_record_mo[key] diff --git a/lib/aci/intf/fc/fault/info.py b/lib/aci/intf/fc/fault/info.py new file mode 100644 index 00000000..76145133 --- /dev/null +++ b/lib/aci/intf/fc/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceFcFaultInfo(): + def __init__(self): + self.interface_fc_fault = {} + self.interface_fc_fault_record = {} + + def get_interface_fc_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/fc-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/fc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/fc-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/fc-[lo0]" + if info['interfaceId'] is None: + if '/fc-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/fc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_fc_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_fault: + return self.interface_fc_fault[key] + + managed_objects = self.get_interface_fc_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_fc_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_fc_fault_info( + managed_object + ) + self.interface_fc_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'l1FcPhysIf.fault.info.%s' % (key), + self.interface_fc_fault[key] + ) + + return self.interface_fc_fault[key] + + def get_interface_fc_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc_fault_record: + return self.interface_fc_fault_record[key] + + managed_objects = self.get_interface_fc_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_fc_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_fc_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_fc_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l1FcPhysIf.faultRecord.info.%s' % (key), + self.interface_fc_fault_record[key] + ) + + return self.interface_fc_fault_record[key] + + def get_interface_fc_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_fc_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_fc_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/fc/fault/main.py b/lib/aci/intf/fc/fault/main.py new file mode 100644 index 00000000..16631335 --- /dev/null +++ b/lib/aci/intf/fc/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fc.fault.api import InterfaceFcFaultApi +from lib.aci.intf.fc.fault.info import InterfaceFcFaultInfo + + +class InterfaceFcFault(InterfaceFcFaultApi, InterfaceFcFaultInfo): + def __init__(self): + InterfaceFcFaultApi.__init__(self) + InterfaceFcFaultInfo.__init__(self) diff --git a/lib/aci/intf/fc/info.py b/lib/aci/intf/fc/info.py new file mode 100644 index 00000000..ae1f3156 --- /dev/null +++ b/lib/aci/intf/fc/info.py @@ -0,0 +1,208 @@ +from lib import filter_helper + + +class InterfaceFcInfo(): + def __init__(self): + self.interface_fc = {} + + def get_interface_fc_summary(self, pod_id, node_id): + ports = self.get_interfaces_fc( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_fc_count(self, pod_id, node_id): + interfaces = self.get_interfaces_fc(pod_id, node_id) + return len(interfaces) + + def get_interface_fc_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + if managed_object['l1RtFcBrConf'] is not None: + info['state'] = {} + for key in managed_object['l1RtFcBrConf']: + info['state'][key] = managed_object['l1RtFcBrConf'][key] + + info['up'] = False + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_fc_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fc: + return self.interface_fc[key] + + interfaces_mo = self.get_interface_fc_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_fc[key] = [] + for interface_mo in interfaces_mo: + self.interface_fc[key].append( + self.get_interface_fc_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'l1FcPhysIf.info.%s' % (key), + self.interface_fc[key] + ) + + return self.interface_fc[key] + + def match_interface_fc(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_fc', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_fc( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_fc_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_fc(interface_info, interface_filter): + continue + + if fault_info: + interface_info['faultInst'] = self.get_interface_fc_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_fc_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_fc_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_fc_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces + + def get_interface_fc(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_fc( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/fc/main.py b/lib/aci/intf/fc/main.py new file mode 100644 index 00000000..e66374ae --- /dev/null +++ b/lib/aci/intf/fc/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.fc.api import InterfaceFcApi +from lib.aci.intf.fc.info import InterfaceFcInfo +from lib.aci.intf.fc.audit.main import InterfaceFcAudit +from lib.aci.intf.fc.event.main import InterfaceFcEvent +from lib.aci.intf.fc.fault.main import InterfaceFcFault + + +class InterfaceFc( + InterfaceFcApi, + InterfaceFcInfo, + InterfaceFcAudit, + InterfaceFcEvent, + InterfaceFcFault + ): + def __init__(self): + InterfaceFcApi.__init__(self) + InterfaceFcInfo.__init__(self) + InterfaceFcAudit.__init__(self) + InterfaceFcEvent.__init__(self) + InterfaceFcFault.__init__(self) diff --git a/lib/aci/intf/fc/output.py b/lib/aci/intf/fc/output.py new file mode 100644 index 00000000..9ddb43c1 --- /dev/null +++ b/lib/aci/intf/fc/output.py @@ -0,0 +1,263 @@ +class InterfaceFcOutput(): + def __init__(self): + pass + + def print_interfaces_fc_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Fc - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_fc_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Fc - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Fc - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_fc_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Fc - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_fc_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Fc - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Fc - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_fc_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Fc - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Fc - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/fcpc/__init__.py b/lib/aci/intf/fcpc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fcpc/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/fcpc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..6b197c82 Binary files /dev/null and b/lib/aci/intf/fcpc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/fcpc/__pycache__/api.cpython-310.pyc b/lib/aci/intf/fcpc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..b3504350 Binary files /dev/null and b/lib/aci/intf/fcpc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/fcpc/__pycache__/info.cpython-310.pyc b/lib/aci/intf/fcpc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..647b370f Binary files /dev/null and b/lib/aci/intf/fcpc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/fcpc/__pycache__/main.cpython-310.pyc b/lib/aci/intf/fcpc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..098da753 Binary files /dev/null and b/lib/aci/intf/fcpc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/fcpc/__pycache__/output.cpython-310.pyc b/lib/aci/intf/fcpc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..63cce795 Binary files /dev/null and b/lib/aci/intf/fcpc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/fcpc/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/fcpc/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..76d62ac6 Binary files /dev/null and b/lib/aci/intf/fcpc/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/fcpc/api.py b/lib/aci/intf/fcpc/api.py new file mode 100644 index 00000000..dc6bd183 --- /dev/null +++ b/lib/aci/intf/fcpc/api.py @@ -0,0 +1,67 @@ +class InterfaceFcPcApi(): + def __init__(self): + self.interface_fcpc_mo = {} + + def get_interface_fcpc_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_fcpc_mo: + return self.interface_fcpc_mo[key] + + cache = self.get_object_cache( + 'ipv4Addr', + object_selector=key + ) + if cache is not None: + self.interface_fcpc_mo[key] = cache + self.log.apic_mo( + 'pcFcAggrIf.%s' % (key), + self.interface_fcpc_mo[key] + ) + return self.interface_fcpc_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcFcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fcpc_mo', + 'API failed' + ) + return None + + self.interface_fcpc_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['pcFcAggrIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'pcFcAggrIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'pcFcAggrIf', + managed_object, + 'faultCounts' + ) + self.interface_fcpc_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcFcAggrIf.%s' % (key), + self.interface_fcpc_mo[key] + ) + + self.set_object_cache( + 'pcFcAggrIf', + self.interface_fcpc_mo[key], + object_selector=key + ) + + return self.interface_fcpc_mo[key] diff --git a/lib/aci/intf/fcpc/audit/__init__.py b/lib/aci/intf/fcpc/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fcpc/audit/api.py b/lib/aci/intf/fcpc/audit/api.py new file mode 100644 index 00000000..3d13f8c7 --- /dev/null +++ b/lib/aci/intf/fcpc/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceFcPcAuditApi(): + def __init__(self): + self.interface_fcpc_audit_mo = {} + + def get_interface_fcpc_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_audit_mo: + return self.interface_fcpc_audit_mo[key] + + cache = self.get_object_cache( + 'pcFcAggrIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_fcpc_audit_mo[key] = cache + self.log.apic_mo( + 'pcFcAggrIf.audit.%s' % (key), + self.interface_fcpc_audit_mo[key] + ) + return self.interface_fcpc_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcFcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fcpc_audit_mo', + 'API failed' + ) + return None + + self.interface_fcpc_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_fcpc_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcFcAggrIf.audit.%s' % (key), + self.interface_fcpc_audit_mo[key] + ) + + self.set_object_cache( + 'pcFcAggrIf.audit', + self.interface_fcpc_audit_mo[key], + object_selector=key + ) + + return self.interface_fcpc_audit_mo[key] diff --git a/lib/aci/intf/fcpc/audit/info.py b/lib/aci/intf/fcpc/audit/info.py new file mode 100644 index 00000000..e32eda71 --- /dev/null +++ b/lib/aci/intf/fcpc/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceFcPcAuditInfo(): + def __init__(self): + self.interface_fcpc_audit = {} + + def get_interface_fcpc_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/fcpc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/fcpc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_fcpc_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_audit: + return self.interface_fcpc_audit[key] + + managed_objects = self.get_interface_fcpc_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_fcpc_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_fcpc_audit_info( + managed_object + ) + self.interface_fcpc_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'pcFcAggrIf.auditRecord.info.%s' % (key), + self.interface_fcpc_audit[key] + ) + + return self.interface_fcpc_audit[key] + + def get_interface_fcpc_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_fcpc_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/fcpc/audit/main.py b/lib/aci/intf/fcpc/audit/main.py new file mode 100644 index 00000000..79e8a2a5 --- /dev/null +++ b/lib/aci/intf/fcpc/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fcpc.audit.api import InterfaceFcPcAuditApi +from lib.aci.intf.fcpc.audit.info import InterfaceFcPcAuditInfo + + +class InterfaceFcPcAudit(InterfaceFcPcAuditApi, InterfaceFcPcAuditInfo): + def __init__(self): + InterfaceFcPcAuditApi.__init__(self) + InterfaceFcPcAuditInfo.__init__(self) diff --git a/lib/aci/intf/fcpc/event/__init__.py b/lib/aci/intf/fcpc/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fcpc/event/api.py b/lib/aci/intf/fcpc/event/api.py new file mode 100644 index 00000000..f77e3f66 --- /dev/null +++ b/lib/aci/intf/fcpc/event/api.py @@ -0,0 +1,54 @@ +class InterfaceFcPcEventApi(): + def __init__(self): + self.interface_fcpc_event_mo = {} + + def get_interface_fcpc_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_event_mo: + return self.interface_fcpc_event_mo[key] + + cache = self.get_object_cache( + 'pcFcAggrIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_fcpc_event_mo[key] = cache + self.log.apic_mo( + 'pcFcAggrIf.eventLog.%s' % (key), + self.interface_fcpc_event_mo[key] + ) + return self.interface_fcpc_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcFcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fcpc_event_mo', + 'API failed' + ) + return None + + self.interface_fcpc_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_fcpc_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcFcAggrIf.eventLog.%s' % (key), + self.interface_fcpc_event_mo[key] + ) + + self.set_object_cache( + 'pcFcAggrIf.eventLog', + self.interface_fcpc_event_mo[key], + object_selector=key + ) + + return self.interface_fcpc_event_mo[key] diff --git a/lib/aci/intf/fcpc/event/info.py b/lib/aci/intf/fcpc/event/info.py new file mode 100644 index 00000000..462335c7 --- /dev/null +++ b/lib/aci/intf/fcpc/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceFcPcEventInfo(): + def __init__(self): + self.interface_fcpc_event = {} + + def get_interface_fcpc_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/fcpc-[lo0]" + info['interfaceId'] = None + if '/fcpc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/fcpc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_fcpc_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_event: + return self.interface_fcpc_event[key] + + managed_objects = self.get_interface_fcpc_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_fcpc_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_fcpc_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_fcpc_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'pcFcAggrIf.eventLog.info.%s' % (key), + self.interface_fcpc_event[key] + ) + + return self.interface_fcpc_event[key] + + def get_interface_fcpc_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_fcpc_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/fcpc/event/main.py b/lib/aci/intf/fcpc/event/main.py new file mode 100644 index 00000000..f630a4f5 --- /dev/null +++ b/lib/aci/intf/fcpc/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fcpc.event.api import InterfaceFcPcEventApi +from lib.aci.intf.fcpc.event.info import InterfaceFcPcEventInfo + + +class InterfaceFcPcEvent(InterfaceFcPcEventApi, InterfaceFcPcEventInfo): + def __init__(self): + InterfaceFcPcEventApi.__init__(self) + InterfaceFcPcEventInfo.__init__(self) diff --git a/lib/aci/intf/fcpc/fault/__init__.py b/lib/aci/intf/fcpc/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/fcpc/fault/api.py b/lib/aci/intf/fcpc/fault/api.py new file mode 100644 index 00000000..e08380fe --- /dev/null +++ b/lib/aci/intf/fcpc/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceFcPcFaultApi(): + def __init__(self): + self.interface_fcpc_fault_mo = {} + self.interface_fcpc_fault_record_mo = {} + + def get_interface_fcpc_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_fault_mo: + return self.interface_fcpc_fault_mo[key] + + cache = self.get_object_cache( + 'pcFcAggrIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_fcpc_fault_mo[key] = cache + self.log.apic_mo( + 'pcFcAggrIf.fault.%s' % (key), + self.interface_fcpc_fault_mo[key] + ) + return self.interface_fcpc_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcFcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fcpc_fault_mo', + 'API failed' + ) + return None + + self.interface_fcpc_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_fcpc_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcFcAggrIf.fault.%s' % (key), + self.interface_fcpc_fault_mo[key] + ) + + self.set_object_cache( + 'pcFcAggrIf.fault', + self.interface_fcpc_fault_mo[key], + object_selector=key + ) + + return self.interface_fcpc_fault_mo[key] + + def get_interface_fcpc_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_fault_record_mo: + return self.interface_fcpc_fault_record_mo[key] + + cache = self.get_object_cache( + 'pcFcAggrIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_fcpc_fault_record_mo[key] = cache + self.log.apic_mo( + 'pcFcAggrIf.faultRecord.%s' % (key), + self.interface_fcpc_fault_record_mo[key] + ) + return self.interface_fcpc_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcFcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_fcpc_fault_record_mo', + 'API failed' + ) + return None + + self.interface_fcpc_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_fcpc_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcFcAggrIf.faultRecord.%s' % (key), + self.interface_fcpc_fault_record_mo[key] + ) + + self.set_object_cache( + 'pcFcAggrIf.faultRecord', + self.interface_fcpc_fault_record_mo[key], + object_selector=key + ) + + return self.interface_fcpc_fault_record_mo[key] diff --git a/lib/aci/intf/fcpc/fault/info.py b/lib/aci/intf/fcpc/fault/info.py new file mode 100644 index 00000000..924466e8 --- /dev/null +++ b/lib/aci/intf/fcpc/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceFcPcFaultInfo(): + def __init__(self): + self.interface_fcpc_fault = {} + self.interface_fcpc_fault_record = {} + + def get_interface_fcpc_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/fcpc-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/fcpc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/fcpc-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/fcpc-[lo0]" + if info['interfaceId'] is None: + if '/fcpc-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/fcpc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_fcpc_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_fault: + return self.interface_fcpc_fault[key] + + managed_objects = self.get_interface_fcpc_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_fcpc_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_fcpc_fault_info( + managed_object + ) + self.interface_fcpc_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'pcFcAggrIf.fault.info.%s' % (key), + self.interface_fcpc_fault[key] + ) + + return self.interface_fcpc_fault[key] + + def get_interface_fcpc_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc_fault_record: + return self.interface_fcpc_fault_record[key] + + managed_objects = self.get_interface_fcpc_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_fcpc_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_fcpc_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_fcpc_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'pcFcAggrIf.faultRecord.info.%s' % (key), + self.interface_fcpc_fault_record[key] + ) + + return self.interface_fcpc_fault_record[key] + + def get_interface_fcpc_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_fcpc_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_fcpc_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/fcpc/fault/main.py b/lib/aci/intf/fcpc/fault/main.py new file mode 100644 index 00000000..a448767b --- /dev/null +++ b/lib/aci/intf/fcpc/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.fcpc.fault.api import InterfaceFcPcFaultApi +from lib.aci.intf.fcpc.fault.info import InterfaceFcPcFaultInfo + + +class InterfaceFcPcFault(InterfaceFcPcFaultApi, InterfaceFcPcFaultInfo): + def __init__(self): + InterfaceFcPcFaultApi.__init__(self) + InterfaceFcPcFaultInfo.__init__(self) diff --git a/lib/aci/intf/fcpc/info.py b/lib/aci/intf/fcpc/info.py new file mode 100644 index 00000000..aa0b22df --- /dev/null +++ b/lib/aci/intf/fcpc/info.py @@ -0,0 +1,202 @@ +from lib import filter_helper + + +class InterfaceFcPcInfo(): + def __init__(self): + self.interface_fcpc = {} + + def get_interface_fcpc_summary(self, pod_id, node_id): + ports = self.get_interfaces_fcpc( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_fcpc_count(self, pod_id, node_id): + interfaces = self.get_interfaces_fcpc(pod_id, node_id) + return len(interfaces) + + def get_interface_fcpc_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + info['up'] = False + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_fcpc_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_fcpc: + return self.interface_fcpc[key] + + interfaces_mo = self.get_interface_fcpc_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_fcpc[key] = [] + for interface_mo in interfaces_mo: + self.interface_fcpc[key].append( + self.get_interface_fcpc_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'pcFcAggrIf.info.%s' % (key), + self.interface_fcpc[key] + ) + + return self.interface_fcpc[key] + + def match_interface_fcpc(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_fcpc', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_fcpc( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_fcpc_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_fcpc(interface_info, interface_filter): + continue + + if fault_info: + interface_info['faultInst'] = self.get_interface_fcpc_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_fcpc_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_fcpc_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_fcpc_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces + + def get_interface_fcpc(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_fcpc( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/fcpc/main.py b/lib/aci/intf/fcpc/main.py new file mode 100644 index 00000000..7fe92295 --- /dev/null +++ b/lib/aci/intf/fcpc/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.fcpc.api import InterfaceFcPcApi +from lib.aci.intf.fcpc.info import InterfaceFcPcInfo +from lib.aci.intf.fcpc.audit.main import InterfaceFcPcAudit +from lib.aci.intf.fcpc.event.main import InterfaceFcPcEvent +from lib.aci.intf.fcpc.fault.main import InterfaceFcPcFault + + +class InterfaceFcPc( + InterfaceFcPcApi, + InterfaceFcPcInfo, + InterfaceFcPcAudit, + InterfaceFcPcEvent, + InterfaceFcPcFault + ): + def __init__(self): + InterfaceFcPcApi.__init__(self) + InterfaceFcPcInfo.__init__(self) + InterfaceFcPcAudit.__init__(self) + InterfaceFcPcEvent.__init__(self) + InterfaceFcPcFault.__init__(self) diff --git a/lib/aci/intf/fcpc/output.py b/lib/aci/intf/fcpc/output.py new file mode 100644 index 00000000..2a2e428b --- /dev/null +++ b/lib/aci/intf/fcpc/output.py @@ -0,0 +1,263 @@ +class InterfaceFcPcOutput(): + def __init__(self): + pass + + def print_interfaces_fcpc_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface FcPc - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_fcpc_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface FcPc - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface FcPc - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_fcpc_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface FcPc - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_fcpc_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface FcPc - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface FcPc - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_fcpc_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface FcPc - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface FcPc - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/ip/__init__.py b/lib/aci/intf/ip/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3951d262 Binary files /dev/null and b/lib/aci/intf/ip/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/__pycache__/main.cpython-310.pyc b/lib/aci/intf/ip/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ab76be6c Binary files /dev/null and b/lib/aci/intf/ip/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/main.py b/lib/aci/intf/ip/main.py new file mode 100644 index 00000000..23959861 --- /dev/null +++ b/lib/aci/intf/ip/main.py @@ -0,0 +1,12 @@ +from lib.aci.intf.ip.v4.address.main import AddressIpv4 +from lib.aci.intf.ip.v4.intf.main import InterfaceIpv4 +from lib.aci.intf.ip.v6.address.main import AddressIpv6 +from lib.aci.intf.ip.v6.intf.main import InterfaceIpv6 + + +class InterfaceIp(AddressIpv4, InterfaceIpv4, AddressIpv6, InterfaceIpv6): + def __init__(self): + AddressIpv4.__init__(self) + InterfaceIpv4.__init__(self) + AddressIpv6.__init__(self) + InterfaceIpv6.__init__(self) diff --git a/lib/aci/intf/ip/v4/__init__.py b/lib/aci/intf/ip/v4/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/v4/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/v4/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..59240d4f Binary files /dev/null and b/lib/aci/intf/ip/v4/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/address/__init__.py b/lib/aci/intf/ip/v4/address/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/v4/address/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/v4/address/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..efbadfe7 Binary files /dev/null and b/lib/aci/intf/ip/v4/address/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/address/__pycache__/api.cpython-310.pyc b/lib/aci/intf/ip/v4/address/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c700c0c3 Binary files /dev/null and b/lib/aci/intf/ip/v4/address/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/address/__pycache__/info.cpython-310.pyc b/lib/aci/intf/ip/v4/address/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1440290e Binary files /dev/null and b/lib/aci/intf/ip/v4/address/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/address/__pycache__/main.cpython-310.pyc b/lib/aci/intf/ip/v4/address/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8c984509 Binary files /dev/null and b/lib/aci/intf/ip/v4/address/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/address/api.py b/lib/aci/intf/ip/v4/address/api.py new file mode 100644 index 00000000..53d2938a --- /dev/null +++ b/lib/aci/intf/ip/v4/address/api.py @@ -0,0 +1,54 @@ +class AddressIpv4Api(): + def __init__(self): + self.node_address_ipv4_mo = {} + + def get_node_address_ipv4_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.node_address_ipv4_mo: + return self.node_address_ipv4_mo[key] + + cache = self.get_object_cache( + 'ipv4Addr', + object_selector=key + ) + if cache is not None: + self.node_address_ipv4_mo[key] = cache + self.log.apic_mo( + 'ipv4Addr.%s' % (key), + self.node_address_ipv4_mo[key] + ) + return self.node_address_ipv4_mo[key] + + class_name = 'topology/pod-%s/node-%s/ipv4Addr' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_node_address_ipv4_mo', + 'API failed' + ) + return None + + self.node_address_ipv4_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.node_address_ipv4_mo[key].append( + managed_object['ipv4Addr']['attributes'] + ) + + self.log.apic_mo( + 'ipv4Addr.%s' % (key), + self.node_address_ipv4_mo[key] + ) + + self.set_object_cache( + 'ipv4Addr', + self.node_address_ipv4_mo[key], + object_selector=key + ) + + return self.node_address_ipv4_mo[key] diff --git a/lib/aci/intf/ip/v4/address/info.py b/lib/aci/intf/ip/v4/address/info.py new file mode 100644 index 00000000..171da2c7 --- /dev/null +++ b/lib/aci/intf/ip/v4/address/info.py @@ -0,0 +1,95 @@ +from lib import ip_helper + + +class AddressIpv4Info(): + def __init__(self): + self.node_address_ipv4 = {} + + def get_node_address_ipv4_info(self, managed_object): + keys = [ + 'addr', + 'dn', + 'ipv4CfgState', + 'operSt', + 'operStQual', + 'type', + 'vpcPeer' + ] + + info = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "addr": "/32" + info['ip'] = info['addr'] + if len(info['addr'].split('/')) == 2: + info['ip'] = info['addr'].split('/')[0] + + # topology/pod-1/node-201/sys/ipv4/inst/dom-mgmt:inb/if-[lo18]/addr-[/32] + info['interface'] = info['dn'].split('/')[7].split('-')[1][1:][:-1] + + return info + + def get_node_addresses_ipv4_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.node_address_ipv4: + return self.node_address_ipv4[key] + + managed_objects = self.get_node_address_ipv4_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.node_address_ipv4[key] = [] + for managed_object in managed_objects: + self.node_address_ipv4[key].append( + self.get_node_address_ipv4_info( + managed_object + ) + ) + + return self.node_address_ipv4[key] + + def match_node_address_ipv4(self, address_info, address_filter): + if address_filter is None or len(address_filter) == 0: + return True + + for ap_rule in address_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ip': + if value != address_info['ip']: + return False + + if key == 'subnet': + if not ip_helper.is_ipv4_in_cidr(address_info['ip'], value): + return False + + return True + + def get_node_address_ipv4(self, pod_id, node_id, address_filter=None): + addresses_info = self.get_node_addresses_ipv4_info( + pod_id, + node_id + ) + if addresses_info is None: + return None + + info = [] + for address_info in addresses_info: + if not self.match_node_address_ipv4(address_info, address_filter): + continue + + info.append( + address_info + ) + + return info diff --git a/lib/aci/intf/ip/v4/address/main.py b/lib/aci/intf/ip/v4/address/main.py new file mode 100644 index 00000000..7d6fa50f --- /dev/null +++ b/lib/aci/intf/ip/v4/address/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.ip.v4.address.api import AddressIpv4Api +from lib.aci.intf.ip.v4.address.info import AddressIpv4Info + + +class AddressIpv4(AddressIpv4Api, AddressIpv4Info): + def __init__(self): + AddressIpv4Api.__init__(self) + AddressIpv4Info.__init__(self) diff --git a/lib/aci/intf/ip/v4/intf/__init__.py b/lib/aci/intf/ip/v4/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/v4/intf/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/v4/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e0671064 Binary files /dev/null and b/lib/aci/intf/ip/v4/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/intf/__pycache__/api.cpython-310.pyc b/lib/aci/intf/ip/v4/intf/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e070d587 Binary files /dev/null and b/lib/aci/intf/ip/v4/intf/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/intf/__pycache__/info.cpython-310.pyc b/lib/aci/intf/ip/v4/intf/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f6f9f711 Binary files /dev/null and b/lib/aci/intf/ip/v4/intf/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/intf/__pycache__/main.cpython-310.pyc b/lib/aci/intf/ip/v4/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0ebf4f64 Binary files /dev/null and b/lib/aci/intf/ip/v4/intf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v4/intf/api.py b/lib/aci/intf/ip/v4/intf/api.py new file mode 100644 index 00000000..13d172f1 --- /dev/null +++ b/lib/aci/intf/ip/v4/intf/api.py @@ -0,0 +1,54 @@ +class InterfaceIpv4Api(): + def __init__(self): + self.node_interface_ipv4_mo = {} + + def get_node_interface_ipv4_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.node_interface_ipv4_mo: + return self.node_interface_ipv4_mo[key] + + cache = self.get_object_cache( + 'ipv4If', + object_selector=key + ) + if cache is not None: + self.node_interface_ipv4_mo[key] = cache + self.log.apic_mo( + 'ipv4If.%s' % (key), + self.node_interface_ipv4_mo[key] + ) + return self.node_interface_ipv4_mo[key] + + class_name = 'topology/pod-%s/node-%s/ipv4If' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_node_interface_ipv4_mo', + 'API failed' + ) + return None + + self.node_interface_ipv4_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.node_interface_ipv4_mo[key].append( + managed_object['ipv4If']['attributes'] + ) + + self.log.apic_mo( + 'ipv4If.%s' % (key), + self.node_interface_ipv4_mo[key] + ) + + self.set_object_cache( + 'ipv4If', + self.node_interface_ipv4_mo[key], + object_selector=key + ) + + return self.node_interface_ipv4_mo[key] diff --git a/lib/aci/intf/ip/v4/intf/info.py b/lib/aci/intf/ip/v4/intf/info.py new file mode 100644 index 00000000..cb1034f2 --- /dev/null +++ b/lib/aci/intf/ip/v4/intf/info.py @@ -0,0 +1,38 @@ +class InterfaceIpv4Info(): + def __init__(self): + pass + + def get_node_interface_ipv4_info(self, managed_object): + keys = [ + 'adminSt', + 'dn', + 'donorIf', + 'id', + 'mode', + 'name', + 'status' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + return info + + def get_node_interface_ipv4(self, pod_id, node_id): + managed_objects = self.get_node_interface_ipv4_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + info = [] + for managed_object in managed_objects: + info.append( + self.get_node_interface_ipv4_info( + managed_object + ) + ) + + return info diff --git a/lib/aci/intf/ip/v4/intf/main.py b/lib/aci/intf/ip/v4/intf/main.py new file mode 100644 index 00000000..1aac1582 --- /dev/null +++ b/lib/aci/intf/ip/v4/intf/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.ip.v4.intf.api import InterfaceIpv4Api +from lib.aci.intf.ip.v4.intf.info import InterfaceIpv4Info + + +class InterfaceIpv4(InterfaceIpv4Api, InterfaceIpv4Info): + def __init__(self): + InterfaceIpv4Api.__init__(self) + InterfaceIpv4Info.__init__(self) diff --git a/lib/aci/intf/ip/v6/__init__.py b/lib/aci/intf/ip/v6/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/v6/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/v6/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..109c5835 Binary files /dev/null and b/lib/aci/intf/ip/v6/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/address/__init__.py b/lib/aci/intf/ip/v6/address/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/v6/address/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/v6/address/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..578463f0 Binary files /dev/null and b/lib/aci/intf/ip/v6/address/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/address/__pycache__/api.cpython-310.pyc b/lib/aci/intf/ip/v6/address/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..dfba2e58 Binary files /dev/null and b/lib/aci/intf/ip/v6/address/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/address/__pycache__/info.cpython-310.pyc b/lib/aci/intf/ip/v6/address/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b51be43d Binary files /dev/null and b/lib/aci/intf/ip/v6/address/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/address/__pycache__/main.cpython-310.pyc b/lib/aci/intf/ip/v6/address/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a4bedeae Binary files /dev/null and b/lib/aci/intf/ip/v6/address/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/address/api.py b/lib/aci/intf/ip/v6/address/api.py new file mode 100644 index 00000000..6fcec51d --- /dev/null +++ b/lib/aci/intf/ip/v6/address/api.py @@ -0,0 +1,54 @@ +class AddressIpv6Api(): + def __init__(self): + self.node_address_ipv6_mo = {} + + def get_node_address_ipv6_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.node_address_ipv6_mo: + return self.node_address_ipv6_mo[key] + + cache = self.get_object_cache( + 'ipv6Addr', + object_selector=key + ) + if cache is not None: + self.node_address_ipv6_mo[key] = cache + self.log.apic_mo( + 'ipv6Addr.%s' % (key), + self.node_address_ipv6_mo[key] + ) + return self.node_address_ipv6_mo[key] + + class_name = 'topology/pod-%s/node-%s/ipv6Addr' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_node_address_ipv6_mo', + 'API failed' + ) + return None + + self.node_address_ipv6_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.node_address_ipv6_mo[key].append( + managed_object + ) + + self.log.apic_mo( + 'ipv6Addr.%s' % (key), + self.node_address_ipv6_mo[key] + ) + + self.set_object_cache( + 'ipv6Addr', + self.node_address_ipv6_mo[key], + object_selector=key + ) + + return self.node_address_ipv6_mo[key] diff --git a/lib/aci/intf/ip/v6/address/info.py b/lib/aci/intf/ip/v6/address/info.py new file mode 100644 index 00000000..ebf7208c --- /dev/null +++ b/lib/aci/intf/ip/v6/address/info.py @@ -0,0 +1,38 @@ +class AddressIpv6Info(): + def __init__(self): + pass + + def get_node_address_ipv6_info(self, managed_object): + keys = [ + 'addr', + 'dn', + 'ipv6CfgState', + 'operSt', + 'operStQual', + 'type', + 'vpcPeer' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + return info + + def get_node_address_ipv6(self, pod_id, node_id): + managed_objects = self.get_node_address_ipv6_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + info = [] + for managed_object in managed_objects: + info.append( + self.get_node_address_ipv6_info( + managed_object + ) + ) + + return info diff --git a/lib/aci/intf/ip/v6/address/main.py b/lib/aci/intf/ip/v6/address/main.py new file mode 100644 index 00000000..f6d29886 --- /dev/null +++ b/lib/aci/intf/ip/v6/address/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.ip.v6.address.api import AddressIpv6Api +from lib.aci.intf.ip.v6.address.info import AddressIpv6Info + + +class AddressIpv6(AddressIpv6Api, AddressIpv6Info): + def __init__(self): + AddressIpv6Api.__init__(self) + AddressIpv6Info.__init__(self) diff --git a/lib/aci/intf/ip/v6/intf/__init__.py b/lib/aci/intf/ip/v6/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/ip/v6/intf/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/ip/v6/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c6f7a783 Binary files /dev/null and b/lib/aci/intf/ip/v6/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/intf/__pycache__/api.cpython-310.pyc b/lib/aci/intf/ip/v6/intf/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3c6f23c3 Binary files /dev/null and b/lib/aci/intf/ip/v6/intf/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/intf/__pycache__/info.cpython-310.pyc b/lib/aci/intf/ip/v6/intf/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..08709dd7 Binary files /dev/null and b/lib/aci/intf/ip/v6/intf/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/intf/__pycache__/main.cpython-310.pyc b/lib/aci/intf/ip/v6/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..090adce9 Binary files /dev/null and b/lib/aci/intf/ip/v6/intf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/ip/v6/intf/api.py b/lib/aci/intf/ip/v6/intf/api.py new file mode 100644 index 00000000..691ccf5c --- /dev/null +++ b/lib/aci/intf/ip/v6/intf/api.py @@ -0,0 +1,54 @@ +class InterfaceIpv6Api(): + def __init__(self): + self.node_interface_ipv6_mo = {} + + def get_node_interface_ipv6_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.node_interface_ipv6_mo: + return self.node_interface_ipv6_mo[key] + + cache = self.get_object_cache( + 'ipv6If', + object_selector=key + ) + if cache is not None: + self.node_interface_ipv6_mo[key] = cache + self.log.apic_mo( + 'ipv6If.%s' % (key), + self.node_interface_ipv6_mo[key] + ) + return self.node_interface_ipv6_mo[key] + + class_name = 'topology/pod-%s/node-%s/ipv6If' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_node_interface_ipv6_mo', + 'API failed' + ) + return None + + self.node_interface_ipv6_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.node_interface_ipv6_mo[key].append( + managed_object + ) + + self.log.apic_mo( + 'ipv6If.%s' % (key), + self.node_interface_ipv6_mo[key] + ) + + self.set_object_cache( + 'ipv6If', + self.node_interface_ipv6_mo[key], + object_selector=key + ) + + return self.node_interface_ipv6_mo[key] diff --git a/lib/aci/intf/ip/v6/intf/info.py b/lib/aci/intf/ip/v6/intf/info.py new file mode 100644 index 00000000..b35c1acd --- /dev/null +++ b/lib/aci/intf/ip/v6/intf/info.py @@ -0,0 +1,38 @@ +class InterfaceIpv6Info(): + def __init__(self): + pass + + def get_node_interface_ipv6_info(self, managed_object): + keys = [ + 'adminSt', + 'dn', + 'donorIf', + 'id', + 'mode', + 'name', + 'status' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + return info + + def get_node_interface_ipv6(self, pod_id, node_id): + managed_objects = self.get_node_interface_ipv6_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + info = [] + for managed_object in managed_objects: + info.append( + self.get_node_interface_ipv6_info( + managed_object + ) + ) + + return info diff --git a/lib/aci/intf/ip/v6/intf/main.py b/lib/aci/intf/ip/v6/intf/main.py new file mode 100644 index 00000000..9da47335 --- /dev/null +++ b/lib/aci/intf/ip/v6/intf/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.ip.v6.intf.api import InterfaceIpv6Api +from lib.aci.intf.ip.v6.intf.info import InterfaceIpv6Info + + +class InterfaceIpv6(InterfaceIpv6Api, InterfaceIpv6Info): + def __init__(self): + InterfaceIpv6Api.__init__(self) + InterfaceIpv6Info.__init__(self) diff --git a/lib/aci/intf/lacp/__init__.py b/lib/aci/intf/lacp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/lacp/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e7a904fd Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/adj_ep.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/adj_ep.cpython-310.pyc new file mode 100644 index 00000000..a9c68180 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/adj_ep.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/api.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6b507dd8 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/info.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..45e4af1d Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/instance.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..e9d79119 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/interface.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..9f8de999 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/lacp_adj_ep.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/lacp_adj_ep.cpython-310.pyc new file mode 100644 index 00000000..e73779b1 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/lacp_adj_ep.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/lacp_instance.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/lacp_instance.cpython-310.pyc new file mode 100644 index 00000000..c2348ca2 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/lacp_instance.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/lacp_stats.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/lacp_stats.cpython-310.pyc new file mode 100644 index 00000000..c22f189e Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/lacp_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/main.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f187df54 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/output.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..a307df59 Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/__pycache__/stats.cpython-310.pyc b/lib/aci/intf/lacp/__pycache__/stats.cpython-310.pyc new file mode 100644 index 00000000..592afedb Binary files /dev/null and b/lib/aci/intf/lacp/__pycache__/stats.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/api.py b/lib/aci/intf/lacp/api.py new file mode 100644 index 00000000..27a7339b --- /dev/null +++ b/lib/aci/intf/lacp/api.py @@ -0,0 +1,60 @@ +class InterfaceLacpApi(): + def __init__(self): + self.interfaces_lacp_mo = {} + + def get_interfaces_lacp_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interfaces_lacp_mo: + return self.interfaces_lacp_mo[key] + + cache = self.get_object_cache( + 'lacpIf', + object_selector=key + ) + if cache is not None: + self.interfaces_lacp_mo[key] = cache + self.log.apic_mo( + 'lacpIf.%s' % (key), + self.interfaces_lacp_mo[key] + ) + return self.interfaces_lacp_mo[key] + + class_name = 'topology/pod-%s/node-%s/lacpIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-class=lacpIfStats' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interfaces_lacp_mo', + 'API failed' + ) + return False + + self.interfaces_lacp_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['lacpIf']['attributes'] + attributes['stats'] = self.get_mo_child_attributes( + 'lacpIf', + managed_object, + 'lacpIfStats' + ) + + self.interfaces_lacp_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lacpIf.%s' % (key), + self.interfaces_lacp_mo[key] + ) + + self.set_object_cache( + 'lacpIf', + self.interfaces_lacp_mo[key], + object_selector=key + ) + + return self.interfaces_lacp_mo[key] diff --git a/lib/aci/intf/lacp/info.py b/lib/aci/intf/lacp/info.py new file mode 100644 index 00000000..371c04f1 --- /dev/null +++ b/lib/aci/intf/lacp/info.py @@ -0,0 +1,119 @@ +from lib import filter_helper + + +class InterfaceLacpInfo(): + def __init__(self): + self.interfaces_lacp = {} + + def get_interface_lacp_count(self, pod_id, node_id): + interfaces = self.get_interface_lacp(pod_id, node_id) + return len(interfaces) + + def get_interface_lacp_info(self, managed_object): + keys = [ + 'activityFlags', + 'adminSt', + 'dn', + 'id', + 'key', + 'lastActive', + 'operPrio', + 'port', + 'prio', + 'txRate', + 'stats' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['__Output']['id'] = 'Blue' + + # Dn format + # topology/pod-1/node-201/sys/lacp/inst/if-[eth1/2] + info['apic'] = self.apic_name + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name(info['nodeId']) + ) + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_interfaces_lacp_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interfaces_lacp: + return self.interfaces_lacp[key] + + interfaces_lacp_mo = self.get_interfaces_lacp_mo(pod_id, node_id) + if interfaces_lacp_mo is None: + return None + + self.interfaces_lacp[key] = [] + for interface_lacp_mo in interfaces_lacp_mo: + self.interfaces_lacp[key].append( + self.get_interface_lacp_info( + interface_lacp_mo + ) + ) + + self.log.apic_mo( + 'lacpIf.info.%s' % (key), + self.interfaces_lacp[key] + ) + + return self.interfaces_lacp[key] + + def match_interface_lacp(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + return True + + def get_interface_lacp(self, pod_id, node_id, interface_filter=None, adjacency_info=False): + all_interfaces = self.get_interfaces_lacp_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_lacp(interface_info, interface_filter): + continue + + if adjacency_info: + interface_info['adjacency'] = self.get_lacp_adjacency_endpoint( + pod_id, + node_id, + interface_info['id'], + allow_multiple=False + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces diff --git a/lib/aci/intf/lacp/instance/__init__.py b/lib/aci/intf/lacp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/lacp/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/lacp/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..263c677a Binary files /dev/null and b/lib/aci/intf/lacp/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/instance/__pycache__/api.cpython-310.pyc b/lib/aci/intf/lacp/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..b4540d84 Binary files /dev/null and b/lib/aci/intf/lacp/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/instance/__pycache__/info.cpython-310.pyc b/lib/aci/intf/lacp/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..a4d6347d Binary files /dev/null and b/lib/aci/intf/lacp/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/instance/__pycache__/main.cpython-310.pyc b/lib/aci/intf/lacp/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e82c2af1 Binary files /dev/null and b/lib/aci/intf/lacp/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/instance/api.py b/lib/aci/intf/lacp/instance/api.py new file mode 100644 index 00000000..43f710ca --- /dev/null +++ b/lib/aci/intf/lacp/instance/api.py @@ -0,0 +1,58 @@ +class InterfaceLacpInstanceApi(): + def __init__(self): + self.lacp_instance_mo = {} + + def get_lacp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lacp_instance_mo: + return self.lacp_instance_mo[key] + + cache = self.get_object_cache( + 'lacpInst', + object_selector=key + ) + if cache is not None: + self.lacp_instance_mo[key] = cache + self.log.apic_mo( + 'lacpInst.%s' % (key), + self.lacp_instance_mo[key] + ) + return self.lacp_instance_mo[key] + + class_name = 'topology/pod-%s/node-%s/lacpInst' % ( + pod_id, + node_id + ) + + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_lacp_instance_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_lacp_instance_mo', + 'Unexpected object count' + ) + return None + + self.lacp_instance_mo[key] = managed_objects['imdata'][0]['lacpInst']['attributes'] + + self.log.apic_mo( + 'lacpInst.%s' % (key), + self.lacp_instance_mo[key] + ) + + self.set_object_cache( + 'lacpInst', + self.lacp_instance_mo[key], + object_selector=key + ) + + return self.lacp_instance_mo[key] diff --git a/lib/aci/intf/lacp/instance/info.py b/lib/aci/intf/lacp/instance/info.py new file mode 100644 index 00000000..3bb5b37b --- /dev/null +++ b/lib/aci/intf/lacp/instance/info.py @@ -0,0 +1,33 @@ +class InterfaceLacpInstanceInfo(): + def __init__(self): + pass + + def get_lacp_instance_info(self, managed_object): + keys = [ + 'adminPrio', + 'adminSt', + 'dn', + 'operPrio', + 'sysMac' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_lacp_instance(self, pod_id, node_id): + managed_object = self.get_lacp_instance_mo(pod_id, node_id) + if managed_object is None: + return None + + return self.get_lacp_instance_info(managed_object) diff --git a/lib/aci/intf/lacp/instance/main.py b/lib/aci/intf/lacp/instance/main.py new file mode 100644 index 00000000..71b05984 --- /dev/null +++ b/lib/aci/intf/lacp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.lacp.instance.api import InterfaceLacpInstanceApi +from lib.aci.intf.lacp.instance.info import InterfaceLacpInstanceInfo + + +class InterfaceLacpInstance(InterfaceLacpInstanceApi, InterfaceLacpInstanceInfo): + def __init__(self): + InterfaceLacpInstanceApi.__init__(self) + InterfaceLacpInstanceInfo.__init__(self) diff --git a/lib/aci/intf/lacp/main.py b/lib/aci/intf/lacp/main.py new file mode 100644 index 00000000..a631e97c --- /dev/null +++ b/lib/aci/intf/lacp/main.py @@ -0,0 +1,10 @@ +from lib.aci.intf.lacp.stats.main import InterfaceLacpStats +from lib.aci.intf.lacp.api import InterfaceLacpApi +from lib.aci.intf.lacp.info import InterfaceLacpInfo + + +class InterfaceLacp(InterfaceLacpStats, InterfaceLacpApi, InterfaceLacpInfo): + def __init__(self): + InterfaceLacpStats.__init__(self) + InterfaceLacpApi.__init__(self) + InterfaceLacpInfo.__init__(self) diff --git a/lib/aci/intf/lacp/output.py b/lib/aci/intf/lacp/output.py new file mode 100644 index 00000000..ff987573 --- /dev/null +++ b/lib/aci/intf/lacp/output.py @@ -0,0 +1,28 @@ +class InterfaceLacpOutput(): + def __init__(self): + pass + + def print_lacp_instance(self, settings): + order = [ + 'adminSt', + 'adminPrio', + 'operPrio', + 'sysMac' + ] + + headers = [ + 'Admin State', + 'Admin Priority', + 'Oper Priority', + 'Sys MAC' + ] + + self.my_output.dictionary( + settings, + title='LACP Settings', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/intf/lacp/stats/__init__.py b/lib/aci/intf/lacp/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/lacp/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/lacp/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d253d149 Binary files /dev/null and b/lib/aci/intf/lacp/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/stats/__pycache__/api.cpython-310.pyc b/lib/aci/intf/lacp/stats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..551e0f9c Binary files /dev/null and b/lib/aci/intf/lacp/stats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/stats/__pycache__/info.cpython-310.pyc b/lib/aci/intf/lacp/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..3e104135 Binary files /dev/null and b/lib/aci/intf/lacp/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/stats/__pycache__/main.cpython-310.pyc b/lib/aci/intf/lacp/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7d215802 Binary files /dev/null and b/lib/aci/intf/lacp/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/lacp/stats/api.py b/lib/aci/intf/lacp/stats/api.py new file mode 100644 index 00000000..feec945a --- /dev/null +++ b/lib/aci/intf/lacp/stats/api.py @@ -0,0 +1,57 @@ +class InterfaceLacpStatsApi(): + def __init__(self): + self.interface_lacp_stats_mo = {} + + def get_interface_lacp_stats_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_lacp_stats_mo: + return self.interface_lacp_stats_mo[key] + + cache = self.get_object_cache( + 'lacpIfStats', + object_selector=key + ) + if cache is not None: + self.interface_lacp_stats_mo[key] = cache + self.log.apic_mo( + 'lacpIfStats.%s' % (key), + self.interface_lacp_stats_mo[key] + ) + return self.interface_lacp_stats_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lacp/inst' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=lacpIfStats' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_lacp_stats_mo', + 'API failed' + ) + return None + + self.interface_lacp_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_lacp_stats_mo[key].append( + managed_object['lacpIfStats']['attributes'] + ) + + self.log.apic_mo( + 'lacpIfStats.%s' % (key), + self.interface_lacp_stats_mo[key] + ) + + self.set_object_cache( + 'lacpIfStats', + self.interface_lacp_stats_mo[key], + object_selector=key + ) + + return self.interface_lacp_stats_mo[key] diff --git a/lib/aci/intf/lacp/stats/info.py b/lib/aci/intf/lacp/stats/info.py new file mode 100644 index 00000000..36cf75a5 --- /dev/null +++ b/lib/aci/intf/lacp/stats/info.py @@ -0,0 +1,72 @@ +class InterfaceLacpStatsInfo(): + def __init__(self): + self.interface_lacp_stats = {} + + def get_interface_lacp_stats_info(self, managed_object): + keys = [ + 'dn', + 'errPktRcvd', + 'markerRcvd', + 'markerRspRcvd', + 'markerRspSent', + 'markerSent', + 'pduRcvd', + 'pduSent', + 'pduTimeOut' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if int(info['errPktRcvd']) > 0: + info['__Output']['errPktRcvd'] = 'Red' + + if int(info['pduTimeOut']) > 0: + info['__Output']['pduTimeOut'] = 'Red' + + # "dn": "topology/pod-1/node-205/sys/lacp/inst/if-[eth1/27]/ifstats" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = info['dn'].split('if-[')[1].split(']')[0] + + return info + + def get_interfaces_lacp_stats_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_lacp_stats: + return self.interface_lacp_stats[key] + + managed_objects = self.get_interface_lacp_stats_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_lacp_stats[key] = [] + for managed_object in managed_objects: + self.interface_lacp_stats[key].append( + self.get_interface_lacp_stats_info( + managed_object + ) + ) + + return self.interface_lacp_stats[key] + + def get_interface_lacp_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_lacp_stats_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/lacp/stats/main.py b/lib/aci/intf/lacp/stats/main.py new file mode 100644 index 00000000..092e15aa --- /dev/null +++ b/lib/aci/intf/lacp/stats/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.lacp.stats.api import InterfaceLacpStatsApi +from lib.aci.intf.lacp.stats.info import InterfaceLacpStatsInfo + + +class InterfaceLacpStats(InterfaceLacpStatsApi, InterfaceLacpStatsInfo): + def __init__(self): + InterfaceLacpStatsApi.__init__(self) + InterfaceLacpStatsInfo.__init__(self) diff --git a/lib/aci/intf/loopback/__init__.py b/lib/aci/intf/loopback/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/loopback/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/loopback/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b3fb0dc2 Binary files /dev/null and b/lib/aci/intf/loopback/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/loopback/__pycache__/api.cpython-310.pyc b/lib/aci/intf/loopback/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..93e96de0 Binary files /dev/null and b/lib/aci/intf/loopback/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/loopback/__pycache__/info.cpython-310.pyc b/lib/aci/intf/loopback/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..0e671da7 Binary files /dev/null and b/lib/aci/intf/loopback/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/loopback/__pycache__/main.cpython-310.pyc b/lib/aci/intf/loopback/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e72f34d9 Binary files /dev/null and b/lib/aci/intf/loopback/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/loopback/__pycache__/output.cpython-310.pyc b/lib/aci/intf/loopback/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..238c88a4 Binary files /dev/null and b/lib/aci/intf/loopback/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/loopback/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/loopback/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..8ace2ca8 Binary files /dev/null and b/lib/aci/intf/loopback/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/loopback/api.py b/lib/aci/intf/loopback/api.py new file mode 100644 index 00000000..265b59b4 --- /dev/null +++ b/lib/aci/intf/loopback/api.py @@ -0,0 +1,73 @@ +class InterfaceLoopbackApi(): + def __init__(self): + self.interface_lb_mo = {} + + def get_interface_loopback_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_lb_mo: + return self.interface_lb_mo[key] + + cache = self.get_object_cache( + 'l3LbRtdIf', + object_selector=key + ) + if cache is not None: + self.interface_lb_mo[key] = cache + self.log.apic_mo( + 'l3LbRtdIf.%s' % (key), + self.interface_lb_mo[key] + ) + return self.interface_lb_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3LbRtdIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-class=ethpmLbRtdIf&rsp-subtree-include=health,fault-count,required' + + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_loopback_mo', + 'API failed' + ) + return None + + self.interface_lb_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3LbRtdIf']['attributes'] + attributes['ethpmLbRtdIf'] = self.get_mo_child_attributes( + 'l3LbRtdIf', + managed_object, + 'ethpmLbRtdIf' + ) + attributes['healthInst'] = self.get_mo_child_attributes( + 'l3LbRtdIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l3LbRtdIf', + managed_object, + 'faultCounts' + ) + self.interface_lb_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3LbRtdIf.%s' % (key), + self.interface_lb_mo[key] + ) + + self.set_object_cache( + 'l3LbRtdIf', + self.interface_lb_mo[key], + object_selector=key + ) + + return self.interface_lb_mo[key] diff --git a/lib/aci/intf/loopback/audit/__init__.py b/lib/aci/intf/loopback/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/loopback/audit/api.py b/lib/aci/intf/loopback/audit/api.py new file mode 100644 index 00000000..1a767a00 --- /dev/null +++ b/lib/aci/intf/loopback/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceLoopbackAuditApi(): + def __init__(self): + self.interface_loopback_audit_mo = {} + + def get_interface_loopback_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_audit_mo: + return self.interface_loopback_audit_mo[key] + + cache = self.get_object_cache( + 'l3LbRtdIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_loopback_audit_mo[key] = cache + self.log.apic_mo( + 'l3LbRtdIf.audit.%s' % (key), + self.interface_loopback_audit_mo[key] + ) + return self.interface_loopback_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3LbRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_loopback_audit_mo', + 'API failed' + ) + return None + + self.interface_loopback_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_loopback_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3LbRtdIf.audit.%s' % (key), + self.interface_loopback_audit_mo[key] + ) + + self.set_object_cache( + 'l3LbRtdIf.audit', + self.interface_loopback_audit_mo[key], + object_selector=key + ) + + return self.interface_loopback_audit_mo[key] diff --git a/lib/aci/intf/loopback/audit/info.py b/lib/aci/intf/loopback/audit/info.py new file mode 100644 index 00000000..5bce601e --- /dev/null +++ b/lib/aci/intf/loopback/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceLoopbackAuditInfo(): + def __init__(self): + self.interface_loopback_audit = {} + + def get_interface_loopback_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/lb-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/lb-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_loopback_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_audit: + return self.interface_loopback_audit[key] + + managed_objects = self.get_interface_loopback_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_loopback_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_loopback_audit_info( + managed_object + ) + self.interface_loopback_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'l3LbRtdIf.auditRecord.info.%s' % (key), + self.interface_loopback_audit[key] + ) + + return self.interface_loopback_audit[key] + + def get_interface_loopback_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_loopback_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/loopback/audit/main.py b/lib/aci/intf/loopback/audit/main.py new file mode 100644 index 00000000..4252eaea --- /dev/null +++ b/lib/aci/intf/loopback/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.loopback.audit.api import InterfaceLoopbackAuditApi +from lib.aci.intf.loopback.audit.info import InterfaceLoopbackAuditInfo + + +class InterfaceLoopbackAudit(InterfaceLoopbackAuditApi, InterfaceLoopbackAuditInfo): + def __init__(self): + InterfaceLoopbackAuditApi.__init__(self) + InterfaceLoopbackAuditInfo.__init__(self) diff --git a/lib/aci/intf/loopback/event/__init__.py b/lib/aci/intf/loopback/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/loopback/event/api.py b/lib/aci/intf/loopback/event/api.py new file mode 100644 index 00000000..cf0cc42a --- /dev/null +++ b/lib/aci/intf/loopback/event/api.py @@ -0,0 +1,54 @@ +class InterfaceLoopbackEventApi(): + def __init__(self): + self.interface_loopback_event_mo = {} + + def get_interface_loopback_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_event_mo: + return self.interface_loopback_event_mo[key] + + cache = self.get_object_cache( + 'l3LbRtdIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_loopback_event_mo[key] = cache + self.log.apic_mo( + 'l3LbRtdIf.eventLog.%s' % (key), + self.interface_loopback_event_mo[key] + ) + return self.interface_loopback_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3LbRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_loopback_event_mo', + 'API failed' + ) + return None + + self.interface_loopback_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_loopback_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3LbRtdIf.eventLog.%s' % (key), + self.interface_loopback_event_mo[key] + ) + + self.set_object_cache( + 'l3LbRtdIf.eventLog', + self.interface_loopback_event_mo[key], + object_selector=key + ) + + return self.interface_loopback_event_mo[key] diff --git a/lib/aci/intf/loopback/event/info.py b/lib/aci/intf/loopback/event/info.py new file mode 100644 index 00000000..262936ab --- /dev/null +++ b/lib/aci/intf/loopback/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceLoopbackEventInfo(): + def __init__(self): + self.interface_loopback_event = {} + + def get_interface_loopback_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/lb-[lo0]" + info['interfaceId'] = None + if '/lb-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/lb-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_loopback_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_event: + return self.interface_loopback_event[key] + + managed_objects = self.get_interface_loopback_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_loopback_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_loopback_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_loopback_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l3LbRtdIf.eventLog.info.%s' % (key), + self.interface_loopback_event[key] + ) + + return self.interface_loopback_event[key] + + def get_interface_loopback_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_loopback_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/loopback/event/main.py b/lib/aci/intf/loopback/event/main.py new file mode 100644 index 00000000..5a34d2c5 --- /dev/null +++ b/lib/aci/intf/loopback/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.loopback.event.api import InterfaceLoopbackEventApi +from lib.aci.intf.loopback.event.info import InterfaceLoopbackEventInfo + + +class InterfaceLoopbackEvent(InterfaceLoopbackEventApi, InterfaceLoopbackEventInfo): + def __init__(self): + InterfaceLoopbackEventApi.__init__(self) + InterfaceLoopbackEventInfo.__init__(self) diff --git a/lib/aci/intf/loopback/fault/__init__.py b/lib/aci/intf/loopback/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/loopback/fault/api.py b/lib/aci/intf/loopback/fault/api.py new file mode 100644 index 00000000..c354f1af --- /dev/null +++ b/lib/aci/intf/loopback/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceLoopbackFaultApi(): + def __init__(self): + self.interface_loopback_fault_mo = {} + self.interface_loopback_fault_record_mo = {} + + def get_interface_loopback_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_fault_mo: + return self.interface_loopback_fault_mo[key] + + cache = self.get_object_cache( + 'l3LbRtdIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_loopback_fault_mo[key] = cache + self.log.apic_mo( + 'l3LbRtdIf.fault.%s' % (key), + self.interface_loopback_fault_mo[key] + ) + return self.interface_loopback_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3LbRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_loopback_fault_mo', + 'API failed' + ) + return None + + self.interface_loopback_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_loopback_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3LbRtdIf.fault.%s' % (key), + self.interface_loopback_fault_mo[key] + ) + + self.set_object_cache( + 'l3LbRtdIf.fault', + self.interface_loopback_fault_mo[key], + object_selector=key + ) + + return self.interface_loopback_fault_mo[key] + + def get_interface_loopback_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_fault_record_mo: + return self.interface_loopback_fault_record_mo[key] + + cache = self.get_object_cache( + 'l3LbRtdIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_loopback_fault_record_mo[key] = cache + self.log.apic_mo( + 'l3LbRtdIf.faultRecord.%s' % (key), + self.interface_loopback_fault_record_mo[key] + ) + return self.interface_loopback_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/l3LbRtdIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_loopback_fault_record_mo', + 'API failed' + ) + return None + + self.interface_loopback_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_loopback_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l3LbRtdIf.faultRecord.%s' % (key), + self.interface_loopback_fault_record_mo[key] + ) + + self.set_object_cache( + 'l3LbRtdIf.faultRecord', + self.interface_loopback_fault_record_mo[key], + object_selector=key + ) + + return self.interface_loopback_fault_record_mo[key] diff --git a/lib/aci/intf/loopback/fault/info.py b/lib/aci/intf/loopback/fault/info.py new file mode 100644 index 00000000..598508f1 --- /dev/null +++ b/lib/aci/intf/loopback/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceLoopbackFaultInfo(): + def __init__(self): + self.interface_loopback_fault = {} + self.interface_loopback_fault_record = {} + + def get_interface_loopback_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/lb-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/lb-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/lb-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/lb-[lo0]" + if info['interfaceId'] is None: + if '/lb-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/lb-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_loopback_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_fault: + return self.interface_loopback_fault[key] + + managed_objects = self.get_interface_loopback_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_loopback_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_loopback_fault_info( + managed_object + ) + self.interface_loopback_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'l3LbRtdIf.fault.info.%s' % (key), + self.interface_loopback_fault[key] + ) + + return self.interface_loopback_fault[key] + + def get_interface_loopback_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_loopback_fault_record: + return self.interface_loopback_fault_record[key] + + managed_objects = self.get_interface_loopback_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_loopback_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_loopback_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_loopback_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l3LbRtdIf.faultRecord.info.%s' % (key), + self.interface_loopback_fault_record[key] + ) + + return self.interface_loopback_fault_record[key] + + def get_interface_loopback_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_loopback_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_loopback_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/loopback/fault/main.py b/lib/aci/intf/loopback/fault/main.py new file mode 100644 index 00000000..786ebcd9 --- /dev/null +++ b/lib/aci/intf/loopback/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.loopback.fault.api import InterfaceLoopbackFaultApi +from lib.aci.intf.loopback.fault.info import InterfaceLoopbackFaultInfo + + +class InterfaceLoopbackFault(InterfaceLoopbackFaultApi, InterfaceLoopbackFaultInfo): + def __init__(self): + InterfaceLoopbackFaultApi.__init__(self) + InterfaceLoopbackFaultInfo.__init__(self) diff --git a/lib/aci/intf/loopback/info.py b/lib/aci/intf/loopback/info.py new file mode 100644 index 00000000..f4f7cbc2 --- /dev/null +++ b/lib/aci/intf/loopback/info.py @@ -0,0 +1,288 @@ +from lib import filter_helper +from lib import ip_helper + + +class InterfaceLoopbackInfo(): + def __init__(self, log_id=None): + self.interface_lb = {} + + def get_interfaces_loopback_count(self, pod_id, node_id): + interfaces = self.get_interfaces_loopback(pod_id, node_id) + return len(interfaces) + + def get_interface_looback_summary(self, pod_id, node_id): + ports = self.get_interfaces_loopback( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_loopback_info(self, managed_object): + self.log.apic_mo( + 'l3LbRtdIf', + managed_object + ) + + keys = [ + 'adminSt', + 'dn', + 'id', + 'qosPrio', + 'rtdOutDefDn', + 'status', + 'type' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['iod'] = int(info['id'].strip('lo')) + + # Dn format + # topology/pod-1/node-201/sys/inst-overlay-1/lb-[lo0] + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['__Output']['id'] = 'Blue' + + if info['adminSt'] == 'up': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + info['state'] = None + if managed_object['ethpmLbRtdIf'] is not None: + info['state'] = {} + + keys = [ + 'currErrIndex', + 'iod', + 'lastErrors', + 'operSt', + 'operStQual' + ] + + for key in keys: + info['state'][key] = None + if key in managed_object['ethpmLbRtdIf']: + info['state'][key] = managed_object['ethpmLbRtdIf'][key] + + if info['state']['operSt'] == 'up': + info['__Output']['state.operSt'] = 'Green' + if info['state']['operStQual'] == 'none': + info['state']['operStQual'] = '' + else: + info['__Output']['state.operSt'] = 'Red' + + info['up'] = False + if info['adminSt'] == 'up' and info['state']['operSt'] == 'up': + info['up'] = True + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_loopback_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_lb: + return self.interface_lb[key] + + interfaces_mo = self.get_interface_loopback_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_lb[key] = [] + for interface_mo in interfaces_mo: + self.interface_lb[key].append( + self.get_interface_loopback_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'l3LbRtdIf.info.%s' % (key), + self.interface_lb[key] + ) + + return self.interface_lb[key] + + def match_interface_loopback(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'ip': + if 'ipv4' in interface_info: + if interface_info['ipv4'] is None: + return False + + if not filter_helper.match_string('%s/32' % (value), interface_info['ipv4']['addr']): + return False + + if key == 'subnet': + if 'ipv4' in interface_info: + if interface_info['ipv4'] is None: + return False + + if not ip_helper.is_ipv4_in_cidr(interface_info['ipv4']['addr'].split('/')[0], value): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_loopback', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_loopback( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_loopback_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + ipv4_addresses_info = self.get_node_address_ipv4( + pod_id, + node_id + ) + + for interface_info in all_interfaces: + if not self.match_interface_loopback(interface_info, interface_filter): + continue + + interface_info['ipv4'] = None + interface_search_pattern = 'if-[%s]' % (interface_info['id']) + for ipv4_address_info in ipv4_addresses_info: + if interface_search_pattern in ipv4_address_info['dn']: + interface_info['ipv4'] = ipv4_address_info + + if not self.match_interface_loopback(interface_info, interface_filter): + continue + + if fault_info: + interface_info['faultInst'] = self.get_interface_loopback_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_loopback_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_loopback_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_loopback_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['iod'] + ) + + return interfaces + + def get_interface_loopback(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_loopback( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/loopback/main.py b/lib/aci/intf/loopback/main.py new file mode 100644 index 00000000..991cd6a5 --- /dev/null +++ b/lib/aci/intf/loopback/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.loopback.api import InterfaceLoopbackApi +from lib.aci.intf.loopback.info import InterfaceLoopbackInfo +from lib.aci.intf.loopback.audit.main import InterfaceLoopbackAudit +from lib.aci.intf.loopback.event.main import InterfaceLoopbackEvent +from lib.aci.intf.loopback.fault.main import InterfaceLoopbackFault + + +class InterfaceLoopback( + InterfaceLoopbackApi, + InterfaceLoopbackInfo, + InterfaceLoopbackAudit, + InterfaceLoopbackEvent, + InterfaceLoopbackFault + ): + def __init__(self): + InterfaceLoopbackApi.__init__(self) + InterfaceLoopbackInfo.__init__(self) + InterfaceLoopbackAudit.__init__(self) + InterfaceLoopbackEvent.__init__(self) + InterfaceLoopbackFault.__init__(self) diff --git a/lib/aci/intf/loopback/output.py b/lib/aci/intf/loopback/output.py new file mode 100644 index 00000000..62d4115d --- /dev/null +++ b/lib/aci/intf/loopback/output.py @@ -0,0 +1,275 @@ +class InterfaceLoopbackOutput(): + def __init__(self): + pass + + def print_interfaces_loopback_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Loopback - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'adminSt', + 'state.operSt', + 'state.operStQual', + 'ipv4.addr', + 'state.lastErrors', + 'state.currErrIndex' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin State', + 'Oper State', + 'Reason', + 'IPv4 Address', + 'Last Errors', + 'Current Error Index' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_loopback_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Loopback - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Loopback - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_loopback_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Loopback - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_loopback_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Loopback - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Loopback - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_loopback_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Loopback - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Loopback - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/macsec/__init__.py b/lib/aci/intf/macsec/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..88ad9488 Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/api.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..582a72ed Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/ca_stats.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/ca_stats.cpython-310.pyc new file mode 100644 index 00000000..ef6998f3 Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/ca_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/info.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e86d0dbd Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/main.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..81f2b9ee Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/output.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..7df81792 Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/rx.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/rx.cpython-310.pyc new file mode 100644 index 00000000..5d3b32b7 Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/rx.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/stats.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/stats.cpython-310.pyc new file mode 100644 index 00000000..0e5e570c Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/stats.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..6d6e8825 Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/__pycache__/tx.cpython-310.pyc b/lib/aci/intf/macsec/__pycache__/tx.cpython-310.pyc new file mode 100644 index 00000000..01e99bcd Binary files /dev/null and b/lib/aci/intf/macsec/__pycache__/tx.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/api.py b/lib/aci/intf/macsec/api.py new file mode 100644 index 00000000..3e554219 --- /dev/null +++ b/lib/aci/intf/macsec/api.py @@ -0,0 +1,67 @@ +class InterfaceMacSecApi(): + def __init__(self): + self.interface_macsec_mo = {} + + def get_interface_macsec_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_macsec_mo: + return self.interface_macsec_mo[key] + + cache = self.get_object_cache( + 'macsecIf', + object_selector=key + ) + if cache is not None: + self.interface_macsec_mo[key] = cache + self.log.apic_mo( + 'macsecIf.%s' % (key), + self.interface_macsec_mo[key] + ) + return self.interface_macsec_mo[key] + + class_name = 'topology/pod-%s/node-%s/macsecIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_mo', + 'API failed' + ) + return None + + self.interface_macsec_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['macsecIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'macsecIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'macsecIf', + managed_object, + 'faultCounts' + ) + self.interface_macsec_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'macsecIf.%s' % (key), + self.interface_macsec_mo[key] + ) + + self.set_object_cache( + 'macsecIf', + self.interface_macsec_mo[key], + object_selector=key + ) + + return self.interface_macsec_mo[key] diff --git a/lib/aci/intf/macsec/audit/__init__.py b/lib/aci/intf/macsec/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/audit/api.py b/lib/aci/intf/macsec/audit/api.py new file mode 100644 index 00000000..79ec984c --- /dev/null +++ b/lib/aci/intf/macsec/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceMacSecAuditApi(): + def __init__(self): + self.interface_macsec_audit_mo = {} + + def get_interface_macsec_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_audit_mo: + return self.interface_macsec_audit_mo[key] + + cache = self.get_object_cache( + 'macsecIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_macsec_audit_mo[key] = cache + self.log.apic_mo( + 'macsecIf.audit.%s' % (key), + self.interface_macsec_audit_mo[key] + ) + return self.interface_macsec_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/macsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_audit_mo', + 'API failed' + ) + return None + + self.interface_macsec_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_macsec_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'macsecIf.audit.%s' % (key), + self.interface_macsec_audit_mo[key] + ) + + self.set_object_cache( + 'macsecIf.audit', + self.interface_macsec_audit_mo[key], + object_selector=key + ) + + return self.interface_macsec_audit_mo[key] diff --git a/lib/aci/intf/macsec/audit/info.py b/lib/aci/intf/macsec/audit/info.py new file mode 100644 index 00000000..6ab1eb55 --- /dev/null +++ b/lib/aci/intf/macsec/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceMacSecAuditInfo(): + def __init__(self): + self.interface_macsec_audit = {} + + def get_interface_macsec_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/macsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/macsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_macsec_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_audit: + return self.interface_macsec_audit[key] + + managed_objects = self.get_interface_macsec_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_macsec_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_macsec_audit_info( + managed_object + ) + self.interface_macsec_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'macsecIf.auditRecord.info.%s' % (key), + self.interface_macsec_audit[key] + ) + + return self.interface_macsec_audit[key] + + def get_interface_macsec_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_macsec_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/macsec/audit/main.py b/lib/aci/intf/macsec/audit/main.py new file mode 100644 index 00000000..1a6ab055 --- /dev/null +++ b/lib/aci/intf/macsec/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.audit.api import InterfaceMacSecAuditApi +from lib.aci.intf.macsec.audit.info import InterfaceMacSecAuditInfo + + +class InterfaceMacSecAudit(InterfaceMacSecAuditApi, InterfaceMacSecAuditInfo): + def __init__(self): + InterfaceMacSecAuditApi.__init__(self) + InterfaceMacSecAuditInfo.__init__(self) diff --git a/lib/aci/intf/macsec/castats/__init__.py b/lib/aci/intf/macsec/castats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/castats/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/macsec/castats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e95cf45b Binary files /dev/null and b/lib/aci/intf/macsec/castats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/castats/__pycache__/api.cpython-310.pyc b/lib/aci/intf/macsec/castats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..eb61dda1 Binary files /dev/null and b/lib/aci/intf/macsec/castats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/castats/__pycache__/info.cpython-310.pyc b/lib/aci/intf/macsec/castats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..eec6b529 Binary files /dev/null and b/lib/aci/intf/macsec/castats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/castats/__pycache__/main.cpython-310.pyc b/lib/aci/intf/macsec/castats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..87b22be9 Binary files /dev/null and b/lib/aci/intf/macsec/castats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/castats/api.py b/lib/aci/intf/macsec/castats/api.py new file mode 100644 index 00000000..195c6a5d --- /dev/null +++ b/lib/aci/intf/macsec/castats/api.py @@ -0,0 +1,62 @@ +class InterfaceMacSecCaStatsApi(): + def __init__(self): + self.interface_macsec_castats_mo = {} + + def get_interface_macsec_castats_mo(self, pod_id, node_id, interface_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + interface_id + ) + if key in self.interface_macsec_castats_mo: + return self.interface_macsec_castats_mo[key] + + cache = self.get_object_cache( + 'macsecCAStats', + object_selector=key + ) + if cache is not None: + self.interface_macsec_castats_mo[key] = cache + self.log.apic_mo( + 'macsecCAStats.%s' % (key), + self.interface_macsec_castats_mo[key] + ) + return self.interface_macsec_castats_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/macsec/inst/if-[%s]' % ( + pod_id, + node_id, + interface_id + ) + query = 'query-target=children&target-subtree-class=macsecCAStats' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_castats_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] == '0': + self.interface_macsec_castats_mo[key] = [] + return self.interface_macsec_castats_mo[key] + + self.interface_macsec_castats_mo[key] = managed_objects['imdata'][0]['macsecCAStats']['attributes'] + + self.log.apic_mo( + 'macsecCAStats.%s' % (key), + self.interface_macsec_castats_mo[key] + ) + + self.set_object_cache( + 'macsecCAStats', + self.interface_macsec_castats_mo[key], + object_selector=key + ) + + return self.interface_macsec_castats_mo[key] diff --git a/lib/aci/intf/macsec/castats/info.py b/lib/aci/intf/macsec/castats/info.py new file mode 100644 index 00000000..c03fdaac --- /dev/null +++ b/lib/aci/intf/macsec/castats/info.py @@ -0,0 +1,36 @@ +class InterfaceMacSecCaStatsInfo(): + def __init__(self): + pass + + def get_interface_macsec_castats_info(self, managed_object): + keys = [ + 'dn', + 'ickDervFail', + 'invalidPeerCpbl', + 'kRekeys', + 'kekDervFail', + 'mkpduRx', + 'mkpduRxDistSak', + 'mkpduTx', + 'mkpduTxDistSak', + 'sakRespRx', + 'saksGen', + 'saksRekeyed', + 'saksRx' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info + + def get_interface_macsec_castats(self, pod_id, node_id, interface_id): + managed_object = self.get_interface_macsec_castats_mo(pod_id, node_id, interface_id) + if managed_object is None: + return None + + return self.get_interface_macsec_castats_info(managed_object) diff --git a/lib/aci/intf/macsec/castats/main.py b/lib/aci/intf/macsec/castats/main.py new file mode 100644 index 00000000..30875b49 --- /dev/null +++ b/lib/aci/intf/macsec/castats/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.castats.api import InterfaceMacSecCaStatsApi +from lib.aci.intf.macsec.castats.info import InterfaceMacSecCaStatsInfo + + +class InterfaceMacSecCaStats(InterfaceMacSecCaStatsApi, InterfaceMacSecCaStatsInfo): + def __init__(self): + InterfaceMacSecCaStatsApi.__init__(self) + InterfaceMacSecCaStatsInfo.__init__(self) diff --git a/lib/aci/intf/macsec/event/__init__.py b/lib/aci/intf/macsec/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/event/api.py b/lib/aci/intf/macsec/event/api.py new file mode 100644 index 00000000..851b637c --- /dev/null +++ b/lib/aci/intf/macsec/event/api.py @@ -0,0 +1,54 @@ +class InterfaceMacSecEventApi(): + def __init__(self): + self.interface_macsec_event_mo = {} + + def get_interface_macsec_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_event_mo: + return self.interface_macsec_event_mo[key] + + cache = self.get_object_cache( + 'macsecIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_macsec_event_mo[key] = cache + self.log.apic_mo( + 'macsecIf.eventLog.%s' % (key), + self.interface_macsec_event_mo[key] + ) + return self.interface_macsec_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/macsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_event_mo', + 'API failed' + ) + return None + + self.interface_macsec_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_macsec_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'macsecIf.eventLog.%s' % (key), + self.interface_macsec_event_mo[key] + ) + + self.set_object_cache( + 'macsecIf.eventLog', + self.interface_macsec_event_mo[key], + object_selector=key + ) + + return self.interface_macsec_event_mo[key] diff --git a/lib/aci/intf/macsec/event/info.py b/lib/aci/intf/macsec/event/info.py new file mode 100644 index 00000000..a43eaeac --- /dev/null +++ b/lib/aci/intf/macsec/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceMacSecEventInfo(): + def __init__(self): + self.interface_macsec_event = {} + + def get_interface_macsec_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/macsec-[lo0]" + info['interfaceId'] = None + if '/macsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/macsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_macsec_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_event: + return self.interface_macsec_event[key] + + managed_objects = self.get_interface_macsec_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_macsec_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_macsec_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_macsec_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'macsecIf.eventLog.info.%s' % (key), + self.interface_macsec_event[key] + ) + + return self.interface_macsec_event[key] + + def get_interface_macsec_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_macsec_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/macsec/event/main.py b/lib/aci/intf/macsec/event/main.py new file mode 100644 index 00000000..c6cf5ec7 --- /dev/null +++ b/lib/aci/intf/macsec/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.event.api import InterfaceMacSecEventApi +from lib.aci.intf.macsec.event.info import InterfaceMacSecEventInfo + + +class InterfaceMacSecEvent(InterfaceMacSecEventApi, InterfaceMacSecEventInfo): + def __init__(self): + InterfaceMacSecEventApi.__init__(self) + InterfaceMacSecEventInfo.__init__(self) diff --git a/lib/aci/intf/macsec/fault/__init__.py b/lib/aci/intf/macsec/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/fault/api.py b/lib/aci/intf/macsec/fault/api.py new file mode 100644 index 00000000..5a713b39 --- /dev/null +++ b/lib/aci/intf/macsec/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceMacSecFaultApi(): + def __init__(self): + self.interface_macsec_fault_mo = {} + self.interface_macsec_fault_record_mo = {} + + def get_interface_macsec_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_fault_mo: + return self.interface_macsec_fault_mo[key] + + cache = self.get_object_cache( + 'macsecIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_macsec_fault_mo[key] = cache + self.log.apic_mo( + 'macsecIf.fault.%s' % (key), + self.interface_macsec_fault_mo[key] + ) + return self.interface_macsec_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/macsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_fault_mo', + 'API failed' + ) + return None + + self.interface_macsec_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_macsec_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'macsecIf.fault.%s' % (key), + self.interface_macsec_fault_mo[key] + ) + + self.set_object_cache( + 'macsecIf.fault', + self.interface_macsec_fault_mo[key], + object_selector=key + ) + + return self.interface_macsec_fault_mo[key] + + def get_interface_macsec_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_fault_record_mo: + return self.interface_macsec_fault_record_mo[key] + + cache = self.get_object_cache( + 'macsecIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_macsec_fault_record_mo[key] = cache + self.log.apic_mo( + 'macsecIf.faultRecord.%s' % (key), + self.interface_macsec_fault_record_mo[key] + ) + return self.interface_macsec_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/macsecIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_fault_record_mo', + 'API failed' + ) + return None + + self.interface_macsec_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_macsec_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'macsecIf.faultRecord.%s' % (key), + self.interface_macsec_fault_record_mo[key] + ) + + self.set_object_cache( + 'macsecIf.faultRecord', + self.interface_macsec_fault_record_mo[key], + object_selector=key + ) + + return self.interface_macsec_fault_record_mo[key] diff --git a/lib/aci/intf/macsec/fault/info.py b/lib/aci/intf/macsec/fault/info.py new file mode 100644 index 00000000..c18621aa --- /dev/null +++ b/lib/aci/intf/macsec/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceMacSecFaultInfo(): + def __init__(self): + self.interface_macsec_fault = {} + self.interface_macsec_fault_record = {} + + def get_interface_macsec_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/macsec-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/macsec-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/macsec-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/macsec-[lo0]" + if info['interfaceId'] is None: + if '/macsec-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/macsec-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_macsec_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_fault: + return self.interface_macsec_fault[key] + + managed_objects = self.get_interface_macsec_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_macsec_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_macsec_fault_info( + managed_object + ) + self.interface_macsec_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'macsecIf.fault.info.%s' % (key), + self.interface_macsec_fault[key] + ) + + return self.interface_macsec_fault[key] + + def get_interface_macsec_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec_fault_record: + return self.interface_macsec_fault_record[key] + + managed_objects = self.get_interface_macsec_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_macsec_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_macsec_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_macsec_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'macsecIf.faultRecord.info.%s' % (key), + self.interface_macsec_fault_record[key] + ) + + return self.interface_macsec_fault_record[key] + + def get_interface_macsec_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_macsec_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_macsec_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/macsec/fault/main.py b/lib/aci/intf/macsec/fault/main.py new file mode 100644 index 00000000..d27f973a --- /dev/null +++ b/lib/aci/intf/macsec/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.fault.api import InterfaceMacSecFaultApi +from lib.aci.intf.macsec.fault.info import InterfaceMacSecFaultInfo + + +class InterfaceMacSecFault(InterfaceMacSecFaultApi, InterfaceMacSecFaultInfo): + def __init__(self): + InterfaceMacSecFaultApi.__init__(self) + InterfaceMacSecFaultInfo.__init__(self) diff --git a/lib/aci/intf/macsec/info.py b/lib/aci/intf/macsec/info.py new file mode 100644 index 00000000..64e48e4f --- /dev/null +++ b/lib/aci/intf/macsec/info.py @@ -0,0 +1,307 @@ +from lib import filter_helper + + +class InterfaceMacSecInfo(): + def __init__(self): + self.interface_macsec = {} + + def get_interface_macsec_summary(self, pod_id, node_id): + ports = self.get_interfaces_macsec( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_macsec_count(self, pod_id, node_id): + interfaces = self.get_interfaces_macsec(pod_id, node_id) + return len(interfaces) + + def get_interface_macsec_info(self, managed_object): + keys = [ + 'adminSt', + 'cipherSuite', + 'cipherSuiteOper', + 'confOffset', + 'confOffsetOper', + 'dn', + 'id', + 'keyChain', + 'keySvrPrio', + 'lastSakKeyTime', + 'mkaNegSt', + 'name', + 'operSt', + 'operStQual', + 'peerCount', + 'portId', + 'replayWindow', + 'sakExpiryTime', + 'sakStatus', + 'secPolicy', + 'sessOperSt', + 'srvStatusFlags', + 'txSCI', + 'txSSCI', + 'vlanTagCtrl' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['iod'] = int(info['id'].split('/')[1]) + + # Dn format + # topology/pod-1/node-201/sys/macsec/inst/if-[eth1/97] + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['__Output']['id'] = 'Blue' + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + if info['adminSt'] == 'enabled' and info['operSt'] == 'up': + info['up'] = True + else: + info['up'] = False + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_macsec_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_macsec: + return self.interface_macsec[key] + + interfaces_mo = self.get_interface_macsec_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_macsec[key] = [] + for interface_mo in interfaces_mo: + self.interface_macsec[key].append( + self.get_interface_macsec_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'macsecIf.info.%s' % (key), + self.interface_macsec[key] + ) + + return self.interface_macsec[key] + + def match_interface_macsec(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'admin': + if value != 'any': + if not filter_helper.match_string(value, interface_info['adminSt']): + return False + + if key == 'oper': + if value != 'any': + if not filter_helper.match_string(value, interface_info['operSt']): + return False + + if key == 'type': + if 'portT' in interface_info: + if value != 'any': + if not filter_helper.match_string(value, interface_info['portT']): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_macsec', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_macsec( + self, + pod_id, + node_id, + interface_filter=None, + stats_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_macsec_info(pod_id, node_id) + if all_interfaces is None: + return None + + phy_ports = self.get_interfaces_phy( + pod_id, + node_id + ) + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_macsec(interface_info, interface_filter): + continue + + for phy_port in phy_ports: + if interface_info['id'] == phy_port['id']: + interface_info['portT'] = phy_port['portT'] + + if not self.match_interface_macsec(interface_info, interface_filter): + continue + + if stats_info: + interface_info['tx'] = self.get_interface_macsec_tx( + pod_id, + node_id, + interface_info['id'] + ) + + interface_info['rx'] = self.get_interface_macsec_rx( + pod_id, + node_id, + interface_info['id'] + ) + + interface_info['stats'] = self.get_interface_macsec_stats( + pod_id, + node_id, + interface_info['id'] + ) + + interface_info['castats'] = self.get_interface_macsec_castats( + pod_id, + node_id, + interface_info['id'] + ) + + if fault_info: + interface_info['faultInst'] = self.get_interface_macsec_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_macsec_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_macsec_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_macsec_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['iod'] + ) + + return interfaces + + def get_interface_macsec(self, pod_id, node_id, port_id, stats_info=False): + interfaces = self.get_interfaces_macsec( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)], + stats_info=stats_info + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/macsec/main.py b/lib/aci/intf/macsec/main.py new file mode 100644 index 00000000..8e718ed2 --- /dev/null +++ b/lib/aci/intf/macsec/main.py @@ -0,0 +1,32 @@ +from lib.aci.intf.macsec.tx.main import InterfaceMacSecTx +from lib.aci.intf.macsec.rx.main import InterfaceMacSecRx +from lib.aci.intf.macsec.stats.main import InterfaceMacSecStats +from lib.aci.intf.macsec.castats.main import InterfaceMacSecCaStats +from lib.aci.intf.macsec.api import InterfaceMacSecApi +from lib.aci.intf.macsec.info import InterfaceMacSecInfo +from lib.aci.intf.macsec.audit.main import InterfaceMacSecAudit +from lib.aci.intf.macsec.event.main import InterfaceMacSecEvent +from lib.aci.intf.macsec.fault.main import InterfaceMacSecFault + + +class InterfaceMacSec( + InterfaceMacSecTx, + InterfaceMacSecRx, + InterfaceMacSecStats, + InterfaceMacSecCaStats, + InterfaceMacSecApi, + InterfaceMacSecInfo, + InterfaceMacSecAudit, + InterfaceMacSecEvent, + InterfaceMacSecFault + ): + def __init__(self): + InterfaceMacSecRx.__init__(self) + InterfaceMacSecTx.__init__(self) + InterfaceMacSecStats.__init__(self) + InterfaceMacSecCaStats.__init__(self) + InterfaceMacSecApi.__init__(self) + InterfaceMacSecInfo.__init__(self) + InterfaceMacSecAudit.__init__(self) + InterfaceMacSecEvent.__init__(self) + InterfaceMacSecFault.__init__(self) diff --git a/lib/aci/intf/macsec/output.py b/lib/aci/intf/macsec/output.py new file mode 100644 index 00000000..89199051 --- /dev/null +++ b/lib/aci/intf/macsec/output.py @@ -0,0 +1,422 @@ +class InterfaceMacSecOutput(): + def __init__(self): + pass + + def print_interfaces_macsec_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface MacSec - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'adminSt', + 'operSt', + 'operStQual', + 'sessOperSt', + 'peerCount', + 'cipherSuiteOper', + 'confOffsetOper', + 'keyChain', + 'keySvrPrio', + 'replayWindow' + + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Oper', + 'Reason', + 'Session', + 'Peers', + 'Cepher Suite', + 'Confid Offset', + 'Key Chain', + 'Ker Server Prio', + 'Replay Window' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_macsec_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface MacSec - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface MacSec - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_macsec_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface MacSec - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_macsec_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface MacSec - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface MacSec - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_macsec_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface MacSec - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface MacSec - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_macsec_verbose(self, interface): + order = [ + 'id', + 'adminSt', + 'operSt', + 'operStQual', + 'sessOperSt', + 'peerCount', + 'cipherSuiteOper', + 'confOffsetOper', + 'keyChain', + 'keySvrPrio', + 'replayWindow' + + ] + + headers = [ + 'Interface', + 'Admin State', + 'Oper State', + 'Reason', + 'Session State', + 'Peers', + 'Cepher Suite', + 'Confid Offset', + 'Key Chain', + 'Ker Server Prio', + 'Replay Window' + ] + + self.my_output.dictionary( + interface, + title='Interface Macsec', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + order = [ + 'castats.kRekeys', + 'castats.mkpduRx', + 'castats.mkpduRxDistSak', + 'castats.mkpduTx', + 'castats.mkpduTxDistSak', + 'castats.sakRespRx', + 'castats.saksGen', + 'castats.saksRekeyed', + 'castats.saksRx', + 'stats.rxSakANNotInUse', + 'stats.mkpduNoRxIfDn', + 'stats.mkpduNoTxIfDn', + 'stats.mkpduRxCANotFnd', + 'stats.mkpduRxErr', + 'stats.mkpduRxSucc', + 'stats.mkpduTxPktBldFail', + 'stats.mkpduTxSucc' + ] + + headers = [ + 'Key Rekeys', + 'MKPDUs Validated/Received', + 'MKPDUs Received/Distributed Secure Association Key', + 'MKPDUs Transmitted', + 'MKPDUs Transmitted/Distributed Secure Association Key', + 'Secure Association Key Responses Received', + 'Secure Association Keys Generated', + 'Secure Association Keys Rekeyed', + 'Secure Association Keys Received', + 'MKPDUs Rx Drop Secure Association Key Use', + 'MKPDUs No Rx on Interface Down', + 'MKPDUs No Tx on Interface Down', + 'MKPDUs Rx Connectivity Association not found', + 'MKPDUs Rx Error', + 'MKPDUs Rx Success', + 'MKPDUs Tx Packet Build Fail', + 'MKPDUs Tx Success' + ] + + self.my_output.dictionary( + interface, + title='MKA Stats', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + order = [ + 'rx.OkPkts', + 'rx.decryptedOctets', + 'rx.decryptedPkts', + 'rx.delayedPkts', + 'rx.invalidatedOctets', + 'rx.invalidatedPkts', + 'rx.invalidPkts', + 'rx.latePkts', + 'rx.notUsingSAPkts', + 'rx.notValidPkts', + 'rx.uncheckedPkts', + 'rx.unusedSAPkts', + 'tx.encryptedOctets', + 'tx.encryptedPkts', + 'tx.protectedOctets', + 'tx.protectedPkts' + ] + + headers = [ + 'OK Packets', + 'Rx Decrypted Octets', + 'Rx Decrypted Packets', + 'Delayed Packets', + 'Invalidated Octets', + 'Invalidated Packets', + 'Invalid Packets', + 'Late Packets', + 'Not Using SA Packets', + 'Not Valid Packets', + 'Unchecked Packets', + 'Unused SA Packets', + 'Tx Encrypted Octets', + 'Tx Encrypted Packets', + 'Tx Protected Octets', + 'Tx Protected Packets' + ] + + self.my_output.dictionary( + interface, + title='SecY Stats', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/intf/macsec/rx/__init__.py b/lib/aci/intf/macsec/rx/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/rx/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/macsec/rx/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..bf6bc3b7 Binary files /dev/null and b/lib/aci/intf/macsec/rx/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/rx/__pycache__/api.cpython-310.pyc b/lib/aci/intf/macsec/rx/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4bc01354 Binary files /dev/null and b/lib/aci/intf/macsec/rx/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/rx/__pycache__/info.cpython-310.pyc b/lib/aci/intf/macsec/rx/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..96a34bfe Binary files /dev/null and b/lib/aci/intf/macsec/rx/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/rx/__pycache__/main.cpython-310.pyc b/lib/aci/intf/macsec/rx/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7e6e7bb7 Binary files /dev/null and b/lib/aci/intf/macsec/rx/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/rx/api.py b/lib/aci/intf/macsec/rx/api.py new file mode 100644 index 00000000..53e994ab --- /dev/null +++ b/lib/aci/intf/macsec/rx/api.py @@ -0,0 +1,63 @@ +class InterfaceMacSecRxApi(): + def __init__(self): + self.interface_macsec_rx_mo = {} + + def get_interface_macsec_rx_mo(self, pod_id, node_id, interface_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + interface_id + ) + if key in self.interface_macsec_rx_mo: + return self.interface_macsec_rx_mo[key] + + cache = self.get_object_cache( + 'dbgIfMacsecrx', + object_selector=key + ) + if cache is not None: + self.interface_macsec_rx_mo[key] = cache + self.log.apic_mo( + 'dbgIfMacsecrx.%s' % (key), + self.interface_macsec_rx_mo[key] + ) + return self.interface_macsec_rx_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/phys-[%s]/dbgIfMacsecrx' % ( + pod_id, + node_id, + interface_id + ) + + managed_objects = self.get_managed_object( + distinguished_name + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_rx_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_interface_macsec_rx_mo', + 'Unexpected object count' + ) + return None + + self.interface_macsec_rx_mo[key] = managed_objects['imdata'][0]['rmonIfMacsecrx']['attributes'] + + self.log.apic_mo( + 'dbgIfMacsecrx.%s' % (key), + self.interface_macsec_rx_mo[key] + ) + + self.set_object_cache( + 'dbgIfMacsecrx', + self.interface_macsec_rx_mo[key], + object_selector=key + ) + + return self.interface_macsec_rx_mo[key] diff --git a/lib/aci/intf/macsec/rx/info.py b/lib/aci/intf/macsec/rx/info.py new file mode 100644 index 00000000..29c8f32c --- /dev/null +++ b/lib/aci/intf/macsec/rx/info.py @@ -0,0 +1,36 @@ +class InterfaceMacSecRxInfo(): + def __init__(self): + pass + + def get_interface_macsec_rx_info(self, managed_object): + keys = [ + 'OkPkts', + 'decryptedOctets', + 'decryptedPkts', + 'delayedPkts', + 'dn', + 'invalidPkts', + 'invalidatedOctets', + 'invalidatedPkts', + 'latePkts', + 'notUsingSAPkts', + 'notValidPkts', + 'uncheckedPkts', + 'unusedSAPkts' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info + + def get_interface_macsec_rx(self, pod_id, node_id, interface_id): + managed_object = self.get_interface_macsec_rx_mo(pod_id, node_id, interface_id) + if managed_object is None: + return None + + return self.get_interface_macsec_rx_info(managed_object) diff --git a/lib/aci/intf/macsec/rx/main.py b/lib/aci/intf/macsec/rx/main.py new file mode 100644 index 00000000..9a1cdf1b --- /dev/null +++ b/lib/aci/intf/macsec/rx/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.rx.api import InterfaceMacSecRxApi +from lib.aci.intf.macsec.rx.info import InterfaceMacSecRxInfo + + +class InterfaceMacSecRx(InterfaceMacSecRxApi, InterfaceMacSecRxInfo): + def __init__(self): + InterfaceMacSecRxApi.__init__(self) + InterfaceMacSecRxInfo.__init__(self) diff --git a/lib/aci/intf/macsec/stats/__init__.py b/lib/aci/intf/macsec/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/macsec/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3cd5db8e Binary files /dev/null and b/lib/aci/intf/macsec/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/stats/__pycache__/api.cpython-310.pyc b/lib/aci/intf/macsec/stats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..f808fa03 Binary files /dev/null and b/lib/aci/intf/macsec/stats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/stats/__pycache__/info.cpython-310.pyc b/lib/aci/intf/macsec/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..cb088582 Binary files /dev/null and b/lib/aci/intf/macsec/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/stats/__pycache__/main.cpython-310.pyc b/lib/aci/intf/macsec/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9add6d85 Binary files /dev/null and b/lib/aci/intf/macsec/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/stats/api.py b/lib/aci/intf/macsec/stats/api.py new file mode 100644 index 00000000..42961a8e --- /dev/null +++ b/lib/aci/intf/macsec/stats/api.py @@ -0,0 +1,67 @@ +class InterfaceMacSecStatsApi(): + def __init__(self): + self.interface_macsec_stats_mo = {} + + def get_interface_macsec_stats_mo(self, pod_id, node_id, interface_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + interface_id + ) + if key in self.interface_macsec_stats_mo: + return self.interface_macsec_stats_mo[key] + + cache = self.get_object_cache( + 'macsecIfStats', + object_selector=key + ) + if cache is not None: + self.interface_macsec_stats_mo[key] = cache + self.log.apic_mo( + 'macsecIfStats.%s' % (key), + self.interface_macsec_stats_mo[key] + ) + return self.interface_macsec_stats_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/macsec/inst/if-[%s]' % ( + pod_id, + node_id, + interface_id + ) + query = 'query-target=children&target-subtree-class=macsecIfStats' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_stats_mo', + 'API failed' + ) + return None + + self.log.apic_mo( + 'macsecIfStats.%s' % (key), + managed_objects + ) + + if managed_objects['totalCount'] == '0': + self.interface_macsec_stats_mo[key] = [] + return self.interface_macsec_stats_mo[key] + + self.interface_macsec_stats_mo[key] = managed_objects['imdata'][0]['macsecIfStats']['attributes'] + + self.log.apic_mo( + 'macsecIfStats.%s' % (key), + self.interface_macsec_stats_mo[key] + ) + + self.set_object_cache( + 'macsecIfStats', + self.interface_macsec_stats_mo[key], + object_selector=key + ) + + return self.interface_macsec_stats_mo[key] diff --git a/lib/aci/intf/macsec/stats/info.py b/lib/aci/intf/macsec/stats/info.py new file mode 100644 index 00000000..625c8877 --- /dev/null +++ b/lib/aci/intf/macsec/stats/info.py @@ -0,0 +1,47 @@ +class InterfaceMacSecStatsInfo(): + def __init__(self): + pass + + def get_interface_macsec_stats_info(self, managed_object): + keys = [ + 'dn', + 'invalidMkpduRx', + 'macsecRxSaInstallFail', + 'macsecTxSaInstallFail', + 'mkpduEtherMismatch', + 'mkpduNoRxIfDn', + 'mkpduNoTxIfDn', + 'mkpduRxBadPeerMN', + 'mkpduRxCANotFnd', + 'mkpduRxErr', + 'mkpduRxNRPListMN', + 'mkpduRxSucc', + 'mkpduTxFail', + 'mkpduTxPktBldFail', + 'mkpduTxSucc', + 'rxSakANNotInUse', + 'rxSakKNMismatch', + 'rxSakKeyMIMismatch', + 'rxSakKsRxTxNotSet', + 'rxSakRxNotSet', + 'sakDecryptFail', + 'sakEncryptFail', + 'sakGenFail', + 'sakHashKeyGenFail' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info + + def get_interface_macsec_stats(self, pod_id, node_id, interface_id): + managed_object = self.get_interface_macsec_stats_mo(pod_id, node_id, interface_id) + if managed_object is None: + return None + + return self.get_interface_macsec_stats_info(managed_object) diff --git a/lib/aci/intf/macsec/stats/main.py b/lib/aci/intf/macsec/stats/main.py new file mode 100644 index 00000000..170387f1 --- /dev/null +++ b/lib/aci/intf/macsec/stats/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.stats.api import InterfaceMacSecStatsApi +from lib.aci.intf.macsec.stats.info import InterfaceMacSecStatsInfo + + +class InterfaceMacSecStats(InterfaceMacSecStatsApi, InterfaceMacSecStatsInfo): + def __init__(self): + InterfaceMacSecStatsApi.__init__(self) + InterfaceMacSecStatsInfo.__init__(self) diff --git a/lib/aci/intf/macsec/tx/__init__.py b/lib/aci/intf/macsec/tx/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/macsec/tx/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/macsec/tx/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1baefc3f Binary files /dev/null and b/lib/aci/intf/macsec/tx/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/tx/__pycache__/api.cpython-310.pyc b/lib/aci/intf/macsec/tx/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5a5417cf Binary files /dev/null and b/lib/aci/intf/macsec/tx/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/tx/__pycache__/info.cpython-310.pyc b/lib/aci/intf/macsec/tx/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ae52eecc Binary files /dev/null and b/lib/aci/intf/macsec/tx/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/tx/__pycache__/main.cpython-310.pyc b/lib/aci/intf/macsec/tx/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..55adda9c Binary files /dev/null and b/lib/aci/intf/macsec/tx/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/macsec/tx/api.py b/lib/aci/intf/macsec/tx/api.py new file mode 100644 index 00000000..b1d6a485 --- /dev/null +++ b/lib/aci/intf/macsec/tx/api.py @@ -0,0 +1,63 @@ +class InterfaceMacSecTxApi(): + def __init__(self): + self.interface_macsec_tx_mo = {} + + def get_interface_macsec_tx_mo(self, pod_id, node_id, interface_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + interface_id + ) + if key in self.interface_macsec_tx_mo: + return self.interface_macsec_tx_mo[key] + + cache = self.get_object_cache( + 'dbgIfMacsectx', + object_selector=key + ) + if cache is not None: + self.interface_macsec_tx_mo[key] = cache + self.log.apic_mo( + 'dbgIfMacsectx.%s' % (key), + self.interface_macsec_tx_mo[key] + ) + return self.interface_macsec_tx_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/phys-[%s]/dbgIfMacsectx' % ( + pod_id, + node_id, + interface_id + ) + + managed_objects = self.get_managed_object( + distinguished_name + ) + + if managed_objects is None: + self.log.error( + 'get_interface_macsec_tx_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_interface_macsec_tx_mo', + 'Unexpected object count' + ) + return None + + self.interface_macsec_tx_mo[key] = managed_objects['imdata'][0]['rmonIfMacsectx']['attributes'] + + self.log.apic_mo( + 'dbgIfMacsectx.%s' % (key), + self.interface_macsec_tx_mo[key] + ) + + self.set_object_cache( + 'dbgIfMacsectx', + self.interface_macsec_tx_mo[key], + object_selector=key + ) + + return self.interface_macsec_tx_mo[key] diff --git a/lib/aci/intf/macsec/tx/info.py b/lib/aci/intf/macsec/tx/info.py new file mode 100644 index 00000000..5cad5503 --- /dev/null +++ b/lib/aci/intf/macsec/tx/info.py @@ -0,0 +1,28 @@ +class InterfaceMacSecTxInfo(): + def __init__(self): + pass + + def get_interface_macsec_tx_info(self, managed_object): + keys = [ + 'dn', + 'encryptedOctets', + 'encryptedPkts', + 'protectedOctets', + 'protectedPkts' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info + + def get_interface_macsec_tx(self, pod_id, node_id, interface_id): + managed_object = self.get_interface_macsec_tx_mo(pod_id, node_id, interface_id) + if managed_object is None: + return None + + return self.get_interface_macsec_tx_info(managed_object) diff --git a/lib/aci/intf/macsec/tx/main.py b/lib/aci/intf/macsec/tx/main.py new file mode 100644 index 00000000..8278a8fa --- /dev/null +++ b/lib/aci/intf/macsec/tx/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.macsec.tx.api import InterfaceMacSecTxApi +from lib.aci.intf.macsec.tx.info import InterfaceMacSecTxInfo + + +class InterfaceMacSecTx(InterfaceMacSecTxApi, InterfaceMacSecTxInfo): + def __init__(self): + InterfaceMacSecTxApi.__init__(self) + InterfaceMacSecTxInfo.__init__(self) diff --git a/lib/aci/intf/main.py b/lib/aci/intf/main.py new file mode 100644 index 00000000..6cd3b789 --- /dev/null +++ b/lib/aci/intf/main.py @@ -0,0 +1,62 @@ +from lib.aci.intf.adjacency.main import InterfaceAdjacency +from lib.aci.intf.cloudsec.main import InterfaceCloudSec +from lib.aci.intf.encapsulated_routed.main import InterfaceEncapsulatedRouted +from lib.aci.intf.fc.main import InterfaceFc +from lib.aci.intf.fcpc.main import InterfaceFcPc +from lib.aci.intf.ip.main import InterfaceIp +from lib.aci.intf.lacp.main import InterfaceLacp +from lib.aci.intf.loopback.main import InterfaceLoopback +from lib.aci.intf.macsec.main import InterfaceMacSec +from lib.aci.intf.management.main import InterfaceMgmt +from lib.aci.intf.phy.main import InterfacePhy +from lib.aci.intf.policy.main import InterfacePolicy +from lib.aci.intf.port_channel.main import InterfacePortChannel +from lib.aci.intf.summary.main import InterfaceSummary +from lib.aci.intf.svi.main import InterfaceSvi +from lib.aci.intf.tunnel.main import InterfaceTunnel +from lib.aci.intf.vfc.main import InterfaceVfc +from lib.aci.intf.virtual_port_channel.main import InterfaceVirtualPortChannel +from lib.aci.intf.vlan.main import InterfaceVlanStats + + +class Interface( + InterfaceAdjacency, + InterfaceCloudSec, + InterfaceEncapsulatedRouted, + InterfaceFc, + InterfaceFcPc, + InterfaceIp, + InterfaceLacp, + InterfaceLoopback, + InterfaceMacSec, + InterfaceMgmt, + InterfacePhy, + InterfacePolicy, + InterfacePortChannel, + InterfaceVirtualPortChannel, + InterfaceSummary, + InterfaceSvi, + InterfaceTunnel, + InterfaceVfc, + InterfaceVlanStats + ): + def __init__(self): + InterfaceAdjacency.__init__(self) + InterfaceCloudSec.__init__(self) + InterfaceEncapsulatedRouted.__init__(self) + InterfaceFc.__init__(self) + InterfaceFcPc.__init__(self) + InterfaceIp.__init__(self) + InterfaceLacp.__init__(self) + InterfaceLoopback.__init__(self) + InterfaceMacSec.__init__(self) + InterfaceMgmt.__init__(self) + InterfacePhy.__init__(self) + InterfacePolicy.__init__(self) + InterfacePortChannel.__init__(self) + InterfaceVirtualPortChannel.__init__(self) + InterfaceSummary.__init__(self) + InterfaceSvi.__init__(self) + InterfaceTunnel.__init__(self) + InterfaceVfc.__init__(self) + InterfaceVlanStats.__init__(self) diff --git a/lib/aci/intf/management/__init__.py b/lib/aci/intf/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/management/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/management/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..964e55df Binary files /dev/null and b/lib/aci/intf/management/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/api.cpython-310.pyc b/lib/aci/intf/management/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..300e5b80 Binary files /dev/null and b/lib/aci/intf/management/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/info.cpython-310.pyc b/lib/aci/intf/management/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ef21669d Binary files /dev/null and b/lib/aci/intf/management/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/main.cpython-310.pyc b/lib/aci/intf/management/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f5436359 Binary files /dev/null and b/lib/aci/intf/management/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/output.cpython-310.pyc b/lib/aci/intf/management/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..b19c6160 Binary files /dev/null and b/lib/aci/intf/management/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/state.cpython-310.pyc b/lib/aci/intf/management/__pycache__/state.cpython-310.pyc new file mode 100644 index 00000000..a11a4926 Binary files /dev/null and b/lib/aci/intf/management/__pycache__/state.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/stats.cpython-310.pyc b/lib/aci/intf/management/__pycache__/stats.cpython-310.pyc new file mode 100644 index 00000000..3798e60a Binary files /dev/null and b/lib/aci/intf/management/__pycache__/stats.cpython-310.pyc differ diff --git a/lib/aci/intf/management/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/management/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..72ba510d Binary files /dev/null and b/lib/aci/intf/management/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/management/api.py b/lib/aci/intf/management/api.py new file mode 100644 index 00000000..5bc826c7 --- /dev/null +++ b/lib/aci/intf/management/api.py @@ -0,0 +1,67 @@ +class InterfaceMgmtApi(): + def __init__(self): + self.interface_mgmt_mo = {} + + def get_interface_management_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_mgmt_mo: + return self.interface_mgmt_mo[key] + + cache = self.get_object_cache( + 'mgmtMgmtIf', + object_selector=key + ) + if cache is not None: + self.interface_mgmt_mo[key] = cache + self.log.apic_mo( + 'mgmtMgmtIf.%s' % (key), + self.interface_mgmt_mo[key] + ) + return self.interface_mgmt_mo[key] + + class_name = 'topology/pod-%s/node-%s/mgmtMgmtIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_mo', + 'API failed' + ) + return None + + self.interface_mgmt_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['mgmtMgmtIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'mgmtMgmtIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'mgmtMgmtIf', + managed_object, + 'faultCounts' + ) + self.interface_mgmt_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'mgmtMgmtIf.%s' % (key), + self.interface_mgmt_mo[key] + ) + + self.set_object_cache( + 'mgmtMgmtIf', + self.interface_mgmt_mo[key], + object_selector=key + ) + + return self.interface_mgmt_mo[key] diff --git a/lib/aci/intf/management/audit/__init__.py b/lib/aci/intf/management/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/management/audit/api.py b/lib/aci/intf/management/audit/api.py new file mode 100644 index 00000000..8a4e7aa5 --- /dev/null +++ b/lib/aci/intf/management/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceMgmtAuditApi(): + def __init__(self): + self.interface_management_audit_mo = {} + + def get_interface_management_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_audit_mo: + return self.interface_management_audit_mo[key] + + cache = self.get_object_cache( + 'mgmtMgmtIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_management_audit_mo[key] = cache + self.log.apic_mo( + 'mgmtMgmtIf.audit.%s' % (key), + self.interface_management_audit_mo[key] + ) + return self.interface_management_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/mgmtMgmtIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_audit_mo', + 'API failed' + ) + return None + + self.interface_management_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_management_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'mgmtMgmtIf.audit.%s' % (key), + self.interface_management_audit_mo[key] + ) + + self.set_object_cache( + 'mgmtMgmtIf.audit', + self.interface_management_audit_mo[key], + object_selector=key + ) + + return self.interface_management_audit_mo[key] diff --git a/lib/aci/intf/management/audit/info.py b/lib/aci/intf/management/audit/info.py new file mode 100644 index 00000000..0b0ec230 --- /dev/null +++ b/lib/aci/intf/management/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceMgmtAuditInfo(): + def __init__(self): + self.interface_management_audit = {} + + def get_interface_management_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/mgmt-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/mgmt-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_management_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_audit: + return self.interface_management_audit[key] + + managed_objects = self.get_interface_management_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_management_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_management_audit_info( + managed_object + ) + self.interface_management_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'mgmtMgmtIf.auditRecord.info.%s' % (key), + self.interface_management_audit[key] + ) + + return self.interface_management_audit[key] + + def get_interface_management_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_management_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/management/audit/main.py b/lib/aci/intf/management/audit/main.py new file mode 100644 index 00000000..d4c491cf --- /dev/null +++ b/lib/aci/intf/management/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.management.audit.api import InterfaceMgmtAuditApi +from lib.aci.intf.management.audit.info import InterfaceMgmtAuditInfo + + +class InterfaceMgmtAudit(InterfaceMgmtAuditApi, InterfaceMgmtAuditInfo): + def __init__(self): + InterfaceMgmtAuditApi.__init__(self) + InterfaceMgmtAuditInfo.__init__(self) diff --git a/lib/aci/intf/management/event/__init__.py b/lib/aci/intf/management/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/management/event/api.py b/lib/aci/intf/management/event/api.py new file mode 100644 index 00000000..60022fb7 --- /dev/null +++ b/lib/aci/intf/management/event/api.py @@ -0,0 +1,54 @@ +class InterfaceManagementEventApi(): + def __init__(self): + self.interface_management_event_mo = {} + + def get_interface_management_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_event_mo: + return self.interface_management_event_mo[key] + + cache = self.get_object_cache( + 'mgmtMgmtIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_management_event_mo[key] = cache + self.log.apic_mo( + 'mgmtMgmtIf.eventLog.%s' % (key), + self.interface_management_event_mo[key] + ) + return self.interface_management_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/mgmtMgmtIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_event_mo', + 'API failed' + ) + return None + + self.interface_management_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_management_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'mgmtMgmtIf.eventLog.%s' % (key), + self.interface_management_event_mo[key] + ) + + self.set_object_cache( + 'mgmtMgmtIf.eventLog', + self.interface_management_event_mo[key], + object_selector=key + ) + + return self.interface_management_event_mo[key] diff --git a/lib/aci/intf/management/event/info.py b/lib/aci/intf/management/event/info.py new file mode 100644 index 00000000..9006b4f3 --- /dev/null +++ b/lib/aci/intf/management/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceManagementEventInfo(): + def __init__(self): + self.interface_management_event = {} + + def get_interface_management_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/mgmt-[mgmt0]/mgmt" + info['interfaceId'] = None + if '/mgmt-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/mgmt-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_management_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_event: + return self.interface_management_event[key] + + managed_objects = self.get_interface_management_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_management_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_management_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_management_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'mgmtMgmtIf.eventLog.info.%s' % (key), + self.interface_management_event[key] + ) + + return self.interface_management_event[key] + + def get_interface_management_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_management_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/management/event/main.py b/lib/aci/intf/management/event/main.py new file mode 100644 index 00000000..65884d3d --- /dev/null +++ b/lib/aci/intf/management/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.management.event.api import InterfaceManagementEventApi +from lib.aci.intf.management.event.info import InterfaceManagementEventInfo + + +class InterfaceManagementEvent(InterfaceManagementEventApi, InterfaceManagementEventInfo): + def __init__(self): + InterfaceManagementEventApi.__init__(self) + InterfaceManagementEventInfo.__init__(self) diff --git a/lib/aci/intf/management/fault/__init__.py b/lib/aci/intf/management/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/management/fault/api.py b/lib/aci/intf/management/fault/api.py new file mode 100644 index 00000000..d88e1f3a --- /dev/null +++ b/lib/aci/intf/management/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceManagementFaultApi(): + def __init__(self): + self.interface_management_fault_mo = {} + self.interface_management_fault_record_mo = {} + + def get_interface_management_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_fault_mo: + return self.interface_management_fault_mo[key] + + cache = self.get_object_cache( + 'mgmtMgmtIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_management_fault_mo[key] = cache + self.log.apic_mo( + 'mgmtMgmtIf.fault.%s' % (key), + self.interface_management_fault_mo[key] + ) + return self.interface_management_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/mgmtMgmtIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_fault_mo', + 'API failed' + ) + return None + + self.interface_management_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_management_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'mgmtMgmtIf.fault.%s' % (key), + self.interface_management_fault_mo[key] + ) + + self.set_object_cache( + 'mgmtMgmtIf.fault', + self.interface_management_fault_mo[key], + object_selector=key + ) + + return self.interface_management_fault_mo[key] + + def get_interface_management_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_fault_record_mo: + return self.interface_management_fault_record_mo[key] + + cache = self.get_object_cache( + 'mgmtMgmtIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_management_fault_record_mo[key] = cache + self.log.apic_mo( + 'mgmtMgmtIf.faultRecord.%s' % (key), + self.interface_management_fault_record_mo[key] + ) + return self.interface_management_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/mgmtMgmtIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_fault_record_mo', + 'API failed' + ) + return None + + self.interface_management_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_management_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'mgmtMgmtIf.faultRecord.%s' % (key), + self.interface_management_fault_record_mo[key] + ) + + self.set_object_cache( + 'mgmtMgmtIf.faultRecord', + self.interface_management_fault_record_mo[key], + object_selector=key + ) + + return self.interface_management_fault_record_mo[key] diff --git a/lib/aci/intf/management/fault/info.py b/lib/aci/intf/management/fault/info.py new file mode 100644 index 00000000..44273e31 --- /dev/null +++ b/lib/aci/intf/management/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceManagementFaultInfo(): + def __init__(self): + self.interface_management_fault = {} + self.interface_management_fault_record = {} + + def get_interface_management_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/mgmt-[mgmt0]/mgmt" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/mgmt-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/mgmt-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/mgmt-[mgmt0]/mgmt" + if info['interfaceId'] is None: + if '/mgmt-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/mgmt-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_management_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_fault: + return self.interface_management_fault[key] + + managed_objects = self.get_interface_management_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_management_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_management_fault_info( + managed_object + ) + self.interface_management_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'mgmtMgmtIf.fault.info.%s' % (key), + self.interface_management_fault[key] + ) + + return self.interface_management_fault[key] + + def get_interface_management_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_management_fault_record: + return self.interface_management_fault_record[key] + + managed_objects = self.get_interface_management_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_management_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_management_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_management_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'mgmtMgmtIf.faultRecord.info.%s' % (key), + self.interface_management_fault_record[key] + ) + + return self.interface_management_fault_record[key] + + def get_interface_management_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_management_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_management_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/management/fault/main.py b/lib/aci/intf/management/fault/main.py new file mode 100644 index 00000000..97c3ff02 --- /dev/null +++ b/lib/aci/intf/management/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.management.fault.api import InterfaceManagementFaultApi +from lib.aci.intf.management.fault.info import InterfaceManagementFaultInfo + + +class InterfaceManagementFault(InterfaceManagementFaultApi, InterfaceManagementFaultInfo): + def __init__(self): + InterfaceManagementFaultApi.__init__(self) + InterfaceManagementFaultInfo.__init__(self) diff --git a/lib/aci/intf/management/info.py b/lib/aci/intf/management/info.py new file mode 100644 index 00000000..eec58fab --- /dev/null +++ b/lib/aci/intf/management/info.py @@ -0,0 +1,265 @@ +from lib import filter_helper + + +class InterfaceMgmtInfo(): + def __init__(self): + self.interface_mgmt = {} + + def get_interface_management_count(self, pod_id, node_id): + interfaces = self.get_interface_management(pod_id, node_id) + return len(interfaces) + + def get_interface_management_summary(self, pod_id, node_id): + ports = self.get_interface_management( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_management_info(self, managed_object): + keys = [ + 'adminSt', + 'autoNeg', + 'dn', + 'fcotChannelNumber', + 'id', + 'mtu', + 'name', + 'snmpTrapSt', + 'speed', + 'status', + 'switchingSt' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # [0]: topology/pod-{id}/node-{id}/sys/mgmt-[{id}] + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + if info['adminSt'] == 'up': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['switchingSt'] == 'enabled': + info['__Output']['switchingSt'] = 'Green' + else: + info['__Output']['switchingSt'] = 'Red' + + info['up'] = False + if info['adminSt'] == 'up': + info['up'] = True + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_management_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_mgmt: + return self.interface_mgmt[key] + + interfaces_mgmt_mo = self.get_interface_management_mo(pod_id, node_id) + if interfaces_mgmt_mo is None: + return None + + self.interface_mgmt[key] = [] + for interface_mgmt_mo in interfaces_mgmt_mo: + self.interface_mgmt[key].append( + self.get_interface_management_info( + interface_mgmt_mo + ) + ) + + self.log.apic_mo( + 'intfMgmt.info.%s' % (key), + self.interface_mgmt[key] + ) + + return self.interface_mgmt[key] + + def match_interface_management(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + # if key == 'admin': + # if value != 'any': + # if not filter_helper.match_string(value, interface_info['adminSt']): + # return False + + # if key == 'oper': + # if value != 'any': + # if not filter_helper.match_string(value, interface_info['state']['operSt']): + # return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_management', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interface_management( + self, + pod_id, + node_id, + interface_filter=None, + state_info=False, + stats_info=False, + cdp_info=False, + lldp_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + interfaces = self.get_interfaces_management_info(pod_id, node_id) + if interfaces is None: + return None + + for interface_info in interfaces: + if not self.match_interface_management(interface_info, interface_filter): + continue + + if state_info: + interface_info['state'] = self.get_interface_management_state( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if cdp_info: + interface_info['cdp'] = self.get_cdp_adjacency_endpoint( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'], + allow_multiple=False + ) + + if lldp_info: + interface_info['lldp'] = self.get_lldp_adjacency_endpoint( + interface_info['podId'], + interface_info['nodeId'], + adjacency_filter=['interface_id:%s' % (interface_info['id'])], + allow_multiple=False + ) + + if stats_info: + interface_info['counters'] = self.get_interface_fault_counts( + interface_info['podId'], + interface_info['nodeId'], + 'mgmt', + interface_info['id'] + ) + + interface_info['stats'] = self.get_interface_management_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if fault_info: + interface_info['faultInst'] = self.get_interface_management_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_management_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_management_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_management_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interface_info = self.my_output.merge_output( + interface_info + ) + + return interfaces diff --git a/lib/aci/intf/management/main.py b/lib/aci/intf/management/main.py new file mode 100644 index 00000000..036d9be4 --- /dev/null +++ b/lib/aci/intf/management/main.py @@ -0,0 +1,29 @@ +from lib.aci.intf.fault_counts.main import InterfaceFaultCounts +from lib.aci.intf.management.state.main import InterfaceManagementState +from lib.aci.intf.management.stats.main import InterfaceManagementStats +from lib.aci.intf.management.api import InterfaceMgmtApi +from lib.aci.intf.management.info import InterfaceMgmtInfo +from lib.aci.intf.management.audit.main import InterfaceMgmtAudit +from lib.aci.intf.management.event.main import InterfaceManagementEvent +from lib.aci.intf.management.fault.main import InterfaceManagementFault + + +class InterfaceMgmt( + InterfaceFaultCounts, + InterfaceManagementState, + InterfaceManagementStats, + InterfaceMgmtApi, + InterfaceMgmtInfo, + InterfaceMgmtAudit, + InterfaceManagementEvent, + InterfaceManagementFault + ): + def __init__(self): + InterfaceFaultCounts.__init__(self) + InterfaceManagementState.__init__(self) + InterfaceManagementStats.__init__(self) + InterfaceMgmtApi.__init__(self) + InterfaceMgmtInfo.__init__(self) + InterfaceMgmtAudit.__init__(self) + InterfaceManagementEvent.__init__(self) + InterfaceManagementFault.__init__(self) diff --git a/lib/aci/intf/management/output.py b/lib/aci/intf/management/output.py new file mode 100644 index 00000000..35f85331 --- /dev/null +++ b/lib/aci/intf/management/output.py @@ -0,0 +1,387 @@ +class InterfaceMgmtOutput(): + def __init__(self): + pass + + def print_interfaces_management_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Management - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'adminSt', + 'switchingSt', + 'state.operSt', + 'autoNeg', + 'state.operDuplex', + 'state.operMtu', + 'state.operSpeed', + 'state.lastLinkStChg' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Switching', + 'Oper', + 'Auto Negotiation', + 'Duplex', + 'MTU', + 'Speed', + 'Last Link State Change' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interfaces_management_address(self, info, title=False): + if title: + self.my_output.default( + 'Interface Management - Address [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'adminSt', + 'state.operSt', + 'state.backplaneMac', + 'stats.addr', + 'state.operRouterMac' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Admin', + 'Oper', + 'MAC Address', + 'IP Address', + 'Router MAC' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interfaces_management_neighbor(self, info, title=False): + if title: + self.my_output.default( + 'Interface Management - CDP/LLDP Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'adminSt', + 'state.operSt', + 'cdp.platId', + 'cdp.sysName', + 'cdp.portId', + 'lldp.sysName', + 'lldp.portIdV' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Admin', + 'Oper', + 'CDP - Platform', + 'CDP - System Name', + 'CDP - Port', + 'LLDP - System Name', + 'LLDP - Port' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interface_management_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Management - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Management - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_management_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Management - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_management_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Management - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Management - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_management_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Management - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Management - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/management/state/__init__.py b/lib/aci/intf/management/state/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/management/state/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/management/state/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7bd70d19 Binary files /dev/null and b/lib/aci/intf/management/state/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/management/state/__pycache__/api.cpython-310.pyc b/lib/aci/intf/management/state/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3a5242d1 Binary files /dev/null and b/lib/aci/intf/management/state/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/management/state/__pycache__/info.cpython-310.pyc b/lib/aci/intf/management/state/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..78f15f08 Binary files /dev/null and b/lib/aci/intf/management/state/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/management/state/__pycache__/main.cpython-310.pyc b/lib/aci/intf/management/state/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..39bb8d4e Binary files /dev/null and b/lib/aci/intf/management/state/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/management/state/api.py b/lib/aci/intf/management/state/api.py new file mode 100644 index 00000000..56d32df1 --- /dev/null +++ b/lib/aci/intf/management/state/api.py @@ -0,0 +1,60 @@ +class InterfaceManagementStateApi(): + def __init__(self): + self.interface_mgmt_state_mo = {} + + def get_interface_management_state_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_mgmt_state_mo: + return self.interface_mgmt_state_mo[key] + + cache = self.get_object_cache( + 'imMgmtIf', + object_selector=key + ) + if cache is not None: + self.interface_mgmt_state_mo[key] = cache + self.log.apic_mo( + 'imMgmtIf.%s' % (key), + self.interface_mgmt_state_mo[key] + ) + return self.interface_mgmt_state_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=imMgmtIf' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_state_mo', + 'API failed' + ) + return None + + self.interface_mgmt_state_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_mgmt_state_mo[key].append( + managed_object['imMgmtIf']['attributes'] + ) + + self.log.apic_mo( + 'imMgmtIf.%s' % (key), + self.interface_mgmt_state_mo[key] + ) + + self.set_object_cache( + 'imMgmtIf', + self.interface_mgmt_state_mo[key], + object_selector=key + ) + + return self.interface_mgmt_state_mo[key] diff --git a/lib/aci/intf/management/state/info.py b/lib/aci/intf/management/state/info.py new file mode 100644 index 00000000..2b204457 --- /dev/null +++ b/lib/aci/intf/management/state/info.py @@ -0,0 +1,72 @@ +class InterfaceManagementStateInfo(): + def __init__(self, log_id=None): + self.interface_management_state = {} + + def get_interface_management_state_info(self, managed_object): + keys = [ + 'backplaneMac', + 'dn', + 'lastLinkStChg', + 'operDuplex', + 'operMtu', + 'operRouterMac', + 'operSpeed', + 'operSt', + 'operStQual', + 'vdcId' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + # "dn": "topology/pod-1/node-205/sys/mgmt-[mgmt0]/mgmt", + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = info['dn'].split('mgmt-[')[1].split(']')[0] + + return info + + def get_interfaces_management_state_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_management_state: + return self.interface_management_state[key] + + managed_objects = self.get_interface_management_state_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_management_state[key] = [] + for managed_object in managed_objects: + self.interface_management_state[key].append( + self.get_interface_management_state_info( + managed_object + ) + ) + + return self.interface_management_state[key] + + def get_interface_management_state(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_management_state_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/management/state/main.py b/lib/aci/intf/management/state/main.py new file mode 100644 index 00000000..d58b28f0 --- /dev/null +++ b/lib/aci/intf/management/state/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.management.state.api import InterfaceManagementStateApi +from lib.aci.intf.management.state.info import InterfaceManagementStateInfo + + +class InterfaceManagementState(InterfaceManagementStateApi, InterfaceManagementStateInfo): + def __init__(self): + InterfaceManagementStateApi.__init__(self) + InterfaceManagementStateInfo.__init__(self) diff --git a/lib/aci/intf/management/stats/__init__.py b/lib/aci/intf/management/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/management/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/management/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..42006237 Binary files /dev/null and b/lib/aci/intf/management/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/management/stats/__pycache__/api.cpython-310.pyc b/lib/aci/intf/management/stats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..1cf9c048 Binary files /dev/null and b/lib/aci/intf/management/stats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/management/stats/__pycache__/info.cpython-310.pyc b/lib/aci/intf/management/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..c3f3405f Binary files /dev/null and b/lib/aci/intf/management/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/management/stats/__pycache__/main.cpython-310.pyc b/lib/aci/intf/management/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ee605b87 Binary files /dev/null and b/lib/aci/intf/management/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/management/stats/api.py b/lib/aci/intf/management/stats/api.py new file mode 100644 index 00000000..0d03bff4 --- /dev/null +++ b/lib/aci/intf/management/stats/api.py @@ -0,0 +1,60 @@ +class InterfaceManagementStatsApi(): + def __init__(self): + self.interface_mgmt_stats_mo = {} + + def get_interface_management_stats_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_mgmt_stats_mo: + return self.interface_mgmt_stats_mo[key] + + cache = self.get_object_cache( + 'mgmtIfStats', + object_selector=key + ) + if cache is not None: + self.interface_mgmt_stats_mo[key] = cache + self.log.apic_mo( + 'mgmtIfStats.%s' % (key), + self.interface_mgmt_stats_mo[key] + ) + return self.interface_mgmt_stats_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv4/inst/dom-management' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=ipv4Addr' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_management_stats_mo', + 'API failed' + ) + return None + + self.interface_mgmt_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_mgmt_stats_mo[key].append( + managed_object['ipv4Addr']['attributes'] + ) + + self.log.apic_mo( + 'mgmtIfStats.%s' % (key), + self.interface_mgmt_stats_mo[key] + ) + + self.set_object_cache( + 'mgmtIfStats', + self.interface_mgmt_stats_mo[key], + object_selector=key + ) + + return self.interface_mgmt_stats_mo[key] diff --git a/lib/aci/intf/management/stats/info.py b/lib/aci/intf/management/stats/info.py new file mode 100644 index 00000000..36e4676e --- /dev/null +++ b/lib/aci/intf/management/stats/info.py @@ -0,0 +1,73 @@ +class InterfaceManagementStatsInfo(): + def __init__(self): + self.interface_management_stats = {} + + def get_interface_management_stats_info(self, managed_object): + keys = [ + 'addr', + 'dn', + 'ipv4CfgFailedBmp', + 'ipv4CfgFailedTs', + 'ipv4CfgState', + 'operSt', + 'operStQual', + 'pref', + 'type', + 'vpcPeer' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + if info['operStQual'] == 'up': + info['operStQual'] = 'link-up-connected' + else: + info['__Output']['operSt'] = 'Red' + + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = info['dn'].split('if-[')[1].split(']')[0] + + return info + + def get_interfaces_management_stats_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_management_stats: + return self.interface_management_stats[key] + + managed_objects = self.get_interface_management_stats_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_management_stats[key] = [] + for managed_object in managed_objects: + self.interface_management_stats[key].append( + self.get_interface_management_stats_info( + managed_object + ) + ) + + return self.interface_management_stats[key] + + def get_interface_management_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_management_stats_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/management/stats/main.py b/lib/aci/intf/management/stats/main.py new file mode 100644 index 00000000..5ebf8315 --- /dev/null +++ b/lib/aci/intf/management/stats/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.management.stats.api import InterfaceManagementStatsApi +from lib.aci.intf.management.stats.info import InterfaceManagementStatsInfo + + +class InterfaceManagementStats(InterfaceManagementStatsApi, InterfaceManagementStatsInfo): + def __init__(self): + InterfaceManagementStatsApi.__init__(self) + InterfaceManagementStatsInfo.__init__(self) diff --git a/lib/aci/intf/output.py b/lib/aci/intf/output.py new file mode 100644 index 00000000..fe07e71b --- /dev/null +++ b/lib/aci/intf/output.py @@ -0,0 +1,56 @@ +from lib.aci.intf.adjacency.output import InterfaceAdjecencyOutput +from lib.aci.intf.cloudsec.output import InterfaceCloudSecOutput +from lib.aci.intf.encapsulated_routed.output import InterfaceEncapsulatedRoutedOutput +from lib.aci.intf.fc.output import InterfaceFcOutput +from lib.aci.intf.fcpc.output import InterfaceFcPcOutput +from lib.aci.intf.lacp.output import InterfaceLacpOutput +from lib.aci.intf.loopback.output import InterfaceLoopbackOutput +from lib.aci.intf.macsec.output import InterfaceMacSecOutput +from lib.aci.intf.management.output import InterfaceMgmtOutput +from lib.aci.intf.phy.output import InterfacePhyOutput +from lib.aci.intf.port_channel.output import InterfacePortChannelOutput +from lib.aci.intf.summary.output import InterfaceSummaryOutput +from lib.aci.intf.svi.output import InterfaceSviOutput +from lib.aci.intf.tunnel.output import InterfaceTunnelOutput +from lib.aci.intf.vfc.output import InterfaceVfcOutput +from lib.aci.intf.virtual_port_channel.output import InterfaceVirtualPortChannelOutput +from lib.aci.intf.vlan.output import InterfaceVlanStatsOutput + + +class InterfaceOutput( + InterfaceAdjecencyOutput, + InterfaceCloudSecOutput, + InterfaceEncapsulatedRoutedOutput, + InterfaceFcOutput, + InterfaceFcPcOutput, + InterfaceLacpOutput, + InterfaceLoopbackOutput, + InterfaceMacSecOutput, + InterfaceMgmtOutput, + InterfacePhyOutput, + InterfacePortChannelOutput, + InterfaceSummaryOutput, + InterfaceSviOutput, + InterfaceTunnelOutput, + InterfaceVfcOutput, + InterfaceVirtualPortChannelOutput, + InterfaceVlanStatsOutput + ): + def __init__(self): + InterfaceAdjecencyOutput.__init__(self) + InterfaceCloudSecOutput.__init__(self) + InterfaceEncapsulatedRoutedOutput.__init__(self) + InterfaceFcOutput.__init__(self) + InterfaceFcPcOutput.__init__(self) + InterfaceLacpOutput.__init__(self) + InterfaceLoopbackOutput.__init__(self) + InterfaceMacSecOutput.__init__(self) + InterfaceMgmtOutput.__init__(self) + InterfacePhyOutput.__init__(self) + InterfacePortChannelOutput.__init__(self) + InterfaceSummaryOutput.__init__(self) + InterfaceSviOutput.__init__(self) + InterfaceTunnelOutput.__init__(self) + InterfaceVfcOutput.__init__(self) + InterfaceVirtualPortChannelOutput.__init__(self) + InterfaceVlanStatsOutput.__init__(self) diff --git a/lib/aci/intf/phy/__init__.py b/lib/aci/intf/phy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c63ad8f6 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8dc6b56f Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/capability.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/capability.cpython-310.pyc new file mode 100644 index 00000000..16488c52 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/capability.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/eee.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/eee.cpython-310.pyc new file mode 100644 index 00000000..12504507 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/eee.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/epg_stats.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/epg_stats.cpython-310.pyc new file mode 100644 index 00000000..d13baa1a Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/epg_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/ether_stats.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/ether_stats.cpython-310.pyc new file mode 100644 index 00000000..305d08bf Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/ether_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/fc_stats.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/fc_stats.cpython-310.pyc new file mode 100644 index 00000000..6bd76a77 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/fc_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..06cd9a42 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/load_interval.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/load_interval.cpython-310.pyc new file mode 100644 index 00000000..3c528bdc Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/load_interval.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7dba83f4 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/output.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..0f131560 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/pc.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/pc.cpython-310.pyc new file mode 100644 index 00000000..732dec67 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/pc.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/qos_stats.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/qos_stats.cpython-310.pyc new file mode 100644 index 00000000..709b300c Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/qos_stats.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/stats.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/stats.cpython-310.pyc new file mode 100644 index 00000000..d0e79750 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/stats.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/phy/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..8c96ebd3 Binary files /dev/null and b/lib/aci/intf/phy/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/api.py b/lib/aci/intf/phy/api.py new file mode 100644 index 00000000..15b5933a --- /dev/null +++ b/lib/aci/intf/phy/api.py @@ -0,0 +1,67 @@ +class InterfacePhyApi(): + def __init__(self): + self.interface_phy_mo = {} + + def get_interface_phy_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_mo: + return self.interface_phy_mo[key] + + cache = self.get_object_cache( + 'l1PhysIf', + object_selector=key + ) + if cache is not None: + self.interface_phy_mo[key] = cache + self.log.apic_mo( + 'l1PhysIf.%s' % (key), + self.interface_phy_mo[key] + ) + return self.interface_phy_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1PhysIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_mo', + 'API failed' + ) + return None + + self.interface_phy_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l1PhysIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'l1PhysIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l1PhysIf', + managed_object, + 'faultCounts' + ) + self.interface_phy_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1PhysIf.%s' % (key), + self.interface_phy_mo[key] + ) + + self.set_object_cache( + 'l1PhysIf', + self.interface_phy_mo[key], + object_selector=key + ) + + return self.interface_phy_mo[key] diff --git a/lib/aci/intf/phy/audit/__init__.py b/lib/aci/intf/phy/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/audit/api.py b/lib/aci/intf/phy/audit/api.py new file mode 100644 index 00000000..031d570f --- /dev/null +++ b/lib/aci/intf/phy/audit/api.py @@ -0,0 +1,54 @@ +class InterfacePhyAuditApi(): + def __init__(self): + self.interface_phy_audit_mo = {} + + def get_interface_phy_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_audit_mo: + return self.interface_phy_audit_mo[key] + + cache = self.get_object_cache( + 'l1PhysIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_phy_audit_mo[key] = cache + self.log.apic_mo( + 'l1PhysIf.audit.%s' % (key), + self.interface_phy_audit_mo[key] + ) + return self.interface_phy_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1PhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_audit_mo', + 'API failed' + ) + return None + + self.interface_phy_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_phy_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1PhysIf.audit.%s' % (key), + self.interface_phy_audit_mo[key] + ) + + self.set_object_cache( + 'l1PhysIf.audit', + self.interface_phy_audit_mo[key], + object_selector=key + ) + + return self.interface_phy_audit_mo[key] diff --git a/lib/aci/intf/phy/audit/info.py b/lib/aci/intf/phy/audit/info.py new file mode 100644 index 00000000..2f53653c --- /dev/null +++ b/lib/aci/intf/phy/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfacePhyAuditInfo(): + def __init__(self): + self.interface_phy_audit = {} + + def get_interface_phy_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/phys-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/phys-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_phy_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_audit: + return self.interface_phy_audit[key] + + managed_objects = self.get_interface_phy_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_phy_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_phy_audit_info( + managed_object + ) + self.interface_phy_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'l1PhysIf.auditRecord.info.%s' % (key), + self.interface_phy_audit[key] + ) + + return self.interface_phy_audit[key] + + def get_interface_phy_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_phy_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/phy/audit/main.py b/lib/aci/intf/phy/audit/main.py new file mode 100644 index 00000000..6ebe43ad --- /dev/null +++ b/lib/aci/intf/phy/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.audit.api import InterfacePhyAuditApi +from lib.aci.intf.phy.audit.info import InterfacePhyAuditInfo + + +class InterfacePhyAudit(InterfacePhyAuditApi, InterfacePhyAuditInfo): + def __init__(self): + InterfacePhyAuditApi.__init__(self) + InterfacePhyAuditInfo.__init__(self) diff --git a/lib/aci/intf/phy/cap/__init__.py b/lib/aci/intf/phy/cap/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/cap/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/cap/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..018de61e Binary files /dev/null and b/lib/aci/intf/phy/cap/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/cap/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/cap/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..80d9f83b Binary files /dev/null and b/lib/aci/intf/phy/cap/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/cap/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/cap/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..8a3c0470 Binary files /dev/null and b/lib/aci/intf/phy/cap/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/cap/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/cap/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b243a533 Binary files /dev/null and b/lib/aci/intf/phy/cap/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/cap/api.py b/lib/aci/intf/phy/cap/api.py new file mode 100644 index 00000000..d013d3be --- /dev/null +++ b/lib/aci/intf/phy/cap/api.py @@ -0,0 +1,60 @@ +class InterfacePhyCapApi(): + def __init__(self): + self.interface_phy_cap_mo = {} + + def get_interface_phy_cap_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_cap_mo: + return self.interface_phy_cap_mo[key] + + cache = self.get_object_cache( + 'ethpmPortCap', + object_selector=key + ) + if cache is not None: + self.interface_phy_cap_mo[key] = cache + self.log.apic_mo( + 'ethpmPortCap.%s' % (key), + self.interface_phy_cap_mo[key] + ) + return self.interface_phy_cap_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=ethpmPortCap' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_cap_mo', + 'API failed' + ) + return None + + self.interface_phy_cap_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_cap_mo[key].append( + managed_object['ethpmPortCap']['attributes'] + ) + + self.log.apic_mo( + 'ethpmPortCap.%s' % (key), + self.interface_phy_cap_mo[key] + ) + + self.set_object_cache( + 'ethpmPortCap', + self.interface_phy_cap_mo[key], + object_selector=key + ) + + return self.interface_phy_cap_mo[key] diff --git a/lib/aci/intf/phy/cap/info.py b/lib/aci/intf/phy/cap/info.py new file mode 100644 index 00000000..1ef3ada5 --- /dev/null +++ b/lib/aci/intf/phy/cap/info.py @@ -0,0 +1,70 @@ +class InterfacePhyCapInfo(): + def __init__(self): + self.interface_phy_cap = {} + + def get_interface_phy_cap_info(self, managed_object): + keys = [ + 'dn', + 'mdix', + 'speed' + ] + + info = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/phys-[eth1/33]/phys/portcap" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = None + if 'phys-[' in info['dn']: + info['interface_id'] = info['dn'].split('phys-[')[1].split(']')[0] + + if 'aggr-[' in info['dn']: + info['interface_id'] = info['dn'].split('aggr-[')[1].split(']')[0] + + if info['interface_id'] is None: + self.log.error( + 'get_interface_phy_cap_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return info + + def get_interfaces_phy_cap_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_cap: + return self.interface_phy_cap[key] + + managed_objects = self.get_interface_phy_cap_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_phy_cap[key] = [] + for managed_object in managed_objects: + self.interface_phy_cap[key].append( + self.get_interface_phy_cap_info( + managed_object + ) + ) + + return self.interface_phy_cap[key] + + def get_interface_phy_cap_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_phy_cap_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/phy/cap/main.py b/lib/aci/intf/phy/cap/main.py new file mode 100644 index 00000000..15adcd66 --- /dev/null +++ b/lib/aci/intf/phy/cap/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.cap.api import InterfacePhyCapApi +from lib.aci.intf.phy.cap.info import InterfacePhyCapInfo + + +class InterfacePhyCap(InterfacePhyCapApi, InterfacePhyCapInfo): + def __init__(self): + InterfacePhyCapApi.__init__(self) + InterfacePhyCapInfo.__init__(self) diff --git a/lib/aci/intf/phy/eee/__init__.py b/lib/aci/intf/phy/eee/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/eee/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/eee/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f5d8cd5a Binary files /dev/null and b/lib/aci/intf/phy/eee/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/eee/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/eee/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..b2507825 Binary files /dev/null and b/lib/aci/intf/phy/eee/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/eee/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/eee/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..8af7dbb5 Binary files /dev/null and b/lib/aci/intf/phy/eee/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/eee/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/eee/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ae31c8d2 Binary files /dev/null and b/lib/aci/intf/phy/eee/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/eee/api.py b/lib/aci/intf/phy/eee/api.py new file mode 100644 index 00000000..4969f110 --- /dev/null +++ b/lib/aci/intf/phy/eee/api.py @@ -0,0 +1,60 @@ +class InterfacePhyEeeApi(): + def __init__(self): + self.interface_phy_eee_mo = {} + + def get_interface_phy_eee_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_eee_mo: + return self.interface_phy_eee_mo[key] + + cache = self.get_object_cache( + 'l1EeeP', + object_selector=key + ) + if cache is not None: + self.interface_phy_eee_mo[key] = cache + self.log.apic_mo( + 'l1EeeP.%s' % (key), + self.interface_phy_eee_mo[key] + ) + return self.interface_phy_eee_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=l1EeeP' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_eee_mo', + 'API failed' + ) + return None + + self.interface_phy_eee_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_eee_mo[key].append( + managed_object['l1EeeP']['attributes'] + ) + + self.log.apic_mo( + 'l1EeeP.%s' % (key), + self.interface_phy_eee_mo[key] + ) + + self.set_object_cache( + 'l1EeeP', + self.interface_phy_eee_mo[key], + object_selector=key + ) + + return self.interface_phy_eee_mo[key] diff --git a/lib/aci/intf/phy/eee/info.py b/lib/aci/intf/phy/eee/info.py new file mode 100644 index 00000000..a3526a21 --- /dev/null +++ b/lib/aci/intf/phy/eee/info.py @@ -0,0 +1,71 @@ +class InterfacePhyEeeInfo(): + def __init__(self): + self.interface_phy_eee = {} + + def get_interface_phy_eee_info(self, managed_object): + keys = [ + 'dn', + 'eeeLat', + 'eeeLpi', + 'eeeState' + ] + + info = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/phys-[eth1/1]/eeep" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = None + if 'phys-[' in info['dn']: + info['interface_id'] = info['dn'].split('phys-[')[1].split(']')[0] + + if 'aggr-[' in info['dn']: + info['interface_id'] = info['dn'].split('aggr-[')[1].split(']')[0] + + if info['interface_id'] is None: + self.log.error( + 'get_interface_phy_eee_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return info + + def get_interfaces_phy_eee_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_eee: + return self.interface_phy_eee[key] + + managed_objects = self.get_interface_phy_eee_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_phy_eee[key] = [] + for managed_object in managed_objects: + self.interface_phy_eee[key].append( + self.get_interface_phy_eee_info( + managed_object + ) + ) + + return self.interface_phy_eee[key] + + def get_interface_phy_eee_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_phy_eee_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/phy/eee/main.py b/lib/aci/intf/phy/eee/main.py new file mode 100644 index 00000000..01465a39 --- /dev/null +++ b/lib/aci/intf/phy/eee/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.eee.api import InterfacePhyEeeApi +from lib.aci.intf.phy.eee.info import InterfacePhyEeeInfo + + +class InterfacePhyEee(InterfacePhyEeeApi, InterfacePhyEeeInfo): + def __init__(self): + InterfacePhyEeeApi.__init__(self) + InterfacePhyEeeInfo.__init__(self) diff --git a/lib/aci/intf/phy/event/__init__.py b/lib/aci/intf/phy/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/event/api.py b/lib/aci/intf/phy/event/api.py new file mode 100644 index 00000000..70de4d03 --- /dev/null +++ b/lib/aci/intf/phy/event/api.py @@ -0,0 +1,54 @@ +class InterfacePhyEventApi(): + def __init__(self): + self.interface_phy_event_mo = {} + + def get_interface_phy_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_event_mo: + return self.interface_phy_event_mo[key] + + cache = self.get_object_cache( + 'l1PhysIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_phy_event_mo[key] = cache + self.log.apic_mo( + 'l1PhysIf.eventLog.%s' % (key), + self.interface_phy_event_mo[key] + ) + return self.interface_phy_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1PhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_event_mo', + 'API failed' + ) + return None + + self.interface_phy_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_phy_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1PhysIf.eventLog.%s' % (key), + self.interface_phy_event_mo[key] + ) + + self.set_object_cache( + 'l1PhysIf.eventLog', + self.interface_phy_event_mo[key], + object_selector=key + ) + + return self.interface_phy_event_mo[key] diff --git a/lib/aci/intf/phy/event/info.py b/lib/aci/intf/phy/event/info.py new file mode 100644 index 00000000..214a35d0 --- /dev/null +++ b/lib/aci/intf/phy/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfacePhyEventInfo(): + def __init__(self): + self.interface_phy_event = {} + + def get_interface_phy_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/phys-[lo0]" + info['interfaceId'] = None + if '/phys-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/phys-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_phy_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_event: + return self.interface_phy_event[key] + + managed_objects = self.get_interface_phy_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_phy_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_phy_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_phy_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l1PhysIf.eventLog.info.%s' % (key), + self.interface_phy_event[key] + ) + + return self.interface_phy_event[key] + + def get_interface_phy_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_phy_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/phy/event/main.py b/lib/aci/intf/phy/event/main.py new file mode 100644 index 00000000..07b856df --- /dev/null +++ b/lib/aci/intf/phy/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.event.api import InterfacePhyEventApi +from lib.aci.intf.phy.event.info import InterfacePhyEventInfo + + +class InterfacePhyEvent(InterfacePhyEventApi, InterfacePhyEventInfo): + def __init__(self): + InterfacePhyEventApi.__init__(self) + InterfacePhyEventInfo.__init__(self) diff --git a/lib/aci/intf/phy/fault/__init__.py b/lib/aci/intf/phy/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/fault/api.py b/lib/aci/intf/phy/fault/api.py new file mode 100644 index 00000000..d9ff12d0 --- /dev/null +++ b/lib/aci/intf/phy/fault/api.py @@ -0,0 +1,124 @@ +class InterfacePhyFaultApi(): + def __init__(self): + self.interface_phy_fault_mo = {} + self.interface_phy_fault_record_mo = {} + + def get_interface_phy_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_fault_mo: + return self.interface_phy_fault_mo[key] + + cache = self.get_object_cache( + 'l1PhysIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_phy_fault_mo[key] = cache + self.log.apic_mo( + 'l1PhysIf.fault.%s' % (key), + self.interface_phy_fault_mo[key] + ) + return self.interface_phy_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1PhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_fault_mo', + 'API failed' + ) + return None + + self.interface_phy_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_phy_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1PhysIf.fault.%s' % (key), + self.interface_phy_fault_mo[key] + ) + + self.set_object_cache( + 'l1PhysIf.fault', + self.interface_phy_fault_mo[key], + object_selector=key + ) + + return self.interface_phy_fault_mo[key] + + def get_interface_phy_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_fault_record_mo: + return self.interface_phy_fault_record_mo[key] + + cache = self.get_object_cache( + 'l1PhysIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_phy_fault_record_mo[key] = cache + self.log.apic_mo( + 'l1PhysIf.faultRecord.%s' % (key), + self.interface_phy_fault_record_mo[key] + ) + return self.interface_phy_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/l1PhysIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_fault_record_mo', + 'API failed' + ) + return None + + self.interface_phy_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_phy_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l1PhysIf.faultRecord.%s' % (key), + self.interface_phy_fault_record_mo[key] + ) + + self.set_object_cache( + 'l1PhysIf.faultRecord', + self.interface_phy_fault_record_mo[key], + object_selector=key + ) + + return self.interface_phy_fault_record_mo[key] diff --git a/lib/aci/intf/phy/fault/info.py b/lib/aci/intf/phy/fault/info.py new file mode 100644 index 00000000..b5d3f9c9 --- /dev/null +++ b/lib/aci/intf/phy/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfacePhyFaultInfo(): + def __init__(self): + self.interface_phy_fault = {} + self.interface_phy_fault_record = {} + + def get_interface_phy_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/phys-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/phys-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/phys-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/phys-[lo0]" + if info['interfaceId'] is None: + if '/phys-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/phys-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_phy_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_fault: + return self.interface_phy_fault[key] + + managed_objects = self.get_interface_phy_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_phy_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_phy_fault_info( + managed_object + ) + self.interface_phy_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'l1PhysIf.fault.info.%s' % (key), + self.interface_phy_fault[key] + ) + + return self.interface_phy_fault[key] + + def get_interface_phy_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_fault_record: + return self.interface_phy_fault_record[key] + + managed_objects = self.get_interface_phy_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_phy_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_phy_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_phy_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l1PhysIf.faultRecord.info.%s' % (key), + self.interface_phy_fault_record[key] + ) + + return self.interface_phy_fault_record[key] + + def get_interface_phy_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_phy_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_phy_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/phy/fault/main.py b/lib/aci/intf/phy/fault/main.py new file mode 100644 index 00000000..51829481 --- /dev/null +++ b/lib/aci/intf/phy/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.fault.api import InterfacePhyFaultApi +from lib.aci.intf.phy.fault.info import InterfacePhyFaultInfo + + +class InterfacePhyFault(InterfacePhyFaultApi, InterfacePhyFaultInfo): + def __init__(self): + InterfacePhyFaultApi.__init__(self) + InterfacePhyFaultInfo.__init__(self) diff --git a/lib/aci/intf/phy/info.py b/lib/aci/intf/phy/info.py new file mode 100644 index 00000000..76f12863 --- /dev/null +++ b/lib/aci/intf/phy/info.py @@ -0,0 +1,732 @@ +import json + +from lib import filter_helper +from lib import ip_helper + + +class InterfacePhyInfo(): + def __init__(self): + self.interface_phy = {} + + def get_interfaces_phy_summary(self, pod_id, node_id): + interfaces = self.get_interfaces_phy( + pod_id, + node_id + ) + + if interfaces is None: + return None + + summary = {} + summary['__Output'] = {} + summary['uplinkUp'] = 0 + summary['uplinkDown'] = 0 + summary['uplinkCount'] = 0 + summary['downlinkUp'] = 0 + summary['downlinkDown'] = 0 + summary['downlinkCount'] = 0 + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + speeds = [ + '100M', + '1G', + '10G', + '25G', + '40G', + '100G', + '400G' + ] + for speed in speeds: + summary['%sUp' % (speed)] = 0 + summary['%sDown' % (speed)] = 0 + + for interface in interfaces: + if interface['up']: + if interface['uplink']: + summary['uplinkUp'] = summary['uplinkUp'] + 1 + if interface['downlink']: + summary['downlinkUp'] = summary['downlinkUp'] + 1 + if interface['stats'] is not None: + if interface['stats']['operSpeed'] in speeds: + summary['%sUp' % (interface['stats']['operSpeed'])] = summary['%sUp' % (interface['stats']['operSpeed'])] + 1 + + if not interface['up']: + if interface['uplink']: + summary['uplinkDown'] = summary['uplinkDown'] + 1 + if interface['downlink']: + summary['downlinkDown'] = summary['downlinkDown'] + 1 + if interface['stats'] is not None: + if interface['stats']['operSpeed'] in speeds: + summary['%sDown' % (interface['stats']['operSpeed'])] = summary['%sDown' % (interface['stats']['operSpeed'])] + 1 + + summary['uplinkCount'] = summary['uplinkUp'] + summary['uplinkDown'] + summary['downlinkCount'] = summary['downlinkUp'] + summary['downlinkDown'] + summary['portUp'] = summary['uplinkUp'] + summary['downlinkUp'] + summary['portDown'] = summary['uplinkDown'] + summary['downlinkDown'] + summary['portCount'] = summary['portUp'] + summary['portDown'] + + for speed in speeds: + summary['%sCount' % (speed)] = summary['%sUp' % (speed)] + summary['%sDown' % (speed)] + + (summary['uplinkSummary'], summary['__Output']['uplinkSummary']) = self.get_interface_summary_output( + summary['uplinkUp'], + summary['uplinkDown'], + summary['uplinkCount'] + ) + + (summary['downlinkSummary'], summary['__Output']['downlinkSummary']) = self.get_interface_summary_output( + summary['downlinkUp'], + summary['downlinkDown'], + summary['downlinkCount'] + ) + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + for speed in speeds: + (summary['%sSummary' % (speed)], summary['__Output']['%sSummary' % (speed)]) = self.get_interface_summary_output( + summary['%sUp' % (speed)], + summary['%sDown' % (speed)], + summary['%sCount' % (speed)] + ) + + return summary + + def get_port_count(self, pod_id, node_id): + ports = self.get_ports( + pod_id, + node_id + ) + + if ports is None: + return 0 + + return len(ports) + + def get_interface_phy_info(self, managed_object): + keys = [ + 'adminSt', + 'autoNeg', + 'bw', + 'delay', + 'descr', + 'dfeDelayMs', + 'dn', + 'dot1qEtherType', + 'fecMode', + 'id', + 'layer', + 'linkDebounce', + 'mdix', + 'medium', + 'mode', + 'mtu', + 'name', + 'portPhyMediaType', + 'portT', + 'routerMac', + 'spanMode', + 'speed', + 'switchingSt', + 'usage' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # [0]: topology/pod-{id}/node-{id}/sys/phys-[{id}] + # [1]: sys/phys-[{id}] + + info['portId'] = int(info['id'].split('/')[1]) + info['portName'] = info['id'][3:] + info['podId'] = info['dn'].split('/')[1][4:] + info['nodeId'] = info['dn'].split('/')[2][5:] + info['nodeName'] = self.get_node_name(info['nodeId']) + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['uplink'] = False + info['downlink'] = False + + if info['portT'] == 'leaf': + info['uplink'] = False + info['downlink'] = True + + if info['portT'] == 'fab': + info['uplink'] = True + info['downlink'] = False + + info['layerT'] = '' + if info['layer'] == 'Layer2': + info['layerT'] = 'switched' + if info['layer'] == 'Layer3': + info['layerT'] = 'routed' + + info['__Output']['id'] = 'Blue' + if info['adminSt'] == 'up': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['switchingSt'] == 'enabled': + info['__Output']['switchingSt'] = 'Green' + else: + info['__Output']['switchingSt'] = 'Red' + + interfaces_stats = self.get_interface_phy_ether_stats( + info['podId'], + info['nodeId'], + interface_filter=['dn:%s' % (info['dn'])] + ) + if len(interfaces_stats) == 0: + info['stats'] = None + if len(interfaces_stats) == 1: + info['stats'] = interfaces_stats[0] + if len(interfaces_stats) > 1: + self.log.error( + 'get_interface_phy_info', + 'Unexpected ether stats object count: %s' % (info['dn']) + ) + self.log.error( + 'get_interface_phy_info', + json.dumps(interfaces_stats, indent=4) + ) + + info['up'] = False + if info['stats'] is not None: + if info['adminSt'] == 'up' and info['switchingSt'] == 'enabled' and info['stats']['operSt'] == 'up': + info['up'] = True + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + info = self.my_output.merge_output(info) + + return info + + def get_interfaces_phy_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy: + return self.interface_phy[key] + + interfaces_mo = self.get_interface_phy_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_phy[key] = [] + for interface_mo in interfaces_mo: + self.interface_phy[key].append( + self.get_interface_phy_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'l1PhysIf.info.%s' % (key), + self.interface_phy[key] + ) + + return self.interface_phy[key] + + def match_interface_phy_epg_stats(self, epg_stats_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'epg': + if not filter_helper.match_string(value, epg_stats_info['vlan']['epgDn']): + return False + + if key == 'vlan': + if not filter_helper.match_id(epg_stats_info['vlan']['id'], value): + return False + + if key == 'evlan': + if not filter_helper.match_id(epg_stats_info['vlan']['evlan'], value): + return False + + if key == 'fvxlan': + if not filter_helper.match_id(epg_stats_info['vlan']['fvxlan'], value): + return False + + return True + + def filter_interface_phy_epg_stats(self, epgs_stats_info, interface_filter): + filtered = [] + + for epg_stats_info in epgs_stats_info: + if self.match_interface_phy_epg_stats(epg_stats_info, interface_filter): + filtered.append( + epg_stats_info + ) + + return filtered + + def match_interface_phy(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ctx': + found = False + for context in value.split(','): + (pod_id, node_id, interface_id) = context.split(':') + if filter_helper.match_string(pod_id, 'pod-%s' % (interface_info['podId'])): + if filter_helper.match_string(node_id, 'node-%s' % (interface_info['nodeId'])): + if filter_helper.match_string(interface_id, interface_info['id']): + found = True + break + + if not found: + return False + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'ids': + found = False + for interface_id in value.split(','): + if filter_helper.match_string(interface_id, interface_info['id']): + found = True + break + + if not found: + return False + + if key == 'dn': + if not filter_helper.match_string(value, interface_info['dn']): + return False + + if key == 'switching': + if not filter_helper.match_string(value, interface_info['switchingSt']): + return False + + if key == 'oper': + if interface_info['stats'] is None: + return False + + if not filter_helper.match_string(value, interface_info['stats']['operSt']): + return False + + if key == 'type': + if not filter_helper.match_string(value, interface_info['portT']): + return False + + if key == 'layer': + if not filter_helper.match_string(value, interface_info['layerT']): + return False + + if key == 'mac': + if interface_info['stats'] is None: + return False + + if not ip_helper.is_mac_match(value, interface_info['stats']['backplaneMac']): + return False + + if key == 'speed': + if interface_info['stats'] is None: + return False + + if not filter_helper.match_string(value, interface_info['stats']['operSpeed']): + return False + + if key == 'fec': + if interface_info['stats'] is None: + return False + + if not filter_helper.match_string(value, interface_info['stats']['operFecMode']): + return False + + if key == 'trans': + if 'fc_stats' in interface_info: + if interface_info['fc_stats'] is None: + return False + + if not filter_helper.match_string(value, interface_info['fc_stats']['guiCiscoPID']): + return False + + if key == 'optics': + if 'fc_stats' in interface_info: + if interface_info['fc_stats'] is None: + return False + + if not filter_helper.match_string(value, interface_info['fc_stats']['type']): + return False + + if key == 'pc': + if interface_info['stats'] is None: + return False + + if value == 'enabled' and len(interface_info['stats']['bundleIndex']) == 0: + return False + + if value == 'enabled' and len(interface_info['stats']['bundleIndex']) > 0: + return False + + if key == 'epg': + if 'epg_stats' in interface_info: + if interface_info['epg_stats'] is None: + return False + + found = False + for epg_stats in interface_info['epg_stats']: + if epg_stats['vlan'] is not None: + if filter_helper.match_string(value, epg_stats['vlan']['epgDn']): + found = True + break + + if not found: + return False + + if key == 'vlan': + if 'epg_stats' in interface_info: + if interface_info['epg_stats'] is None: + return False + + found = False + for epg_stats in interface_info['epg_stats']: + if epg_stats['vlan'] is not None: + if filter_helper.match_id(epg_stats['vlan']['id'], value): + found = True + break + + if not found: + return False + + if key == 'evlan': + if 'epg_stats' in interface_info: + if interface_info['epg_stats'] is None: + return False + + found = False + for epg_stats in interface_info['epg_stats']: + if epg_stats['vlan'] is not None: + if filter_helper.match_id(epg_stats['vlan']['evlan'], value): + found = True + break + + if not found: + return False + + if key == 'fvxlan': + if 'epg_stats' in interface_info: + if interface_info['epg_stats'] is None: + return False + + found = False + for epg_stats in interface_info['epg_stats']: + if epg_stats['vlan'] is not None: + if filter_helper.match_id(epg_stats['vlan']['fvxlan'], value): + found = True + break + + if not found: + return False + + if key == 'nei': + if 'cdp' in interface_info and 'lldp' in interface_info: + found = False + + if interface_info['cdp'] is not None: + for cdp_info in interface_info['cdp']: + if filter_helper.match_string(value, cdp_info['sysName']): + found = True + break + + if interface_info['lldp'] is not None: + for lldp_info in interface_info['lldp']: + if filter_helper.match_string(value, lldp_info['sysName']): + found = True + break + + if not found: + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_phy', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_phy( + self, + pod_id, + node_id, + interface_filter=None, + ether_stats_info=False, + fc_stats_info=False, + epg_stats_info=False, + load_info=False, + eee_info=False, + cdp_info=False, + lldp_info=False, + policy_info=False, + qos_info=False, + qos_references=None, + cap_info=False, + pc_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_phy_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_phy(interface_info, interface_filter): + continue + + if epg_stats_info: + interface_info['epg_stats'] = None + if interface_info['stats'] is not None: + interface_info['epg_stats'] = self.get_interface_phy_epg_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'], + vlan_info=True, + vlans=interface_info['stats']['allowedVlans'] + ) + + if not self.match_interface_phy(interface_info, interface_filter): + continue + + if interface_info['epg_stats'] is not None: + interface_info['epg_stats'] = self.my_output.merge_output( + self.filter_interface_phy_epg_stats( + interface_info['epg_stats'], + interface_filter + ) + ) + + if ether_stats_info: + interface_info['ether_stats'] = self.get_interface_phy_rmon_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if fc_stats_info: + interface_info['fc_stats'] = None + interface_fc_stats = self.get_interface_phy_fc_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_filter=['dn:%s' % (interface_info['dn'])] + ) + if interface_fc_stats is not None: + if len(interface_fc_stats) != 1: + self.log.error( + 'get_interfaces_phy', + 'Unexpected fc stats count (%s): %s' % ( + len(interface_fc_stats), + interface_info['dn'] + ) + ) + else: + interface_info['fc_stats'] = interface_fc_stats[0] + + if not self.match_interface_phy(interface_info, interface_filter): + continue + + if load_info: + interface_info['load'] = self.get_interface_phy_load_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if eee_info: + interface_info['eee'] = self.get_interface_phy_eee_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if cdp_info: + interface_info['cdp'] = self.get_cdp_adjacency_endpoint( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'], + allow_multiple=True + ) + + if lldp_info: + interface_info['lldp'] = self.get_lldp_adjacency_endpoint( + interface_info['podId'], + interface_info['nodeId'], + adjacency_filter=['interface_id:%s' % (interface_info['id'])], + allow_multiple=True + ) + + if cdp_info or lldp_info: + if not self.match_interface_phy(interface_info, interface_filter): + continue + + if policy_info: + interface_info['policy_selector'] = self.get_interface_policy_group_selector( + interface_info['podId'], + interface_info['nodeId'], + interface_info['portName'], + group_info=True + ) + + if qos_info: + qos_filter = ['interface_id:%s' % (interface_info['id'])] + if interface_filter is not None: + for value in interface_filter: + if value.startswith('qos:'): + qos_filter.append(value) + + interface_info['qos'] = self.get_interfaces_phy_qos_stats( + interface_info['podId'], + interface_info['nodeId'], + qos_filter=qos_filter, + qos_references=qos_references + ) + + if len(interface_info['qos']) == 0: + continue + + if cap_info: + interface_info['load'] = self.get_interface_phy_cap_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if pc_info: + interface_info['pc'] = self.get_interface_phy_pc_stats( + interface_info['podId'], + interface_info['nodeId'], + interface_info['id'] + ) + + if fault_info: + interface_info['faultInst'] = self.get_interface_phy_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_phy_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_phy_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_phy_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['portId'] + ) + + return interfaces + + def get_interface_phy( + self, + pod_id, + node_id, + interface_id, + ether_stats_info=False, + fc_stats_info=False, + epg_stats_info=False, + load_info=False, + eee_info=False, + cdp_info=False, + lldp_info=False, + policy_info=False, + qos_info=False, + qos_references=None, + cap_info=False, + pc_info=False + ): + interfaces = self.get_interfaces_phy( + pod_id, + node_id, + interface_filter=['id:%s' % (interface_id)], + ether_stats_info=ether_stats_info, + fc_stats_info=fc_stats_info, + epg_stats_info=epg_stats_info, + load_info=load_info, + eee_info=eee_info, + cdp_info=cdp_info, + lldp_info=lldp_info, + policy_info=policy_info, + qos_info=qos_info, + qos_references=qos_references, + cap_info=cap_info, + pc_info=pc_info + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/phy/load/__init__.py b/lib/aci/intf/phy/load/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/load/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/load/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..00241cda Binary files /dev/null and b/lib/aci/intf/phy/load/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/load/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/load/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6fa6e940 Binary files /dev/null and b/lib/aci/intf/phy/load/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/load/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/load/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..c09d9d88 Binary files /dev/null and b/lib/aci/intf/phy/load/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/load/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/load/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f6959afa Binary files /dev/null and b/lib/aci/intf/phy/load/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/load/api.py b/lib/aci/intf/phy/load/api.py new file mode 100644 index 00000000..d0fdadb4 --- /dev/null +++ b/lib/aci/intf/phy/load/api.py @@ -0,0 +1,60 @@ +class InterfacePhyLoadApi(): + def __init__(self): + self.interface_phy_load_mo = {} + + def get_interface_phy_load_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_load_mo: + return self.interface_phy_load_mo[key] + + cache = self.get_object_cache( + 'l1LoadP', + object_selector=key + ) + if cache is not None: + self.interface_phy_load_mo[key] = cache + self.log.apic_mo( + 'l1LoadP.%s' % (key), + self.interface_phy_load_mo[key] + ) + return self.interface_phy_load_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=l1LoadP' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_load_mo', + 'API failed' + ) + return None + + self.interface_phy_load_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_load_mo[key].append( + managed_object['l1LoadP']['attributes'] + ) + + self.log.apic_mo( + 'l1LoadP.%s' % (key), + self.interface_phy_load_mo[key] + ) + + self.set_object_cache( + 'l1LoadP', + self.interface_phy_load_mo[key], + object_selector=key + ) + + return self.interface_phy_load_mo[key] diff --git a/lib/aci/intf/phy/load/info.py b/lib/aci/intf/phy/load/info.py new file mode 100644 index 00000000..77f18f41 --- /dev/null +++ b/lib/aci/intf/phy/load/info.py @@ -0,0 +1,71 @@ +class InterfacePhyLoadInfo(): + def __init__(self): + self.interface_phy_load = {} + + def get_interface_phy_load_info(self, managed_object): + keys = [ + 'dn', + 'loadIntvl1', + 'loadIntvl2', + 'loadIntvl3' + ] + + info = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/phys-[eth1/1]/loadp" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = None + if 'phys-[' in info['dn']: + info['interface_id'] = info['dn'].split('phys-[')[1].split(']')[0] + + if 'aggr-[' in info['dn']: + info['interface_id'] = info['dn'].split('aggr-[')[1].split(']')[0] + + if info['interface_id'] is None: + self.log.error( + 'get_interface_phy_load_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return info + + def get_interfaces_phy_load_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_load: + return self.interface_phy_load[key] + + managed_objects = self.get_interface_phy_load_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_phy_load[key] = [] + for managed_object in managed_objects: + self.interface_phy_load[key].append( + self.get_interface_phy_load_info( + managed_object + ) + ) + + return self.interface_phy_load[key] + + def get_interface_phy_load_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_phy_load_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/phy/load/main.py b/lib/aci/intf/phy/load/main.py new file mode 100644 index 00000000..4c7f61ee --- /dev/null +++ b/lib/aci/intf/phy/load/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.load.api import InterfacePhyLoadApi +from lib.aci.intf.phy.load.info import InterfacePhyLoadInfo + + +class InterfacePhyLoad(InterfacePhyLoadApi, InterfacePhyLoadInfo): + def __init__(self): + InterfacePhyLoadApi.__init__(self) + InterfacePhyLoadInfo.__init__(self) diff --git a/lib/aci/intf/phy/main.py b/lib/aci/intf/phy/main.py new file mode 100644 index 00000000..b30788f0 --- /dev/null +++ b/lib/aci/intf/phy/main.py @@ -0,0 +1,35 @@ +from lib.aci.intf.phy.cap.main import InterfacePhyCap +from lib.aci.intf.phy.eee.main import InterfacePhyEee +from lib.aci.intf.phy.load.main import InterfacePhyLoad +from lib.aci.intf.phy.pc.main import InterfacePhyPc +from lib.aci.intf.phy.stats.main import InterfacePhyStats +from lib.aci.intf.phy.api import InterfacePhyApi +from lib.aci.intf.phy.info import InterfacePhyInfo +from lib.aci.intf.phy.audit.main import InterfacePhyAudit +from lib.aci.intf.phy.event.main import InterfacePhyEvent +from lib.aci.intf.phy.fault.main import InterfacePhyFault + + +class InterfacePhy( + InterfacePhyCap, + InterfacePhyEee, + InterfacePhyLoad, + InterfacePhyPc, + InterfacePhyStats, + InterfacePhyApi, + InterfacePhyInfo, + InterfacePhyAudit, + InterfacePhyEvent, + InterfacePhyFault + ): + def __init__(self): + InterfacePhyCap.__init__(self) + InterfacePhyEee.__init__(self) + InterfacePhyLoad.__init__(self) + InterfacePhyPc.__init__(self) + InterfacePhyStats.__init__(self) + InterfacePhyApi.__init__(self) + InterfacePhyInfo.__init__(self) + InterfacePhyAudit.__init__(self) + InterfacePhyEvent.__init__(self) + InterfacePhyFault.__init__(self) diff --git a/lib/aci/intf/phy/output.py b/lib/aci/intf/phy/output.py new file mode 100644 index 00000000..ab5e56fc --- /dev/null +++ b/lib/aci/intf/phy/output.py @@ -0,0 +1,1633 @@ +from lib import filter_helper + + +class InterfacePhyOutput(): + def __init__(self): + pass + + def print_interfaces_phy_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'portName', + 'adminSt', + 'switchingSt', + 'stats.operSt', + 'stats.operStQual' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Switching', + 'Oper', + 'Reason' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_l2(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Layer2 [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'portT', + 'layerT', + 'stats.bundleIndex', + 'stats.backplaneMac', + 'stats.operMode', + 'stats.operSpeed', + 'stats.operDuplex', + 'mtu', + 'stats.operFecMode' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Type', + 'Layer', + 'PC', + 'MAC', + 'Mode', + 'Speed', + 'Duplex', + 'MTU', + 'FEC' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_ether(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Ether Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'ether_stats.pkts', + 'ether_stats.broadcastPkts', + 'ether_stats.multicastPkts', + 'ether_stats.rXNoErrors', + 'ether_stats.tXNoErrors', + 'ether_stats.pkts64Octets', + 'ether_stats.pkts65to127Octets', + 'ether_stats.pkts128to255Octets', + 'ether_stats.pkts256to511Octets', + 'ether_stats.pkts512to1023Octets', + 'ether_stats.pkts1024to1518Octets' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Packets', + 'Broadcast', + 'Multicast', + 'Rx', + 'Tx', + 'Size up to 64B', + 'Size 65-1270B', + 'Size 128-255B', + 'Size 256-511B', + 'Size 512-1023', + 'Size 1024-1518' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_err(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Errors [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'ether_stats.oversizePkts', + 'ether_stats.undersizePkts', + 'ether_stats.rxGiantPkts', + 'ether_stats.rxOversizePkts', + 'ether_stats.txGiantPkts', + 'ether_stats.txOversizePkts', + 'ether_stats.collisions', + 'ether_stats.cRCAlignErrors', + 'ether_stats.dropEvents' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Oversize', + 'Undersize', + 'Rx giant', + 'Rx oversize', + 'Tx giant', + 'Tx oversize', + 'Collisions', + 'CRC errors', + 'Drops' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_trans(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Trans [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'fc_stats.state', + 'fc_stats.type', + 'fc_stats.guiName', + 'fc_stats.guiCiscoPID', + 'fc_stats.guiPN', + 'fc_stats.guiRev', + 'fc_stats.guiSN' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Present', + 'Optics', + 'Name', + 'Type', + 'PN', + 'Rev', + 'SN' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_vlan(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'stats.nativeVlan', + 'stats.primaryVlan', + 'stats.operVlans', + 'epg_stats.nameApTenant', + 'epg_stats.vlan.id', + 'epg_stats.vlan.encap', + 'epg_stats.vlan.fabEncap', + 'epg_stats.vlan.operSt' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Native', + 'Primary', + 'Oper Vlans', + 'EPG', + 'Internal VLAN', + 'Encap VLAN', + 'Fabric VxLAN', + 'VLAN Oper State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['epg_stats'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def get_interface_phy_vlans(self, interfaces): + info = [] + nodes = [] + for interface in interfaces: + if interface['pod_node_name'] not in nodes: + nodes.append( + interface['pod_node_name'] + ) + + for node in nodes: + vlans = {} + for interface in interfaces: + if interface['pod_node_name'] != node: + continue + + if interface['stats'] is None: + continue + + interace_vlans = filter_helper.get_values_from_range( + interface['stats']['allowedVlans'] + ) + for interface_vlan in interace_vlans: + if interface_vlan not in vlans: + vlans[interface_vlan] = {} + vlans[interface_vlan]['apic'] = interface['apic'] + vlans[interface_vlan]['pod_node_name'] = node + vlans[interface_vlan]['interface'] = [] + vlans[interface_vlan]['vlan'] = interface_vlan + vlans[interface_vlan]['evlan'] = None + vlans[interface_vlan]['fvxlan'] = None + vlans[interface_vlan]['epg'] = None + + vlans[interface_vlan]['interface'].append( + interface['id'] + ) + + if 'epg_stats' not in interface or interface['epg_stats'] is None: + continue + + for epg_info in interface['epg_stats']: + if 'vlan' not in epg_info or epg_info['vlan'] is None: + continue + + if int(epg_info['vlan']['id']) != interface_vlan: + continue + + if vlans[interface_vlan]['epg'] is not None and vlans[interface_vlan]['epg'] != epg_info['nameApTenant']: + self.log.error( + 'get_interfaces_phy_vlans', + 'Unexpected epg allocation: %s' % (interface) + ) + continue + + vlans[interface_vlan]['epg'] = epg_info['nameApTenant'] + + if epg_info['vlan']['evlan'] is not None and len(epg_info['vlan']['evlan']) > 0: + if vlans[interface_vlan]['evlan'] is not None and vlans[interface_vlan]['evlan'] != epg_info['vlan']['evlan']: + self.log.error( + 'get_interfaces_phy_vlans', + 'Unexpected evlan allocation: %s' % (interface) + ) + continue + + vlans[interface_vlan]['evlan'] = epg_info['vlan']['evlan'] + + if epg_info['vlan']['fvxlan'] is not None and len(epg_info['vlan']['fvxlan']) > 0: + if vlans[interface_vlan]['fvxlan'] is not None and vlans[interface_vlan]['fvxlan'] != epg_info['vlan']['fvxlan']: + self.log.error( + 'get_interfaces_phy_vlans', + 'Unexpected fvxlan allocation: %s' % (interface) + ) + continue + + vlans[interface_vlan]['fvxlan'] = epg_info['vlan']['fvxlan'] + + for vlan_id in vlans: + info.append( + vlans[vlan_id] + ) + + info = sorted( + info, + key=lambda i: i['vlan'] + ) + + return info + + def print_interfaces_phy_vlan_pivot(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + info = self.get_interface_phy_vlans( + info + ) + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'vlan', + 'epg', + 'evlan', + 'fxvlan', + 'interface' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Internal VLAN', + 'EPG', + 'Encap', + 'Fabric', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_epg(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - EPG [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'epg_stats.nameApTenant', + 'epg_stats.fvBD.nameTenant', + 'epg_stats.fvBD.fvSubnets' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'EPG', + 'Bridge Domain', + 'Subnets' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['epg_stats'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_load(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Load [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'load.loadIntvl1', + 'load.loadIntvl2', + 'load.loadIntvl3' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Load Interval 1', + 'Load Interval 2', + 'Load Interval 3' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_eee(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - EEE [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'eee.eeeLat', + 'eee.eeeLpi', + 'eee.eeeState' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Eee Lat', + 'Eee Lpi', + 'Eee State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_nei(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - CDP/LLDP Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'cdp.sysName', + 'cdp.platId', + 'cdp.portId', + 'lldp.sysName', + 'lldp.portIdV' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'CDP System Name', + 'CDP Platform', + 'CDP Port ID', + 'LLDP System Name', + 'LLDP Port ID' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cdp', 'lldp'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_cdp(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - CDP Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'cdp.sysName', + 'cdp.platId', + 'cdp.portId', + 'cdp.cap', + 'cdp.stQual' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'CDP System Name', + 'Platform', + 'Port ID', + 'Capability', + 'State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cdp'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_lldp(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - LLDP Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'lldp.sysName', + 'lldp.portIdV', + 'lldp.capability', + 'lldp.mgmtIp', + 'lldp.mgmtPortMac', + 'lldp.stQual' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'LLDP System Name', + 'Port ID', + 'Capability', + 'Mgmt IP', + 'Mgmt MAC', + 'State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cdp', 'lldp'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_policy(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Policy [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'portT', + 'policy_selector.policy_group_type', + 'policy_selector.policy_group_name', + 'policy_selector.policy_group_info.policy.infraRsHIfPol', + 'policy_selector.policy_group_info.policy.infraRsLinkFlapPol', + 'policy_selector.policy_group_info.policy.infraRsCdpIfPol', + 'policy_selector.policy_group_info.policy.infraRsMcpIfPol', + 'policy_selector.policy_group_info.policy.infraRsLldpIfPol', + 'policy_selector.policy_group_info.policy.infraRsStpIfPol' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Type', + 'Policy Group Type', + 'Policy Group Name', + 'Link Level', + 'Link Flap', + 'CDP', + 'MCP', + 'LLDP', + 'STP' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_policy_group(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Policy Group [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'portT', + 'policy_selector.profile', + 'policy_selector.name', + 'policy_selector.policy_group_type_name', + 'policy_selector.policy_group_name', + 'policy_selector.policy_group_info.aaep_name' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Type', + 'Leaf Interface Profile', + 'Interface Selector', + 'Policy Group Type', + 'Policy Group Name', + 'Attached Entity Profile' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_phy_aaep(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - AAEP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + for item in info: + try: + item['infraRsDomP'] = item['policy_selector']['policy_group_info']['aaep']['infraRsDomP'] + except BaseException: + item['infraRsDomP'] = None + + order = order + [ + 'pod_node_name', + 'portName', + 'stats.operSt', + 'portT', + 'policy_selector.policy_group_name', + 'policy_selector.policy_group_info.aaep.name', + 'infraRsDomP.domainType', + 'infraRsDomP.domainName' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Oper', + 'Type', + 'Policy Group Name', + 'Attached Entity Profile', + 'Domain Type', + 'Domain Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['infraRsDomP'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_interfaces_phy_qos(self, info, stream='default', title=False): + if title: + self.my_output.default( + 'Interface Phy - QoS [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'adminSt', + 'stats.operSt', + 'qos.id', + 'qos.RxAdmitBytesCount', + 'qos.RxAdmitPacketsCount', + 'qos.RxDropBytesCount', + 'qos.RxDropPacketsCount', + 'qos.TxAdmitBytesCount', + 'qos.TxAdmitPacketsCount', + 'qos.TxDropBytesCount', + 'qos.TxDropPacketsCount' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Interface', + 'Admin', + 'Oper', + 'Class', + 'Rx Admit [B]', + 'Rx Admin', + 'Rx Drop [B]', + 'Rx Drop', + 'Tx Admit [B]', + 'Tx Admin', + 'Tx Drop [B]', + 'Tx Drop' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['qos'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream=stream + ) + + def print_interface_phy_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Phy - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Phy - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_phy_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Phy - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_phy_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Phy - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Phy - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_phy_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Phy - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Phy - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_phy(self, port): + order = [ + 'pod_node_name', + 'id', + 'adminSt', + 'usage', + 'stats.operSpeed', + 'stats.operSt', + 'stats.operStQual', + 'stats.backplaneMac', + 'stats.lastLinkStChg', + 'stats.operRouterMac', + 'stats.operMdix', + 'stats.operMode', + 'stats.accessVlan', + 'stats.nativeVlan', + 'stats.resetCtr', + 'stats.operVlans', + 'stats.allowedVlans', + 'stats.bundleIndex', + 'bw', + 'delay', + 'mdix', + 'medium', + 'mtu', + 'routerMac', + 'speed', + 'fecMode', + 'autoNeg', + 'linkDebounce', + 'dot1qEtherType', + 'layerT', + 'mode', + 'switchingSt', + 'spanMode' + ] + + headers = [ + 'Node', + 'Port', + 'Admin State', + 'Usage', + 'Oper Speed', + 'Oper State', + 'Oper State Reason', + 'Backplane Mac', + 'Last Link State Change', + 'Oper Router Mac', + 'Oper Mdix', + 'Oper Mode', + 'Access VLAN', + 'Native VLAN', + 'Reset Counter', + 'Operational VLANs', + 'Allowed VLANs', + 'Port Channel', + 'Bandwidth (kb)', + 'Delay (usec)', + 'Mdix', + 'Medium', + 'MTU', + 'Router Mac', + 'Speed', + 'Forward Error Correction', + 'Auto Negotiation', + 'Link Debounce Interval (msec)', + 'Dot1Q Ether Type', + 'Layer', + 'Mode', + 'Switching State', + 'Destination SPAN Mode' + ] + + if 'load_interval' in port: + order = order + [ + 'load_interval.loadIntvl1', + 'load_interval.loadIntvl2', + 'load_interval.loadIntvl3' + ] + + headers = headers + [ + 'Load Interval 1', + 'Load Interval 2', + 'Load Interval 3' + ] + + if 'eee' in port: + order = order + [ + 'eee.eeeLat', + 'eee.eeeLpi', + 'eee.eeeState' + ] + + headers = headers + [ + 'Eee Lat', + 'Eee Lpi', + 'Eee State' + ] + + if 'capability' in port: + order = order + [ + 'capability.speed', + 'capability.mdix' + ] + + headers = headers + [ + 'Capability Speed', + 'Capability Mdix' + ] + + if 'pc' in port: + order = order + [ + 'pc.channelingSt' + ] + + headers = headers + [ + 'Channeling State' + ] + + if 'fc_stats' in port: + order = order + [ + 'fc_stats.isFcotPresent', + 'fc_stats.typeName', + 'fc_stats.actualType', + 'fc_stats.guiName', + 'fc_stats.guiPN', + 'fc_stats.guiRev', + 'fc_stats.guiSN' + ] + + headers = headers + [ + 'Transceiver Present', + 'Transceiver Type', + 'Transceiver Actual Type', + 'Transceiver Name', + 'Transceiver Part Number', + 'Transceiver Revision', + 'Transceiver Serial Number' + ] + + self.my_output.dictionary( + port, + title='Fabric Port Details', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + self.print_interface_phy_cdp_adjacency(port) + self.print_interface_phy_lldp_adjacency(port) + self.print_interface_phy_epg_stats(port) + self.print_interface_phy_vlan(port) + self.print_interface_phy_ether_stats(port) + self.print_interface_phy_qos_stats(port) + + def print_interface_phy_cdp_adjacency(self, port): + if 'cdp' in port and len(port['cdp']) > 0: + for lldp_info in port['cdp']: + order = [ + 'sysName', + 'ver', + 'platId', + 'portId', + 'cap', + 'stQual' + ] + + headers = [ + 'System Name', + 'System Version', + 'Platform', + 'Port ID', + 'Capability', + 'State' + ] + + self.my_output.dictionary( + lldp_info, + title='CDP', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_interface_phy_lldp_adjacency(self, port): + if 'lldp' in port and len(port['lldp']) > 0: + for lldp_info in port['lldp']: + order = [ + 'sysName', + 'sysDesc', + 'portDesc', + 'portIdT', + 'portIdV', + 'capability' + ] + + headers = [ + 'System Name', + 'System Description', + 'Port Description', + 'Port Id Type', + 'Port Id Value', + 'Capability' + ] + + self.my_output.dictionary( + lldp_info, + title='LLDP', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_interface_phy_epg_stats(self, port): + if 'epg_stats' not in port or port['epg_stats'] is None: + return + + self.print_epgs_properties( + port['epg_stats'] + ) + + def print_interface_phy_vlan(self, port): + if 'epg_stats' not in port or port['epg_stats'] is None: + return + + order = [ + 'epg_stats.nameApTenant', + 'epg_stats.vlan.id', + 'epg_stats.vlan.encap', + 'epg_stats.vlan.fabEncap', + 'epg_stats.vlan.operSt' + ] + + headers = [ + 'EPG', + 'Internal VLAN', + 'Encap VLAN', + 'Fabric VxLAN', + 'VLAN Oper State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + [port], + order, + ['epg_stats'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_interface_phy_ether_stats(self, port): + if 'ether_stats' in port: + order = [ + 'pkts', + 'broadcastPkts', + 'multicastPkts', + 'pkts64Octets', + 'pkts65to127Octets', + 'pkts128to255Octets', + 'pkts256to511Octets', + 'pkts512to1023Octets', + 'pkts1024to1518Octets', + 'oversizePkts', + 'undersizePkts', + 'rXNoErrors', + 'rxGiantPkts', + 'rxOversizePkts', + 'tXNoErrors', + 'txGiantPkts', + 'txOversizePkts', + 'collisions', + 'cRCAlignErrors', + 'dropEvents' + ] + + headers = [ + 'Packets with no errors', + 'Broadcast', + 'Multicast', + 'Size up to 64B', + 'Size 65-1270B', + 'Size 128-255B', + 'Size 256-511B', + 'Size 512-1023', + 'Size 1024-1518', + 'Oversize', + 'Undersize', + 'Rx with no errors', + 'Rx giant', + 'Rx oversize', + 'Tx with no errors', + 'Tx giant', + 'Tx oversize', + 'Collisions', + 'CRC errors', + 'Drops' + ] + + self.my_output.dictionary( + port['ether_stats'], + title='Ethernet Packets Statistics', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_interface_phy_qos_stats(self, port): + if 'qos' not in port or port['qos'] is None: + return + + order = [ + 'id', + 'RxAdmitBytesCount', + 'RxAdmitPacketsCount', + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxAdmitBytesCount', + 'TxAdmitPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + headers = [ + 'Class', + 'Rx Admit [B]', + 'Rx Admin', + 'Rx Drop [B]', + 'Rx Drop', + 'Tx Admit [B]', + 'Tx Admin', + 'Tx Drop [B]', + 'Tx Drop' + ] + + self.my_output.my_table( + port['qos'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/phy/pc/__init__.py b/lib/aci/intf/phy/pc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/pc/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/pc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..54fc2f41 Binary files /dev/null and b/lib/aci/intf/phy/pc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/pc/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/pc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..16369ad4 Binary files /dev/null and b/lib/aci/intf/phy/pc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/pc/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/pc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..8417633a Binary files /dev/null and b/lib/aci/intf/phy/pc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/pc/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/pc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..993a457f Binary files /dev/null and b/lib/aci/intf/phy/pc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/pc/api.py b/lib/aci/intf/phy/pc/api.py new file mode 100644 index 00000000..2981157d --- /dev/null +++ b/lib/aci/intf/phy/pc/api.py @@ -0,0 +1,60 @@ +class InterfacePhyPcApi(): + def __init__(self): + self.interface_phy_pc_mo = {} + + def get_interface_phy_pc_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_pc_mo: + return self.interface_phy_pc_mo[key] + + cache = self.get_object_cache( + 'pcAggrMbrIf', + object_selector=key + ) + if cache is not None: + self.interface_phy_pc_mo[key] = cache + self.log.apic_mo( + 'pcAggrMbrIf.%s' % (key), + self.interface_phy_pc_mo[key] + ) + return self.interface_phy_pc_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=pcAggrMbrIf' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_pc_mo', + 'API failed' + ) + return None + + self.interface_phy_pc_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_pc_mo[key].append( + managed_object['pcAggrMbrIf']['attributes'] + ) + + self.log.apic_mo( + 'pcAggrMbrIf.%s' % (key), + self.interface_phy_pc_mo[key] + ) + + self.set_object_cache( + 'pcAggrMbrIf', + self.interface_phy_pc_mo[key], + object_selector=key + ) + + return self.interface_phy_pc_mo[key] diff --git a/lib/aci/intf/phy/pc/info.py b/lib/aci/intf/phy/pc/info.py new file mode 100644 index 00000000..973856f3 --- /dev/null +++ b/lib/aci/intf/phy/pc/info.py @@ -0,0 +1,88 @@ +class InterfacePhyPcInfo(): + def __init__(self): + self.interface_phy_pc = {} + + def get_interface_phy_pc_info(self, managed_object): + # { + # "bdlPortNum": "255", + # "bfdState": "5", + # "channelingSt": "unknown", + # "childAction": "", + # "dn": "topology/pod-1/node-205/sys/phys-[eth1/33]/aggrmbrif", + # "flags": "", + # "ltlProgrammed": "no", + # "modTs": "never", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "", + # "nameAlias": "", + # "operSt": "down", + # "pcMode": "on", + # "status": "", + # "summOperSt": "down", + # "uptime": "00:00:00:00.000" + # }, + keys = [ + 'dn', + 'channelingSt', + 'pcMode' + ] + + info = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/phys-[eth1/33]/aggrmbrif" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = None + if 'phys-[' in info['dn']: + info['interface_id'] = info['dn'].split('phys-[')[1].split(']')[0] + + if 'aggr-[' in info['dn']: + info['interface_id'] = info['dn'].split('aggr-[')[1].split(']')[0] + + if info['interface_id'] is None: + self.log.error( + 'get_interface_phy_pc_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return info + + def get_interfaces_phy_pc_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_pc: + return self.interface_phy_pc[key] + + managed_objects = self.get_interface_phy_pc_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_phy_pc[key] = [] + for managed_object in managed_objects: + self.interface_phy_pc[key].append( + self.get_interface_phy_pc_info( + managed_object + ) + ) + + return self.interface_phy_pc[key] + + def get_interface_phy_pc_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_phy_pc_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/phy/pc/main.py b/lib/aci/intf/phy/pc/main.py new file mode 100644 index 00000000..50791445 --- /dev/null +++ b/lib/aci/intf/phy/pc/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.pc.api import InterfacePhyPcApi +from lib.aci.intf.phy.pc.info import InterfacePhyPcInfo + + +class InterfacePhyPc(InterfacePhyPcApi, InterfacePhyPcInfo): + def __init__(self): + InterfacePhyPcApi.__init__(self) + InterfacePhyPcInfo.__init__(self) diff --git a/lib/aci/intf/phy/stats/__init__.py b/lib/aci/intf/phy/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..42b0aef0 Binary files /dev/null and b/lib/aci/intf/phy/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..39c0302f Binary files /dev/null and b/lib/aci/intf/phy/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/epg/__init__.py b/lib/aci/intf/phy/stats/epg/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/stats/epg/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/stats/epg/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..348139ca Binary files /dev/null and b/lib/aci/intf/phy/stats/epg/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/epg/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/stats/epg/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3475cec8 Binary files /dev/null and b/lib/aci/intf/phy/stats/epg/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/epg/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/stats/epg/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..d0b03910 Binary files /dev/null and b/lib/aci/intf/phy/stats/epg/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/epg/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/stats/epg/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..aff172b8 Binary files /dev/null and b/lib/aci/intf/phy/stats/epg/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/epg/api.py b/lib/aci/intf/phy/stats/epg/api.py new file mode 100644 index 00000000..accdcaf7 --- /dev/null +++ b/lib/aci/intf/phy/stats/epg/api.py @@ -0,0 +1,74 @@ +class InterfacePhyEpgStatsApi(): + def __init__(self): + self.interface_phy_epg_stats_mo = {} + + def get_interface_phy_epg_stats_mo(self, pod_id, node_id, interface_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + '.'.join(interface_id.split('/')) + ) + if key in self.interface_phy_epg_stats_mo: + return self.interface_phy_epg_stats_mo[key] + + cache = self.get_object_cache( + 'l1EthIfToEPg', + object_selector=key + ) + if cache is not None: + self.interface_phy_epg_stats_mo[key] = cache + self.log.apic_mo( + 'l1EthIfToEPg.%s' % (key), + self.interface_phy_epg_stats_mo[key] + ) + return self.interface_phy_epg_stats_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/phys-[%s]' % ( + pod_id, + node_id, + interface_id + ) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=l1EthIfToEPg' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_epg_stats_mo', + 'API failed' + ) + return None + + self.interface_phy_epg_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'children' in managed_object['l1PhysIf']: + for deploy_child in managed_object['l1PhysIf']['children']: + for resource_child in deploy_child['pconsCtrlrDeployCtx']['children']: + epg_info = self.get_epg( + resource_child['pconsResourceCtx']['attributes']['ctxDn'] + ) + if epg_info is not None: + self.interface_phy_epg_stats_mo[key].append( + epg_info + ) + + self.interface_phy_epg_stats_mo[key] = sorted( + self.interface_phy_epg_stats_mo[key], + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'l1EthIfToEPg.%s' % (key), + self.interface_phy_epg_stats_mo[key] + ) + + self.set_object_cache( + 'l1EthIfToEPg', + self.interface_phy_epg_stats_mo[key], + object_selector=key + ) + + return self.interface_phy_epg_stats_mo[key] diff --git a/lib/aci/intf/phy/stats/epg/info.py b/lib/aci/intf/phy/stats/epg/info.py new file mode 100644 index 00000000..aff322d5 --- /dev/null +++ b/lib/aci/intf/phy/stats/epg/info.py @@ -0,0 +1,52 @@ +class InterfacePhyEpgStatsInfo(): + def __init__(self): + pass + + def get_interface_phy_epg_stats_info(self, managed_object): + info = {} + for key in managed_object: + info[key] = managed_object[key] + return info + + def get_interface_phy_epg_stats(self, pod_id, node_id, interface_id, vlan_info=False, vlans=None): + epg_stats_mo = self.get_interface_phy_epg_stats_mo(pod_id, node_id, interface_id) + if epg_stats_mo is None: + return None + + epg_stats = [] + for epg_stat_mo in epg_stats_mo: + epg_stat_info = self.get_interface_phy_epg_stats_info(epg_stat_mo) + if vlan_info: + vlan_stats = self.get_vlan_stats( + pod_id, + node_id, + vlan_filter=[ + 'epg:%s' % (epg_stat_info['dn']), + 'vlan:%s' % (vlans) + ] + ) + epg_stat_info['vlan'] = None + if vlan_stats is not None: + if len(vlan_stats) == 0: + epg_stat_info['vlan'] = None + if len(vlan_stats) == 1: + epg_stat_info['vlan'] = vlan_stats[0] + if len(vlan_stats) > 1: + self.log.error( + 'get_interface_phy_epg_stats', + 'Unexpected epg vlan stats: %s/%s/%s' % ( + pod_id, + node_id, + interface_id + ) + ) + self.log.error( + 'get_interface_phy_epg_stats', + vlan_stats + ) + + epg_stats.append( + epg_stat_info + ) + + return epg_stats diff --git a/lib/aci/intf/phy/stats/epg/main.py b/lib/aci/intf/phy/stats/epg/main.py new file mode 100644 index 00000000..0b7827e8 --- /dev/null +++ b/lib/aci/intf/phy/stats/epg/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.stats.epg.api import InterfacePhyEpgStatsApi +from lib.aci.intf.phy.stats.epg.info import InterfacePhyEpgStatsInfo + + +class InterfacePhyEpgStats(InterfacePhyEpgStatsApi, InterfacePhyEpgStatsInfo): + def __init__(self): + InterfacePhyEpgStatsApi.__init__(self) + InterfacePhyEpgStatsInfo.__init__(self) diff --git a/lib/aci/intf/phy/stats/ether/__init__.py b/lib/aci/intf/phy/stats/ether/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/stats/ether/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/stats/ether/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4f192841 Binary files /dev/null and b/lib/aci/intf/phy/stats/ether/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/ether/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/stats/ether/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2868b76a Binary files /dev/null and b/lib/aci/intf/phy/stats/ether/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/ether/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/stats/ether/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..45ecbc94 Binary files /dev/null and b/lib/aci/intf/phy/stats/ether/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/ether/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/stats/ether/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..36b53ecc Binary files /dev/null and b/lib/aci/intf/phy/stats/ether/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/ether/api.py b/lib/aci/intf/phy/stats/ether/api.py new file mode 100644 index 00000000..997877cf --- /dev/null +++ b/lib/aci/intf/phy/stats/ether/api.py @@ -0,0 +1,54 @@ +class InterfacePhyEtherStatsApi(): + def __init__(self): + self.interface_phy_ether_stats_mo = {} + + def get_interface_phy_ether_stats_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_ether_stats_mo: + return self.interface_phy_ether_stats_mo[key] + + cache = self.get_object_cache( + 'ethpmPhysIf', + object_selector=key + ) + if cache is not None: + self.interface_phy_ether_stats_mo[key] = cache + self.log.apic_mo( + 'ethpmPhysIf.%s' % (key), + self.interface_phy_ether_stats_mo[key] + ) + return self.interface_phy_ether_stats_mo[key] + + class_name = 'topology/pod-%s/node-%s/ethpmPhysIf' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_ether_stats_mo', + 'API failed' + ) + return None + + self.interface_phy_ether_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_ether_stats_mo[key].append( + managed_object['ethpmPhysIf']['attributes'] + ) + + self.log.apic_mo( + 'ethpmPhysIf.%s' % (key), + self.interface_phy_ether_stats_mo[key] + ) + + self.set_object_cache( + 'ethpmPhysIf', + self.interface_phy_ether_stats_mo[key], + object_selector=key + ) + + return self.interface_phy_ether_stats_mo[key] diff --git a/lib/aci/intf/phy/stats/ether/info.py b/lib/aci/intf/phy/stats/ether/info.py new file mode 100644 index 00000000..9c831318 --- /dev/null +++ b/lib/aci/intf/phy/stats/ether/info.py @@ -0,0 +1,113 @@ +from lib import filter_helper + + +class InterfacePhyEtherStatsInfo(): + def __init__(self): + self.interface_phy_ether_stats = {} + + def get_interface_phy_ether_stats_info(self, managed_object): + keys = [ + 'accessVlan', + 'allowedVlans', + 'backplaneMac', + 'bundleIndex', + 'cfgAccessVlan', + 'cfgNativeVlan', + 'dn', + 'encap', + 'intfT', + 'lastLinkStChg', + 'media', + 'nativeVlan', + 'operDuplex', + 'operErrDisQual', + 'operFecMode', + 'operFlowCtrl', + 'operMdix', + 'operMode', + 'operModeDetail', + 'operPhyEnSt', + 'operRouterMac', + 'operSpeed', + 'operSt', + 'operStQual', + 'operVlans', + 'osSum', + 'resetCtr', + 'primaryVlan', + 'txT' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['__Output']['bundleIndex'] = 'Yellow' + if info['operStQual'] == 'none': + info['operStQual'] = 'connected' + + if info['bundleIndex'] == 'unspecified': + info['bundleIndex'] = '' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_interfaces_phy_ether_stats_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_ether_stats: + return self.interface_phy_ether_stats[key] + + interfaces_stats_mo = self.get_interface_phy_ether_stats_mo(pod_id, node_id) + if interfaces_stats_mo is not None: + self.interface_phy_ether_stats[key] = [] + for interface_stats_mo in interfaces_stats_mo: + self.interface_phy_ether_stats[key].append( + self.get_interface_phy_ether_stats_info( + interface_stats_mo + ) + ) + + self.log.apic_mo( + 'ethpmPhysIf.info.%s' % (key), + self.interface_phy_ether_stats[key] + ) + + return self.interface_phy_ether_stats[key] + + def match_interface_phy_ether_stats(self, interface_phy_ether_stats_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'dn': + if not filter_helper.match_string('%s/*' % (value), interface_phy_ether_stats_info['dn']): + return False + + return True + + def get_interface_phy_ether_stats(self, pod_id, node_id, interface_filter=None): + all_interfaces_phy_ether_stats = self.get_interfaces_phy_ether_stats_info(pod_id, node_id) + if all_interfaces_phy_ether_stats is None: + return None + + interfaces = [] + + for interface_phy_ether_stats_info in all_interfaces_phy_ether_stats: + if not self.match_interface_phy_ether_stats(interface_phy_ether_stats_info, interface_filter): + continue + + interfaces.append( + interface_phy_ether_stats_info + ) + + return interfaces diff --git a/lib/aci/intf/phy/stats/ether/main.py b/lib/aci/intf/phy/stats/ether/main.py new file mode 100644 index 00000000..4850d24d --- /dev/null +++ b/lib/aci/intf/phy/stats/ether/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.stats.ether.api import InterfacePhyEtherStatsApi +from lib.aci.intf.phy.stats.ether.info import InterfacePhyEtherStatsInfo + + +class InterfacePhyEtherStats(InterfacePhyEtherStatsApi, InterfacePhyEtherStatsInfo): + def __init__(self): + InterfacePhyEtherStatsApi.__init__(self) + InterfacePhyEtherStatsInfo.__init__(self) diff --git a/lib/aci/intf/phy/stats/fc/__init__.py b/lib/aci/intf/phy/stats/fc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/stats/fc/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/stats/fc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8d7b59b Binary files /dev/null and b/lib/aci/intf/phy/stats/fc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/fc/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/stats/fc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5d983c6d Binary files /dev/null and b/lib/aci/intf/phy/stats/fc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/fc/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/stats/fc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e477bfc7 Binary files /dev/null and b/lib/aci/intf/phy/stats/fc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/fc/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/stats/fc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..158d1bd8 Binary files /dev/null and b/lib/aci/intf/phy/stats/fc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/fc/api.py b/lib/aci/intf/phy/stats/fc/api.py new file mode 100644 index 00000000..f4d6874e --- /dev/null +++ b/lib/aci/intf/phy/stats/fc/api.py @@ -0,0 +1,54 @@ +class InterfacePhyFcStatsApi(): + def __init__(self): + self.interface_phy_fc_stats_mo = {} + + def get_interface_phy_fc_stats_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_fc_stats_mo: + return self.interface_phy_fc_stats_mo[key] + + cache = self.get_object_cache( + 'ethpmFcot', + object_selector=key + ) + if cache is not None: + self.interface_phy_fc_stats_mo[key] = cache + self.log.apic_mo( + 'ethpmFcot.%s' % (key), + self.interface_phy_fc_stats_mo[key] + ) + return self.interface_phy_fc_stats_mo[key] + + class_name = 'topology/pod-%s/node-%s/ethpmFcot' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_fc_stats_mo', + 'API failed' + ) + return None + + self.interface_phy_fc_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_fc_stats_mo[key].append( + managed_object['ethpmFcot']['attributes'] + ) + + self.log.apic_mo( + 'ethpmFcot.%s' % (key), + self.interface_phy_fc_stats_mo[key] + ) + + self.set_object_cache( + 'ethpmFcot', + self.interface_phy_fc_stats_mo[key], + object_selector=key + ) + + return self.interface_phy_fc_stats_mo[key] diff --git a/lib/aci/intf/phy/stats/fc/info.py b/lib/aci/intf/phy/stats/fc/info.py new file mode 100644 index 00000000..28b0dbe0 --- /dev/null +++ b/lib/aci/intf/phy/stats/fc/info.py @@ -0,0 +1,85 @@ +from lib import filter_helper + + +class InterfacePhyFcStatsInfo(): + def __init__(self): + self.interface_phy_fc_stats = {} + + def get_interface_phy_fc_stats_info(self, managed_object): + keys = [ + 'actualType', + 'dn', + 'guiCiscoPID', + 'guiCiscoPN', + 'guiName', + 'guiPN', + 'guiRev', + 'guiSN', + 'isFcotPresent', + 'state', + 'type', + 'typeName' + ] + + info = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key].strip() + + return info + + def get_interfaces_phy_fc_stats_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_phy_fc_stats: + return self.interface_phy_fc_stats[key] + + interfaces_stats_mo = self.get_interface_phy_fc_stats_mo(pod_id, node_id) + if interfaces_stats_mo is None: + return None + + self.interface_phy_fc_stats[key] = [] + for interface_stats_mo in interfaces_stats_mo: + self.interface_phy_fc_stats[key].append( + self.get_interface_phy_fc_stats_info( + interface_stats_mo + ) + ) + + self.log.apic_mo( + 'ethpmPhysIf.info.%s' % (key), + self.interface_phy_fc_stats[key] + ) + + return self.interface_phy_fc_stats[key] + + def match_interface_phy_fc_stats(self, interface_phy_fc_stats_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'dn': + if not filter_helper.match_string('%s/*' % (value), interface_phy_fc_stats_info['dn']): + return False + + return True + + def get_interface_phy_fc_stats(self, pod_id, node_id, interface_filter=None): + all_interfaces_phy_fc_stats = self.get_interfaces_phy_fc_stats_info(pod_id, node_id) + if all_interfaces_phy_fc_stats is None: + return None + + interfaces = [] + + for interface_phy_fc_stats_info in all_interfaces_phy_fc_stats: + if not self.match_interface_phy_fc_stats(interface_phy_fc_stats_info, interface_filter): + continue + + interfaces.append( + interface_phy_fc_stats_info + ) + + return interfaces diff --git a/lib/aci/intf/phy/stats/fc/main.py b/lib/aci/intf/phy/stats/fc/main.py new file mode 100644 index 00000000..fc50f564 --- /dev/null +++ b/lib/aci/intf/phy/stats/fc/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.stats.fc.api import InterfacePhyFcStatsApi +from lib.aci.intf.phy.stats.fc.info import InterfacePhyFcStatsInfo + + +class InterfacePhyFcStats(InterfacePhyFcStatsApi, InterfacePhyFcStatsInfo): + def __init__(self): + InterfacePhyFcStatsApi.__init__(self) + InterfacePhyFcStatsInfo.__init__(self) diff --git a/lib/aci/intf/phy/stats/main.py b/lib/aci/intf/phy/stats/main.py new file mode 100644 index 00000000..01848669 --- /dev/null +++ b/lib/aci/intf/phy/stats/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.phy.stats.epg.main import InterfacePhyEpgStats +from lib.aci.intf.phy.stats.ether.main import InterfacePhyEtherStats +from lib.aci.intf.phy.stats.fc.main import InterfacePhyFcStats +from lib.aci.intf.phy.stats.qos.main import InterfacePhyQosStats +from lib.aci.intf.phy.stats.rmon.main import InterfacePhyRmonStats + + +class InterfacePhyStats( + InterfacePhyEpgStats, + InterfacePhyEtherStats, + InterfacePhyFcStats, + InterfacePhyQosStats, + InterfacePhyRmonStats + ): + def __init__(self): + InterfacePhyEpgStats.__init__(self) + InterfacePhyEtherStats.__init__(self) + InterfacePhyFcStats.__init__(self) + InterfacePhyQosStats.__init__(self) + InterfacePhyRmonStats.__init__(self) diff --git a/lib/aci/intf/phy/stats/qos/__init__.py b/lib/aci/intf/phy/stats/qos/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/stats/qos/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/stats/qos/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e6316fdf Binary files /dev/null and b/lib/aci/intf/phy/stats/qos/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/qos/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/stats/qos/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e955cded Binary files /dev/null and b/lib/aci/intf/phy/stats/qos/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/qos/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/stats/qos/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..3ca65297 Binary files /dev/null and b/lib/aci/intf/phy/stats/qos/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/qos/__pycache__/live.cpython-310.pyc b/lib/aci/intf/phy/stats/qos/__pycache__/live.cpython-310.pyc new file mode 100644 index 00000000..b282a599 Binary files /dev/null and b/lib/aci/intf/phy/stats/qos/__pycache__/live.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/qos/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/stats/qos/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8ab2c315 Binary files /dev/null and b/lib/aci/intf/phy/stats/qos/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/qos/api.py b/lib/aci/intf/phy/stats/qos/api.py new file mode 100644 index 00000000..c1694289 --- /dev/null +++ b/lib/aci/intf/phy/stats/qos/api.py @@ -0,0 +1,55 @@ +class InterfacePhyQosStatsApi(): + def __init__(self): + self.interface_phy_qos_stats_mo = {} + + def get_interface_phy_qos_stats_mo(self, pod_id, node_id, cache_enabled=True): + key = '%s.%s' % ( + pod_id, + node_id + ) + if cache_enabled: + if key in self.interface_phy_qos_stats_mo: + return self.interface_phy_qos_stats_mo[key] + + cache = self.get_object_cache( + 'qosmIfClass', + object_selector=key + ) + if cache is not None: + self.interface_phy_qos_stats_mo[key] = cache + self.log.apic_mo( + 'qosmIfClass.%s' % (key), + self.interface_phy_qos_stats_mo[key] + ) + return self.interface_phy_qos_stats_mo[key] + + class_name = 'topology/pod-%s/node-%s/qosmIfClass' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_qos_stats_mo', + 'API failed' + ) + return None + + self.interface_phy_qos_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_qos_stats_mo[key].append( + managed_object['qosmIfClass']['attributes'] + ) + + self.log.apic_mo( + 'qosmIfClass.%s' % (key), + self.interface_phy_qos_stats_mo[key] + ) + + self.set_object_cache( + 'qosmIfClass', + self.interface_phy_qos_stats_mo[key], + object_selector=key + ) + + return self.interface_phy_qos_stats_mo[key] diff --git a/lib/aci/intf/phy/stats/qos/info.py b/lib/aci/intf/phy/stats/qos/info.py new file mode 100644 index 00000000..6cd457c3 --- /dev/null +++ b/lib/aci/intf/phy/stats/qos/info.py @@ -0,0 +1,215 @@ +class InterfacePhyQosStatsInfo(): + def __init__(self): + self.interface_phy_qos_stats = {} + + def get_interface_phy_qos_stats_info(self, managed_object): + info = {} + info['__Output'] = {} + info['id'] = managed_object['id'] + info['dn'] = managed_object['dn'] + info['interface_id'] = managed_object['dn'].split('[')[1].split(']')[0] + + keys = [ + 'RxAdmitBytesCount', + 'RxAdmitPacketsCount', + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxAdmitBytesCount', + 'TxAdmitPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + for key in keys: + try: + info[key] = int(managed_object[key].strip()) + except BaseException: + info[key] = 0 + + keys = [ + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + for key in keys: + if info[key] > 0: + info['__Output'][key] = 'Red' + + return info + + def get_interfaces_phy_qos_stats_info(self, pod_id, node_id, cache_enabled=True): + key = '%s.%s' % (pod_id, node_id) + if cache_enabled: + if key in self.interface_phy_qos_stats: + return self.interface_phy_qos_stats[key] + + interfaces_qos_stats_mo = self.get_interface_phy_qos_stats_mo(pod_id, node_id, cache_enabled=cache_enabled) + if interfaces_qos_stats_mo is not None: + self.interface_phy_qos_stats[key] = [] + for interface_qos_stats_mo in interfaces_qos_stats_mo: + self.interface_phy_qos_stats[key].append( + self.get_interface_phy_qos_stats_info( + interface_qos_stats_mo + ) + ) + + self.log.apic_mo( + 'qosmIfClass.info.%s' % (key), + self.interface_phy_qos_stats[key] + ) + + return self.interface_phy_qos_stats[key] + + def match_interface_phy_qos_stats(self, interface_phy_qos_stats_info, qos_stats_filter): + if qos_stats_filter is None or len(qos_stats_filter) == 0: + return True + + for ap_rule in qos_stats_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'interface_id': + if value != interface_phy_qos_stats_info['interface_id']: + return False + + if key == 'qos': + if value == 'data': + keys = [ + 'RxAdmitBytesCount', + 'RxAdmitPacketsCount', + 'TxAdmitBytesCount', + 'TxAdmitPacketsCount', + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + is_traffic = False + for key in keys: + if interface_phy_qos_stats_info[key] > 0: + is_traffic = True + + if not is_traffic: + return False + + if value == 'data-rx': + keys = [ + 'RxAdmitBytesCount', + 'RxAdmitPacketsCount', + 'RxDropBytesCount', + 'RxDropPacketsCount' + ] + is_traffic = False + for key in keys: + if interface_phy_qos_stats_info[key] > 0: + is_traffic = True + + if not is_traffic: + return False + + if value == 'data-tx': + keys = [ + 'TxAdmitBytesCount', + 'TxAdmitPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + is_traffic = False + for key in keys: + if interface_phy_qos_stats_info[key] > 0: + is_traffic = True + + if not is_traffic: + return False + + if value == 'drops': + keys = [ + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + is_drops = False + for key in keys: + if interface_phy_qos_stats_info[key] > 0: + is_drops = True + + if not is_drops: + return False + + if value == 'drops-rx': + keys = [ + 'RxDropBytesCount', + 'RxDropPacketsCount' + ] + + is_drops = False + for key in keys: + if interface_phy_qos_stats_info[key] > 0: + is_drops = True + + if not is_drops: + return False + + if value == 'drops-tx': + keys = [ + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + is_drops = False + for key in keys: + if interface_phy_qos_stats_info[key] > 0: + is_drops = True + + if not is_drops: + return False + + return True + + def get_interface_phy_qos_stats(self, pod_id, node_id, interface_id): + stats = self.get_interfaces_phy_qos_stats( + pod_id, + node_id, + qos_filter=['interface_id:%s' % (interface_id)] + ) + + return stats + + def get_interfaces_phy_qos_stats(self, pod_id, node_id, qos_filter=None, qos_references=None): + cache_enabled = True + if qos_references is not None: + cache_enabled = False + + all_interfaces_phy_qos_stats = self.get_interfaces_phy_qos_stats_info(pod_id, node_id, cache_enabled=cache_enabled) + if all_interfaces_phy_qos_stats is None: + return None + + stats = [] + for interface_phy_qos_stats in all_interfaces_phy_qos_stats: + if qos_references is not None: + for qos_reference in qos_references: + if qos_reference['id'] == interface_phy_qos_stats['interface_id']: + for interface_phy_qos_reference_class in qos_reference['qos']: + if interface_phy_qos_reference_class['id'] == interface_phy_qos_stats['id']: + interface_phy_qos_stats = self.get_interface_phy_qos_stats_delta( + interface_phy_qos_stats, + interface_phy_qos_reference_class + ) + + if not self.match_interface_phy_qos_stats(interface_phy_qos_stats, qos_filter): + continue + + stats.append( + interface_phy_qos_stats + ) + + stats = sorted( + stats, + key=lambda i: (i['interface_id'], i['id'].lower()) + ) + + return stats diff --git a/lib/aci/intf/phy/stats/qos/live.py b/lib/aci/intf/phy/stats/qos/live.py new file mode 100644 index 00000000..ffad769e --- /dev/null +++ b/lib/aci/intf/phy/stats/qos/live.py @@ -0,0 +1,41 @@ +import copy + + +class InterfacePhyQosStatsLive(): + def __init__(self): + pass + + def get_interface_phy_qos_stats_delta(self, qos_stats, qos_stats_reference): + keys = [ + 'RxAdmitBytesCount', + 'RxAdmitPacketsCount', + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxAdmitBytesCount', + 'TxAdmitPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + qos_delta = copy.deepcopy(qos_stats) + qos_delta['__Output'] = {} + for key in keys: + if qos_stats[key] < qos_stats_reference[key]: + self.log.error('get_interface_phy_qos_stats_delta', qos_stats['interface_id']) + qos_delta[key] = 0 + continue + + qos_delta[key] = qos_stats[key] - qos_stats_reference[key] + + keys = [ + 'RxDropBytesCount', + 'RxDropPacketsCount', + 'TxDropBytesCount', + 'TxDropPacketsCount' + ] + + for key in keys: + if qos_delta[key] > 0: + qos_delta['__Output'][key] = 'Red' + + return qos_delta diff --git a/lib/aci/intf/phy/stats/qos/main.py b/lib/aci/intf/phy/stats/qos/main.py new file mode 100644 index 00000000..d4813000 --- /dev/null +++ b/lib/aci/intf/phy/stats/qos/main.py @@ -0,0 +1,10 @@ +from lib.aci.intf.phy.stats.qos.api import InterfacePhyQosStatsApi +from lib.aci.intf.phy.stats.qos.info import InterfacePhyQosStatsInfo +from lib.aci.intf.phy.stats.qos.live import InterfacePhyQosStatsLive + + +class InterfacePhyQosStats(InterfacePhyQosStatsApi, InterfacePhyQosStatsInfo, InterfacePhyQosStatsLive): + def __init__(self): + InterfacePhyQosStatsApi.__init__(self) + InterfacePhyQosStatsInfo.__init__(self) + InterfacePhyQosStatsLive.__init__(self) diff --git a/lib/aci/intf/phy/stats/rmon/__init__.py b/lib/aci/intf/phy/stats/rmon/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/phy/stats/rmon/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/phy/stats/rmon/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1f249c13 Binary files /dev/null and b/lib/aci/intf/phy/stats/rmon/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/rmon/__pycache__/api.cpython-310.pyc b/lib/aci/intf/phy/stats/rmon/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..62990fad Binary files /dev/null and b/lib/aci/intf/phy/stats/rmon/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/rmon/__pycache__/info.cpython-310.pyc b/lib/aci/intf/phy/stats/rmon/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..97a5423f Binary files /dev/null and b/lib/aci/intf/phy/stats/rmon/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/rmon/__pycache__/main.cpython-310.pyc b/lib/aci/intf/phy/stats/rmon/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4d189ff3 Binary files /dev/null and b/lib/aci/intf/phy/stats/rmon/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/phy/stats/rmon/api.py b/lib/aci/intf/phy/stats/rmon/api.py new file mode 100644 index 00000000..445e4d43 --- /dev/null +++ b/lib/aci/intf/phy/stats/rmon/api.py @@ -0,0 +1,60 @@ +class InterfacePhyRmonStatsApi(): + def __init__(self): + self.interface_phy_rmon_stats_mo = {} + + def get_interface_phy_rmon_stats_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_rmon_stats_mo: + return self.interface_phy_rmon_stats_mo[key] + + cache = self.get_object_cache( + 'rmonEtherStats', + object_selector=key + ) + if cache is not None: + self.interface_phy_rmon_stats_mo[key] = cache + self.log.apic_mo( + 'rmonEtherStats.%s' % (key), + self.interface_phy_rmon_stats_mo[key] + ) + return self.interface_phy_rmon_stats_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys' % ( + pod_id, + node_id + ) + query = 'query-target=subtree&target-subtree-class=rmonEtherStats' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_phy_rmon_stats_mo', + 'API failed' + ) + return None + + self.interface_phy_rmon_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.interface_phy_rmon_stats_mo[key].append( + managed_object['rmonEtherStats']['attributes'] + ) + + self.log.apic_mo( + 'rmonEtherStats.%s' % (key), + self.interface_phy_rmon_stats_mo[key] + ) + + self.set_object_cache( + 'rmonEtherStats', + self.interface_phy_rmon_stats_mo[key], + object_selector=key + ) + + return self.interface_phy_rmon_stats_mo[key] diff --git a/lib/aci/intf/phy/stats/rmon/info.py b/lib/aci/intf/phy/stats/rmon/info.py new file mode 100644 index 00000000..316d1941 --- /dev/null +++ b/lib/aci/intf/phy/stats/rmon/info.py @@ -0,0 +1,81 @@ +class InterfacePhyRmonStatsInfo(): + def __init__(self): + self.interface_phy_rmon_stats = {} + + def get_interface_phy_rmon_stats_info(self, managed_object): + info = {} + for key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/phys-[eth1/1]/dbgEtherStats" + info['pod_id'] = info['dn'].split('/')[1] + info['node_id'] = info['dn'].split('/')[2] + info['interface_id'] = None + if info['dn'].split('/')[4].startswith('phys-'): + info['interface_id'] = info['dn'].split('phys-[')[1].split(']')[0] + + if info['dn'].split('/')[4].startswith('aggr-'): + info['interface_id'] = info['dn'].split('aggr-[')[1].split(']')[0] + + # topology/pod-1/node-205/sys/mgmt-[mgmt0]/dbgEtherStats + if info['dn'].split('/')[4].startswith('mgmt-'): + info['interface_id'] = info['dn'].split('mgmt-[')[1].split(']')[0] + + if info['dn'].split('/')[4].startswith('ctx-'): + # topology/pod-1/node-205/sys/ctx-[vxlan-2523141]/encrtd-[eth1/24.52]/dbgEtherStats + if info['dn'].split('/')[5].startswith('encrtd-'): + info['interface_id'] = info['dn'].split('encrtd-[')[1].split(']')[0] + info['context_id'] = info['dn'].split('ctx-[')[1].split(']')[0] + + # topology/pod-1/node-205/sys/ctx-[vxlan-2195458]/bd-[vxlan-16121819]/svi-[vlan11]/dbgEtherStats + if info['dn'].split('/')[5].startswith('bd-'): + info['interface_id'] = info['dn'].split('svi-[')[1].split(']')[0] + info['context_id'] = info['dn'].split('ctx-[')[1].split(']')[0] + + # topology/pod-1/node-205/sys/inst-overlay-1/encrtd-[eth1/35.9]/dbgEtherStats + if info['dn'].split('/')[4].startswith('inst-'): + info['interface_id'] = info['dn'].split('encrtd-[')[1].split(']')[0] + + if info['interface_id'] is None: + self.log.error( + 'get_interface_phy_rmon_info', + 'Unsupported dn: %s' % (info['dn']) + ) + + return info + + def get_interfaces_phy_rmon_stats_info(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_phy_rmon_stats: + return self.interface_phy_rmon_stats[key] + + managed_objects = self.get_interface_phy_rmon_stats_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_phy_rmon_stats[key] = [] + for managed_object in managed_objects: + self.interface_phy_rmon_stats[key].append( + self.get_interface_phy_rmon_stats_info( + managed_object + ) + ) + + return self.interface_phy_rmon_stats[key] + + def get_interface_phy_rmon_stats(self, pod_id, node_id, interface_id): + interfaces_info = self.get_interfaces_phy_rmon_stats_info(pod_id, node_id) + if interfaces_info is None: + return None + + for interface_info in interfaces_info: + if interface_id == interface_info['interface_id']: + return interface_info + + return None diff --git a/lib/aci/intf/phy/stats/rmon/main.py b/lib/aci/intf/phy/stats/rmon/main.py new file mode 100644 index 00000000..ff13bfdf --- /dev/null +++ b/lib/aci/intf/phy/stats/rmon/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.phy.stats.rmon.api import InterfacePhyRmonStatsApi +from lib.aci.intf.phy.stats.rmon.info import InterfacePhyRmonStatsInfo + + +class InterfacePhyRmonStats(InterfacePhyRmonStatsApi, InterfacePhyRmonStatsInfo): + def __init__(self): + InterfacePhyRmonStatsApi.__init__(self) + InterfacePhyRmonStatsInfo.__init__(self) diff --git a/lib/aci/intf/policy/__init__.py b/lib/aci/intf/policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/policy/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/policy/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..561083dd Binary files /dev/null and b/lib/aci/intf/policy/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/__pycache__/api.cpython-310.pyc b/lib/aci/intf/policy/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6e95f10a Binary files /dev/null and b/lib/aci/intf/policy/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/__pycache__/info.cpython-310.pyc b/lib/aci/intf/policy/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ae43dfb1 Binary files /dev/null and b/lib/aci/intf/policy/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/__pycache__/main.cpython-310.pyc b/lib/aci/intf/policy/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..734f5c7e Binary files /dev/null and b/lib/aci/intf/policy/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/group/__init__.py b/lib/aci/intf/policy/group/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/policy/group/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/policy/group/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2c68df4d Binary files /dev/null and b/lib/aci/intf/policy/group/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/group/__pycache__/api.cpython-310.pyc b/lib/aci/intf/policy/group/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..a8caf8ba Binary files /dev/null and b/lib/aci/intf/policy/group/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/group/__pycache__/info.cpython-310.pyc b/lib/aci/intf/policy/group/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..03d36baa Binary files /dev/null and b/lib/aci/intf/policy/group/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/group/__pycache__/main.cpython-310.pyc b/lib/aci/intf/policy/group/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2663ac17 Binary files /dev/null and b/lib/aci/intf/policy/group/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/group/info.py b/lib/aci/intf/policy/group/info.py new file mode 100644 index 00000000..806dddfc --- /dev/null +++ b/lib/aci/intf/policy/group/info.py @@ -0,0 +1,47 @@ +class InterfacePolicyGroupInfo(): + def __init__(self): + pass + + def get_interface_policy_group_selector(self, pod_id, node_id, interface_id, group_info=False): + node_profiles = self.get_node_interface_policy_profiles(pod_id, node_id) + if node_profiles is None: + return None + + for node_profile in node_profiles: + selector_info = self.get_interface_policy_profile_selectors(node_profile['name'], interface_id) + if selector_info is not None: + if group_info: + selector_info['policy_group_info'] = None + + if selector_info['policy_group_type'] == 'infraAccBndlGrp': + info = self.get_policy_groups_access_interface_vpc( + policy_group_filter=['name:%s' % (selector_info['policy_group_name'])], + aaep_info=True + ) + if info is not None and len(info) == 1: + selector_info['policy_group_info'] = info[0] + + if selector_info['policy_group_type'] == 'infraAccPortGrp': + info = self.get_policy_groups_access_interface_port( + policy_group_filter=['name:%s' % (selector_info['policy_group_name'])], + aaep_info=True + ) + if info is not None and len(info) == 1: + selector_info['policy_group_info'] = info[0] + + if selector_info['policy_group_type'] == 'infraBrkoutPortGrp': + info = self.get_policy_groups_access_interface_breakout( + policy_group_filter=['name:%s' % (selector_info['policy_group_name'])] + ) + if info is not None and len(info) == 1: + selector_info['policy_group_info'] = info[0] + + if selector_info['policy_group_type'] not in ['infraAccBndlGrp', 'infraAccPortGrp', 'infraBrkoutPortGrp']: + self.log.error( + 'get_interface_policy_group_selector', + 'Unsupported: %s' % (selector_info['policy_group_type']) + ) + + return selector_info + + return None diff --git a/lib/aci/intf/policy/group/main.py b/lib/aci/intf/policy/group/main.py new file mode 100644 index 00000000..f09019a2 --- /dev/null +++ b/lib/aci/intf/policy/group/main.py @@ -0,0 +1,6 @@ +from lib.aci.intf.policy.group.info import InterfacePolicyGroupInfo + + +class InterfacePolicyGroup(InterfacePolicyGroupInfo): + def __init__(self): + InterfacePolicyGroupInfo.__init__(self) diff --git a/lib/aci/intf/policy/main.py b/lib/aci/intf/policy/main.py new file mode 100644 index 00000000..5256f74d --- /dev/null +++ b/lib/aci/intf/policy/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.policy.group.main import InterfacePolicyGroup +from lib.aci.intf.policy.profile.main import InterfacePolicyProfile + + +class InterfacePolicy(InterfacePolicyGroup, InterfacePolicyProfile): + def __init__(self): + InterfacePolicyGroup.__init__(self) + InterfacePolicyProfile.__init__(self) diff --git a/lib/aci/intf/policy/profile/__init__.py b/lib/aci/intf/policy/profile/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/policy/profile/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/policy/profile/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2c68df4d Binary files /dev/null and b/lib/aci/intf/policy/profile/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/profile/__pycache__/api.cpython-310.pyc b/lib/aci/intf/policy/profile/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..50b522b2 Binary files /dev/null and b/lib/aci/intf/policy/profile/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/profile/__pycache__/info.cpython-310.pyc b/lib/aci/intf/policy/profile/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..099cd1e0 Binary files /dev/null and b/lib/aci/intf/policy/profile/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/profile/__pycache__/main.cpython-310.pyc b/lib/aci/intf/policy/profile/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..52f2e774 Binary files /dev/null and b/lib/aci/intf/policy/profile/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/policy/profile/api.py b/lib/aci/intf/policy/profile/api.py new file mode 100644 index 00000000..1e48788c --- /dev/null +++ b/lib/aci/intf/policy/profile/api.py @@ -0,0 +1,87 @@ +class InterfacePolicyProfileApi(): + def __init__(self): + self.interface_policy_profile_mo = {} + + def get_interface_policy_profile_mo(self, profile_name): + key = profile_name + if key in self.interface_policy_profile_mo: + return self.interface_policy_profile_mo[key] + + cache = self.get_object_cache( + 'accportprof', + object_selector=key + ) + if cache is not None: + self.interface_policy_profile_mo[key] = cache + self.log.apic_mo( + 'accportprof.%s' % (key), + self.interface_policy_profile_mo[key] + ) + return self.interface_policy_profile_mo[key] + + # https:///api/node/mo/uni/infra/accportprof-SPN_IntProf.json?query-target=subtree&target-subtree-class=infraHPortS,infraRsAccBaseGrp,infraPortBlk,infraSubPortBlk&_dc=1684139157872 + distinguished_name = 'uni/infra/accportprof-%s' % ( + profile_name + ) + + children = [ + 'infraHPortS', + 'infraRsAccBaseGrp', + 'infraPortBlk', + 'infraSubPortBlk' + ] + query = 'query-target=subtree&target-subtree-class=%s' % (','.join(children)) + + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_interface_policy_profile_mo', + 'API failed' + ) + return None + + self.interface_policy_profile_mo[key] = {} + self.interface_policy_profile_mo[key]['profile'] = profile_name + self.interface_policy_profile_mo[key]['infraHPortS'] = [] + self.interface_policy_profile_mo[key]['infraRsAccBaseGrp'] = [] + self.interface_policy_profile_mo[key]['infraPortBlk'] = [] + self.interface_policy_profile_mo[key]['infraSubPortBlk'] = [] + + for managed_object in managed_objects['imdata']: + if 'infraHPortS' in managed_object: + self.interface_policy_profile_mo[key]['infraHPortS'].append( + managed_object['infraHPortS']['attributes'] + ) + + if 'infraRsAccBaseGrp' in managed_object: + self.interface_policy_profile_mo[key]['infraRsAccBaseGrp'].append( + managed_object['infraRsAccBaseGrp']['attributes'] + ) + + if 'infraPortBlk' in managed_object: + self.interface_policy_profile_mo[key]['infraPortBlk'].append( + managed_object['infraPortBlk']['attributes'] + ) + + if 'infraSubPortBlk' in managed_object: + self.interface_policy_profile_mo[key]['infraSubPortBlk'].append( + managed_object['infraSubPortBlk']['attributes'] + ) + + self.log.apic_mo( + 'accportprof.%s' % (key), + self.interface_policy_profile_mo[key] + ) + + self.set_object_cache( + 'accportprof', + self.interface_policy_profile_mo[key], + object_selector=key + ) + + return self.interface_policy_profile_mo[key] diff --git a/lib/aci/intf/policy/profile/info.py b/lib/aci/intf/policy/profile/info.py new file mode 100644 index 00000000..af3ea64f --- /dev/null +++ b/lib/aci/intf/policy/profile/info.py @@ -0,0 +1,164 @@ +class InterfacePolicyProfileInfo(): + def __init__(self): + self.interface_policy_profile = {} + + def get_interface_policy_profile_info(self, managed_object): + info = {} + + info['profile'] = managed_object['profile'] + info['selectors'] = [] + + if managed_object['infraHPortS'] is not None: + for selector_mo in managed_object['infraHPortS']: + selector_info = {} + selector_info['profile'] = selector_mo['dn'].split('/')[2][12:] + selector_info['name'] = selector_mo['name'] + # dn: "uni/infra/accportprof-ESX-R3DC-DVS_IntProf/hports-ESX-R3DC_ParentSel-typ-range" + selector_info['dn'] = selector_mo['dn'] + selector_info['dn_name'] = selector_mo['dn'].split('/')[-1] + selector_info['block'] = [] + selector_info['policy_group_type'] = None + selector_info['policy_group_type_name'] = None + selector_info['policy_group_name'] = None + info['selectors'].append( + selector_info + ) + + if managed_object['infraRsAccBaseGrp'] is not None: + for port_group_mo in managed_object['infraRsAccBaseGrp']: + # dn: "uni/infra/accportprof-ESX-R3DC-DVS_IntProf/hports-ESX-R3DC_ParentSel-typ-range/portblk-3a62d357434b3409" + port_group_selector_dn_name = port_group_mo['dn'].split('/')[3] + for selector_info in info['selectors']: + if selector_info['dn_name'] == port_group_selector_dn_name: + if port_group_mo['tCl'] == 'infraAccPortGrp': + selector_info['policy_group_type'] = port_group_mo['tCl'] + selector_info['policy_group_type_name'] = 'Access' + # tDn: "uni/infra/funcprof/accportgrp-ESX-R3DC-DVS_PolGrp" + selector_info['policy_group_name'] = port_group_mo['tDn'].split('/')[3][11:] + break + + if port_group_mo['tCl'] == 'infraAccBndlGrp': + selector_info['policy_group_type'] = port_group_mo['tCl'] + selector_info['policy_group_type_name'] = 'PC/VPC' + # "tDn": "uni/infra/funcprof/accbundle-UCSB1-FI-A_PolGrp" + selector_info['policy_group_name'] = port_group_mo['tDn'].split('/')[3][10:] + break + + if port_group_mo['tCl'] == 'infraBrkoutPortGrp': + selector_info['policy_group_type'] = port_group_mo['tCl'] + selector_info['policy_group_type_name'] = 'Breakout' + # 'dn': 'uni/infra/accportprof-k8s_CL2207_IntProf/hports-k8s_CL2207_brk_25g_4x_ParentIntSel-typ-range/rsaccBaseGrp' + selector_info['policy_group_name'] = port_group_mo['tDn'].split('/')[3][12:] + break + + self.log.error( + 'get_interface_policy_profile_info', + 'Unsupported infraRsAccBaseGrp tCl: %s' % (port_group_mo['tCl']) + ) + + if managed_object['infraPortBlk'] is not None: + for port_block_mo in managed_object['infraPortBlk']: + # dn: "uni/infra/accportprof-ESX-R3DC-DVS_IntProf/hports-ESX-R3DC_ParentSel-typ-range/portblk-4507c5cf36080774" + port_block_selector_dn_name = port_block_mo['dn'].split('/')[3] + for selector_info in info['selectors']: + if selector_info['dn_name'] == port_block_selector_dn_name: + block_info = {} + block_info['fromCard'] = int(port_block_mo['fromCard']) + block_info['toCard'] = int(port_block_mo['toCard']) + block_info['fromPort'] = int(port_block_mo['fromPort']) + block_info['toPort'] = int(port_block_mo['toPort']) + block_info['fromSubPort'] = None + block_info['toSubPort'] = None + selector_info['block'].append( + block_info + ) + + if managed_object['infraSubPortBlk'] is not None: + for port_block_mo in managed_object['infraSubPortBlk']: + # dn: "uni/infra/accportprof-ESX-R3DC-DVS_IntProf/hports-ESX-R3DC_ParentSel-typ-range/portblk-4507c5cf36080774" + port_block_selector_dn_name = port_block_mo['dn'].split('/')[3] + for selector_info in info['selectors']: + if selector_info['dn_name'] == port_block_selector_dn_name: + block_info = {} + block_info['fromCard'] = int(port_block_mo['fromCard']) + block_info['toCard'] = int(port_block_mo['toCard']) + block_info['fromPort'] = int(port_block_mo['fromPort']) + block_info['toPort'] = int(port_block_mo['toPort']) + block_info['fromSubPort'] = int(port_block_mo['fromSubPort']) + block_info['toSubPort'] = int(port_block_mo['toSubPort']) + selector_info['block'].append( + block_info + ) + + return info + + def get_interface_policy_profile(self, profile_name): + if profile_name in self.interface_policy_profile: + return self.interface_policy_profile[profile_name] + + profile_mo = self.get_interface_policy_profile_mo(profile_name) + if profile_mo is None: + return None + + self.interface_policy_profile[profile_name] = self.get_interface_policy_profile_info(profile_mo) + + self.log.apic_mo( + 'accportprof.info.%s' % (profile_name), + self.interface_policy_profile[profile_name] + ) + + return self.interface_policy_profile[profile_name] + + def match_interface_policy_profile_selector_block(self, selector_info, interface_id): + card_id = int(interface_id.split('/')[0]) + port_id = int(interface_id.split('/')[1]) + sub_port_id = None + if len(interface_id.split('/')) == 3: + sub_port_id = int(interface_id.split('/')[2]) + + for block_info in selector_info['block']: + if block_info['fromSubPort'] is None and sub_port_id is not None: + continue + + if block_info['fromSubPort'] is not None and sub_port_id is None: + continue + + if block_info['toCard'] < card_id < block_info['toCard']: + return True + + if block_info['fromCard'] <= card_id <= block_info['toCard']: + if block_info['fromCard'] == block_info['toCard']: + if block_info['fromPort'] == port_id == block_info['toPort']: + if sub_port_id is None: + return True + + if block_info['fromSubPort'] <= sub_port_id <= block_info['toSubPort']: + return True + + if block_info['fromPort'] <= port_id <= block_info['toPort']: + if sub_port_id is None: + return True + + if block_info['fromSubPort'] <= sub_port_id <= block_info['toSubPort']: + return True + + continue + + if block_info['fromCard'] == card_id and port_id >= block_info['fromPort']: + return True + + if block_info['toCard'] == card_id and port_id <= block_info['toPort']: + return True + + return False + + def get_interface_policy_profile_selectors(self, profile_name, interface_id): + profile_info = self.get_interface_policy_profile(profile_name) + if profile_info is None: + return None + + for selector_info in profile_info['selectors']: + if self.match_interface_policy_profile_selector_block(selector_info, interface_id): + return selector_info + + return None diff --git a/lib/aci/intf/policy/profile/main.py b/lib/aci/intf/policy/profile/main.py new file mode 100644 index 00000000..5863969d --- /dev/null +++ b/lib/aci/intf/policy/profile/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.policy.profile.api import InterfacePolicyProfileApi +from lib.aci.intf.policy.profile.info import InterfacePolicyProfileInfo + + +class InterfacePolicyProfile(InterfacePolicyProfileApi, InterfacePolicyProfileInfo): + def __init__(self): + InterfacePolicyProfileApi.__init__(self) + InterfacePolicyProfileInfo.__init__(self) diff --git a/lib/aci/intf/port_channel/__init__.py b/lib/aci/intf/port_channel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/port_channel/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4e102512 Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/api.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..66a81d25 Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/info.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..fe7fa63b Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/main.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3efc66ce Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/members.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/members.cpython-310.pyc new file mode 100644 index 00000000..7ecbac4d Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/members.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/output.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..d48b2b50 Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/relations.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/relations.cpython-310.pyc new file mode 100644 index 00000000..3c55b9ac Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/relations.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/port_channel/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..183a3fbb Binary files /dev/null and b/lib/aci/intf/port_channel/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/api.py b/lib/aci/intf/port_channel/api.py new file mode 100644 index 00000000..d8ec76e0 --- /dev/null +++ b/lib/aci/intf/port_channel/api.py @@ -0,0 +1,92 @@ +class InterfacePortChannelApi(): + def __init__(self): + self.interfaces_pc_mo = {} + + def get_interface_port_channels_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interfaces_pc_mo: + return self.interfaces_pc_mo[key] + + cache = self.get_object_cache( + 'pcAggrIf', + object_selector=key + ) + if cache is not None: + self.interfaces_pc_mo[key] = cache + self.log.apic_mo( + 'pcAggrIf.%s' % (key), + self.interfaces_pc_mo[key] + ) + return self.interfaces_pc_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_port_channels_mo', + 'API failed' + ) + return None + + self.interfaces_pc_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['pcAggrIf']['attributes'] + attributes['ethpmAggrIf'] = self.get_mo_child_attributes( + 'pcAggrIf', + managed_object, + 'ethpmAggrIf', + include_grandchildren=True + ) + attributes['rmonIfOut'] = self.get_mo_child_attributes( + 'pcAggrIf', + managed_object, + 'rmonIfOut' + ) + attributes['rmonIfIn'] = self.get_mo_child_attributes( + 'pcAggrIf', + managed_object, + 'rmonIfIn' + ) + attributes['rmonEtherStats'] = self.get_mo_child_attributes( + 'pcAggrIf', + managed_object, + 'rmonEtherStats' + ) + attributes['pcRsMbrIfs'] = self.get_mo_children_attributes( + 'pcAggrIf', + managed_object, + 'pcRsMbrIfs', + include_grandchildren=True + ) + attributes['healthInst'] = self.get_mo_child_attributes( + 'pcAggrIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'pcAggrIf', + managed_object, + 'faultCounts' + ) + + self.interfaces_pc_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcAggrIf.%s' % (key), + self.interfaces_pc_mo[key] + ) + + self.set_object_cache( + 'pcAggrIf', + self.interfaces_pc_mo[key], + object_selector=key + ) + + return self.interfaces_pc_mo[key] diff --git a/lib/aci/intf/port_channel/audit/__init__.py b/lib/aci/intf/port_channel/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/port_channel/audit/api.py b/lib/aci/intf/port_channel/audit/api.py new file mode 100644 index 00000000..5d61debd --- /dev/null +++ b/lib/aci/intf/port_channel/audit/api.py @@ -0,0 +1,54 @@ +class InterfacePortChannelAuditApi(): + def __init__(self): + self.interface_port_channel_audit_mo = {} + + def get_interface_port_channel_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_audit_mo: + return self.interface_port_channel_audit_mo[key] + + cache = self.get_object_cache( + 'pcAggrIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_port_channel_audit_mo[key] = cache + self.log.apic_mo( + 'pcAggrIf.audit.%s' % (key), + self.interface_port_channel_audit_mo[key] + ) + return self.interface_port_channel_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_port_channel_audit_mo', + 'API failed' + ) + return None + + self.interface_port_channel_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_port_channel_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcAggrIf.audit.%s' % (key), + self.interface_port_channel_audit_mo[key] + ) + + self.set_object_cache( + 'pcAggrIf.audit', + self.interface_port_channel_audit_mo[key], + object_selector=key + ) + + return self.interface_port_channel_audit_mo[key] diff --git a/lib/aci/intf/port_channel/audit/info.py b/lib/aci/intf/port_channel/audit/info.py new file mode 100644 index 00000000..3195e1a1 --- /dev/null +++ b/lib/aci/intf/port_channel/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfacePortChannelAuditInfo(): + def __init__(self): + self.interface_port_channel_audit = {} + + def get_interface_port_channel_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if 'sys/aggr-[' in info['affected']: + info['interfaceId'] = info['affected'].split('sys/aggr-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_port_channel_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_audit: + return self.interface_port_channel_audit[key] + + managed_objects = self.get_interface_port_channel_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_port_channel_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_port_channel_audit_info( + managed_object + ) + self.interface_port_channel_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'pcAggrIf.auditRecord.info.%s' % (key), + self.interface_port_channel_audit[key] + ) + + return self.interface_port_channel_audit[key] + + def get_interface_port_channel_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_port_channel_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/port_channel/audit/main.py b/lib/aci/intf/port_channel/audit/main.py new file mode 100644 index 00000000..a1869961 --- /dev/null +++ b/lib/aci/intf/port_channel/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.port_channel.audit.api import InterfacePortChannelAuditApi +from lib.aci.intf.port_channel.audit.info import InterfacePortChannelAuditInfo + + +class InterfacePortChannelAudit(InterfacePortChannelAuditApi, InterfacePortChannelAuditInfo): + def __init__(self): + InterfacePortChannelAuditApi.__init__(self) + InterfacePortChannelAuditInfo.__init__(self) diff --git a/lib/aci/intf/port_channel/event/__init__.py b/lib/aci/intf/port_channel/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/port_channel/event/api.py b/lib/aci/intf/port_channel/event/api.py new file mode 100644 index 00000000..cbb8a71f --- /dev/null +++ b/lib/aci/intf/port_channel/event/api.py @@ -0,0 +1,54 @@ +class InterfacePortChannelEventApi(): + def __init__(self): + self.interface_port_channel_event_mo = {} + + def get_interface_port_channel_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_event_mo: + return self.interface_port_channel_event_mo[key] + + cache = self.get_object_cache( + 'pcAggrIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_port_channel_event_mo[key] = cache + self.log.apic_mo( + 'pcAggrIf.eventLog.%s' % (key), + self.interface_port_channel_event_mo[key] + ) + return self.interface_port_channel_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_port_channel_event_mo', + 'API failed' + ) + return None + + self.interface_port_channel_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_port_channel_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcAggrIf.eventLog.%s' % (key), + self.interface_port_channel_event_mo[key] + ) + + self.set_object_cache( + 'pcAggrIf.eventLog', + self.interface_port_channel_event_mo[key], + object_selector=key + ) + + return self.interface_port_channel_event_mo[key] diff --git a/lib/aci/intf/port_channel/event/info.py b/lib/aci/intf/port_channel/event/info.py new file mode 100644 index 00000000..a599eae1 --- /dev/null +++ b/lib/aci/intf/port_channel/event/info.py @@ -0,0 +1,115 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfacePortChannelEventInfo(): + def __init__(self): + self.interface_port_channel_event = {} + + def get_interface_port_channel_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/aggr-[po2]/aggrif + info['interfaceId'] = None + if len(info['affected'].split('/')) == 6: + if info['affected'].split('/')[4].startswith('aggr-'): + info['interfaceId'] = info['affected'].split('/')[4].split('-')[1].split('[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_port_channel_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_event: + return self.interface_port_channel_event[key] + + managed_objects = self.get_interface_port_channel_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_port_channel_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_port_channel_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_port_channel_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'pcAggrIf.eventLog.info.%s' % (key), + self.interface_port_channel_event[key] + ) + + return self.interface_port_channel_event[key] + + def get_interface_port_channel_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_port_channel_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/port_channel/event/main.py b/lib/aci/intf/port_channel/event/main.py new file mode 100644 index 00000000..d8ff72f1 --- /dev/null +++ b/lib/aci/intf/port_channel/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.port_channel.event.api import InterfacePortChannelEventApi +from lib.aci.intf.port_channel.event.info import InterfacePortChannelEventInfo + + +class InterfacePortChannelEvent(InterfacePortChannelEventApi, InterfacePortChannelEventInfo): + def __init__(self): + InterfacePortChannelEventApi.__init__(self) + InterfacePortChannelEventInfo.__init__(self) diff --git a/lib/aci/intf/port_channel/fault/__init__.py b/lib/aci/intf/port_channel/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/port_channel/fault/api.py b/lib/aci/intf/port_channel/fault/api.py new file mode 100644 index 00000000..69d281d5 --- /dev/null +++ b/lib/aci/intf/port_channel/fault/api.py @@ -0,0 +1,124 @@ +class InterfacePortChannelFaultApi(): + def __init__(self): + self.interface_port_channel_fault_mo = {} + self.interface_port_channel_fault_record_mo = {} + + def get_interface_port_channel_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_fault_mo: + return self.interface_port_channel_fault_mo[key] + + cache = self.get_object_cache( + 'pcAggrIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_port_channel_fault_mo[key] = cache + self.log.apic_mo( + 'pcAggrIf.fault.%s' % (key), + self.interface_port_channel_fault_mo[key] + ) + return self.interface_port_channel_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_port_channel_fault_mo', + 'API failed' + ) + return None + + self.interface_port_channel_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_port_channel_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcAggrIf.fault.%s' % (key), + self.interface_port_channel_fault_mo[key] + ) + + self.set_object_cache( + 'pcAggrIf.fault', + self.interface_port_channel_fault_mo[key], + object_selector=key + ) + + return self.interface_port_channel_fault_mo[key] + + def get_interface_port_channel_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_fault_record_mo: + return self.interface_port_channel_fault_record_mo[key] + + cache = self.get_object_cache( + 'pcAggrIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_port_channel_fault_record_mo[key] = cache + self.log.apic_mo( + 'pcAggrIf.faultRecord.%s' % (key), + self.interface_port_channel_fault_record_mo[key] + ) + return self.interface_port_channel_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/pcAggrIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_port_channel_fault_record_mo', + 'API failed' + ) + return None + + self.interface_port_channel_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_port_channel_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'pcAggrIf.faultRecord.%s' % (key), + self.interface_port_channel_fault_record_mo[key] + ) + + self.set_object_cache( + 'pcAggrIf.faultRecord', + self.interface_port_channel_fault_record_mo[key], + object_selector=key + ) + + return self.interface_port_channel_fault_record_mo[key] diff --git a/lib/aci/intf/port_channel/fault/info.py b/lib/aci/intf/port_channel/fault/info.py new file mode 100644 index 00000000..3c429fbe --- /dev/null +++ b/lib/aci/intf/port_channel/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfacePortChannelFaultInfo(): + def __init__(self): + self.interface_port_channel_fault = {} + self.interface_port_channel_fault_record = {} + + def get_interface_port_channel_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/aggr-[po2]/aggrif + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'sys/aggr-[' in info['affected']: + info['interfaceId'] = info['affected'].split('sys/aggr-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/aggr-[po1]/aggrif/fault-F0532" + if info['interfaceId'] is None: + if 'sys/aggr-[' in info['dn']: + info['interfaceId'] = info['dn'].split('sys/aggr-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_port_channel_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_fault: + return self.interface_port_channel_fault[key] + + managed_objects = self.get_interface_port_channel_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_port_channel_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_port_channel_fault_info( + managed_object + ) + self.interface_port_channel_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'pcAggrIf.fault.info.%s' % (key), + self.interface_port_channel_fault[key] + ) + + return self.interface_port_channel_fault[key] + + def get_interface_port_channel_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_port_channel_fault_record: + return self.interface_port_channel_fault_record[key] + + managed_objects = self.get_interface_port_channel_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_port_channel_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_port_channel_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_port_channel_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'pcAggrIf.faultRecord.info.%s' % (key), + self.interface_port_channel_fault_record[key] + ) + + return self.interface_port_channel_fault_record[key] + + def get_interface_port_channel_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_port_channel_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_port_channel_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/port_channel/fault/main.py b/lib/aci/intf/port_channel/fault/main.py new file mode 100644 index 00000000..f0cf4129 --- /dev/null +++ b/lib/aci/intf/port_channel/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.port_channel.fault.api import InterfacePortChannelFaultApi +from lib.aci.intf.port_channel.fault.info import InterfacePortChannelFaultInfo + + +class InterfacePortChannelFault(InterfacePortChannelFaultApi, InterfacePortChannelFaultInfo): + def __init__(self): + InterfacePortChannelFaultApi.__init__(self) + InterfacePortChannelFaultInfo.__init__(self) diff --git a/lib/aci/intf/port_channel/info.py b/lib/aci/intf/port_channel/info.py new file mode 100644 index 00000000..31498968 --- /dev/null +++ b/lib/aci/intf/port_channel/info.py @@ -0,0 +1,502 @@ +from lib import filter_helper + + +class InterfacePortChannelInfo(): + def __init__(self): + self.interfaces_pc = {} + + def get_interface_port_channel_count(self, pod_id, node_id): + interfaces = self.get_interface_port_channels(pod_id, node_id) + return len(interfaces) + + def get_interface_port_channel_state_info(self, managed_object): + if managed_object is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'accessVlan', + 'activeMbrs', + 'allowedVlans', + 'backplaneMac', + 'bundleBupId', + 'bundleIndex', + 'cfgAccessVlan', + 'cfgNativeVlan', + 'errVlans', + 'hwBdId', + 'hwResourceId', + 'intfT', + 'iod', + 'lastErrors', + 'lastLinkStChg', + 'nativeVlan', + 'numActivePorts', + 'numMbrUp', + 'operDceMode', + 'operDuplex', + 'operMode', + 'operRouterMac', + 'operSpeed', + 'operSt', + 'operStQual', + 'operVlans', + 'primaryVlan' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['portId'] = [] + for active_member in managed_object['activeMbrs'].split(','): + if active_member != 'unspecified': + info['portId'].append(active_member) + + info['portIds'] = ','.join(info['portId']) + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + if info['operStQual'] == 'none': + info['operStQual'] = '' + else: + info['__Output']['operSt'] = 'Red' + + if info['accessVlan'] == 'unknown': + info['accessVlan'] = '' + + if info['nativeVlan'] == 'unknown': + info['nativeVlan'] = '' + + if info['cfgAccessVlan'] == 'unknown': + info['cfgAccessVlan'] = '' + + if info['cfgNativeVlan'] == 'unknown': + info['cfgNativeVlan'] = '' + + return info + + def get_interface_port_channel_member_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'parentSKey', + 'rn', + 'state', + 'stateQual', + 'tCl', + 'tDn', + 'tSKey' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interface_port_channel_info(self, managed_object): + keys = [ + 'activePorts', + 'adminSt', + 'autoNeg', + 'bw', + 'ctrl', + 'delay', + 'dn', + 'dot1qEtherType', + 'ethpmCfgFailedBmp', + 'ethpmCfgFailedTs', + 'ethpmCfgState', + 'fcotChannelNumber', + 'fop', + 'hashDist', + 'id', + 'iod', + 'isPlatformSupported', + 'isReflectiveRelayCfgSupported', + 'lastBundleMbr', + 'lastBundleTime', + 'lastSt', + 'lastStCause', + 'lastUnbundleMbr', + 'lastUnbundleTime', + 'layer', + 'linkDebounce', + 'ltl', + 'maxActive', + 'maxLinks', + 'mdix', + 'medium', + 'minLinks', + 'mode', + 'mtu', + 'name', + 'operChannelMode', + 'pcId', + 'pcMode', + 'pcmCfgFailedBmp', + 'pcmCfgFailedTs', + 'pcmCfgState', + 'portT', + 'prioFlowCtrl', + 'reflectiveRelayEn', + 'routerMac', + 'snmpTrapSt', + 'spanMode', + 'speed', + 'suspMinlinks', + 'switchingSt', + 'usage', + 'rmonIfOut', + 'rmonIfIn', + 'rmonEtherStats' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['state'] = self.get_interface_port_channel_state_info(managed_object['ethpmAggrIf']) + info['state'] = self.my_output.merge_output( + info['state'] + ) + + info['member'] = [] + for member_managed_object in managed_object['pcRsMbrIfs']: + info['member'].append( + self.get_interface_port_channel_member_info( + member_managed_object + ) + ) + + info['memberCount'] = len(info['member']) + info['memberSummary'] = '%s/%s' % ( + info['activePorts'], + info['memberCount'] + ) + if int(info['activePorts']) < info['memberCount']: + info['__Output']['activePorts'] = 'Red' + info['__Output']['memberSummary'] = 'Red' + + for member in info['member']: + if member['tSKey'] in info['state']['portId']: + member['isActiveMemberTick'] = '\u2713' + member['__Output']['isActiveMemberTick'] = 'Green' + else: + member['isActiveMemberTick'] = '\u2717' + member['__Output']['isActiveMemberTick'] = 'Red' + + # topology/pod-1/node-201/sys/aggr-[po15] + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['layerT'] = '' + if info['layer'] == 'Layer2': + info['layerT'] = 'switched' + if info['layer'] == 'Layer3': + info['layerT'] = 'routed' + + info['__Output']['id'] = 'Blue' + + if info['adminSt'] == 'up': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['switchingSt'] == 'enabled': + info['__Output']['switchingSt'] = 'Green' + else: + info['__Output']['switchingSt'] = 'Red' + + if info['pcMode'] == 'active': + info['__Output']['pcMode'] = 'Green' + else: + info['__Output']['pcMode'] = 'Red' + + info['operChannelModeT'] = info['operChannelMode'] + if info['operChannelMode'] == 'active': + info['operChannelModeT'] = 'lacp-active' + info['__Output']['operChannelMode'] = 'Green' + info['__Output']['operChannelModeT'] = 'Green' + else: + info['__Output']['operChannelMode'] = 'Red' + info['__Output']['operChannelModeT'] = 'Red' + + info['up'] = False + if info['adminSt'] == 'up' and info['state']['operSt'] == 'up': + info['up'] = True + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interface_port_channels_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interfaces_pc: + return self.interfaces_pc[key] + + interfaces_pc_mo = self.get_interface_port_channels_mo(pod_id, node_id) + if interfaces_pc_mo is None: + return None + + self.interfaces_pc[key] = [] + for interface_pc_mo in interfaces_pc_mo: + self.interfaces_pc[key].append( + self.get_interface_port_channel_info( + interface_pc_mo + ) + ) + + self.log.apic_mo( + 'pcAggrIf.info.%s' % (key), + self.interfaces_pc[key] + ) + + return self.interfaces_pc[key] + + def match_interface_port_channel(self, interface_port_channel_info, interface_port_channel_filter): + if interface_port_channel_filter is None or len(interface_port_channel_filter) == 0: + return True + + for ap_rule in interface_port_channel_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + found = False + + if key == 'id': + found = True + if not filter_helper.match_string(value, interface_port_channel_info['id']): + return False + + if key == 'name': + found = True + if not filter_helper.match_string(value, interface_port_channel_info['name']): + return False + + if key == 'domain': + found = True + if 'vpcDomain' in interface_port_channel_info: + if not filter_helper.match_string(value, interface_port_channel_info['vpcDomain']): + return False + + if key == 'speed': + found = True + if not filter_helper.match_string(value, interface_port_channel_info['state']['operSpeed']): + return False + + if key == 'state': + found = True + if value != 'any': + if not filter_helper.match_string(value, interface_port_channel_info['state']['operSt']): + return False + + if key == 'fault': + found = True + if value == 'any': + if not interface_port_channel_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_port_channel', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not found: + self.log.error( + 'match_interface_port_channel', + 'Unsupported filtering key: %s' % (key) + ) + + return True + + def get_interface_port_channel( + self, + pod_id, + node_id, + interface_port_channel_filter=None, + vpc_domain_info=False, + vpc_domains=None, + lacp_info=False, + member_info=False, + vlan_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interface_port_channels = self.get_interface_port_channels_info(pod_id, node_id) + if all_interface_port_channels is None: + return None + + interface_port_channels = [] + + for interface_port_channel_info in all_interface_port_channels: + if not self.match_interface_port_channel(interface_port_channel_info, interface_port_channel_filter): + continue + + if member_info: + for member in interface_port_channel_info['member']: + member = self.get_interface_port_channel_member_phy_info( + pod_id, + node_id, + member + ) + + if lacp_info: + interface_port_channel_info['lacp'] = self.get_interface_port_channel_lacp_members( + pod_id, + node_id, + interface_port_channel_info + ) + + if vlan_info: + interface_port_channel_info['vlan'] = [] + if len(interface_port_channel_info['state']['operVlans']) > 0: + vlans = self.get_oper_vlans_list( + interface_port_channel_info['state']['operVlans'] + ) + interface_port_channel_info['vlan'] = self.get_vlan_stats( + pod_id, + node_id, + vlan_filter=['vlans:%s' % (','.join(vlans))] + ) + + if vpc_domain_info: + interface_port_channel_info['vpcDomain'] = '' + interface_port_channel_info['__Output']['vpcDomain'] = 'Yellow' + if vpc_domains is None: + vpc_domains = self.get_interface_virtual_port_channel( + pod_id=pod_id, + node_id=node_id + ) + + for vpc_domain in vpc_domains: + for vpc_domain_member in vpc_domain['member']: + if vpc_domain_member['name'] == interface_port_channel_info['name']: + interface_port_channel_info['vpcDomain'] = vpc_domain['id'] + break + + if not self.match_interface_port_channel(interface_port_channel_info, interface_port_channel_filter): + continue + + if fault_info: + interface_port_channel_info['faultInst'] = self.get_interface_port_channel_id_fault( + pod_id, + node_id, + interface_port_channel_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_port_channel_info['faultRecord'] = self.get_interface_port_channel_id_fault( + pod_id, + node_id, + interface_port_channel_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_port_channel_info['eventLog'] = self.get_interface_port_channel_id_event( + pod_id, + node_id, + interface_port_channel_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_port_channel_info['auditLog'] = self.get_interface_port_channel_id_audit( + pod_id, + node_id, + interface_port_channel_info['id'], + audit_filter=audit_filter + ) + + interface_port_channels.append( + interface_port_channel_info + ) + + interface_port_channels = sorted( + interface_port_channels, + key=lambda i: int(i['id'][2:]) + ) + + return interface_port_channels + + def get_interface_port_channel_summary(self, pod_id, node_id): + ports = self.get_interface_port_channel( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + if summary['portDown'] > 0: + summary['__Output']['portDown'] = 'Red' + + return summary diff --git a/lib/aci/intf/port_channel/main.py b/lib/aci/intf/port_channel/main.py new file mode 100644 index 00000000..3d77ee0b --- /dev/null +++ b/lib/aci/intf/port_channel/main.py @@ -0,0 +1,26 @@ +from lib.aci.intf.port_channel.members.main import InterfacePortChannelMembers +from lib.aci.intf.port_channel.relations.main import InterfacePortChannelRelations +from lib.aci.intf.port_channel.api import InterfacePortChannelApi +from lib.aci.intf.port_channel.info import InterfacePortChannelInfo +from lib.aci.intf.port_channel.audit.main import InterfacePortChannelAudit +from lib.aci.intf.port_channel.event.main import InterfacePortChannelEvent +from lib.aci.intf.port_channel.fault.main import InterfacePortChannelFault + + +class InterfacePortChannel( + InterfacePortChannelApi, + InterfacePortChannelInfo, + InterfacePortChannelMembers, + InterfacePortChannelRelations, + InterfacePortChannelAudit, + InterfacePortChannelEvent, + InterfacePortChannelFault + ): + def __init__(self): + InterfacePortChannelMembers.__init__(self) + InterfacePortChannelRelations.__init__(self) + InterfacePortChannelApi.__init__(self) + InterfacePortChannelInfo.__init__(self) + InterfacePortChannelAudit.__init__(self) + InterfacePortChannelEvent.__init__(self) + InterfacePortChannelFault.__init__(self) diff --git a/lib/aci/intf/port_channel/members/__init__.py b/lib/aci/intf/port_channel/members/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/port_channel/members/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/port_channel/members/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..566a7082 Binary files /dev/null and b/lib/aci/intf/port_channel/members/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/members/__pycache__/main.cpython-310.pyc b/lib/aci/intf/port_channel/members/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..cbf25c92 Binary files /dev/null and b/lib/aci/intf/port_channel/members/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/members/main.py b/lib/aci/intf/port_channel/members/main.py new file mode 100644 index 00000000..88e763e3 --- /dev/null +++ b/lib/aci/intf/port_channel/members/main.py @@ -0,0 +1,63 @@ +class InterfacePortChannelMembers(): + def __init__(self): + pass + + def get_interface_port_channel_member_phy_info(self, pod_id, node_id, member_info): + inteface_phy_info = self.get_interface_phy( + pod_id, + node_id, + member_info['tSKey'] + ) + if inteface_phy_info is not None: + member_info['adminSt'] = inteface_phy_info['adminSt'] + member_info['__Output']['adminSt'] = inteface_phy_info['__Output']['adminSt'] + member_info['operSt'] = inteface_phy_info['stats']['operSt'] + member_info['__Output']['operSt'] = inteface_phy_info['__Output']['stats.operSt'] + member_info['operMode'] = inteface_phy_info['stats']['operMode'] + member_info['operDuplex'] = inteface_phy_info['stats']['operDuplex'] + member_info['operSpeed'] = inteface_phy_info['stats']['operSpeed'] + member_info['operVlans'] = inteface_phy_info['stats']['operVlans'] + + return member_info + + def get_interface_port_channel_lacp_members(self, pod_id, node_id, interface_info): + lacp_members = [] + for member_info in interface_info['member']: + lacp_info = {} + lacp_info['__Output'] = {} + lacp_info['pod_node_name'] = interface_info['pod_node_name'] + lacp_info['id'] = interface_info['id'] + lacp_info['__Output']['id'] = interface_info['__Output']['id'] + lacp_info['isActiveMemberTick'] = member_info['isActiveMemberTick'] + lacp_info['__Output']['isActiveMemberTick'] = member_info['__Output']['isActiveMemberTick'] + + lacp_info['adjacency'] = self.get_lacp_adjacency_endpoint( + pod_id, + node_id, + member_info['tSKey'], + allow_multiple=False + ) + + lacp_info['local'] = self.get_interface_lacp( + pod_id, + node_id, + interface_filter=['id:%s' % (member_info['tSKey'])] + )[0] + lacp_info['local'] = self.my_output.merge_output( + lacp_info['local'] + ) + + lacp_info['stats'] = self.get_interface_lacp_stats( + pod_id, + node_id, + member_info['tSKey'] + ) + lacp_info['stats'] = self.my_output.merge_output( + lacp_info['stats'] + ) + + lacp_members.append( + lacp_info + ) + + return lacp_members diff --git a/lib/aci/intf/port_channel/output.py b/lib/aci/intf/port_channel/output.py new file mode 100644 index 00000000..41ab29e5 --- /dev/null +++ b/lib/aci/intf/port_channel/output.py @@ -0,0 +1,761 @@ +class InterfacePortChannelOutput(): + def __init__(self): + pass + + def print_interfaces_port_channel_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'name', + 'operChannelModeT', + 'adminSt', + 'state.operSt', + 'state.operStQual', + 'vpcDomain', + 'memberSummary', + 'layerT', + 'state.operMode', + 'state.operSpeed' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Id', + 'Name', + 'Protocol', + 'Admin', + 'State', + 'Reason', + 'VPC', + 'Members', + 'Layer', + 'Mode', + 'Speed' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_port_channel_member(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel Member - Phy State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'member.isActiveMemberTick', + 'member.tSKey', + 'member.health', + 'member.faults', + 'member.adminSt', + 'member.operSt', + 'member.operMode', + 'member.operDuplex', + 'member.operSpeed', + 'member.operVlans' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Id', + 'Active', + 'Interface Id', + 'Health', + 'Faults', + 'Admin', + 'Oper', + 'Mode', + 'Duplex', + 'Speed', + 'VLAN' + ] + + row_separator = False + for item in info: + if len(item['member']) > 1: + row_separator = True + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['member'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=row_separator, + underline=True, + table=True + ) + + def print_interfaces_port_channel_lacp(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel Member - LACP State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'id', + 'isActiveMemberTick', + 'local.id', + 'local.adminSt', + 'local.port', + 'local.operPrio', + 'local.activityFlags', + 'local.key' + ] + + headers = [ + 'Node', + 'Id', + 'Active', + 'Interface', + 'Admin', + 'Port Num', + 'Port Priority', + 'Activity Flags', + 'Key' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if title: + self.my_output.default( + 'Interface Port Channel Member - LACP Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'id', + 'isActiveMemberTick', + 'local.id', + 'adjacency.port', + 'adjacency.portPrio', + 'adjacency.sysId', + 'adjacency.activityFlags', + 'adjacency.key' + ] + + headers = [ + 'Node', + 'Id', + 'Active', + 'Interface', + 'Nbr Port Num', + 'Nbr Port Priority', + 'Nbr System Id', + 'Nbr Activity Flags', + 'Nbr Key' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if title: + self.my_output.default( + 'Interface Port Channel Member - LACP PDU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'id', + 'isActiveMemberTick', + 'local.id', + 'stats.pduSent', + 'stats.pduRcvd', + 'stats.pduTimeOut', + 'stats.markerSent', + 'stats.markerRcvd', + 'stats.markerRspSent', + 'stats.markerRspRcvd' + ] + + headers = [ + 'Node', + 'Id', + 'Active', + 'Interface', + 'PDU Sent', + 'PDU Rcvd', + 'PDU Timeout', + 'Marker Sent', + 'Marker Rcvd', + 'Marker Rsp Sent', + 'Marker Rsp Rcvd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_port_channel_vlan(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel - VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'state.allowedVlans', + 'state.operVlans', + 'state.primaryVlan', + 'vlan.id', + 'vlan.hwId', + 'vlan.encap', + 'vlan.name', + 'vlan.fabEncap' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Id', + 'Allowed VLANs', + 'Oper VLANs', + 'Primary VLAN', + 'VLAN ID', + 'HW ID', + 'Encap', + 'EPG', + 'Fabric Encap' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlan'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interfaces_port_channel_stats(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel - Traffic Counters [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'rmonIfIn.octets', + 'rmonIfIn.nUcastPkts', + 'rmonIfIn.multicastPkts', + 'rmonIfIn.broadcastPkts', + 'rmonIfIn.discards', + 'rmonIfIn.errors', + 'rmonIfOut.octets', + 'rmonIfOut.nUcastPkts', + 'rmonIfOut.multicastPkts', + 'rmonIfOut.broadcastPkts', + 'rmonIfOut.discards', + 'rmonIfOut.errors', + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Id', + 'Bytes In', + 'Ucast', + 'Mcast', + 'Bcast', + 'Disc', + 'Err', + 'Bytes Out', + 'Ucast', + 'Mcast', + 'Bcast', + 'Disc', + 'Err', + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=False, + underline=True, + table=True + ) + + def print_interfaces_port_channel_ether(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel - Ether Counters [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'rmonEtherStats.pkts', + 'rmonEtherStats.octets', + 'rmonEtherStats.multicastPkts', + 'rmonEtherStats.broadcastPkts', + 'rmonEtherStats.pkts64Octets', + 'rmonEtherStats.pkts65to127Octets', + 'rmonEtherStats.pkts128to255Octets', + 'rmonEtherStats.pkts256to511Octets', + 'rmonEtherStats.pkts512to1023Octets', + 'rmonEtherStats.pkts1024to1518Octets' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Id', + 'Packets', + 'Bytes', + 'Mcast', + 'Bcast', + '<64B', + '65B-127B', + '128B-255B', + '256B-511B', + '512B-1023B', + '1024B-1518B' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=False, + underline=True, + table=True + ) + + def print_interface_port_channel_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Port Channel - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Port Channel Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_port_channel_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Port Channel - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_port_channel_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Port Channel - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Port Channel - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_port_channel_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Port Channel - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Port Channel - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_port_channel_summary(self, interface): + order = [ + 'apic', + 'pod_node_name', + 'id', + 'name', + 'adminSt', + 'switchingSt', + 'operChannelMode', + 'layerT', + 'minLinks', + 'maxLinks', + 'activePorts', + 'mode', + 'speed', + 'state.backplaneMac', + 'vpcDomain' + + ] + + headers = [ + 'Apic', + 'Node', + 'Id', + 'Name', + 'Admin State', + 'Switching State', + 'Operational Mode', + 'Layer', + 'Min Links', + 'Max Links', + 'Active Links', + 'Mode', + 'Speed', + 'MAC Address', + 'vpcDomain' + ] + + self.my_output.dictionary( + interface, + title='Interface Port Channel', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_interface_port_channel_vlan(self, interface): + order = [ + 'state.allowedVlans', + 'state.operVlans', + 'state.cfgAccessVlan', + 'state.accessVlan', + 'state.cfgNativeVlan', + 'state.nativeVlan' + ] + + headers = [ + 'Allowed VLANs', + 'Oper VLANs', + 'Configured Access VLAN', + 'Access VLAN', + 'Configured Native VLAN', + 'Native VLAN' + ] + + self.my_output.dictionary( + interface, + title='VLANs', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/intf/port_channel/relations/__init__.py b/lib/aci/intf/port_channel/relations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/port_channel/relations/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/port_channel/relations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f6cb31bb Binary files /dev/null and b/lib/aci/intf/port_channel/relations/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/relations/__pycache__/api.cpython-310.pyc b/lib/aci/intf/port_channel/relations/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8d413d86 Binary files /dev/null and b/lib/aci/intf/port_channel/relations/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/relations/__pycache__/info.cpython-310.pyc b/lib/aci/intf/port_channel/relations/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..61be933d Binary files /dev/null and b/lib/aci/intf/port_channel/relations/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/relations/__pycache__/main.cpython-310.pyc b/lib/aci/intf/port_channel/relations/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..fa8e7960 Binary files /dev/null and b/lib/aci/intf/port_channel/relations/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/port_channel/relations/api.py b/lib/aci/intf/port_channel/relations/api.py new file mode 100644 index 00000000..4da230f3 --- /dev/null +++ b/lib/aci/intf/port_channel/relations/api.py @@ -0,0 +1,59 @@ +class InterfacePortChannelRelationsApi(): + def __init__(self): + self.interface_pc_relations_mo = {} + + def get_interface_port_channel_relations_mo(self, pod_id, node_id, port_channel_id): + key = '%s.%s.%s' % ( + pod_id, + node_id, + port_channel_id + ) + if key in self.interface_pc_relations_mo: + return self.interface_pc_relations_mo[key] + + cache = self.get_object_cache( + 'pcAggrIfRelations', + object_selector=key + ) + if cache is not None: + self.interface_pc_relations_mo[key] = cache + self.log.apic_mo( + 'pcAggrIfRelations.%s' % (key), + self.interface_pc_relations_mo[key] + ) + return self.interface_pc_relations_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/aggr-[%s]' % (pod_id, node_id, port_channel_id) + query = 'rsp-subtree-include=relations' + + managed_object = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_object is None: + self.log.error( + 'get_interface_port_channel_relations', + 'API failed' + ) + return None + + self.interface_pc_relations_mo[key] = {} + for section in managed_object['imdata']: + for section_key in section: + self.interface_pc_relations_mo[key][section_key] = {} + for attribute in section[section_key]['attributes']: + self.interface_pc_relations_mo[key][section_key][attribute] = section[section_key]['attributes'][attribute] + + self.log.apic_mo( + 'pcAggrIfRelations.%s' % (key), + self.interface_pc_relations_mo[key] + ) + + self.set_object_cache( + 'pcAggrIfRelations', + self.interface_pc_relations_mo[key], + object_selector=key + ) + + return self.interface_pc_relations_mo[key] diff --git a/lib/aci/intf/port_channel/relations/info.py b/lib/aci/intf/port_channel/relations/info.py new file mode 100644 index 00000000..e30904ad --- /dev/null +++ b/lib/aci/intf/port_channel/relations/info.py @@ -0,0 +1,22 @@ +class InterfacePortChannelRelationsInfo(): + def __init__(self): + pass + + def get_interface_port_channel_relations_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_interface_port_channel_relations(self, pod_id, node_id, port_channel_id): + managed_object = self.get_interface_port_channel_relations_mo( + pod_id, + node_id, + port_channel_id + ) + if managed_object is None: + return None + + return self.get_interface_port_channel_relations_info(managed_object) diff --git a/lib/aci/intf/port_channel/relations/main.py b/lib/aci/intf/port_channel/relations/main.py new file mode 100644 index 00000000..27f7e457 --- /dev/null +++ b/lib/aci/intf/port_channel/relations/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.port_channel.relations.api import InterfacePortChannelRelationsApi +from lib.aci.intf.port_channel.relations.info import InterfacePortChannelRelationsInfo + + +class InterfacePortChannelRelations(InterfacePortChannelRelationsApi, InterfacePortChannelRelationsInfo): + def __init__(self): + InterfacePortChannelRelationsApi.__init__(self) + InterfacePortChannelRelationsInfo.__init__(self) diff --git a/lib/aci/intf/summary/__init__.py b/lib/aci/intf/summary/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/summary/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/summary/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..249ae00b Binary files /dev/null and b/lib/aci/intf/summary/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/summary/__pycache__/main.cpython-310.pyc b/lib/aci/intf/summary/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..dc7a7d46 Binary files /dev/null and b/lib/aci/intf/summary/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/summary/__pycache__/output.cpython-310.pyc b/lib/aci/intf/summary/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e606de92 Binary files /dev/null and b/lib/aci/intf/summary/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/summary/main.py b/lib/aci/intf/summary/main.py new file mode 100644 index 00000000..1b5f90cd --- /dev/null +++ b/lib/aci/intf/summary/main.py @@ -0,0 +1,254 @@ +import time + +import concurrent.futures +from concurrent.futures import ProcessPoolExecutor + + +class InterfaceSummary(): + def __init__(self): + self.interface_types = [ + 'cloudsec', + 'fc', + 'fcpc', + 'l3e', + 'lb', + 'macsec', + 'mgmt', + 'pc', + 'phy', + 'svi', + 'tun', + 'vfc', + 'vpc' + ] + + def get_interface_summary_output(self, port_up, port_down, port_count): + if port_up == 0 and port_down == 0 and port_count == 0: + return ('0/0/0', '') + + output = '' + color = ':' + + output = '%s%s/' % (output, port_up) + port_color = ''.join(['G' * len(str(port_up))]) + color = '%s%s.' % (color, port_color) + + output = '%s%s/' % (output, port_down) + if port_down == 0: + port_color = '.' + color = '%s%s.' % (color, port_color) + else: + port_color = ''.join(['R' * len(str(port_down))]) + color = '%s%s.' % (color, port_color) + + output = '%s%s' % (output, port_count) + port_color = ''.join(['.' * len(str(port_up))]) + color = '%s%s' % (color, port_color) + + return (output, color) + + def get_interface_type_summary(self, pod_id, node_id, interface_type): + if interface_type == 'cloudsec': + interfaces = self.get_interface_cloudsec_summary( + pod_id, + node_id + ) + + if interface_type == 'fc': + interfaces = self.get_interface_fc_summary( + pod_id, + node_id + ) + + if interface_type == 'fcpc': + interfaces = self.get_interface_fcpc_summary( + pod_id, + node_id + ) + + if interface_type == 'l3e': + interfaces = self.get_interface_encap_routed_summary( + pod_id, + node_id + ) + + if interface_type == 'lb': + interfaces = self.get_interface_looback_summary( + pod_id, + node_id + ) + + if interface_type == 'macsec': + interfaces = self.get_interface_macsec_summary( + pod_id, + node_id + ) + + if interface_type == 'mgmt': + interfaces = self.get_interface_management_summary( + pod_id, + node_id + ) + + if interface_type == 'pc': + interfaces = self.get_interface_port_channel_summary( + pod_id, + node_id + ) + + if interface_type == 'phy': + interfaces = self.get_interfaces_phy_summary( + pod_id, + node_id + ) + + if interface_type == 'svi': + interfaces = self.get_interface_svi_summary( + pod_id, + node_id + ) + + if interface_type == 'tun': + interfaces = self.get_interface_tunnel_summary( + pod_id, + node_id + ) + + if interface_type == 'vfc': + interfaces = self.get_interface_vfc_summary( + pod_id, + node_id + ) + + if interface_type == 'vpc': + interfaces = self.get_interface_virtual_port_channel_summary( + pod_id, + node_id + ) + + self.log.apic_mo( + 'intf_%s_summary' % (interface_type), + interfaces + ) + + def get_interface_summary(self, pod_id=None, node_id=None): + start_time = int(time.time() * 1000) + self.log.debug( + 'get_interface_summary', + 'Start summary collection preparation' + ) + + with ProcessPoolExecutor() as executor: + pool = [executor.submit(self.get_interface_type_summary, pod_id, node_id, key) for key in self.interface_types] + result = concurrent.futures.wait( + pool, + timeout=30, + return_when=concurrent.futures.ALL_COMPLETED + ) + self.log.debug( + 'get_interface_summary', + 'Not completed: %s' % (str(result[1])) + ) + executor.shutdown( + wait=False, + cancel_futures=True + ) + + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_interface_summary', + 'Finished summary collection: %s ms' % (duration) + ) + + summary = {} + summary['__Output'] = {} + for key in self.interface_types: + summary[key] = self.log.get_apic_mo('intf_%s_summary' % (key)) + if summary[key] is None: + self.log.error( + 'get_interface_summary', + 'Failed with %s' % (key) + ) + continue + + for item in summary[key]['__Output']: + summary['__Output']['%s.%s' % (key, item)] = summary[key]['__Output'][item] + + return summary + + def print_interface_summary(self, summary): + order = [ + 'cloudsec.portSummary', + 'fc.portSummary', + 'fcpc.portSummary', + 'l3e.portSummary', + 'lb.portSummary', + 'macsec.portSummary', + 'mgmt.portSummary', + 'pc.portSummary', + 'phy.portSummary', + 'svi.portSummary', + 'tun.portSummary', + 'vfc.portSummary', + 'vpc.portSummary' + ] + + headers = [ + 'cloudsec', + 'fc', + 'fcpc', + 'l3e', + 'lb', + 'macsec', + 'mgmt', + 'pc', + 'phy', + 'svi', + 'tun', + 'vfc', + 'vpc' + ] + + self.my_output.dictionary( + summary, + title='Interface State Summary', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + order = [ + 'uplinkSummary', + 'downlinkSummary', + '100MSummary', + '1GSummary', + '10GSummary', + '25GSummary', + '40GSummary', + '100GSummary', + '400GSummary' + ] + + headers = [ + 'Uplink', + 'Downlink', + '100M', + '1G', + '10G', + '25G', + '40G', + '100G', + '400G' + ] + + self.my_output.dictionary( + summary['phy'], + title='Physical Interfaces', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/intf/summary/output.py b/lib/aci/intf/summary/output.py new file mode 100644 index 00000000..b10cf961 --- /dev/null +++ b/lib/aci/intf/summary/output.py @@ -0,0 +1,86 @@ +import time + +import concurrent.futures +from concurrent.futures import ProcessPoolExecutor + + +class InterfaceSummaryOutput(): + def __init__(self): + pass + + def print_interface_summary(self, summary): + order = [ + 'cloudsec.portSummary', + 'fc.portSummary', + 'fcpc.portSummary', + 'l3e.portSummary', + 'lb.portSummary', + 'macsec.portSummary', + 'mgmt.portSummary', + 'pc.portSummary', + 'phy.portSummary', + 'svi.portSummary', + 'tun.portSummary', + 'vfc.portSummary', + 'vpc.portSummary' + ] + + headers = [ + 'cloudsec', + 'fc', + 'fcpc', + 'l3e', + 'lb', + 'macsec', + 'mgmt', + 'pc', + 'phy', + 'svi', + 'tun', + 'vfc', + 'vpc' + ] + + self.my_output.dictionary( + summary, + title='Interface State Summary', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + order = [ + 'uplinkSummary', + 'downlinkSummary', + '100MSummary', + '1GSummary', + '10GSummary', + '25GSummary', + '40GSummary', + '100GSummary', + '400GSummary' + ] + + headers = [ + 'Uplink', + 'Downlink', + '100M', + '1G', + '10G', + '25G', + '40G', + '100G', + '400G' + ] + + self.my_output.dictionary( + summary['phy'], + title='Physical Interfaces', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/intf/svi/__init__.py b/lib/aci/intf/svi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/svi/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/svi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2957214c Binary files /dev/null and b/lib/aci/intf/svi/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/__pycache__/api.cpython-310.pyc b/lib/aci/intf/svi/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..556b2535 Binary files /dev/null and b/lib/aci/intf/svi/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/__pycache__/info.cpython-310.pyc b/lib/aci/intf/svi/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..774565b9 Binary files /dev/null and b/lib/aci/intf/svi/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/__pycache__/main.cpython-310.pyc b/lib/aci/intf/svi/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4ee6b4f2 Binary files /dev/null and b/lib/aci/intf/svi/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/__pycache__/output.cpython-310.pyc b/lib/aci/intf/svi/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..726174b7 Binary files /dev/null and b/lib/aci/intf/svi/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/svi/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..22ced4c6 Binary files /dev/null and b/lib/aci/intf/svi/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/api.py b/lib/aci/intf/svi/api.py new file mode 100644 index 00000000..cf118f00 --- /dev/null +++ b/lib/aci/intf/svi/api.py @@ -0,0 +1,70 @@ +class InterfaceSviApi(): + def __init__(self): + self.interface_svi_mo = {} + + def get_interface_svi_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_svi_mo: + return self.interface_svi_mo[key] + + cache = self.get_object_cache( + 'sviIf', + object_selector=key + ) + if cache is not None: + self.interface_svi_mo[key] = cache + self.log.apic_mo( + 'sviIf.%s' % (key), + self.interface_svi_mo[key] + ) + return self.interface_svi_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2BD' % (pod_id, node_id) + query = 'rsp-subtree=full&rsp-subtree-class=sviIf&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_svi_mo', + 'API failed' + ) + return None + + self.interface_svi_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2BD']['attributes'] + for section in managed_object['l2BD']['children']: + for section_key in section: + if section_key == 'sviIf': + attributes[section_key] = {} + for attribute in section[section_key]['attributes']: + attributes[section_key][attribute] = section[section_key]['attributes'][attribute] + + for sub_section in section[section_key]['children']: + for sub_section_key in sub_section: + attributes[sub_section_key] = {} + for attribute in sub_section[sub_section_key]['attributes']: + attributes[sub_section_key][attribute] = sub_section[sub_section_key]['attributes'][attribute] + + self.interface_svi_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'sviIf.%s' % (key), + self.interface_svi_mo[key] + ) + + self.set_object_cache( + 'sviIf', + self.interface_svi_mo[key], + object_selector=key + ) + + return self.interface_svi_mo[key] diff --git a/lib/aci/intf/svi/audit/__init__.py b/lib/aci/intf/svi/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/svi/audit/api.py b/lib/aci/intf/svi/audit/api.py new file mode 100644 index 00000000..6e6690f7 --- /dev/null +++ b/lib/aci/intf/svi/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceSviAuditApi(): + def __init__(self): + self.interface_svi_audit_mo = {} + + def get_interface_svi_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_audit_mo: + return self.interface_svi_audit_mo[key] + + cache = self.get_object_cache( + 'sviIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_svi_audit_mo[key] = cache + self.log.apic_mo( + 'sviIf.audit.%s' % (key), + self.interface_svi_audit_mo[key] + ) + return self.interface_svi_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/sviIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_svi_audit_mo', + 'API failed' + ) + return None + + self.interface_svi_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_svi_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'sviIf.audit.%s' % (key), + self.interface_svi_audit_mo[key] + ) + + self.set_object_cache( + 'sviIf.audit', + self.interface_svi_audit_mo[key], + object_selector=key + ) + + return self.interface_svi_audit_mo[key] diff --git a/lib/aci/intf/svi/audit/info.py b/lib/aci/intf/svi/audit/info.py new file mode 100644 index 00000000..45b08419 --- /dev/null +++ b/lib/aci/intf/svi/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceSviAuditInfo(): + def __init__(self): + self.interface_svi_audit = {} + + def get_interface_svi_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/svi-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/svi-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_svi_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_audit: + return self.interface_svi_audit[key] + + managed_objects = self.get_interface_svi_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_svi_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_svi_audit_info( + managed_object + ) + self.interface_svi_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'sviIf.auditRecord.info.%s' % (key), + self.interface_svi_audit[key] + ) + + return self.interface_svi_audit[key] + + def get_interface_svi_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_svi_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/svi/audit/main.py b/lib/aci/intf/svi/audit/main.py new file mode 100644 index 00000000..e718b526 --- /dev/null +++ b/lib/aci/intf/svi/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.svi.audit.api import InterfaceSviAuditApi +from lib.aci.intf.svi.audit.info import InterfaceSviAuditInfo + + +class InterfaceSviAudit(InterfaceSviAuditApi, InterfaceSviAuditInfo): + def __init__(self): + InterfaceSviAuditApi.__init__(self) + InterfaceSviAuditInfo.__init__(self) diff --git a/lib/aci/intf/svi/event/__init__.py b/lib/aci/intf/svi/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/svi/event/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/svi/event/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..85471a97 Binary files /dev/null and b/lib/aci/intf/svi/event/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/event/__pycache__/api.cpython-310.pyc b/lib/aci/intf/svi/event/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..386c3f57 Binary files /dev/null and b/lib/aci/intf/svi/event/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/event/__pycache__/info.cpython-310.pyc b/lib/aci/intf/svi/event/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ca1cbba6 Binary files /dev/null and b/lib/aci/intf/svi/event/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/event/__pycache__/main.cpython-310.pyc b/lib/aci/intf/svi/event/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7bd060f4 Binary files /dev/null and b/lib/aci/intf/svi/event/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/event/api.py b/lib/aci/intf/svi/event/api.py new file mode 100644 index 00000000..de939082 --- /dev/null +++ b/lib/aci/intf/svi/event/api.py @@ -0,0 +1,54 @@ +class InterfaceSviEventApi(): + def __init__(self): + self.interface_svi_event_mo = {} + + def get_interface_svi_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_event_mo: + return self.interface_svi_event_mo[key] + + cache = self.get_object_cache( + 'svi.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_svi_event_mo[key] = cache + self.log.apic_mo( + 'svi.eventLog.%s' % (key), + self.interface_svi_event_mo[key] + ) + return self.interface_svi_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2BD' % (pod_id, node_id) + query = 'rsp-subtree=full&rsp-subtree-class=sviIf&rsp-subtree-include=event-logs,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_svi_event_mo', + 'API failed' + ) + return None + + self.interface_svi_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_svi_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'svi.eventLog.%s' % (key), + self.interface_svi_event_mo[key] + ) + + self.set_object_cache( + 'svi.eventLog', + self.interface_svi_event_mo[key], + object_selector=key + ) + + return self.interface_svi_event_mo[key] diff --git a/lib/aci/intf/svi/event/info.py b/lib/aci/intf/svi/event/info.py new file mode 100644 index 00000000..e77b4b83 --- /dev/null +++ b/lib/aci/intf/svi/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceSviEventInfo(): + def __init__(self): + self.interface_svi_event = {} + + def get_interface_svi_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/ctx-[vxlan-2228224]/bd-[vxlan-15597460]/svi-[vlan33]" + info['interfaceId'] = None + if '/svi-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/svi-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_svi_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_event: + return self.interface_svi_event[key] + + managed_objects = self.get_interface_svi_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_svi_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_svi_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_svi_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'svi.eventLog.info.%s' % (key), + self.interface_svi_event[key] + ) + + return self.interface_svi_event[key] + + def get_interface_svi_vlan_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_svi_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/svi/event/main.py b/lib/aci/intf/svi/event/main.py new file mode 100644 index 00000000..966dd89a --- /dev/null +++ b/lib/aci/intf/svi/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.svi.event.api import InterfaceSviEventApi +from lib.aci.intf.svi.event.info import InterfaceSviEventInfo + + +class InterfaceSviEvent(InterfaceSviEventApi, InterfaceSviEventInfo): + def __init__(self): + InterfaceSviEventApi.__init__(self) + InterfaceSviEventInfo.__init__(self) diff --git a/lib/aci/intf/svi/fault/__init__.py b/lib/aci/intf/svi/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/svi/fault/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/svi/fault/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..85471a97 Binary files /dev/null and b/lib/aci/intf/svi/fault/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/fault/__pycache__/api.cpython-310.pyc b/lib/aci/intf/svi/fault/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..bb8bc868 Binary files /dev/null and b/lib/aci/intf/svi/fault/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/fault/__pycache__/info.cpython-310.pyc b/lib/aci/intf/svi/fault/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..07e32bc6 Binary files /dev/null and b/lib/aci/intf/svi/fault/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/fault/__pycache__/main.cpython-310.pyc b/lib/aci/intf/svi/fault/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..bd3accf7 Binary files /dev/null and b/lib/aci/intf/svi/fault/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/svi/fault/api.py b/lib/aci/intf/svi/fault/api.py new file mode 100644 index 00000000..e3662358 --- /dev/null +++ b/lib/aci/intf/svi/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceSviFaultApi(): + def __init__(self): + self.interface_svi_fault_mo = {} + self.interface_svi_fault_record_mo = {} + + def get_interface_svi_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_fault_mo: + return self.interface_svi_fault_mo[key] + + cache = self.get_object_cache( + 'svi.fault', + object_selector=key + ) + if cache is not None: + self.interface_svi_fault_mo[key] = cache + self.log.apic_mo( + 'svi.fault.%s' % (key), + self.interface_svi_fault_mo[key] + ) + return self.interface_svi_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2BD' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_svi_fault_mo', + 'API failed' + ) + return None + + self.interface_svi_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_svi_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'svi.fault.%s' % (key), + self.interface_svi_fault_mo[key] + ) + + self.set_object_cache( + 'svi.fault', + self.interface_svi_fault_mo[key], + object_selector=key + ) + + return self.interface_svi_fault_mo[key] + + def get_interface_svi_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_fault_record_mo: + return self.interface_svi_fault_record_mo[key] + + cache = self.get_object_cache( + 'svi.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_svi_fault_record_mo[key] = cache + self.log.apic_mo( + 'svi.faultRecord.%s' % (key), + self.interface_svi_fault_record_mo[key] + ) + return self.interface_svi_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2BD' % (pod_id, node_id) + query = 'rsp-subtree=full&rsp-subtree-class=sviIf&rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_svi_fault_record_mo', + 'API failed' + ) + return None + + self.interface_svi_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_svi_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'svi.faultRecord.%s' % (key), + self.interface_svi_fault_record_mo[key] + ) + + self.set_object_cache( + 'svi.faultRecord', + self.interface_svi_fault_record_mo[key], + object_selector=key + ) + + return self.interface_svi_fault_record_mo[key] diff --git a/lib/aci/intf/svi/fault/info.py b/lib/aci/intf/svi/fault/info.py new file mode 100644 index 00000000..8f024a62 --- /dev/null +++ b/lib/aci/intf/svi/fault/info.py @@ -0,0 +1,148 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceSviFaultInfo(): + def __init__(self): + self.interface_svi_fault = {} + self.interface_svi_fault_record = {} + + def get_interface_svi_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/ctx-[vxlan-2228224]/bd-[vxlan-15597460]/svi-[vlan33]" + info['interfaceId'] = None + if not managed_object['delegated']: + if 'affected' in info: + if '/svi-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/svi-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/ctx-[vxlan-2293761]/bd-[vxlan-15237056]/svi-[vlan30]/fault-F112128" + if info['interfaceId'] is None: + if '/svi-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/svi-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_svi_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_fault: + return self.interface_svi_fault[key] + + managed_objects = self.get_interface_svi_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_svi_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_svi_fault_info( + managed_object + ) + self.interface_svi_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'svi.fault.info.%s' % (key), + self.interface_svi_fault[key] + ) + + return self.interface_svi_fault[key] + + def get_interface_svi_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi_fault_record: + return self.interface_svi_fault_record[key] + + managed_objects = self.get_interface_svi_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_svi_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_svi_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_svi_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'svi.faultRecord.info.%s' % (key), + self.interface_svi_fault_record[key] + ) + + return self.interface_svi_fault_record[key] + + def get_interface_svi_vlan_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_svi_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_svi_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/svi/fault/main.py b/lib/aci/intf/svi/fault/main.py new file mode 100644 index 00000000..336b1479 --- /dev/null +++ b/lib/aci/intf/svi/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.svi.fault.api import InterfaceSviFaultApi +from lib.aci.intf.svi.fault.info import InterfaceSviFaultInfo + + +class InterfaceSviFault(InterfaceSviFaultApi, InterfaceSviFaultInfo): + def __init__(self): + InterfaceSviFaultApi.__init__(self) + InterfaceSviFaultInfo.__init__(self) diff --git a/lib/aci/intf/svi/info.py b/lib/aci/intf/svi/info.py new file mode 100644 index 00000000..a581994c --- /dev/null +++ b/lib/aci/intf/svi/info.py @@ -0,0 +1,484 @@ +from lib import filter_helper +from lib import ip_helper + + +class InterfaceSviInfo(): + def __init__(self): + self.interface_svi = {} + + def get_interface_svi_summary(self, pod_id, node_id): + ports = self.get_interfaces_svi( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_svi_count(self, pod_id, node_id): + interfaces = self.get_interfaces_svi(pod_id, node_id) + return len(interfaces) + + def get_interface_svi_info(self, managed_object): + if 'sviIf' not in managed_object: + return None + + keys = [ + 'accEncap', + 'addr', + 'adminSt', + 'bdDefDn', + 'bridgeMode', + 'dn', + 'epMoveDetectMode', + 'epOperSt', + 'epOperStQual', + 'epUpSeqNum', + 'fabEncap', + 'fwdCtrl', + 'fwdMode', + 'hwId', + 'hwResourceId', + 'id', + 'ipv6McastAllow', + 'mcastAllow', + 'mcastOperSt', + 'operSt', + 'pcTag', + 'qiqL2ProtTunMask', + 'qosPrio', + 'serviceEnabled', + 'servicepcTag', + 'type', + 'unkMacUcastAct', + 'unkMcastAct', + 'v6unkMcastAct' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['__Output']['id'] = 'Blue' + + if info['adminSt'] == 'active': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + keys = [ + 'adminSt', + 'bw', + 'carDel', + 'delay', + 'descr', + 'id', + 'iod', + 'mac', + 'medium', + 'mtu', + 'operSt', + 'operStQual', + 'rn', + 'vlanId', + 'vlanT', + 'vmac', + 'vmacChgQual', + 'faultCounts' + ] + + info['sviIf'] = {} + for key in keys: + info['sviIf'][key] = None + if key in managed_object['sviIf']: + info['sviIf'][key] = managed_object['sviIf'][key] + + info['__Output']['sviIf.id'] = 'Blue' + + if info['sviIf']['adminSt'] == 'up': + info['__Output']['sviIf.adminSt'] = 'Green' + else: + info['__Output']['sviIf.adminSt'] = 'Red' + + if info['sviIf']['operSt'] == 'up': + info['__Output']['sviIf.operSt'] = 'Green' + if info['sviIf']['operStQual'] == 'none': + info['sviIf']['operStQual'] = '' + else: + info['__Output']['sviIf.operSt'] = 'Red' + + info['up'] = False + if info['adminSt'] == 'active' and info['operSt'] == 'up': + if info['sviIf']['adminSt'] == 'up' and info['sviIf']['operSt'] == 'up': + info['up'] = True + + info['counters'] = {} + info['counters']['inOctets'] = managed_object['rmonIfIn']['octets'] + info['counters']['inPackets'] = managed_object['rmonIfIn']['ucastPkts'] + info['counters']['inMcast'] = managed_object['rmonIfIn']['multicastPkts'] + info['counters']['inDiscards'] = managed_object['rmonIfIn']['discards'] + info['counters']['inErrors'] = managed_object['rmonIfIn']['errors'] + info['counters']['outOctets'] = managed_object['rmonIfOut']['octets'] + info['counters']['outPackets'] = managed_object['rmonIfOut']['ucastPkts'] + info['counters']['outMcast'] = managed_object['rmonIfOut']['multicastPkts'] + info['counters']['outDiscards'] = managed_object['rmonIfOut']['discards'] + info['counters']['outErrors'] = managed_object['rmonIfOut']['errors'] + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + info['accEncapT'] = info['accEncap'] + if info['accEncap'] == 'unknown': + info['accEncapT'] = '--' + + info['sviIf']['type'] = '--' + if info['sviIf']['vlanT'] == 'bd-regular': + info['sviIf']['type'] = 'Reg' + if info['sviIf']['vlanT'] == 'bd-external': + info['sviIf']['type'] = 'Ext' + + return info + + def get_interfaces_svi_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_svi: + return self.interface_svi[key] + + interfaces_mo = self.get_interface_svi_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_svi[key] = [] + for interface_mo in interfaces_mo: + interface_info = self.get_interface_svi_info( + interface_mo + ) + if interface_info is not None: + self.interface_svi[key].append( + interface_info + ) + + self.log.apic_mo( + 'sviIf.info.%s' % (key), + self.interface_svi[key] + ) + + return self.interface_svi[key] + + def match_interface_svi(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + found = False + + if key == 'id': + found = True + if not filter_helper.match_string(value, interface_info['sviIf']['id']): + return False + + if key == 'mac': + found = True + if not ip_helper.is_mac_match(value, interface_info['sviIf']['mac']): + return False + + if key == 'vlan': + found = True + matched = False + + if value.startswith('gt'): + if not filter_helper.match_integer(value, int(interface_info['sviIf']['vlanId'])): + return False + matched = True + + if value.startswith('ge'): + if not filter_helper.match_integer(value, int(interface_info['sviIf']['vlanId'])): + return False + matched = True + + if value.startswith('lt'): + if not filter_helper.match_integer(value, int(interface_info['sviIf']['vlanId'])): + return False + matched = True + + if value.startswith('le'): + if not filter_helper.match_integer(value, int(interface_info['sviIf']['vlanId'])): + return False + matched = True + + if '-' in value: + if not filter_helper.match_integer(value, int(interface_info['sviIf']['vlanId'])): + return False + matched = True + + if not matched: + if not filter_helper.match_string(value, interface_info['sviIf']['vlanId']): + return False + + if key == 'fabric': + found = True + if not filter_helper.match_string(value, interface_info['fabEncap']): + return False + + if key == 'access': + found = True + if not filter_helper.match_string(value, interface_info['accEncap']): + return False + + if key == 'admin': + found = True + if value != 'any': + if not filter_helper.match_string(value, interface_info['adminSt']): + return False + + if key == 'oper': + found = True + if value != 'any': + if not filter_helper.match_string(value, interface_info['operSt']): + return False + + if key == 'type': + found = True + if value != 'any': + if value == 'int': + if not filter_helper.match_string('bd-regular', interface_info['sviIf']['vlanT']): + return False + + if value == 'ext': + if not filter_helper.match_string('bd-external', interface_info['sviIf']['vlanT']): + return False + + if key == 'ip': + found = True + if 'ipv4_address' in interface_info: + found = False + for ip_address in interface_info['ipv4_address']: + if ip_helper.is_ipv4_in_cidr(value, ip_address): + found = True + break + + if not found: + return False + + if key == 'subnet': + found = True + if 'ipv4_address' in interface_info: + found = False + for ip_address in interface_info['ipv4_address']: + if ip_helper.is_subnet_in_subnet(ip_address, value): + found = True + break + + if not found: + return False + + if key == 'fault': + found = True + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_svi', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not found: + self.log.error( + 'match_interface_svi', + 'Unsupported filtering key: %s' % (key) + ) + + return True + + def get_interfaces_svi( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_svi_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + ipv4_addresses_info = self.get_node_address_ipv4( + pod_id, + node_id + ) + + for interface_info in all_interfaces: + if not self.match_interface_svi(interface_info, interface_filter): + continue + + interface_info['ipv4_address'] = [] + interface_info['ipv4_info'] = [] + search_pattern = 'if-[%s]' % ( + interface_info['sviIf']['id'] + ) + for ipv4_address_info in ipv4_addresses_info: + if search_pattern in ipv4_address_info['dn']: + address_info = {} + address_info['__Output'] = {} + address_info['addr'] = ipv4_address_info['addr'] + address_info['iaddr'] = ip_helper.ipv4_to_int( + ipv4_address_info['addr'].split('/')[0] + ) + address_info['operSt'] = ipv4_address_info['operSt'] + address_info['operStQual'] = ipv4_address_info['operStQual'] + address_info['type'] = ipv4_address_info['type'] + address_info['vpcPeer'] = ipv4_address_info['vpcPeer'] + + if address_info['operSt'] == 'up': + address_info['__Output']['operSt'] = 'Green' + address_info['operStQual'] = '' + else: + address_info['__Output']['operSt'] = 'Red' + + interface_info['ipv4_info'].append( + address_info + ) + + interface_info['ipv4_address'].append( + ipv4_address_info['addr'] + ) + + interface_info['ipv4_info'] = sorted( + interface_info['ipv4_info'], + key=lambda i: i['iaddr'] + ) + + interface_info['ipv4_addressT'] = [] + for ipv4_info in interface_info['ipv4_info']: + if ipv4_info['type'] == 'primary' and len(interface_info['ipv4_info']) > 1: + interface_info['ipv4_addressT'].append( + '%s (pri)' % ( + ipv4_info['addr'] + ) + ) + continue + + interface_info['ipv4_addressT'].append( + ipv4_info['addr'] + ) + + if not self.match_interface_svi(interface_info, interface_filter): + continue + + if fault_info: + interface_info['faultInst'] = self.get_interface_svi_vlan_fault( + pod_id, + node_id, + interface_info['sviIf']['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_svi_vlan_fault( + pod_id, + node_id, + interface_info['sviIf']['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_svi_vlan_event( + pod_id, + node_id, + interface_info['sviIf']['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_svi_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: int(i['id']) + ) + + return interfaces + + def get_interface_svi(self, pod_id, node_id, interface_id): + interfaces = self.get_interfaces_svi( + pod_id, + node_id, + interface_filter=['id:%s' % (interface_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/svi/main.py b/lib/aci/intf/svi/main.py new file mode 100644 index 00000000..49b7ea72 --- /dev/null +++ b/lib/aci/intf/svi/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.svi.api import InterfaceSviApi +from lib.aci.intf.svi.info import InterfaceSviInfo +from lib.aci.intf.svi.audit.main import InterfaceSviAudit +from lib.aci.intf.svi.event.main import InterfaceSviEvent +from lib.aci.intf.svi.fault.main import InterfaceSviFault + + +class InterfaceSvi( + InterfaceSviApi, + InterfaceSviInfo, + InterfaceSviAudit, + InterfaceSviEvent, + InterfaceSviFault + ): + def __init__(self): + InterfaceSviApi.__init__(self) + InterfaceSviInfo.__init__(self) + InterfaceSviAudit.__init__(self) + InterfaceSviEvent.__init__(self) + InterfaceSviFault.__init__(self) diff --git a/lib/aci/intf/svi/output.py b/lib/aci/intf/svi/output.py new file mode 100644 index 00000000..b22c7f67 --- /dev/null +++ b/lib/aci/intf/svi/output.py @@ -0,0 +1,364 @@ +class InterfaceSviOutput(): + def __init__(self): + pass + + def print_interfaces_svi_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface SVI - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'sviIf.id', + 'sviIf.adminSt', + 'sviIf.operSt', + 'sviIf.operStQual', + 'sviIf.type', + 'sviIf.medium', + 'mcastAllow', + 'sviIf.mtu', + 'sviIf.vlanId', + 'accEncapT', + 'fabEncap', + 'sviIf.mac', + 'ipv4_addressT' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Oper', + 'Reason', + 'Type', + 'Medium', + 'Mcast', + 'MTU', + 'VLAN', + 'Access Encap', + 'Fabric Encap', + 'MAC', + 'IPv4' + ] + + row_separator = False + for item in info: + if len(item['ipv4_addressT']) == 0: + item['ipv4_addressT'].append('--') + if len(item['ipv4_addressT']) > 1: + row_separator = True + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ipv4_addressT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=row_separator, + underline=True, + table=True + ) + + def print_interfaces_svi_counter(self, info, title=False): + if title: + self.my_output.default( + 'Interface SVI - Counters [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'sviIf.id', + 'sviIf.adminSt', + 'sviIf.operSt', + 'counters.inPackets', + 'counters.outPackets', + 'counters.inMcast', + 'counters.outMcast', + 'counters.inDiscards', + 'counters.outDiscards', + 'counters.inErrors', + 'counters.outErrors' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Oper', + 'Pkts In', + 'Pkts Out', + 'Mcast In', + 'Mcast Out', + 'Disc In', + 'Disc Out', + 'Err In', + 'Err Out' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_svi_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface SVI - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface SVI - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'vlanId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_svi_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface SVI - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'vlanId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_svi_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface SVI - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface SVI - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'vlanId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_svi_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface SVI - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface SVI - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/tunnel/__init__.py b/lib/aci/intf/tunnel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/tunnel/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/tunnel/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9a19abb9 Binary files /dev/null and b/lib/aci/intf/tunnel/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/tunnel/__pycache__/api.cpython-310.pyc b/lib/aci/intf/tunnel/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3f8f3623 Binary files /dev/null and b/lib/aci/intf/tunnel/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/tunnel/__pycache__/info.cpython-310.pyc b/lib/aci/intf/tunnel/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..7e9606c9 Binary files /dev/null and b/lib/aci/intf/tunnel/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/tunnel/__pycache__/main.cpython-310.pyc b/lib/aci/intf/tunnel/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..16e49a4d Binary files /dev/null and b/lib/aci/intf/tunnel/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/tunnel/__pycache__/output.cpython-310.pyc b/lib/aci/intf/tunnel/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..a1c869ca Binary files /dev/null and b/lib/aci/intf/tunnel/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/tunnel/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/tunnel/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..9d4b6def Binary files /dev/null and b/lib/aci/intf/tunnel/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/tunnel/api.py b/lib/aci/intf/tunnel/api.py new file mode 100644 index 00000000..8ae33d78 --- /dev/null +++ b/lib/aci/intf/tunnel/api.py @@ -0,0 +1,67 @@ +class InterfaceTunnelApi(): + def __init__(self): + self.interface_tunnel_mo = {} + + def get_interface_tunnel_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_tunnel_mo: + return self.interface_tunnel_mo[key] + + cache = self.get_object_cache( + 'tunnelIf', + object_selector=key + ) + if cache is not None: + self.interface_tunnel_mo[key] = cache + self.log.apic_mo( + 'tunnelIf.%s' % (key), + self.interface_tunnel_mo[key] + ) + return self.interface_tunnel_mo[key] + + class_name = 'topology/pod-%s/node-%s/tunnelIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_tunnel_mo', + 'API failed' + ) + return None + + self.interface_tunnel_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['tunnelIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'tunnelIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'tunnelIf', + managed_object, + 'faultCounts' + ) + self.interface_tunnel_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'tunnelIf.%s' % (key), + self.interface_tunnel_mo[key] + ) + + self.set_object_cache( + 'tunnelIf', + self.interface_tunnel_mo[key], + object_selector=key + ) + + return self.interface_tunnel_mo[key] diff --git a/lib/aci/intf/tunnel/audit/__init__.py b/lib/aci/intf/tunnel/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/tunnel/audit/api.py b/lib/aci/intf/tunnel/audit/api.py new file mode 100644 index 00000000..3fdaff79 --- /dev/null +++ b/lib/aci/intf/tunnel/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceTunnelAuditApi(): + def __init__(self): + self.interface_tunnel_audit_mo = {} + + def get_interface_tunnel_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_audit_mo: + return self.interface_tunnel_audit_mo[key] + + cache = self.get_object_cache( + 'tunnelIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_tunnel_audit_mo[key] = cache + self.log.apic_mo( + 'tunnelIf.audit.%s' % (key), + self.interface_tunnel_audit_mo[key] + ) + return self.interface_tunnel_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/tunnelIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_tunnel_audit_mo', + 'API failed' + ) + return None + + self.interface_tunnel_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_tunnel_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'tunnelIf.audit.%s' % (key), + self.interface_tunnel_audit_mo[key] + ) + + self.set_object_cache( + 'tunnelIf.audit', + self.interface_tunnel_audit_mo[key], + object_selector=key + ) + + return self.interface_tunnel_audit_mo[key] diff --git a/lib/aci/intf/tunnel/audit/info.py b/lib/aci/intf/tunnel/audit/info.py new file mode 100644 index 00000000..4f875467 --- /dev/null +++ b/lib/aci/intf/tunnel/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceTunnelAuditInfo(): + def __init__(self): + self.interface_tunnel_audit = {} + + def get_interface_tunnel_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/tunnel-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/tunnel-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_tunnel_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_audit: + return self.interface_tunnel_audit[key] + + managed_objects = self.get_interface_tunnel_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_tunnel_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_tunnel_audit_info( + managed_object + ) + self.interface_tunnel_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'tunnelIf.auditRecord.info.%s' % (key), + self.interface_tunnel_audit[key] + ) + + return self.interface_tunnel_audit[key] + + def get_interface_tunnel_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_tunnel_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/tunnel/audit/main.py b/lib/aci/intf/tunnel/audit/main.py new file mode 100644 index 00000000..e8366469 --- /dev/null +++ b/lib/aci/intf/tunnel/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.tunnel.audit.api import InterfaceTunnelAuditApi +from lib.aci.intf.tunnel.audit.info import InterfaceTunnelAuditInfo + + +class InterfaceTunnelAudit(InterfaceTunnelAuditApi, InterfaceTunnelAuditInfo): + def __init__(self): + InterfaceTunnelAuditApi.__init__(self) + InterfaceTunnelAuditInfo.__init__(self) diff --git a/lib/aci/intf/tunnel/event/__init__.py b/lib/aci/intf/tunnel/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/tunnel/event/api.py b/lib/aci/intf/tunnel/event/api.py new file mode 100644 index 00000000..f07ce0bd --- /dev/null +++ b/lib/aci/intf/tunnel/event/api.py @@ -0,0 +1,54 @@ +class InterfaceTunnelEventApi(): + def __init__(self): + self.interface_tunnel_event_mo = {} + + def get_interface_tunnel_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_event_mo: + return self.interface_tunnel_event_mo[key] + + cache = self.get_object_cache( + 'tunnelIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_tunnel_event_mo[key] = cache + self.log.apic_mo( + 'tunnelIf.eventLog.%s' % (key), + self.interface_tunnel_event_mo[key] + ) + return self.interface_tunnel_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/tunnelIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_tunnel_event_mo', + 'API failed' + ) + return None + + self.interface_tunnel_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_tunnel_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'tunnelIf.eventLog.%s' % (key), + self.interface_tunnel_event_mo[key] + ) + + self.set_object_cache( + 'tunnelIf.eventLog', + self.interface_tunnel_event_mo[key], + object_selector=key + ) + + return self.interface_tunnel_event_mo[key] diff --git a/lib/aci/intf/tunnel/event/info.py b/lib/aci/intf/tunnel/event/info.py new file mode 100644 index 00000000..6d74709e --- /dev/null +++ b/lib/aci/intf/tunnel/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceTunnelEventInfo(): + def __init__(self): + self.interface_tunnel_event = {} + + def get_interface_tunnel_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/tunnel-[lo0]" + info['interfaceId'] = None + if '/tunnel-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/tunnel-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_tunnel_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_event: + return self.interface_tunnel_event[key] + + managed_objects = self.get_interface_tunnel_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_tunnel_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_tunnel_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_tunnel_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'tunnelIf.eventLog.info.%s' % (key), + self.interface_tunnel_event[key] + ) + + return self.interface_tunnel_event[key] + + def get_interface_tunnel_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_tunnel_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/tunnel/event/main.py b/lib/aci/intf/tunnel/event/main.py new file mode 100644 index 00000000..c353fc39 --- /dev/null +++ b/lib/aci/intf/tunnel/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.tunnel.event.api import InterfaceTunnelEventApi +from lib.aci.intf.tunnel.event.info import InterfaceTunnelEventInfo + + +class InterfaceTunnelEvent(InterfaceTunnelEventApi, InterfaceTunnelEventInfo): + def __init__(self): + InterfaceTunnelEventApi.__init__(self) + InterfaceTunnelEventInfo.__init__(self) diff --git a/lib/aci/intf/tunnel/fault/__init__.py b/lib/aci/intf/tunnel/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/tunnel/fault/api.py b/lib/aci/intf/tunnel/fault/api.py new file mode 100644 index 00000000..f0d900b6 --- /dev/null +++ b/lib/aci/intf/tunnel/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceTunnelFaultApi(): + def __init__(self): + self.interface_tunnel_fault_mo = {} + self.interface_tunnel_fault_record_mo = {} + + def get_interface_tunnel_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_fault_mo: + return self.interface_tunnel_fault_mo[key] + + cache = self.get_object_cache( + 'tunnelIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_tunnel_fault_mo[key] = cache + self.log.apic_mo( + 'tunnelIf.fault.%s' % (key), + self.interface_tunnel_fault_mo[key] + ) + return self.interface_tunnel_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/tunnelIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_tunnel_fault_mo', + 'API failed' + ) + return None + + self.interface_tunnel_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_tunnel_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'tunnelIf.fault.%s' % (key), + self.interface_tunnel_fault_mo[key] + ) + + self.set_object_cache( + 'tunnelIf.fault', + self.interface_tunnel_fault_mo[key], + object_selector=key + ) + + return self.interface_tunnel_fault_mo[key] + + def get_interface_tunnel_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_fault_record_mo: + return self.interface_tunnel_fault_record_mo[key] + + cache = self.get_object_cache( + 'tunnelIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_tunnel_fault_record_mo[key] = cache + self.log.apic_mo( + 'tunnelIf.faultRecord.%s' % (key), + self.interface_tunnel_fault_record_mo[key] + ) + return self.interface_tunnel_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/tunnelIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_tunnel_fault_record_mo', + 'API failed' + ) + return None + + self.interface_tunnel_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_tunnel_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'tunnelIf.faultRecord.%s' % (key), + self.interface_tunnel_fault_record_mo[key] + ) + + self.set_object_cache( + 'tunnelIf.faultRecord', + self.interface_tunnel_fault_record_mo[key], + object_selector=key + ) + + return self.interface_tunnel_fault_record_mo[key] diff --git a/lib/aci/intf/tunnel/fault/info.py b/lib/aci/intf/tunnel/fault/info.py new file mode 100644 index 00000000..71f9ec3a --- /dev/null +++ b/lib/aci/intf/tunnel/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceTunnelFaultInfo(): + def __init__(self): + self.interface_tunnel_fault = {} + self.interface_tunnel_fault_record = {} + + def get_interface_tunnel_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/tunnel-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/tunnel-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/tunnel-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/tunnel-[lo0]" + if info['interfaceId'] is None: + if '/tunnel-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/tunnel-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_tunnel_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_fault: + return self.interface_tunnel_fault[key] + + managed_objects = self.get_interface_tunnel_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_tunnel_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_tunnel_fault_info( + managed_object + ) + self.interface_tunnel_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'tunnelIf.fault.info.%s' % (key), + self.interface_tunnel_fault[key] + ) + + return self.interface_tunnel_fault[key] + + def get_interface_tunnel_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel_fault_record: + return self.interface_tunnel_fault_record[key] + + managed_objects = self.get_interface_tunnel_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_tunnel_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_tunnel_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_tunnel_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'tunnelIf.faultRecord.info.%s' % (key), + self.interface_tunnel_fault_record[key] + ) + + return self.interface_tunnel_fault_record[key] + + def get_interface_tunnel_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_tunnel_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_tunnel_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/tunnel/fault/main.py b/lib/aci/intf/tunnel/fault/main.py new file mode 100644 index 00000000..55d76cc5 --- /dev/null +++ b/lib/aci/intf/tunnel/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.tunnel.fault.api import InterfaceTunnelFaultApi +from lib.aci.intf.tunnel.fault.info import InterfaceTunnelFaultInfo + + +class InterfaceTunnelFault(InterfaceTunnelFaultApi, InterfaceTunnelFaultInfo): + def __init__(self): + InterfaceTunnelFaultApi.__init__(self) + InterfaceTunnelFaultInfo.__init__(self) diff --git a/lib/aci/intf/tunnel/info.py b/lib/aci/intf/tunnel/info.py new file mode 100644 index 00000000..16ffa2d7 --- /dev/null +++ b/lib/aci/intf/tunnel/info.py @@ -0,0 +1,359 @@ +from lib import filter_helper +from lib import ip_helper + + +class InterfaceTunnelInfo(): + def __init__(self): + self.interface_tunnel = {} + + self.interface_tunnel_endpoint_type = { + 'physical': 'Physical', + 'proxy-acast-mac': 'Proxy Anycast MAC', + 'proxy-acast-v4': 'Proxy Anycast IPv4', + 'proxy-acast-v6': 'Proxy Anycast IPv6', + 'fabric-ext': 'Fabric External', + 'rl-mcast-hrep': 'Remote Leaf Multicast', + 'rl-ucast': 'Remote Leaf Unicast' + } + + def get_interface_tunnel_summary(self, pod_id, node_id): + ports = self.get_interfaces_tunnel( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_tunnel_count(self, pod_id, node_id): + interfaces = self.get_interfaces_tunnel(pod_id, node_id) + return len(interfaces) + + def get_interface_tunnel_info(self, managed_object): + keys = [ + 'aclTcamStQual', + 'adminSt', + 'cfgdMtu', + 'delInProg', + 'dest', + 'dn', + 'id', + 'idRequestorDn', + 'iod', + 'keepAlvIntvl', + 'keepAlvRetries', + 'mac', + 'operSt', + 'operStQual', + 'src', + 'tLayer', + 'tType', + 'tmCfgFailedBmp', + 'tmCfgFailedTs', + 'tmCfgState', + 'type', + 'underlayVrfName', + 'v6Src', + 'vrfName' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # topology/pod-1/node-201/sys/tunnel/inst/if-[eth1/97] + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['src_ip'] = info['src'] + if info['src'].endswith('/32'): + info['src_ip'] = info['src_ip'].split('/32')[0] + + info['dest_ip'] = info['dest'] + if info['dest'].endswith('/32'): + info['dest_ip'] = info['dest_ip'].split('/32')[0] + + info['typeT'] = [] + for tunnel_type in info['type'].split(','): + if tunnel_type in self.interface_tunnel_endpoint_type: + info['typeT'].append( + self.interface_tunnel_endpoint_type[tunnel_type] + ) + else: + info['typeT'].append( + tunnel_type + ) + + info['typeT'] = sorted( + info['typeT'] + ) + + info['tunnelId'] = int(info['id'].strip('tunnel')) + info['__Output']['id'] = 'Blue' + + if info['adminSt'] == 'up': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + if info['operStQual'] == 'none': + info['operStQual'] = '' + else: + info['__Output']['operSt'] = 'Red' + + if info['adminSt'] == 'up' and info['operSt'] == 'up': + info['up'] = True + else: + info['up'] = False + + info['requestor'] = '' + if len(info['idRequestorDn']) > 0: + if info['idRequestorDn'].startswith('topology'): + if len(info['idRequestorDn'].split('/')) > 4: + info['requestor'] = info['idRequestorDn'].split('/')[4] + + info['dest_node'] = [] + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interface_tunnel_info_resolved(self, info): + tep_found = False + nodes = self.get_nodes() + for node in nodes: + node_address_info = self.get_node_address_ipv4( + node['podId'], + node['id'], + address_filter=['ip:%s' % (info['dest_ip'])] + ) + if node_address_info is not None and len(node_address_info) == 1: + tep_found = True + info['dest_node'].append( + 'pod-%s/%s/%s' % ( + node['podId'], + node['name'], + node_address_info[0]['interface'] + ) + ) + + if not tep_found: + # Tunnel destined to node (tep) + destination_node_info = self.get_node( + node_ip=info['dest_ip'] + ) + if destination_node_info is not None: + info['dest_node'].append( + destination_node_info['pod_node_name'] + ) + tep_found = True + + return info + + def get_interfaces_tunnel_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_tunnel: + return self.interface_tunnel[key] + + interfaces_mo = self.get_interface_tunnel_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_tunnel[key] = [] + for interface_mo in interfaces_mo: + self.interface_tunnel[key].append( + self.get_interface_tunnel_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'tunnelIf.info.%s' % (key), + self.interface_tunnel[key] + ) + + return self.interface_tunnel[key] + + def match_interface_tunnel(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'admin': + if value != 'any': + if not filter_helper.match_string(value, interface_info['adminSt']): + return False + + if key == 'oper': + if value != 'any': + if not filter_helper.match_string(value, interface_info['operSt']): + return False + + if key == 'vrf': + if not filter_helper.match_string(value, interface_info['vrfName']): + return False + + if key == 'layer': + if value != 'any': + if not filter_helper.match_string(value, interface_info['tLayer']): + return False + + if key == 'ip': + if not filter_helper.match_string(value, interface_info['src_ip']) and not filter_helper.match_string(value, interface_info['dest']): + return False + + if key == 'subnet': + if not ip_helper.is_ipv4_in_cidr(interface_info['src_ip'], value) and not ip_helper.is_ipv4_in_cidr(interface_info['dest'], value): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_tunnel', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_tunnel( + self, + pod_id, + node_id, + interface_filter=None, + resolve=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_tunnel_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_tunnel(interface_info, interface_filter): + continue + + if resolve: + interface_info = self.get_interface_tunnel_info_resolved( + interface_info + ) + + if fault_info: + interface_info['faultInst'] = self.get_interface_tunnel_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_tunnel_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_tunnel_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_tunnel_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['tunnelId'] + ) + + return interfaces + + def get_interface_tunnel(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_tunnel( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/tunnel/main.py b/lib/aci/intf/tunnel/main.py new file mode 100644 index 00000000..28cee6ad --- /dev/null +++ b/lib/aci/intf/tunnel/main.py @@ -0,0 +1,20 @@ +from lib.aci.intf.tunnel.api import InterfaceTunnelApi +from lib.aci.intf.tunnel.info import InterfaceTunnelInfo +from lib.aci.intf.tunnel.audit.main import InterfaceTunnelAudit +from lib.aci.intf.tunnel.event.main import InterfaceTunnelEvent +from lib.aci.intf.tunnel.fault.main import InterfaceTunnelFault + + +class InterfaceTunnel( + InterfaceTunnelApi, + InterfaceTunnelInfo, + InterfaceTunnelAudit, + InterfaceTunnelEvent, + InterfaceTunnelFault + ): + def __init__(self): + InterfaceTunnelApi.__init__(self) + InterfaceTunnelInfo.__init__(self) + InterfaceTunnelAudit.__init__(self) + InterfaceTunnelEvent.__init__(self) + InterfaceTunnelFault.__init__(self) diff --git a/lib/aci/intf/tunnel/output.py b/lib/aci/intf/tunnel/output.py new file mode 100644 index 00000000..d38a56c7 --- /dev/null +++ b/lib/aci/intf/tunnel/output.py @@ -0,0 +1,296 @@ +class InterfaceTunnelOutput(): + def __init__(self): + pass + + def print_interfaces_tunnel_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Tunnel - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'adminSt', + 'operSt', + 'operStQual', + 'tLayer', + 'tType', + 'typeT', + 'requestor', + 'src_ip', + 'dest_ip', + 'dest_node', + 'vrfName', + 'cfgdMtu', + 'keepAlvIntvl', + 'keepAlvRetries' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface', + 'Admin', + 'Oper', + 'Reason', + 'Layer', + 'Encap', + 'Type', + 'Req', + 'Src IP', + 'Dest IP', + 'Dest Node', + 'VRF', + 'MTU', + 'Keepalive Int', + 'Keepalive Retr' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['dest_node', 'typeT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + row_separator=True, + table=True + ) + + def print_interface_tunnel_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Loopback - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Loopback - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_tunnel_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Loopback - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_tunnel_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Loopback - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Loopback - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_tunnel_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Tunnel - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Tunnel - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/vfc/__init__.py b/lib/aci/intf/vfc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/vfc/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/vfc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1c619365 Binary files /dev/null and b/lib/aci/intf/vfc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/vfc/__pycache__/api.cpython-310.pyc b/lib/aci/intf/vfc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5c89c0c0 Binary files /dev/null and b/lib/aci/intf/vfc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/vfc/__pycache__/info.cpython-310.pyc b/lib/aci/intf/vfc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..78abb862 Binary files /dev/null and b/lib/aci/intf/vfc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/vfc/__pycache__/main.cpython-310.pyc b/lib/aci/intf/vfc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9e6e7d8f Binary files /dev/null and b/lib/aci/intf/vfc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/vfc/__pycache__/output.cpython-310.pyc b/lib/aci/intf/vfc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..3cdae82c Binary files /dev/null and b/lib/aci/intf/vfc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/vfc/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/vfc/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..200b2573 Binary files /dev/null and b/lib/aci/intf/vfc/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/vfc/api.py b/lib/aci/intf/vfc/api.py new file mode 100644 index 00000000..123f31ba --- /dev/null +++ b/lib/aci/intf/vfc/api.py @@ -0,0 +1,67 @@ +class InterfaceVfcApi(): + def __init__(self): + self.interface_vfc_mo = {} + + def get_interface_vfc_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.interface_vfc_mo: + return self.interface_vfc_mo[key] + + cache = self.get_object_cache( + 'l2VfcIf', + object_selector=key + ) + if cache is not None: + self.interface_vfc_mo[key] = cache + self.log.apic_mo( + 'l2VfcIf.%s' % (key), + self.interface_vfc_mo[key] + ) + return self.interface_vfc_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2VfcIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_vfc_mo', + 'API failed' + ) + return None + + self.interface_vfc_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2VfcIf']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'l2VfcIf', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l2VfcIf', + managed_object, + 'faultCounts' + ) + self.interface_vfc_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l2VfcIf.%s' % (key), + self.interface_vfc_mo[key] + ) + + self.set_object_cache( + 'l2VfcIf', + self.interface_vfc_mo[key], + object_selector=key + ) + + return self.interface_vfc_mo[key] diff --git a/lib/aci/intf/vfc/audit/__init__.py b/lib/aci/intf/vfc/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/vfc/audit/api.py b/lib/aci/intf/vfc/audit/api.py new file mode 100644 index 00000000..f89a3748 --- /dev/null +++ b/lib/aci/intf/vfc/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceVfcAuditApi(): + def __init__(self): + self.interface_vfc_audit_mo = {} + + def get_interface_vfc_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_audit_mo: + return self.interface_vfc_audit_mo[key] + + cache = self.get_object_cache( + 'l2VfcIf.audit', + object_selector=key + ) + if cache is not None: + self.interface_vfc_audit_mo[key] = cache + self.log.apic_mo( + 'l2VfcIf.audit.%s' % (key), + self.interface_vfc_audit_mo[key] + ) + return self.interface_vfc_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2VfcIf' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_vfc_audit_mo', + 'API failed' + ) + return None + + self.interface_vfc_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_vfc_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l2VfcIf.audit.%s' % (key), + self.interface_vfc_audit_mo[key] + ) + + self.set_object_cache( + 'l2VfcIf.audit', + self.interface_vfc_audit_mo[key], + object_selector=key + ) + + return self.interface_vfc_audit_mo[key] diff --git a/lib/aci/intf/vfc/audit/info.py b/lib/aci/intf/vfc/audit/info.py new file mode 100644 index 00000000..caf6ab1e --- /dev/null +++ b/lib/aci/intf/vfc/audit/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceVfcAuditInfo(): + def __init__(self): + self.interface_vfc_audit = {} + + def get_interface_vfc_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['interfaceId'] = None + if '/vfc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/vfc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_vfc_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_audit: + return self.interface_vfc_audit[key] + + managed_objects = self.get_interface_vfc_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_vfc_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_vfc_audit_info( + managed_object + ) + self.interface_vfc_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'l2VfcIf.auditRecord.info.%s' % (key), + self.interface_vfc_audit[key] + ) + + return self.interface_vfc_audit[key] + + def get_interface_vfc_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_vfc_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/vfc/audit/main.py b/lib/aci/intf/vfc/audit/main.py new file mode 100644 index 00000000..36de7f81 --- /dev/null +++ b/lib/aci/intf/vfc/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.vfc.audit.api import InterfaceVfcAuditApi +from lib.aci.intf.vfc.audit.info import InterfaceVfcAuditInfo + + +class InterfaceVfcAudit(InterfaceVfcAuditApi, InterfaceVfcAuditInfo): + def __init__(self): + InterfaceVfcAuditApi.__init__(self) + InterfaceVfcAuditInfo.__init__(self) diff --git a/lib/aci/intf/vfc/event/__init__.py b/lib/aci/intf/vfc/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/vfc/event/api.py b/lib/aci/intf/vfc/event/api.py new file mode 100644 index 00000000..8f12945d --- /dev/null +++ b/lib/aci/intf/vfc/event/api.py @@ -0,0 +1,54 @@ +class InterfaceVfcEventApi(): + def __init__(self): + self.interface_vfc_event_mo = {} + + def get_interface_vfc_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_event_mo: + return self.interface_vfc_event_mo[key] + + cache = self.get_object_cache( + 'l2VfcIf.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_vfc_event_mo[key] = cache + self.log.apic_mo( + 'l2VfcIf.eventLog.%s' % (key), + self.interface_vfc_event_mo[key] + ) + return self.interface_vfc_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2VfcIf' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_vfc_event_mo', + 'API failed' + ) + return None + + self.interface_vfc_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_vfc_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l2VfcIf.eventLog.%s' % (key), + self.interface_vfc_event_mo[key] + ) + + self.set_object_cache( + 'l2VfcIf.eventLog', + self.interface_vfc_event_mo[key], + object_selector=key + ) + + return self.interface_vfc_event_mo[key] diff --git a/lib/aci/intf/vfc/event/info.py b/lib/aci/intf/vfc/event/info.py new file mode 100644 index 00000000..330c1836 --- /dev/null +++ b/lib/aci/intf/vfc/event/info.py @@ -0,0 +1,114 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceVfcEventInfo(): + def __init__(self): + self.interface_vfc_event = {} + + def get_interface_vfc_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/vfc-[lo0]" + info['interfaceId'] = None + if '/vfc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/vfc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_vfc_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_event: + return self.interface_vfc_event[key] + + managed_objects = self.get_interface_vfc_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_vfc_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_vfc_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_vfc_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l2VfcIf.eventLog.info.%s' % (key), + self.interface_vfc_event[key] + ) + + return self.interface_vfc_event[key] + + def get_interface_vfc_id_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_interface_vfc_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interfaceId'] is not None: + if event_info['interfaceId'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/vfc/event/main.py b/lib/aci/intf/vfc/event/main.py new file mode 100644 index 00000000..81be3769 --- /dev/null +++ b/lib/aci/intf/vfc/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.vfc.event.api import InterfaceVfcEventApi +from lib.aci.intf.vfc.event.info import InterfaceVfcEventInfo + + +class InterfaceVfcEvent(InterfaceVfcEventApi, InterfaceVfcEventInfo): + def __init__(self): + InterfaceVfcEventApi.__init__(self) + InterfaceVfcEventInfo.__init__(self) diff --git a/lib/aci/intf/vfc/fault/__init__.py b/lib/aci/intf/vfc/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/vfc/fault/api.py b/lib/aci/intf/vfc/fault/api.py new file mode 100644 index 00000000..b9ba3446 --- /dev/null +++ b/lib/aci/intf/vfc/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceVfcFaultApi(): + def __init__(self): + self.interface_vfc_fault_mo = {} + self.interface_vfc_fault_record_mo = {} + + def get_interface_vfc_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_fault_mo: + return self.interface_vfc_fault_mo[key] + + cache = self.get_object_cache( + 'l2VfcIf.fault', + object_selector=key + ) + if cache is not None: + self.interface_vfc_fault_mo[key] = cache + self.log.apic_mo( + 'l2VfcIf.fault.%s' % (key), + self.interface_vfc_fault_mo[key] + ) + return self.interface_vfc_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2VfcIf' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_vfc_fault_mo', + 'API failed' + ) + return None + + self.interface_vfc_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_vfc_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l2VfcIf.fault.%s' % (key), + self.interface_vfc_fault_mo[key] + ) + + self.set_object_cache( + 'l2VfcIf.fault', + self.interface_vfc_fault_mo[key], + object_selector=key + ) + + return self.interface_vfc_fault_mo[key] + + def get_interface_vfc_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_fault_record_mo: + return self.interface_vfc_fault_record_mo[key] + + cache = self.get_object_cache( + 'l2VfcIf.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_vfc_fault_record_mo[key] = cache + self.log.apic_mo( + 'l2VfcIf.faultRecord.%s' % (key), + self.interface_vfc_fault_record_mo[key] + ) + return self.interface_vfc_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/l2VfcIf' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_vfc_fault_record_mo', + 'API failed' + ) + return None + + self.interface_vfc_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_vfc_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'l2VfcIf.faultRecord.%s' % (key), + self.interface_vfc_fault_record_mo[key] + ) + + self.set_object_cache( + 'l2VfcIf.faultRecord', + self.interface_vfc_fault_record_mo[key], + object_selector=key + ) + + return self.interface_vfc_fault_record_mo[key] diff --git a/lib/aci/intf/vfc/fault/info.py b/lib/aci/intf/vfc/fault/info.py new file mode 100644 index 00000000..8cc0c319 --- /dev/null +++ b/lib/aci/intf/vfc/fault/info.py @@ -0,0 +1,149 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceVfcFaultInfo(): + def __init__(self): + self.interface_vfc_fault = {} + self.interface_vfc_fault_record = {} + + def get_interface_vfc_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/inst-overlay-1/vfc-[lo0]" + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if '/vfc-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/vfc-[')[1].split(']')[0] + + # "dn": "topology/pod-1/node-2208/sys/inst-overlay-1/vfc-[lo0]" + if info['interfaceId'] is None: + if '/vfc-[' in info['dn']: + info['interfaceId'] = info['dn'].split('/vfc-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_vfc_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_fault: + return self.interface_vfc_fault[key] + + managed_objects = self.get_interface_vfc_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_vfc_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_vfc_fault_info( + managed_object + ) + self.interface_vfc_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'l2VfcIf.fault.info.%s' % (key), + self.interface_vfc_fault[key] + ) + + return self.interface_vfc_fault[key] + + def get_interface_vfc_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc_fault_record: + return self.interface_vfc_fault_record[key] + + managed_objects = self.get_interface_vfc_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_vfc_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_vfc_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_vfc_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l2VfcIf.faultRecord.info.%s' % (key), + self.interface_vfc_fault_record[key] + ) + + return self.interface_vfc_fault_record[key] + + def get_interface_vfc_id_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_vfc_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_vfc_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interfaceId'] is not None: + if fault_info['interfaceId'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/vfc/fault/main.py b/lib/aci/intf/vfc/fault/main.py new file mode 100644 index 00000000..5ab1e425 --- /dev/null +++ b/lib/aci/intf/vfc/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.vfc.fault.api import InterfaceVfcFaultApi +from lib.aci.intf.vfc.fault.info import InterfaceVfcFaultInfo + + +class InterfaceVfcFault(InterfaceVfcFaultApi, InterfaceVfcFaultInfo): + def __init__(self): + InterfaceVfcFaultApi.__init__(self) + InterfaceVfcFaultInfo.__init__(self) diff --git a/lib/aci/intf/vfc/info.py b/lib/aci/intf/vfc/info.py new file mode 100644 index 00000000..6e0037f8 --- /dev/null +++ b/lib/aci/intf/vfc/info.py @@ -0,0 +1,202 @@ +from lib import filter_helper + + +class InterfaceVfcInfo(): + def __init__(self): + self.interface_vfc = {} + + def get_interface_vfc_summary(self, pod_id, node_id): + ports = self.get_interfaces_vfc( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + if port['up']: + summary['portUp'] = summary['portUp'] + 1 + + if not port['up']: + summary['portDown'] = summary['portDown'] + 1 + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_vfc_count(self, pod_id, node_id): + interfaces = self.get_interfaces_vfc(pod_id, node_id) + return len(interfaces) + + def get_interface_vfc_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + info['up'] = False + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_interfaces_vfc_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_vfc: + return self.interface_vfc[key] + + interfaces_mo = self.get_interface_vfc_mo(pod_id, node_id) + if interfaces_mo is None: + return None + + self.interface_vfc[key] = [] + for interface_mo in interfaces_mo: + self.interface_vfc[key].append( + self.get_interface_vfc_info( + interface_mo + ) + ) + + self.log.apic_mo( + 'vfcIf.info.%s' % (key), + self.interface_vfc[key] + ) + + return self.interface_vfc[key] + + def match_interface_vfc(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'fault': + if value == 'any': + if not interface_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_interface_vfc', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_interfaces_vfc( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_vfc_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_vfc(interface_info, interface_filter): + continue + + if fault_info: + interface_info['faultInst'] = self.get_interface_vfc_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_vfc_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_vfc_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_vfc_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces + + def get_interface_vfc(self, pod_id, node_id, port_id): + interfaces = self.get_interfaces_vfc( + pod_id, + node_id, + interface_filter=['id:%s' % (port_id)] + ) + + if interfaces is None or len(interfaces) != 1: + return None + + return interfaces[0] diff --git a/lib/aci/intf/vfc/main.py b/lib/aci/intf/vfc/main.py new file mode 100644 index 00000000..53578aa6 --- /dev/null +++ b/lib/aci/intf/vfc/main.py @@ -0,0 +1,17 @@ +from lib.aci.intf.vfc.api import InterfaceVfcApi +from lib.aci.intf.vfc.info import InterfaceVfcInfo +from lib.aci.intf.vfc.event.main import InterfaceVfcEvent +from lib.aci.intf.vfc.fault.main import InterfaceVfcFault + + +class InterfaceVfc( + InterfaceVfcApi, + InterfaceVfcInfo, + InterfaceVfcEvent, + InterfaceVfcFault + ): + def __init__(self): + InterfaceVfcApi.__init__(self) + InterfaceVfcInfo.__init__(self) + InterfaceVfcEvent.__init__(self) + InterfaceVfcFault.__init__(self) diff --git a/lib/aci/intf/vfc/output.py b/lib/aci/intf/vfc/output.py new file mode 100644 index 00000000..89e5710b --- /dev/null +++ b/lib/aci/intf/vfc/output.py @@ -0,0 +1,263 @@ +class InterfaceVfcOutput(): + def __init__(self): + pass + + def print_interfaces_vfc_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Vfc - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_vfc_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Vfc - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Vfc - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_vfc_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Vfc - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_vfc_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Vfc - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Vfc - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_vfc_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Vfc - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Vfc - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/intf/virtual_port_channel/__init__.py b/lib/aci/intf/virtual_port_channel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..cbac3f29 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/api.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8f5331ab Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/info.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b0b20ff7 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/main.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d5662d64 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/member.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/member.cpython-310.pyc new file mode 100644 index 00000000..4270b79f Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/member.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/output.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..c2a9b77d Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/__pycache__/summary.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..0ac36801 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/api.py b/lib/aci/intf/virtual_port_channel/api.py new file mode 100644 index 00000000..26429f1c --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/api.py @@ -0,0 +1,70 @@ +class InterfaceVirtualPortChannelApi(): + def __init__(self): + self.interfaces_vpc_mo = {} + + def get_interfaces_virtual_port_channel_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interfaces_vpc_mo: + return self.interfaces_vpc_mo[key] + + cache = self.get_object_cache( + 'vpcDom', + object_selector=key + ) + if cache is not None: + self.interfaces_vpc_mo[key] = cache + self.log.apic_mo( + 'vpcDom.%s' % (key), + self.interfaces_vpc_mo[key] + ) + return self.interfaces_vpc_mo[key] + + class_name = 'topology/pod-%s/node-%s/vpcDom' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count,required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interfaces_virtual_port_channel_mo', + 'API failed' + ) + return None + + self.interfaces_vpc_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['vpcDom']['attributes'] + attributes['vpcIf'] = self.get_mo_children_attributes( + 'vpcDom', + managed_object, + 'vpcIf', + include_grandchildren=True + ) + attributes['healthInst'] = self.get_mo_child_attributes( + 'vpcDom', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'vpcDom', + managed_object, + 'faultCounts' + ) + self.interfaces_vpc_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'vpcDom.%s' % (key), + self.interfaces_vpc_mo[key] + ) + + self.set_object_cache( + 'vpcDom', + self.interfaces_vpc_mo[key], + object_selector=key + ) + + return self.interfaces_vpc_mo[key] diff --git a/lib/aci/intf/virtual_port_channel/audit/__init__.py b/lib/aci/intf/virtual_port_channel/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/virtual_port_channel/audit/api.py b/lib/aci/intf/virtual_port_channel/audit/api.py new file mode 100644 index 00000000..ec0bec60 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/audit/api.py @@ -0,0 +1,54 @@ +class InterfaceVirtualPortChannelAuditApi(): + def __init__(self): + self.interface_virtual_port_channel_audit_mo = {} + + def get_interface_virtual_port_channel_audit_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_audit_mo: + return self.interface_virtual_port_channel_audit_mo[key] + + cache = self.get_object_cache( + 'vpcDom.audit', + object_selector=key + ) + if cache is not None: + self.interface_virtual_port_channel_audit_mo[key] = cache + self.log.apic_mo( + 'vpcDom.audit.%s' % (key), + self.interface_virtual_port_channel_audit_mo[key] + ) + return self.interface_virtual_port_channel_audit_mo[key] + + class_name = 'topology/pod-%s/node-%s/vpcDom' % (pod_id, node_id) + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_virtual_port_channel_audit_mo', + 'API failed' + ) + return None + + self.interface_virtual_port_channel_audit_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.interface_virtual_port_channel_audit_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'vpcDom.audit.%s' % (key), + self.interface_virtual_port_channel_audit_mo[key] + ) + + self.set_object_cache( + 'vpcDom.audit', + self.interface_virtual_port_channel_audit_mo[key], + object_selector=key + ) + + return self.interface_virtual_port_channel_audit_mo[key] diff --git a/lib/aci/intf/virtual_port_channel/audit/info.py b/lib/aci/intf/virtual_port_channel/audit/info.py new file mode 100644 index 00000000..a32dd9b6 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/audit/info.py @@ -0,0 +1,111 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceVirtualPortChannelAuditInfo(): + def __init__(self): + self.interface_virtual_port_channel_audit = {} + + def get_interface_virtual_port_channel_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domainId'] = None + info['interfaceId'] = None + if 'sys/vpc/inst/dom-' in info['affected']: + info['domainId'] = info['affected'].split('sys/vpc/inst/dom-')[1].split('/')[0] + if '/if-' in info['affected']: + info['interfaceId'] = info['affected'].split('sys/vpc/inst/dom-')[1].split('/')[1].split('if-')[1] + + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_virtual_port_channel_audit(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_audit: + return self.interface_virtual_port_channel_audit[key] + + managed_objects = self.get_interface_virtual_port_channel_audit_mo( + pod_id, + node_id + ) + if managed_objects is None: + return None + + self.interface_virtual_port_channel_audit[key] = [] + for managed_object in managed_objects: + audit_info = self.get_interface_virtual_port_channel_audit_info( + managed_object + ) + self.interface_virtual_port_channel_audit[key].append( + audit_info + ) + + self.log.apic_mo( + 'vpcDom.auditRecord.info.%s' % (key), + self.interface_virtual_port_channel_audit[key] + ) + + return self.interface_virtual_port_channel_audit[key] + + def get_interface_virtual_port_channel_id_audit(self, pod_id, node_id, interface_id, audit_filter=None): + audits = [] + + all_audits = self.get_interface_virtual_port_channel_audit( + pod_id, + node_id + ) + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['interfaceId'] is not None: + if audit_info['interfaceId'] == interface_id: + if not self.match_system_fault(audit_info, audit_filter): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/intf/virtual_port_channel/audit/main.py b/lib/aci/intf/virtual_port_channel/audit/main.py new file mode 100644 index 00000000..b7105a73 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.virtual_port_channel.audit.api import InterfaceVirtualPortChannelAuditApi +from lib.aci.intf.virtual_port_channel.audit.info import InterfaceVirtualPortChannelAuditInfo + + +class InterfaceVirtualPortChannelAudit(InterfaceVirtualPortChannelAuditApi, InterfaceVirtualPortChannelAuditInfo): + def __init__(self): + InterfaceVirtualPortChannelAuditApi.__init__(self) + InterfaceVirtualPortChannelAuditInfo.__init__(self) diff --git a/lib/aci/intf/virtual_port_channel/event/__init__.py b/lib/aci/intf/virtual_port_channel/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/virtual_port_channel/event/api.py b/lib/aci/intf/virtual_port_channel/event/api.py new file mode 100644 index 00000000..cc277458 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/event/api.py @@ -0,0 +1,54 @@ +class InterfaceVirtualPortChannelEventApi(): + def __init__(self): + self.interface_virtual_port_channel_event_mo = {} + + def get_interface_virtual_port_channel_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_event_mo: + return self.interface_virtual_port_channel_event_mo[key] + + cache = self.get_object_cache( + 'vpcDom.eventLog', + object_selector=key + ) + if cache is not None: + self.interface_virtual_port_channel_event_mo[key] = cache + self.log.apic_mo( + 'vpcDom.eventLog.%s' % (key), + self.interface_virtual_port_channel_event_mo[key] + ) + return self.interface_virtual_port_channel_event_mo[key] + + class_name = 'topology/pod-%s/node-%s/vpcDom' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_virtual_port_channel_event_mo', + 'API failed' + ) + return None + + self.interface_virtual_port_channel_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.interface_virtual_port_channel_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'vpcDom.eventLog.%s' % (key), + self.interface_virtual_port_channel_event_mo[key] + ) + + self.set_object_cache( + 'vpcDom.eventLog', + self.interface_virtual_port_channel_event_mo[key], + object_selector=key + ) + + return self.interface_virtual_port_channel_event_mo[key] diff --git a/lib/aci/intf/virtual_port_channel/event/info.py b/lib/aci/intf/virtual_port_channel/event/info.py new file mode 100644 index 00000000..3ac5286e --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/event/info.py @@ -0,0 +1,121 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceVirtualPortChannelEventInfo(): + def __init__(self): + self.interface_virtual_port_channel_event = {} + + def get_interface_virtual_port_channel_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/vpc/inst/dom-278/if-687" + info['domainId'] = None + info['interfaceId'] = None + if 'sys/vpc/inst/dom-' in info['affected']: + info['domainId'] = info['affected'].split('sys/vpc/inst/dom-')[1].split('/')[0] + if '/if-' in info['affected']: + info['interfaceId'] = info['affected'].split('sys/vpc/inst/dom-')[1].split('/')[1].split('if-')[1] + + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_virtual_port_channel_event(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_event: + return self.interface_virtual_port_channel_event[key] + + managed_objects = self.get_interface_virtual_port_channel_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_virtual_port_channel_event[key] = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_interface_virtual_port_channel_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.interface_virtual_port_channel_event[key].append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'vpcDom.eventLog.info.%s' % (key), + self.interface_virtual_port_channel_event[key] + ) + + return self.interface_virtual_port_channel_event[key] + + def get_interface_virtual_port_channel_domain_id_event(self, pod_id, node_id, domain_id, event_filter=None): + events = [] + + all_events = self.get_interface_virtual_port_channel_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['domainId'] is not None: + if event_info['domainId'] == domain_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/intf/virtual_port_channel/event/main.py b/lib/aci/intf/virtual_port_channel/event/main.py new file mode 100644 index 00000000..64d126d9 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.virtual_port_channel.event.api import InterfaceVirtualPortChannelEventApi +from lib.aci.intf.virtual_port_channel.event.info import InterfaceVirtualPortChannelEventInfo + + +class InterfaceVirtualPortChannelEvent(InterfaceVirtualPortChannelEventApi, InterfaceVirtualPortChannelEventInfo): + def __init__(self): + InterfaceVirtualPortChannelEventApi.__init__(self) + InterfaceVirtualPortChannelEventInfo.__init__(self) diff --git a/lib/aci/intf/virtual_port_channel/fault/__init__.py b/lib/aci/intf/virtual_port_channel/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/virtual_port_channel/fault/api.py b/lib/aci/intf/virtual_port_channel/fault/api.py new file mode 100644 index 00000000..8898be34 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/fault/api.py @@ -0,0 +1,124 @@ +class InterfaceVirtualPortChannelFaultApi(): + def __init__(self): + self.interface_virtual_port_channel_fault_mo = {} + self.interface_virtual_port_channel_fault_record_mo = {} + + def get_interface_virtual_port_channel_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_fault_mo: + return self.interface_virtual_port_channel_fault_mo[key] + + cache = self.get_object_cache( + 'vpcDom.fault', + object_selector=key + ) + if cache is not None: + self.interface_virtual_port_channel_fault_mo[key] = cache + self.log.apic_mo( + 'vpcDom.fault.%s' % (key), + self.interface_virtual_port_channel_fault_mo[key] + ) + return self.interface_virtual_port_channel_fault_mo[key] + + class_name = 'topology/pod-%s/node-%s/vpcDom' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_virtual_port_channel_fault_mo', + 'API failed' + ) + return None + + self.interface_virtual_port_channel_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.interface_virtual_port_channel_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'vpcDom.fault.%s' % (key), + self.interface_virtual_port_channel_fault_mo[key] + ) + + self.set_object_cache( + 'vpcDom.fault', + self.interface_virtual_port_channel_fault_mo[key], + object_selector=key + ) + + return self.interface_virtual_port_channel_fault_mo[key] + + def get_interface_virtual_port_channel_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_fault_record_mo: + return self.interface_virtual_port_channel_fault_record_mo[key] + + cache = self.get_object_cache( + 'vpcDom.faultRecord', + object_selector=key + ) + if cache is not None: + self.interface_virtual_port_channel_fault_record_mo[key] = cache + self.log.apic_mo( + 'vpcDom.faultRecord.%s' % (key), + self.interface_virtual_port_channel_fault_record_mo[key] + ) + return self.interface_virtual_port_channel_fault_record_mo[key] + + class_name = 'topology/pod-%s/node-%s/vpcDom' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_interface_virtual_port_channel_fault_record_mo', + 'API failed' + ) + return None + + self.interface_virtual_port_channel_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.interface_virtual_port_channel_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'vpcDom.faultRecord.%s' % (key), + self.interface_virtual_port_channel_fault_record_mo[key] + ) + + self.set_object_cache( + 'vpcDom.faultRecord', + self.interface_virtual_port_channel_fault_record_mo[key], + object_selector=key + ) + + return self.interface_virtual_port_channel_fault_record_mo[key] diff --git a/lib/aci/intf/virtual_port_channel/fault/info.py b/lib/aci/intf/virtual_port_channel/fault/info.py new file mode 100644 index 00000000..66ebfb46 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/fault/info.py @@ -0,0 +1,158 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class InterfaceVirtualPortChannelFaultInfo(): + def __init__(self): + self.interface_virtual_port_channel_fault = {} + self.interface_virtual_port_channel_fault_record = {} + + def get_interface_virtual_port_channel_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/vpc/inst/dom-278/if-687" + info['domainId'] = None + info['interfaceId'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'sys/vpc/inst/dom-' in info['affected']: + info['domainId'] = info['affected'].split('sys/vpc/inst/dom-')[1].split('/')[0] + if '/if-' in info['affected']: + info['interfaceId'] = info['affected'].split('/')[7].split('if-')[1] + + # "dn": "topology/pod-1/node-2208/sys/vpc/inst/dom-278/if-686/fault-F1296", + if info['domainId'] is None: + if 'sys/vpc/inst/dom-' in info['dn']: + info['domainId'] = info['dn'].split('sys/vpc/inst/dom-')[1].split('/')[0] + if '/if-' in info['dn']: + info['interfaceId'] = info['dn'].split('/')[7].split('if-')[1] + + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_interface_virtual_port_channel_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_fault: + return self.interface_virtual_port_channel_fault[key] + + managed_objects = self.get_interface_virtual_port_channel_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_virtual_port_channel_fault[key] = [] + for managed_object in managed_objects: + fault_info = self.get_interface_virtual_port_channel_fault_info( + managed_object + ) + self.interface_virtual_port_channel_fault[key].append( + fault_info + ) + + self.log.apic_mo( + 'vpcDom.fault.info.%s' % (key), + self.interface_virtual_port_channel_fault[key] + ) + + return self.interface_virtual_port_channel_fault[key] + + def get_interface_virtual_port_channel_fault_record(self, pod_id, node_id, deduplicate=True): + key = '%s.%s' % (pod_id, node_id) + if key in self.interface_virtual_port_channel_fault_record: + return self.interface_virtual_port_channel_fault_record[key] + + managed_objects = self.get_interface_virtual_port_channel_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.interface_virtual_port_channel_fault_record[key] = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_interface_virtual_port_channel_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.interface_virtual_port_channel_fault_record[key].append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'vpcDom.faultRecord.info.%s' % (key), + self.interface_virtual_port_channel_fault_record[key] + ) + + return self.interface_virtual_port_channel_fault_record[key] + + def get_interface_virtual_port_channel_domain_id_fault(self, pod_id, node_id, domain_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_interface_virtual_port_channel_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_interface_virtual_port_channel_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['domainId'] is not None: + if fault_info['domainId'] == domain_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/intf/virtual_port_channel/fault/main.py b/lib/aci/intf/virtual_port_channel/fault/main.py new file mode 100644 index 00000000..8397e0fb --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.virtual_port_channel.fault.api import InterfaceVirtualPortChannelFaultApi +from lib.aci.intf.virtual_port_channel.fault.info import InterfaceVirtualPortChannelFaultInfo + + +class InterfaceVirtualPortChannelFault(InterfaceVirtualPortChannelFaultApi, InterfaceVirtualPortChannelFaultInfo): + def __init__(self): + InterfaceVirtualPortChannelFaultApi.__init__(self) + InterfaceVirtualPortChannelFaultInfo.__init__(self) diff --git a/lib/aci/intf/virtual_port_channel/info.py b/lib/aci/intf/virtual_port_channel/info.py new file mode 100644 index 00000000..ceb87828 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/info.py @@ -0,0 +1,261 @@ +from lib import filter_helper + + +class InterfaceVirtualPortChannelInfo(): + def __init__(self): + self.interfaces_vpc = {} + + def get_interface_virtual_port_channel_summary(self, pod_id, node_id): + ports = self.get_interface_virtual_port_channel( + pod_id, + node_id + ) + + if ports is None: + return None + + summary = {} + summary['__Output'] = {} + summary['portUp'] = 0 + summary['portDown'] = 0 + summary['portCount'] = 0 + + for port in ports: + summary['portUp'] = summary['portUp'] + port['localMemberUp'] + summary['portDown'] = summary['portDown'] + port['localMemberDown'] + + summary['portCount'] = summary['portUp'] + summary['portDown'] + + (summary['portSummary'], summary['__Output']['portSummary']) = self.get_interface_summary_output( + summary['portUp'], + summary['portDown'], + summary['portCount'] + ) + + return summary + + def get_interface_virtual_port_channel_info(self, managed_object): + keys = [ + 'compatQual', + 'compatQualStr', + 'compatSt', + 'deadIntvl', + 'dn', + 'dualActiveSt', + 'id', + 'lacpRole', + 'localMAC', + 'localPrio', + 'operRole', + 'operSt', + 'orphanPortList', + 'peerIp', + 'peerMAC', + 'peerPrio', + 'peerSt', + 'peerStQual', + 'peerVersion', + 'rolePrio', + 'summOperRole', + 'sysMac', + 'sysPrio', + 'virtualIp', + 'vpcMAC', + 'vpcPrio' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "topology/pod-1/node-201/sys/vpc/inst/dom-100" + info['podId'] = info['dn'].split('/')[1].split('-')[1] + info['nodeId'] = info['dn'].split('/')[2].split('-')[1] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['__Output']['id'] = 'Blue' + + if info['peerSt'] == 'up': + info['__Output']['peerSt'] = 'Green' + info['peerStQual'] = '' + info['up'] = True + else: + info['__Output']['peerSt'] = 'Red' + info['up'] = False + + if info['compatSt'] == 'pass': + info['__Output']['compatSt'] = 'Green' + info['compatQualStr'] = '' + else: + info['__Output']['compatSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + info['member'] = [] + for vpc_interface_mo in managed_object['vpcIf']: + member_info = self.get_interface_virtual_port_channel_member_info( + vpc_interface_mo + ) + member_info['pod_node_name'] = info['pod_node_name'] + member_info['domainId'] = info['id'] + + info['member'].append( + member_info + ) + + info = self.add_interface_virtual_port_channel_members_summary( + info + ) + + return info + + def get_interfaces_virtual_port_channel_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.interfaces_vpc: + return self.interfaces_vpc[key] + + interfaces_vpc_mo = self.get_interfaces_virtual_port_channel_mo(pod_id, node_id) + if interfaces_vpc_mo is None: + return None + + self.interfaces_vpc[key] = [] + for interface_vpc_mo in interfaces_vpc_mo: + self.interfaces_vpc[key].append( + self.get_interface_virtual_port_channel_info( + interface_vpc_mo + ) + ) + + self.log.apic_mo( + 'vpcDom.info.%s' % (key), + self.interfaces_vpc[key] + ) + + return self.interfaces_vpc[key] + + def match_interface_virtual_port_channel(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, interface_info['id']): + return False + + if key == 'state': + if value != 'any': + if not filter_helper.match_string(value, interface_info['peerSt']): + return False + + if key == 'member': + if 'memberSt' in interface_info: + if value != 'any': + if not filter_helper.match_string(value, interface_info['memberSt']): + return False + + return True + + def get_interface_virtual_port_channel( + self, + pod_id, + node_id, + interface_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_interfaces = self.get_interfaces_virtual_port_channel_info(pod_id, node_id) + if all_interfaces is None: + return None + + interfaces = [] + + for interface_info in all_interfaces: + if not self.match_interface_virtual_port_channel(interface_info, interface_filter): + continue + + for member_info in interface_info['member']: + member_info['pc'] = self.get_interface_port_channel( + pod_id, + node_id, + interface_port_channel_filter=['name:%s' % (member_info['name'])] + ) + + member_info['vlan'] = [] + if len(member_info['cfgdTrunkVlans']) > 0: + member_info['vlan'] = self.get_vlan_stats( + pod_id, + node_id, + vlan_filter=['evlans:%s' % (member_info['cfgdTrunkVlans'])] + ) + + if fault_info: + interface_info['faultInst'] = self.get_interface_virtual_port_channel_domain_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultInst' + ) + + if hfault_info: + interface_info['faultRecord'] = self.get_interface_virtual_port_channel_domain_id_fault( + pod_id, + node_id, + interface_info['id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + interface_info['eventLog'] = self.get_interface_virtual_port_channel_domain_id_event( + pod_id, + node_id, + interface_info['id'], + event_filter=event_filter + ) + + if audit_info: + interface_info['auditLog'] = self.get_interface_virtual_port_channel_id_audit( + pod_id, + node_id, + interface_info['id'], + audit_filter=audit_filter + ) + + interfaces.append( + interface_info + ) + + interfaces = sorted( + interfaces, + key=lambda i: i['id'] + ) + + return interfaces diff --git a/lib/aci/intf/virtual_port_channel/main.py b/lib/aci/intf/virtual_port_channel/main.py new file mode 100644 index 00000000..c1c6c1d6 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/main.py @@ -0,0 +1,23 @@ +from lib.aci.intf.virtual_port_channel.member.main import InterfaceVirtualPortChannelMember +from lib.aci.intf.virtual_port_channel.api import InterfaceVirtualPortChannelApi +from lib.aci.intf.virtual_port_channel.info import InterfaceVirtualPortChannelInfo +from lib.aci.intf.virtual_port_channel.audit.main import InterfaceVirtualPortChannelAudit +from lib.aci.intf.virtual_port_channel.event.main import InterfaceVirtualPortChannelEvent +from lib.aci.intf.virtual_port_channel.fault.main import InterfaceVirtualPortChannelFault + + +class InterfaceVirtualPortChannel( + InterfaceVirtualPortChannelMember, + InterfaceVirtualPortChannelApi, + InterfaceVirtualPortChannelInfo, + InterfaceVirtualPortChannelAudit, + InterfaceVirtualPortChannelEvent, + InterfaceVirtualPortChannelFault + ): + def __init__(self): + InterfaceVirtualPortChannelMember.__init__(self) + InterfaceVirtualPortChannelApi.__init__(self) + InterfaceVirtualPortChannelInfo.__init__(self) + InterfaceVirtualPortChannelAudit.__init__(self) + InterfaceVirtualPortChannelEvent.__init__(self) + InterfaceVirtualPortChannelFault.__init__(self) diff --git a/lib/aci/intf/virtual_port_channel/member/__init__.py b/lib/aci/intf/virtual_port_channel/member/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/virtual_port_channel/member/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/member/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a102a59f Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/member/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/member/__pycache__/api.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/member/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d1191034 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/member/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/member/__pycache__/info.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/member/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..254a8a21 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/member/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/member/__pycache__/main.cpython-310.pyc b/lib/aci/intf/virtual_port_channel/member/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d6fee243 Binary files /dev/null and b/lib/aci/intf/virtual_port_channel/member/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/virtual_port_channel/member/info.py b/lib/aci/intf/virtual_port_channel/member/info.py new file mode 100644 index 00000000..61a20434 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/member/info.py @@ -0,0 +1,107 @@ +class InterfaceVirtualPortChannelMemberInfo(): + def __init__(self): + self.interface_vpc_members = {} + + def get_interface_virtual_port_channel_member_info(self, managed_object): + keys = [ + 'accBndlGrpDn', + 'cfgdAccessVlan', + 'cfgdTrunkVlans', + 'cfgdVlans', + 'compatSt', + 'descr', + 'fabEncMismatchVlans', + 'fabEncMismatchVlansSet', + 'id', + 'localOperSt', + 'name', + 'pcMode', + 'peerCfgdVlans', + 'peerUpVlans', + 'remoteOperSt', + 'suspVlans', + 'upVlans', + 'usage' + ] + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['localOperSt'] == 'up': + info['__Output']['localOperSt'] = 'Green' + else: + info['__Output']['localOperSt'] = 'Red' + + if info['remoteOperSt'] == 'up': + info['__Output']['remoteOperSt'] = 'Green' + else: + info['__Output']['remoteOperSt'] = 'Red' + + info['__Output']['domainId'] = 'Blue' + info['__Output']['id'] = 'Blue' + + for key in ['cfgdTrunkVlans', 'cfgdVlans', 'upVlans', 'suspVlans', 'peerCfgdVlans', 'peerUpVlans']: + info['%sT' % (key)] = [] + if len(info[key]) > 0: + info['%sT' % (key)] = info[key].split(',') + if len(info['%sT' % (key)]) == 0: + info['%sT' % (key)].append('--') + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def add_interface_virtual_port_channel_members_summary(self, info): + info['localMemberUp'] = 0 + info['localMemberDown'] = 0 + info['peerMemberUp'] = 0 + info['peerMemberDown'] = 0 + + for member in info['member']: + if member['localOperSt'] == 'up': + info['localMemberUp'] = info['localMemberUp'] + 1 + else: + info['localMemberDown'] = info['localMemberDown'] + 1 + + if member['remoteOperSt'] == 'up': + info['peerMemberUp'] = info['peerMemberUp'] + 1 + else: + info['peerMemberDown'] = info['peerMemberDown'] + 1 + + info['localMemberSummary'] = '%s/%s' % ( + info['localMemberUp'], + len(info['member']) + ) + + info['peerMemberSummary'] = '%s/%s' % ( + info['peerMemberUp'], + len(info['member']) + ) + + info['memberSt'] = 'up' + if info['localMemberUp'] == len(info['member']): + info['__Output']['localMemberSummary'] = 'Green' + else: + info['__Output']['localMemberSummary'] = 'Red' + info['memberSt'] = 'down' + + if info['peerMemberUp'] == len(info['member']): + info['__Output']['peerMemberSummary'] = 'Green' + else: + info['__Output']['peerMemberSummary'] = 'Red' + info['memberSt'] = 'down' + + return info diff --git a/lib/aci/intf/virtual_port_channel/member/main.py b/lib/aci/intf/virtual_port_channel/member/main.py new file mode 100644 index 00000000..6db3b8b3 --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/member/main.py @@ -0,0 +1,6 @@ +from lib.aci.intf.virtual_port_channel.member.info import InterfaceVirtualPortChannelMemberInfo + + +class InterfaceVirtualPortChannelMember(InterfaceVirtualPortChannelMemberInfo): + def __init__(self): + InterfaceVirtualPortChannelMemberInfo.__init__(self) diff --git a/lib/aci/intf/virtual_port_channel/output.py b/lib/aci/intf/virtual_port_channel/output.py new file mode 100644 index 00000000..693ec8dc --- /dev/null +++ b/lib/aci/intf/virtual_port_channel/output.py @@ -0,0 +1,520 @@ +class InterfaceVirtualPortChannelOutput(): + def __init__(self): + pass + + def print_interfaces_virtual_port_channel_state(self, info, title=False): + if title: + self.my_output.default( + 'Interface Virtual Port Channel - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'health', + 'faults', + 'id', + 'lacpRole', + 'summOperRole', + 'operSt', + 'peerSt', + 'peerStQual', + 'compatSt', + 'compatQualStr', + 'localMemberSummary', + 'peerMemberSummary' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Health', + 'Faults', + 'Domain', + 'LACP Role', + 'Oper Role', + 'Oper State', + 'Peer State', + 'Reason', + 'Constistency', + 'Reason', + 'Local Members', + 'Remote Members' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interfaces_virtual_port_channel_address(self, info, title=False): + if title: + self.my_output.default( + 'Interface Virtual Port Channel - Address [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'id', + 'virtualIp', + 'vpcMAC', + 'localMAC', + 'localPrio', + 'peerIp', + 'peerMAC', + 'peerPrio' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Domain', + 'VPC IP', + 'VPC MAC', + 'Local MAC', + 'Local Prio', + 'Peer IP', + 'Peer MAC', + 'Peer Prio' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interfaces_virtual_port_channel_member(self, info, title=False): + if title: + self.my_output.default( + 'Interface Virtual Port Channel - Members [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainId', + 'health', + 'faults', + 'id', + 'pc.id', + 'name', + 'pcMode', + 'localOperSt', + 'remoteOperSt' + ] + + headers = [ + 'Node', + 'Domain', + 'Health', + 'Faults', + 'Member', + 'PC', + 'Description', + 'PC Mode', + 'Local State', + 'Remote State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['pc'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_interfaces_virtual_port_channel_vlan(self, info, title=False): + if title: + self.my_output.default( + 'Interface Virtual Port Channel Member - Configured VLANs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainId', + 'health', + 'faults', + 'id', + 'pc.id', + 'cfgdAccessVlan', + 'cfgdTrunkVlansT', + 'cfgdVlansT', + 'upVlansT', + 'suspVlansT', + 'peerCfgdVlansT', + 'peerUpVlansT' + ] + + headers = [ + 'Node', + 'Domain', + 'Health', + 'Faults', + 'Member', + 'PC', + 'Cfg Access Vlans', + 'Cfg Trunk Vlans', + 'Cfg Vlans', + 'Up Vlans', + 'Susp Vlans', + 'Peer Cfg Vlans', + 'Peer Up Vlans' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['pc', 'cfgdTrunkVlansT', 'cfgdVlansT', 'upVlansT', 'suspVlansT', 'peerCfgdVlansT', 'peerUpVlansT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interfaces_virtual_port_channel_vlan_epg(self, info, title=False): + if title: + self.my_output.default( + 'Interface Virtual Port Channel Member - VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'domainId', + 'health', + 'faults', + 'id', + 'pc.id', + 'vlan.id', + 'vlan.hwId', + 'vlan.encap', + 'vlan.name', + 'vlan.fabEncap' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Domain', + 'Health', + 'Faults', + 'Member', + 'PC', + 'VLAN ID', + 'HW ID', + 'Encap', + 'EPG', + 'Fabric Encap' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['pc', 'vlan'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_virtual_port_channel_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Virtual Port Channel - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Virtual Port Channel - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainId', + 'interfaceIdT', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Domain', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_interface_virtual_port_channel_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Interface Virtual Port Channel - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainId', + 'interfaceIdT', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Domain', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_virtual_port_channel_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Virtual Port Channel - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Virtual Port Channel - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainId', + 'interfaceId', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Domain', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_interface_virtual_port_channel_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Interface Virtual Port Channel - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Interface Virtual Port Channel - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainId', + 'interfaceIdT', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Domain', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + diff --git a/lib/aci/intf/vlan/__init__.py b/lib/aci/intf/vlan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/intf/vlan/__pycache__/__init__.cpython-310.pyc b/lib/aci/intf/vlan/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f4fc13ff Binary files /dev/null and b/lib/aci/intf/vlan/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/intf/vlan/__pycache__/api.cpython-310.pyc b/lib/aci/intf/vlan/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..fb6ab557 Binary files /dev/null and b/lib/aci/intf/vlan/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/intf/vlan/__pycache__/info.cpython-310.pyc b/lib/aci/intf/vlan/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..df1c032c Binary files /dev/null and b/lib/aci/intf/vlan/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/intf/vlan/__pycache__/main.cpython-310.pyc b/lib/aci/intf/vlan/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0be20147 Binary files /dev/null and b/lib/aci/intf/vlan/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/intf/vlan/__pycache__/output.cpython-310.pyc b/lib/aci/intf/vlan/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..8e4ad177 Binary files /dev/null and b/lib/aci/intf/vlan/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/intf/vlan/api.py b/lib/aci/intf/vlan/api.py new file mode 100644 index 00000000..b2f8c121 --- /dev/null +++ b/lib/aci/intf/vlan/api.py @@ -0,0 +1,51 @@ +class InterfaceVlanStatsApi(): + def __init__(self): + self.vlan_stats_mo = {} + + def get_vlan_stats_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.vlan_stats_mo: + return self.vlan_stats_mo[key] + + cache = self.get_object_cache( + 'vlanCktEp', + object_selector=key + ) + if cache is not None: + self.vlan_stats_mo[key] = cache + self.log.apic_mo( + 'vlanCktEp.%s' % (key), + self.vlan_stats_mo[key] + ) + return self.vlan_stats_mo[key] + + class_name = 'topology/pod-%s/node-%s/vlanCktEp' % (pod_id, node_id) + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_vlan_stats_mo', + 'API failed' + ) + return None + + self.vlan_stats_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.vlan_stats_mo[key].append( + managed_object['vlanCktEp']['attributes'] + ) + + self.log.apic_mo( + 'vlanCktEp.%s' % (key), + self.vlan_stats_mo[key] + ) + + self.set_object_cache( + 'vlanCktEp', + self.vlan_stats_mo[key], + object_selector=key + ) + + return self.vlan_stats_mo[key] diff --git a/lib/aci/intf/vlan/info.py b/lib/aci/intf/vlan/info.py new file mode 100644 index 00000000..615665b1 --- /dev/null +++ b/lib/aci/intf/vlan/info.py @@ -0,0 +1,150 @@ +from lib import filter_helper + + +class InterfaceVlanStatsInfo(): + def __init__(self): + self.vlan_stats = {} + + def get_vlan_stats_info(self, managed_object): + keys = [ + 'adminSt', + 'ctrl', + 'dn', + 'encap', + 'epgDn', + 'fabEncap', + 'fwdCtrl', + 'hwId', + 'id', + 'name', + 'operSt', + 'operStQual', + 'type' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key].strip() + + if info['adminSt'] == 'active': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + info['fvxlan'] = '' + if 'vxlan-' in info['fabEncap']: + info['fvxlan'] = info['fabEncap'].split('vxlan-')[1] + + info['evlan'] = '' + if 'vlan-' in info['encap']: + info['evlan'] = info['encap'].split('vlan-')[1] + + return info + + def get_vlans_stats_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.vlan_stats: + return self.vlan_stats[key] + + vlan_stats_mo = self.get_vlan_stats_mo(pod_id, node_id) + if vlan_stats_mo is None: + return None + + self.vlan_stats[key] = [] + for managed_object in vlan_stats_mo: + self.vlan_stats[key].append( + self.get_vlan_stats_info( + managed_object + ) + ) + + self.log.apic_mo( + 'vlanCktEp.info.%s' % (key), + self.vlan_stats[key] + ) + + return self.vlan_stats[key] + + def get_oper_vlans_list(self, oper_vlans): + vlans = [] + + for item in oper_vlans.split(','): + if '-' in item: + start_index = int(item.split('-')[0]) + end_index = int(item.split('-')[1]) + + index = start_index + while True: + vlans.append(str(index)) + index = index + 1 + if index > end_index: + break + + if '-' not in item: + vlans.append(item) + + return vlans + + def match_vlan_stats(self, vlan_stats_info, vlan_filter): + if vlan_filter is None or len(vlan_filter) == 0: + return True + + for ap_rule in vlan_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'vlans': + if not filter_helper.match_id(vlan_stats_info['id'], value): + return False + + if key == 'vlan': + if not filter_helper.match_id(vlan_stats_info['id'], value): + return False + + if key == 'evlan': + if not filter_helper.match_id(vlan_stats_info['evlan'], value): + return False + + if key == 'evlans': + if not filter_helper.match_id(vlan_stats_info['evlan'], value): + return False + + if key == 'fvxlan': + if not filter_helper.match_id(vlan_stats_info['fvxlan'], value): + return False + + if key == 'epg': + if not filter_helper.match_string(value, vlan_stats_info['epgDn']): + return False + + return True + + def get_vlan_stats(self, pod_id, node_id, vlan_filter=None): + all_vlan_stats = self.get_vlans_stats_info(pod_id, node_id) + if all_vlan_stats is None: + return None + + vlan_stats = [] + + for vlan_stats_info in all_vlan_stats: + if not self.match_vlan_stats(vlan_stats_info, vlan_filter): + continue + + vlan_stats.append( + vlan_stats_info + ) + + vlan_stats = sorted( + vlan_stats, + key=lambda i: int(i['id']) + ) + + return vlan_stats diff --git a/lib/aci/intf/vlan/main.py b/lib/aci/intf/vlan/main.py new file mode 100644 index 00000000..ff76306a --- /dev/null +++ b/lib/aci/intf/vlan/main.py @@ -0,0 +1,8 @@ +from lib.aci.intf.vlan.api import InterfaceVlanStatsApi +from lib.aci.intf.vlan.info import InterfaceVlanStatsInfo + + +class InterfaceVlanStats(InterfaceVlanStatsApi, InterfaceVlanStatsInfo): + def __init__(self): + InterfaceVlanStatsApi.__init__(self) + InterfaceVlanStatsInfo.__init__(self) diff --git a/lib/aci/intf/vlan/output.py b/lib/aci/intf/vlan/output.py new file mode 100644 index 00000000..8cd396c7 --- /dev/null +++ b/lib/aci/intf/vlan/output.py @@ -0,0 +1,29 @@ +class InterfaceVlanStatsOutput(): + def __init__(self): + pass + + def print_vlan_stats(self, info): + order = [ + 'adminSt', + 'operSt', + 'id', + 'encap', + 'epgDn' + ] + + headers = [ + 'Admin State', + 'Oper State', + 'Internal VLAN', + 'Encapsulation VLAN', + 'EPG Dn' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/l2out/__init__.py b/lib/aci/l2out/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l2out/__pycache__/__init__.cpython-310.pyc b/lib/aci/l2out/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c5c9cfbb Binary files /dev/null and b/lib/aci/l2out/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/l2out/__pycache__/api.cpython-310.pyc b/lib/aci/l2out/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d252ecbb Binary files /dev/null and b/lib/aci/l2out/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/l2out/__pycache__/info.cpython-310.pyc b/lib/aci/l2out/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1d75d6a4 Binary files /dev/null and b/lib/aci/l2out/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/l2out/__pycache__/main.cpython-310.pyc b/lib/aci/l2out/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d7b340c9 Binary files /dev/null and b/lib/aci/l2out/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/l2out/__pycache__/output.cpython-310.pyc b/lib/aci/l2out/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..c13e890f Binary files /dev/null and b/lib/aci/l2out/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/l2out/api.py b/lib/aci/l2out/api.py new file mode 100644 index 00000000..fe6acc77 --- /dev/null +++ b/lib/aci/l2out/api.py @@ -0,0 +1,126 @@ +class L2OutApi(): + def __init__(self): + self.l2out_mo = None + self.l2out_path_mo = None + + def get_l2out_mo(self): + if self.l2out_mo is not None: + return self.l2out_mo + + cache = self.get_object_cache( + 'l2extOut' + ) + if cache is not None: + self.l2out_mo = cache + self.log.apic_mo( + 'l2extOut', + self.l2out_mo + ) + return self.l2out_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=l2extLNodeP,l2extInstP,l2extRsEBd,l2extRsL2DomAtt' + managed_objects = self.get_class( + 'l2extOut', + query=query + ) + if managed_objects is None: + self.log.error( + 'get_l2out_mo', + 'API failed' + ) + return None + + self.l2out_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2extOut']['attributes'] + attributes['l2extLNodeP'] = self.get_mo_children_attributes( + 'l2extOut', + managed_object, + 'l2extLNodeP' + ) + attributes['l2extInstP'] = self.get_mo_children_attributes( + 'l2extOut', + managed_object, + 'l2extInstP' + ) + attributes['l2extRsEBd'] = self.get_mo_child_attributes( + 'l2extOut', + managed_object, + 'l2extRsEBd' + ) + attributes['l2extRsL2DomAtt'] = self.get_mo_child_attributes( + 'l2extOut', + managed_object, + 'l2extRsL2DomAtt' + ) + attributes['l2extRsPathL2OutAtt'] = self.get_mo_children_attributes( + 'l2extOut', + managed_object, + 'l2extRsPathL2OutAtt' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l2extOut', + managed_object, + 'faultCounts' + ) + + self.l2out_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extOut', + self.l2out_mo + ) + + self.set_object_cache( + 'l2extOut', + self.l2out_mo + ) + + return self.l2out_mo + + def get_l2out_path_mo(self): + if self.l2out_path_mo is not None: + return self.l2out_path_mo + + cache = self.get_object_cache( + 'l2extRsPathL2OutAtt' + ) + if cache is not None: + self.l2out_path_mo = cache + self.log.apic_mo( + 'l2extRsPathL2OutAtt', + self.l2out_path_mo + ) + return self.l2out_path_mo + + managed_objects = self.get_class( + 'l2extRsPathL2OutAtt', + node_class=True + ) + if managed_objects is None: + self.log.error( + 'get_l2out_paths_mo', + 'API failed' + ) + return None + + self.l2out_path_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2extRsPathL2OutAtt']['attributes'] + self.l2out_path_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extRsPathL2OutAtt', + self.l2out_path_mo + ) + + self.set_object_cache( + 'l2extRsPathL2OutAtt', + self.l2out_path_mo + ) + + return self.l2out_path_mo diff --git a/lib/aci/l2out/audit/__init__.py b/lib/aci/l2out/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l2out/audit/api.py b/lib/aci/l2out/audit/api.py new file mode 100644 index 00000000..18da357f --- /dev/null +++ b/lib/aci/l2out/audit/api.py @@ -0,0 +1,48 @@ +class L2OutAuditApi(): + def __init__(self): + self.l2out_audit_mo = None + + def get_l2out_audit_mo(self): + cache = self.get_object_cache( + 'l2extOut.audit' + ) + if cache is not None: + self.l2out_audit_mo = cache + self.log.apic_mo( + 'l2extOut.audit', + self.l2out_audit_mo + ) + return self.l2out_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'l2extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l2out_audit_mo', + 'API failed' + ) + return None + + self.l2out_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.l2out_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extOut.audit', + self.l2out_audit_mo + ) + + self.set_object_cache( + 'l2extOut.audit', + self.l2out_audit_mo + ) + + return self.l2out_audit_mo diff --git a/lib/aci/l2out/audit/info.py b/lib/aci/l2out/audit/info.py new file mode 100644 index 00000000..fd01547a --- /dev/null +++ b/lib/aci/l2out/audit/info.py @@ -0,0 +1,110 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class L2OutAuditInfo(): + def __init__(self): + self.l2out_audit = None + + def get_l2out_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['l2outName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/l2out-Test + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/l2out-' in info['affected']: + info['l2outName'] = info['affected'].split('/l2out-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['l2outName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['l2outName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_l2out_audit(self): + if self.l2out_audit is not None: + return self.l2out_audit + + managed_objects = self.get_l2out_audit_mo() + if managed_objects is None: + return None + + self.l2out_audit = [] + for managed_object in managed_objects: + audit_info = self.get_l2out_audit_info( + managed_object + ) + self.l2out_audit.append( + audit_info + ) + + self.log.apic_mo( + 'l2extOut.auditRecord.info', + self.l2out_audit + ) + + return self.l2out_audit + + def get_l2out_id_audit(self, tenant_name, l2out_name, audit_filter=None): + audits = [] + + all_audits = self.get_l2out_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['l2outName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['l2outName'] == l2out_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/l2out/audit/main.py b/lib/aci/l2out/audit/main.py new file mode 100644 index 00000000..50a07647 --- /dev/null +++ b/lib/aci/l2out/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.l2out.audit.api import L2OutAuditApi +from lib.aci.l2out.audit.info import L2OutAuditInfo + + +class L2OutAudit(L2OutAuditApi, L2OutAuditInfo): + def __init__(self): + L2OutAuditApi.__init__(self) + L2OutAuditInfo.__init__(self) diff --git a/lib/aci/l2out/event/__init__.py b/lib/aci/l2out/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l2out/event/api.py b/lib/aci/l2out/event/api.py new file mode 100644 index 00000000..f84ec357 --- /dev/null +++ b/lib/aci/l2out/event/api.py @@ -0,0 +1,51 @@ +class L2OutEventApi(): + def __init__(self): + self.l2out_event_mo = None + + def get_l2out_event_mo(self): + if self.l2out_event_mo is not None: + return self.l2out_event_mo + + cache = self.get_object_cache( + 'l2extOut.eventLog' + ) + if cache is not None: + self.l2out_event_mo = cache + self.log.apic_mo( + 'l2extOut.eventLog', + self.l2out_event_mo + ) + return self.l2out_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'l2extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l2out_event_mo', + 'API failed' + ) + return None + + self.l2out_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.l2out_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extOut.eventLog', + self.l2out_event_mo + ) + + self.set_object_cache( + 'l2extOut.eventLog', + self.l2out_event_mo + ) + + return self.l2out_event_mo diff --git a/lib/aci/l2out/event/info.py b/lib/aci/l2out/event/info.py new file mode 100644 index 00000000..56ca1538 --- /dev/null +++ b/lib/aci/l2out/event/info.py @@ -0,0 +1,124 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class L2OutEventInfo(): + def __init__(self): + self.l2out_event = None + + def get_l2out_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['l2outName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/l2out-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/l2out-' in info['affected']: + info['l2outName'] = info['affected'].split('/l2out-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/l2out-bmk8s_2_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/l2out-' in info['dn']: + info['l2outName'] = info['dn'].split('/l2out-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['l2outName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['l2outName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_l2out_event(self, deduplicate=True): + if self.l2out_event is not None: + return self.l2out_event + + managed_objects = self.get_l2out_event_mo() + if managed_objects is None: + return None + + self.l2out_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_l2out_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.l2out_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l2extOut.eventLog.info', + self.l2out_event + ) + + return self.l2out_event + + def get_l2out_id_event(self, tenant_name, l2out_name, event_filter=None): + events = [] + + all_events = self.get_l2out_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['l2outName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['l2outName'] == l2out_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/l2out/event/main.py b/lib/aci/l2out/event/main.py new file mode 100644 index 00000000..78ce717c --- /dev/null +++ b/lib/aci/l2out/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.l2out.event.api import L2OutEventApi +from lib.aci.l2out.event.info import L2OutEventInfo + + +class L2OutEvent(L2OutEventApi, L2OutEventInfo): + def __init__(self): + L2OutEventApi.__init__(self) + L2OutEventInfo.__init__(self) diff --git a/lib/aci/l2out/fault/__init__.py b/lib/aci/l2out/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l2out/fault/api.py b/lib/aci/l2out/fault/api.py new file mode 100644 index 00000000..c8ab7e6d --- /dev/null +++ b/lib/aci/l2out/fault/api.py @@ -0,0 +1,118 @@ +class L2OutFaultApi(): + def __init__(self): + self.l2out_fault_mo = None + self.l2out_fault_record_mo = None + + def get_l2out_fault_mo(self): + cache = self.get_object_cache( + 'l2extOut.fault' + ) + if cache is not None: + self.l2out_fault_mo = cache + self.log.apic_mo( + 'l2extOut.fault', + self.l2out_fault_mo + ) + return self.l2out_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'l2extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l2out_fault_mo', + 'API failed' + ) + return None + + self.l2out_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.l2out_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.l2out_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extOut.fault', + self.l2out_fault_mo + ) + + self.set_object_cache( + 'l2extOut.fault', + self.l2out_fault_mo + ) + + return self.l2out_fault_mo + + def get_l2out_fault_record_mo(self): + cache = self.get_object_cache( + 'l2extOut.faultRecord' + ) + if cache is not None: + self.l2out_fault_record_mo = cache + self.log.apic_mo( + 'l2extOut.faultRecord', + self.l2out_fault_record_mo + ) + return self.l2out_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'l2extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l2out_fault_record_mo', + 'API failed' + ) + return None + + self.l2out_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.l2out_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.l2out_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2extOut.faultRecord', + self.l2out_fault_record_mo + ) + + self.set_object_cache( + 'l2extOut.faultRecord', + self.l2out_fault_record_mo + ) + + return self.l2out_fault_record_mo diff --git a/lib/aci/l2out/fault/info.py b/lib/aci/l2out/fault/info.py new file mode 100644 index 00000000..148c587f --- /dev/null +++ b/lib/aci/l2out/fault/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class L2OutFaultInfo(): + def __init__(self): + self.l2out_fault = None + self.l2out_fault_record = None + + def get_l2out_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['l2outName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/l2out-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/l2out-' in info['affected']: + info['l2outName'] = info['affected'].split('/l2out-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/l2out-bmk8s_2_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/l2out-' in info['dn']: + info['l2outName'] = info['dn'].split('/l2out-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['l2outName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['l2outName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_l2out_fault(self): + if self.l2out_fault is not None: + return self.l2out_fault + + managed_objects = self.get_l2out_fault_mo() + if managed_objects is None: + return None + + self.l2out_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_l2out_fault_info( + managed_object + ) + self.l2out_fault.append( + fault_info + ) + + self.log.apic_mo( + 'l2extOut.fault.info', + self.l2out_fault + ) + + return self.l2out_fault + + def get_l2out_fault_record(self, deduplicate=True): + if self.l2out_fault_record is not None: + return self.l2out_fault_record + + managed_objects = self.get_l2out_fault_record_mo() + if managed_objects is None: + return None + + self.l2out_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_l2out_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.l2out_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l2extOut.faultRecord.info', + self.l2out_fault_record + ) + + return self.l2out_fault_record + + def get_l2out_id_fault(self, tenant_name, l2out_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_l2out_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_l2out_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['l2outName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['l2outName'] == l2out_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/l2out/fault/main.py b/lib/aci/l2out/fault/main.py new file mode 100644 index 00000000..e662ed5d --- /dev/null +++ b/lib/aci/l2out/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.l2out.fault.api import L2OutFaultApi +from lib.aci.l2out.fault.info import L2OutFaultInfo + + +class L2OutFault(L2OutFaultApi, L2OutFaultInfo): + def __init__(self): + L2OutFaultApi.__init__(self) + L2OutFaultInfo.__init__(self) diff --git a/lib/aci/l2out/info.py b/lib/aci/l2out/info.py new file mode 100644 index 00000000..bed93796 --- /dev/null +++ b/lib/aci/l2out/info.py @@ -0,0 +1,300 @@ +import copy +from lib import filter_helper + + +class L2OutInfo(): + def __init__(self): + self.l2out = None + self.l2out_with_path = None + + def get_l2out_count(self, tenant_name=None): + l2out_filter = None + if tenant_name is not None: + l2out_filter = ['tenant:%s' % (tenant_name)] + + l2outs = self.get_l2outs( + l2out_filter=l2out_filter + ) + return len(l2outs) + + def get_l2out_ext_epg_info(self, managed_object): + keys = [ + 'annotation', + 'configSt', + 'descr', + 'exceptionTag', + 'floodOnEncap', + 'isSharedSrvMsiteEPg', + 'matchT', + 'name', + 'nameAlias', + 'pcEnfPref', + 'pcTag', + 'prefGrMemb', + 'prio', + 'rn', + 'targetDscp' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['configSt'] == 'applied': + info['__Output']['configSt'] = 'Green' + else: + info['__Output']['configSt'] = 'Red' + + # "rn": "instP-L2Out-ext-epg" + info['name'] = info['rn'][6:] + + return info + + def get_l2out_name_from_dn(self, l2out_dn): + # [0]: uni/tn-{name}/l2out-{name} + tenant = l2out_dn.split('/')[1][3:] + if '/l2out-' in l2out_dn: + name = l2out_dn.split('/')[2][6:] + if '/out-' in l2out_dn: + name = l2out_dn.split('/')[2][4:] + l2out_name = '%s/%s' % ( + tenant, + name + ) + return l2out_name + + def get_l2out_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name', + 'targetDscp', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # [0]: uni/tn-{name}/ap-{name} + info['tenant'] = info['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + # Associated BD + info['fvBD'] = None + if managed_object['l2extRsEBd']['tCl'] == 'fvBD': + info['fvBD'] = {} + info['fvBD']['dn'] = managed_object['l2extRsEBd']['tDn'] + info['fvBD']['tenant'] = info['fvBD']['dn'].split('/')[1][3:] + info['fvBD']['name'] = info['fvBD']['dn'].split('/')[2][3:] + info['fvBD']['encap'] = managed_object['l2extRsEBd']['encap'] + info['fvBD']['nameTenant'] = '%s/%s' % ( + info['fvBD']['tenant'], + info['fvBD']['name'] + ) + + # Associated external physical domain + info['l2extDomP'] = None + if managed_object['l2extRsL2DomAtt'] is not None: + if managed_object['l2extRsL2DomAtt']['tCl'] == 'l2extDomP': + info['l2extDomP'] = {} + info['l2extDomP']['dn'] = managed_object['l2extRsL2DomAtt']['tDn'] + # "tDn": "uni/l2dom-Infra_L2dom" + info['l2extDomP']['name'] = info['l2extDomP']['dn'].split('/')[1][6:] + + # External EPG + info['l2extInstP'] = [] + for epg_mo in managed_object['l2extInstP']: + info['l2extInstP'].append( + self.get_l2out_ext_epg_info( + epg_mo + ) + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_l2outs_info(self, path_info=False): + if self.l2out is None: + l2outs = self.get_l2out_mo() + if l2outs is not None: + self.l2out = [] + for managed_object in l2outs: + self.l2out.append( + self.get_l2out_info( + managed_object + ) + ) + + if not path_info: + return self.l2out + + if self.l2out_with_path is not None: + return self.l2out_with_path + + l2outs_with_path_mo = self.get_l2out_path_mo() + if l2outs_with_path_mo is None: + return None + + self.l2out_with_path = copy.deepcopy( + self.l2out + ) + + for l2out_with_path in self.l2out_with_path: + l2out_with_path['path'] = [] + for managed_object in l2outs_with_path_mo: + if managed_object['tCl'] == 'fabricPathEp': + # dn: "uni/tn-k8s/l2out-Test/lnodep-default/lifp-default/rspathL2OutAtt-[topology/pod-1/paths-2207/pathep-[eth1/30]]" + path_l2out_tenant = managed_object['dn'].split('/')[1][3:] + path_l2out_name = managed_object['dn'].split('/')[2][6:] + if path_l2out_tenant != l2out_with_path['tenant']: + continue + if path_l2out_name != l2out_with_path['name']: + continue + + l2out_with_path['path'].append( + managed_object['dn'].split('rspathL2OutAtt-[')[1][:-1] + ) + + return self.l2out_with_path + + def match_l2out(self, l2out_info, l2out_filter): + if l2out_filter is None or len(l2out_filter) == 0: + return True + + for ap_rule in l2out_filter: + (key, value) = ap_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, l2out_info['name']): + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, l2out_info['dn']): + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, l2out_info['tenant']): + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not l2out_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_l2out', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_l2out', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_l2outs( + self, + l2out_filter=None, + path_info=False, + node_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_l2outs = self.get_l2outs_info( + path_info=path_info + ) + if all_l2outs is None: + return None + + l2outs = [] + + for l2out_info in all_l2outs: + if not self.match_l2out(l2out_info, l2out_filter): + continue + + if node_info: + ap_node_info = self.get_l2out_node( + l2out_info['tenant'], + l2out_info['name'] + ) + l2out_info['node'] = None + l2out_info['interface'] = None + if ap_node_info is not None: + l2out_info['node'] = ap_node_info['node'] + l2out_info['interface'] = ap_node_info['interface'] + + if fault_info: + l2out_info['faultInst'] = self.get_l2out_id_fault( + l2out_info['tenant'], + l2out_info['name'], + 'faultInst' + ) + + if hfault_info: + l2out_info['faultRecord'] = self.get_l2out_id_fault( + l2out_info['tenant'], + l2out_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + l2out_info['eventLog'] = self.get_l2out_id_event( + l2out_info['tenant'], + l2out_info['name'], + event_filter=event_filter + ) + + if audit_info: + l2out_info['auditLog'] = self.get_l2out_id_audit( + l2out_info['tenant'], + l2out_info['name'], + audit_filter=audit_filter + ) + + l2outs.append(l2out_info) + + l2outs = sorted( + l2outs, + key=lambda i: i['nameTenant'].lower() + ) + + self.log.apic_mo( + 'l2extOut.info', + l2outs + ) + + return l2outs diff --git a/lib/aci/l2out/main.py b/lib/aci/l2out/main.py new file mode 100644 index 00000000..9fc26d99 --- /dev/null +++ b/lib/aci/l2out/main.py @@ -0,0 +1,23 @@ +from lib.aci.l2out.api import L2OutApi +from lib.aci.l2out.info import L2OutInfo +from lib.aci.l2out.audit.main import L2OutAudit +from lib.aci.l2out.event.main import L2OutEvent +from lib.aci.l2out.fault.main import L2OutFault +from lib.aci.l2out.node.main import L2OutNode + + +class L2Out( + L2OutApi, + L2OutInfo, + L2OutAudit, + L2OutEvent, + L2OutFault, + L2OutNode + ): + def __init__(self): + L2OutApi.__init__(self) + L2OutInfo.__init__(self) + L2OutAudit.__init__(self) + L2OutEvent.__init__(self) + L2OutFault.__init__(self) + L2OutNode.__init__(self) diff --git a/lib/aci/l2out/node/__init__.py b/lib/aci/l2out/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l2out/node/api.py b/lib/aci/l2out/node/api.py new file mode 100644 index 00000000..8cff38c3 --- /dev/null +++ b/lib/aci/l2out/node/api.py @@ -0,0 +1,61 @@ +class L2OutNodeApi(): + def __init__(self): + self.l2out_node_mo = {} + + def get_l2out_node_mo(self, tenant_name, l2out_name): + key = '%s.%s' % (tenant_name, l2out_name) + if key in self.l2out_node_mo: + return self.l2out_node_mo[key] + + cache = self.get_object_cache( + 'l2extOut.%s' % (key) + ) + if cache is not None: + self.l2out_node_mo[key] = cache + self.log.apic_mo( + 'l2extOut.%s' % (key), + self.l2out_node_mo[key] + ) + return self.l2out_node_mo[key] + + distinguished_name = 'uni/tn-%s/l2out-%s' % (tenant_name, l2out_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=L2ExtOutToNwIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_l2out_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_l2out_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2extOut']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'l2extOut', + managed_object + ) + self.l2out_node_mo[key] = attributes + + self.log.apic_mo( + 'l2extOut.%s' % (key), + self.l2out_node_mo[key] + ) + + self.set_object_cache( + 'l2extOut.%s' % (key), + self.l2out_node_mo[key] + ) + + return self.l2out_node_mo[key] diff --git a/lib/aci/l2out/node/info.py b/lib/aci/l2out/node/info.py new file mode 100644 index 00000000..649eee5f --- /dev/null +++ b/lib/aci/l2out/node/info.py @@ -0,0 +1,82 @@ +class L2OutNodeInfo(): + def __init__(self): + self.l2out_node = {} + + def get_l2out_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_l2out_node(self, tenant_name, l2out_name): + key = '%s.%s' % (tenant_name, l2out_name) + if key in self.l2out_node: + return self.l2out_node[key] + + # one object or None value is expected + nodes_mo = self.get_l2out_node_mo(tenant_name, l2out_name) + if nodes_mo is None: + return None + + self.l2out_node[key] = self.get_l2out_node_info( + nodes_mo + ) + + self.log.apic_mo( + 'l2extOut.%s.info' % (key), + self.l2out_node[key] + ) + + return self.l2out_node[key] diff --git a/lib/aci/l2out/node/main.py b/lib/aci/l2out/node/main.py new file mode 100644 index 00000000..06a5ecae --- /dev/null +++ b/lib/aci/l2out/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.l2out.node.api import L2OutNodeApi +from lib.aci.l2out.node.info import L2OutNodeInfo + + +class L2OutNode(L2OutNodeApi, L2OutNodeInfo): + def __init__(self): + L2OutNodeApi.__init__(self) + L2OutNodeInfo.__init__(self) diff --git a/lib/aci/l2out/output.py b/lib/aci/l2out/output.py new file mode 100644 index 00000000..33ff6611 --- /dev/null +++ b/lib/aci/l2out/output.py @@ -0,0 +1,338 @@ +class L2OutOutput(): + def __init__(self): + pass + + def print_l2outs(self, info, title=False): + if title: + self.my_output.default( + 'L2Out [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'targetDscp', + 'fvBD.nameTenant', + 'fvBD.encap', + 'l2extDomP.name', + 'path' + ] + + headers = [ + 'Faults', + 'L2 Out', + 'Target DSCP', + 'Bridge Domain', + 'Encapsulation', + 'Ext Phy Domain', + 'Path' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['path'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_l2outs_node(self, info, title=False): + if title: + self.my_output.default( + 'L2Out - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'L2Out', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_l2outs_interface(self, info, title=False): + if title: + self.my_output.default( + 'L2Out - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'L2Out', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_l2outs_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L2Out - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L2Out - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'L2Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_l2outs_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'L2Out - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'L2Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_l2outs_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L2Out - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L2Out - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'L2Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_l2outs_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L2Out - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L2Out - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'L2Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/l3out/__init__.py b/lib/aci/l3out/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l3out/__pycache__/__init__.cpython-310.pyc b/lib/aci/l3out/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ebe9252c Binary files /dev/null and b/lib/aci/l3out/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/api.cpython-310.pyc b/lib/aci/l3out/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8d58dfff Binary files /dev/null and b/lib/aci/l3out/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/bgp.cpython-310.pyc b/lib/aci/l3out/__pycache__/bgp.cpython-310.pyc new file mode 100644 index 00000000..6b53d55c Binary files /dev/null and b/lib/aci/l3out/__pycache__/bgp.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/domain.cpython-310.pyc b/lib/aci/l3out/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..4a8a5f11 Binary files /dev/null and b/lib/aci/l3out/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/eigrp.cpython-310.pyc b/lib/aci/l3out/__pycache__/eigrp.cpython-310.pyc new file mode 100644 index 00000000..9042b2bc Binary files /dev/null and b/lib/aci/l3out/__pycache__/eigrp.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/epg.cpython-310.pyc b/lib/aci/l3out/__pycache__/epg.cpython-310.pyc new file mode 100644 index 00000000..98b31856 Binary files /dev/null and b/lib/aci/l3out/__pycache__/epg.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/info.cpython-310.pyc b/lib/aci/l3out/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..5e908b7f Binary files /dev/null and b/lib/aci/l3out/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/main.cpython-310.pyc b/lib/aci/l3out/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..bb76b59d Binary files /dev/null and b/lib/aci/l3out/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/node.cpython-310.pyc b/lib/aci/l3out/__pycache__/node.cpython-310.pyc new file mode 100644 index 00000000..c34c117a Binary files /dev/null and b/lib/aci/l3out/__pycache__/node.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/ospf.cpython-310.pyc b/lib/aci/l3out/__pycache__/ospf.cpython-310.pyc new file mode 100644 index 00000000..8ef04b25 Binary files /dev/null and b/lib/aci/l3out/__pycache__/ospf.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/output.cpython-310.pyc b/lib/aci/l3out/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..cb6f03a6 Binary files /dev/null and b/lib/aci/l3out/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/pim.cpython-310.pyc b/lib/aci/l3out/__pycache__/pim.cpython-310.pyc new file mode 100644 index 00000000..947178ff Binary files /dev/null and b/lib/aci/l3out/__pycache__/pim.cpython-310.pyc differ diff --git a/lib/aci/l3out/__pycache__/vrf.cpython-310.pyc b/lib/aci/l3out/__pycache__/vrf.cpython-310.pyc new file mode 100644 index 00000000..a5819fcc Binary files /dev/null and b/lib/aci/l3out/__pycache__/vrf.cpython-310.pyc differ diff --git a/lib/aci/l3out/api.py b/lib/aci/l3out/api.py new file mode 100644 index 00000000..234d2b59 --- /dev/null +++ b/lib/aci/l3out/api.py @@ -0,0 +1,76 @@ +class L3OutApi(): + def __init__(self): + self.l3out_mo = None + + def get_l3out_mo(self): + if self.l3out_mo is not None: + return self.l3out_mo + + cache = self.get_object_cache( + 'l3extOut' + ) + if cache is not None: + self.l3out_mo = cache + self.log.apic_mo( + 'l3extOut', + self.l3out_mo + ) + return self.l3out_mo + + children = [ + 'bgpExtP', + 'ospfExtP', + 'eigrpExtP', + 'pimExtP', + 'l3extRsEctx', + 'l3extRsL3DomAtt' + ] + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=l3extLNodeP,l3extInstP,%s' % (','.join(children)) + managed_objects = self.get_class( + 'l3extOut', + query=query + ) + if managed_objects is None: + return None + + self.l3out_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3extOut']['attributes'] + attributes['l3extLNodeP'] = self.get_mo_children_attributes( + 'l3extOut', + managed_object, + 'l3extLNodeP' + ) + attributes['l3extInstP'] = self.get_mo_children_attributes( + 'l3extOut', + managed_object, + 'l3extInstP' + ) + for child_name in children: + attributes[child_name] = self.get_mo_child_attributes( + 'l3extOut', + managed_object, + child_name + ) + + attributes['faultCounts'] = self.get_mo_child_attributes( + 'l3extOut', + managed_object, + 'faultCounts' + ) + + self.l3out_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extOut', + self.l3out_mo + ) + + self.set_object_cache( + 'l3extOut', + self.l3out_mo + ) + + return self.l3out_mo diff --git a/lib/aci/l3out/audit/__init__.py b/lib/aci/l3out/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l3out/audit/api.py b/lib/aci/l3out/audit/api.py new file mode 100644 index 00000000..bedac29f --- /dev/null +++ b/lib/aci/l3out/audit/api.py @@ -0,0 +1,48 @@ +class L3OutAuditApi(): + def __init__(self): + self.l3out_audit_mo = None + + def get_l3out_audit_mo(self): + cache = self.get_object_cache( + 'l3extOut.audit' + ) + if cache is not None: + self.l3out_audit_mo = cache + self.log.apic_mo( + 'l3extOut.audit', + self.l3out_audit_mo + ) + return self.l3out_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'l3extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l3out_audit_mo', + 'API failed' + ) + return None + + self.l3out_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.l3out_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extOut.audit', + self.l3out_audit_mo + ) + + self.set_object_cache( + 'l3extOut.audit', + self.l3out_audit_mo + ) + + return self.l3out_audit_mo diff --git a/lib/aci/l3out/audit/info.py b/lib/aci/l3out/audit/info.py new file mode 100644 index 00000000..9a6392cb --- /dev/null +++ b/lib/aci/l3out/audit/info.py @@ -0,0 +1,113 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class L3OutAuditInfo(): + def __init__(self): + self.l3out_audit = None + + def get_l3out_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['l3outName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/l3out-Test + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/l3out-' in info['affected']: + info['l3outName'] = info['affected'].split('/l3out-')[1].split('/')[0] + + if '/out-' in info['affected']: + info['l3outName'] = info['affected'].split('/out-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['l3outName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['l3outName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "3033-04-39T13:33:45.167+03:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_l3out_audit(self): + if self.l3out_audit is not None: + return self.l3out_audit + + managed_objects = self.get_l3out_audit_mo() + if managed_objects is None: + return None + + self.l3out_audit = [] + for managed_object in managed_objects: + audit_info = self.get_l3out_audit_info( + managed_object + ) + self.l3out_audit.append( + audit_info + ) + + self.log.apic_mo( + 'l3extOut.auditRecord.info', + self.l3out_audit + ) + + return self.l3out_audit + + def get_l3out_id_audit(self, tenant_name, l3out_name, audit_filter=None): + audits = [] + + all_audits = self.get_l3out_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['l3outName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['l3outName'] == l3out_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/l3out/audit/main.py b/lib/aci/l3out/audit/main.py new file mode 100644 index 00000000..52c8c063 --- /dev/null +++ b/lib/aci/l3out/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.l3out.audit.api import L3OutAuditApi +from lib.aci.l3out.audit.info import L3OutAuditInfo + + +class L3OutAudit(L3OutAuditApi, L3OutAuditInfo): + def __init__(self): + L3OutAuditApi.__init__(self) + L3OutAuditInfo.__init__(self) diff --git a/lib/aci/l3out/bgp.py b/lib/aci/l3out/bgp.py new file mode 100644 index 00000000..83d11f0d --- /dev/null +++ b/lib/aci/l3out/bgp.py @@ -0,0 +1,19 @@ +class L3OutBgp(): + def __init__(self): + pass + + def get_l3out_bgp_info(self, managed_object): + info = {} + info['__Output'] = {} + + if managed_object is None: + info['enabled'] = False + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + return info + + info['enabled'] = True + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + + return info diff --git a/lib/aci/l3out/domain.py b/lib/aci/l3out/domain.py new file mode 100644 index 00000000..5bbb7fee --- /dev/null +++ b/lib/aci/l3out/domain.py @@ -0,0 +1,12 @@ +class L3OutDomain(): + def __init__(self): + pass + + def get_l3out_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['dn'] = managed_object['tDn'] + info['name'] = managed_object['tDn'].split('/')[1][6:] + + return info diff --git a/lib/aci/l3out/eigrp.py b/lib/aci/l3out/eigrp.py new file mode 100644 index 00000000..7a8ffe1d --- /dev/null +++ b/lib/aci/l3out/eigrp.py @@ -0,0 +1,19 @@ +class L3OutEigrp(): + def __init__(self): + pass + + def get_l3out_eigrp_info(self, managed_object): + info = {} + info['__Output'] = {} + + if managed_object is None: + info['enabled'] = False + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + return info + + info['enabled'] = True + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + + return info diff --git a/lib/aci/l3out/epg.py b/lib/aci/l3out/epg.py new file mode 100644 index 00000000..d32b54a8 --- /dev/null +++ b/lib/aci/l3out/epg.py @@ -0,0 +1,38 @@ +class L3OutEpg(): + def __init__(self): + pass + + def get_l3out_epg_info(self, managed_object): + keys = [ + 'annotation', + 'configSt', + 'descr', + 'exceptionTag', + 'floodOnEncap', + 'isSharedSrvMsiteEPg', + 'matchT', + 'name', + 'nameAlias', + 'pcEnfPref', + 'pcTag', + 'prefGrMemb', + 'prio', + 'rn', + 'status', + 'targetDscp' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['configSt'] == 'applied': + info['__Output']['configSt'] = 'Green' + else: + info['__Output']['configSt'] = 'Red' + + return info diff --git a/lib/aci/l3out/event/__init__.py b/lib/aci/l3out/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l3out/event/api.py b/lib/aci/l3out/event/api.py new file mode 100644 index 00000000..62daf304 --- /dev/null +++ b/lib/aci/l3out/event/api.py @@ -0,0 +1,51 @@ +class L3OutEventApi(): + def __init__(self): + self.l3out_event_mo = None + + def get_l3out_event_mo(self): + if self.l3out_event_mo is not None: + return self.l3out_event_mo + + cache = self.get_object_cache( + 'l3extOut.eventLog' + ) + if cache is not None: + self.l3out_event_mo = cache + self.log.apic_mo( + 'l3extOut.eventLog', + self.l3out_event_mo + ) + return self.l3out_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'l3extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l3out_event_mo', + 'API failed' + ) + return None + + self.l3out_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.l3out_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extOut.eventLog', + self.l3out_event_mo + ) + + self.set_object_cache( + 'l3extOut.eventLog', + self.l3out_event_mo + ) + + return self.l3out_event_mo diff --git a/lib/aci/l3out/event/info.py b/lib/aci/l3out/event/info.py new file mode 100644 index 00000000..7acd5728 --- /dev/null +++ b/lib/aci/l3out/event/info.py @@ -0,0 +1,130 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class L3OutEventInfo(): + def __init__(self): + self.l3out_event = None + + def get_l3out_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['l3outName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/l3out-bmk8s_3_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/l3out-' in info['affected']: + info['l3outName'] = info['affected'].split('/l3out-')[1].split('/')[0] + + if '/out-' in info['affected']: + info['l3outName'] = info['affected'].split('/out-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/l3out-bmk8s_3_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/l3out-' in info['dn']: + info['l3outName'] = info['dn'].split('/l3out-')[1].split('/')[0] + + if '/out-' in info['dn']: + info['l3outName'] = info['dn'].split('/out-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['l3outName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['l3outName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "3033-04-39T13:33:45.167+03:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_l3out_event(self, deduplicate=True): + if self.l3out_event is not None: + return self.l3out_event + + managed_objects = self.get_l3out_event_mo() + if managed_objects is None: + return None + + self.l3out_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_l3out_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.l3out_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'l3extOut.eventLog.info', + self.l3out_event + ) + + return self.l3out_event + + def get_l3out_id_event(self, tenant_name, l3out_name, event_filter=None): + events = [] + + all_events = self.get_l3out_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['l3outName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['l3outName'] == l3out_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/l3out/event/main.py b/lib/aci/l3out/event/main.py new file mode 100644 index 00000000..a945684e --- /dev/null +++ b/lib/aci/l3out/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.l3out.event.api import L3OutEventApi +from lib.aci.l3out.event.info import L3OutEventInfo + + +class L3OutEvent(L3OutEventApi, L3OutEventInfo): + def __init__(self): + L3OutEventApi.__init__(self) + L3OutEventInfo.__init__(self) diff --git a/lib/aci/l3out/fault/__init__.py b/lib/aci/l3out/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l3out/fault/api.py b/lib/aci/l3out/fault/api.py new file mode 100644 index 00000000..3bf37c3d --- /dev/null +++ b/lib/aci/l3out/fault/api.py @@ -0,0 +1,118 @@ +class L3OutFaultApi(): + def __init__(self): + self.l3out_fault_mo = None + self.l3out_fault_record_mo = None + + def get_l3out_fault_mo(self): + cache = self.get_object_cache( + 'l3extOut.fault' + ) + if cache is not None: + self.l3out_fault_mo = cache + self.log.apic_mo( + 'l3extOut.fault', + self.l3out_fault_mo + ) + return self.l3out_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'l3extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l3out_fault_mo', + 'API failed' + ) + return None + + self.l3out_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.l3out_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.l3out_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extOut.fault', + self.l3out_fault_mo + ) + + self.set_object_cache( + 'l3extOut.fault', + self.l3out_fault_mo + ) + + return self.l3out_fault_mo + + def get_l3out_fault_record_mo(self): + cache = self.get_object_cache( + 'l3extOut.faultRecord' + ) + if cache is not None: + self.l3out_fault_record_mo = cache + self.log.apic_mo( + 'l3extOut.faultRecord', + self.l3out_fault_record_mo + ) + return self.l3out_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'l3extOut', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_l3out_fault_record_mo', + 'API failed' + ) + return None + + self.l3out_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.l3out_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.l3out_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extOut.faultRecord', + self.l3out_fault_record_mo + ) + + self.set_object_cache( + 'l3extOut.faultRecord', + self.l3out_fault_record_mo + ) + + return self.l3out_fault_record_mo diff --git a/lib/aci/l3out/fault/info.py b/lib/aci/l3out/fault/info.py new file mode 100644 index 00000000..0420bbfc --- /dev/null +++ b/lib/aci/l3out/fault/info.py @@ -0,0 +1,161 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class L3OutFaultInfo(): + def __init__(self): + self.l3out_fault = None + self.l3out_fault_record = None + + def get_l3out_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['l3outName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/l3out-bmk8s_3_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/l3out-' in info['affected']: + info['l3outName'] = info['affected'].split('/l3out-')[1].split('/')[0] + + if '/out-' in info['affected']: + info['l3outName'] = info['affected'].split('/out-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/l3out-bmk8s_3_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/l3out-' in info['dn']: + info['l3outName'] = info['dn'].split('/l3out-')[1].split('/')[0] + + if '/out-' in info['dn']: + info['l3outName'] = info['dn'].split('/out-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['l3outName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['l3outName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "3033-04-39T13:33:45.167+03:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_l3out_fault(self): + if self.l3out_fault is not None: + return self.l3out_fault + + managed_objects = self.get_l3out_fault_mo() + if managed_objects is None: + return None + + self.l3out_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_l3out_fault_info( + managed_object + ) + self.l3out_fault.append( + fault_info + ) + + self.log.apic_mo( + 'l3extOut.fault.info', + self.l3out_fault + ) + + return self.l3out_fault + + def get_l3out_fault_record(self, deduplicate=True): + if self.l3out_fault_record is not None: + return self.l3out_fault_record + + managed_objects = self.get_l3out_fault_record_mo() + if managed_objects is None: + return None + + self.l3out_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_l3out_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.l3out_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'l3extOut.faultRecord.info', + self.l3out_fault_record + ) + + return self.l3out_fault_record + + def get_l3out_id_fault(self, tenant_name, l3out_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_l3out_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_l3out_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['l3outName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['l3outName'] == l3out_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/l3out/fault/main.py b/lib/aci/l3out/fault/main.py new file mode 100644 index 00000000..d62bd620 --- /dev/null +++ b/lib/aci/l3out/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.l3out.fault.api import L3OutFaultApi +from lib.aci.l3out.fault.info import L3OutFaultInfo + + +class L3OutFault(L3OutFaultApi, L3OutFaultInfo): + def __init__(self): + L3OutFaultApi.__init__(self) + L3OutFaultInfo.__init__(self) diff --git a/lib/aci/l3out/info.py b/lib/aci/l3out/info.py new file mode 100644 index 00000000..3c84c67b --- /dev/null +++ b/lib/aci/l3out/info.py @@ -0,0 +1,370 @@ +from lib import filter_helper + + +class L3OutInfo(): + def __init__(self): + self.l3out = None + + def get_l3out_count(self, tenant_name=None, mpls=None): + l3out_filter = [] + + if tenant_name is not None: + l3out_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if mpls is not None: + if mpls: + l3out_filter.append( + 'mpls:enabled' + ) + else: + l3out_filter.append( + 'mpls:disabled' + ) + + l3outs = self.get_l3outs( + l3out_filter=l3out_filter + ) + + return len(l3outs) + + def get_l3out_name_from_dn(self, l3out_dn): + # [0]: uni/tn-{name}/l3out-{name} + tenant = l3out_dn.split('/')[1][3:] + if '/l3out-' in l3out_dn: + name = l3out_dn.split('/')[2][6:] + if '/out-' in l3out_dn: + name = l3out_dn.split('/')[2][4:] + l3out_name = '%s/%s' % ( + tenant, + name + ) + return l3out_name + + def get_l3out_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'enforceRtctrl', + 'mplsEnabled', + 'name', + 'targetDscp', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['mplsEnabled'] == 'yes': + info['mplsEnabled'] = True + info['mplsEnabledTick'] = '\u2713' + info['__Output']['mplsEnabledTick'] = 'Green' + else: + info['mplsEnabled'] = False + info['mplsEnabledTick'] = '\u2717' + info['__Output']['mplsEnabledTick'] = 'Red' + + # Dn format + # [0]: uni/tn-{name}/l3out-{name} + info['tenant'] = info['dn'].split('/')[1][3:] + + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + info['l3extRsL3DomAtt'] = None + if managed_object['l3extRsL3DomAtt'] is not None: + info['l3extRsL3DomAtt'] = self.get_l3out_domain_info( + managed_object['l3extRsL3DomAtt'] + ) + + info['bgpExtP'] = self.get_l3out_bgp_info( + managed_object['bgpExtP'] + ) + + info['ospfExtP'] = self.get_l3out_ospf_info( + managed_object['ospfExtP'] + ) + + info['eigrpExtP'] = self.get_l3out_eigrp_info( + managed_object['eigrpExtP'] + ) + + info['pimExtP'] = self.get_l3out_pim_info( + managed_object['pimExtP'] + ) + + info['l3extRsEctx'] = self.get_l3out_vrf_info( + managed_object['l3extRsEctx'] + ) + + profile_filter = [] + profile_filter.append('tenant:%s' % info['tenant']) + profile_filter.append('l3out:%s' % info['name']) + info['logicalNodeProfile'] = self.get_l3out_logical_node_profiles( + profile_filter=profile_filter + ) + + info['l3extInstP'] = [] + for epg_mo in managed_object['l3extInstP']: + epg_info = self.get_l3out_epg_info( + epg_mo + ) + if epg_mo is not None: + info['l3extInstP'].append( + epg_info + ) + + node_dns = [] + info['configured_node'] = [] + for logical_node_profile in info['logicalNodeProfile']: + for node_info in logical_node_profile['configured_node']: + if node_info['nodeDn'] not in node_dns: + node_dns.append( + node_info['nodeDn'] + ) + info['configured_node'].append( + node_info + ) + + info['configured_node'] = sorted( + info['configured_node'], + key=lambda i: i['nodeT'] + ) + + info['bgp_peer_connectivity_profile'] = [] + for logical_node_profile in info['logicalNodeProfile']: + for bgp_info in logical_node_profile['bgp_peer_connectivity_profile']: + info['bgp_peer_connectivity_profile'].append( + bgp_info + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_l3outs_info(self): + if self.l3out is not None: + return self.l3out + + managed_objects = self.get_l3out_mo() + if managed_objects is None: + return None + + self.l3out = [] + for managed_object in managed_objects: + self.l3out.append( + self.get_l3out_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l3extOut.info', + self.l3out + ) + + return self.l3out + + def match_l3out(self, l3out_info, l3out_filter): + if l3out_filter is None or len(l3out_filter) == 0: + return True + + for ap_rule in l3out_filter: + (key, value) = ap_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, l3out_info['name']): + return False + + if key == 'names': + key_found = True + found = False + for name in value.split(','): + if '/' in name: + if filter_helper.match_string(name, l3out_info['nameTenant']): + found = True + break + else: + if not filter_helper.match_string(name, l3out_info['name']): + return False + + if not found: + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, l3out_info['dn']): + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, l3out_info['tenant']): + return False + + if key == 'vrf': + key_found = True + if not filter_helper.match_string(value, l3out_info['l3extRsEctx']['nameTenant']): + return False + + if key == 'domain': + key_found = True + if l3out_info['l3extRsL3DomAtt'] is None: + return False + + if not filter_helper.match_string(value, l3out_info['l3extRsL3DomAtt']['name']): + return False + + if key == 'mpls': + key_found = True + if value == 'enabled': + if not l3out_info['mplsEnabled']: + return False + + if value == 'disabled': + if l3out_info['mplsEnabled']: + return False + + if key == 'bgp': + key_found = True + if value == 'enabled': + if not l3out_info['bgpExtP']['enabled']: + return False + + if value == 'disabled': + if l3out_info['bgpExtP']['enabled']: + return False + + if key == 'eigrp': + key_found = True + if value == 'enabled': + if not l3out_info['eigrpExtP']['enabled']: + return False + + if value == 'disabled': + if l3out_info['eigrpExtP']['enabled']: + return False + + if key == 'ospf': + key_found = True + if value == 'enabled': + if not l3out_info['ospfExtP']['enabled']: + return False + + if value == 'disabled': + if l3out_info['ospfExtP']['enabled']: + return False + + if key == 'pim': + key_found = True + if value == 'enabled': + if not l3out_info['pimExtP']['enabled']: + return False + + if value == 'disabled': + if l3out_info['pimExtP']['enabled']: + return False + + if key == 'node': + key_found = True + found = False + for node in l3out_info['nodes']: + if filter_helper.match_string(value, node['nodeId']): + found = True + + if not found: + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not l3out_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_l3out', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_l3out', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_l3outs( + self, + l3out_filter=None, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_outs = self.get_l3outs_info() + if all_outs is None: + return None + + l3outs = [] + + for l3out_info in all_outs: + if not self.match_l3out(l3out_info, l3out_filter): + continue + + if fault_info: + l3out_info['faultInst'] = self.get_l3out_id_fault( + l3out_info['tenant'], + l3out_info['name'], + 'faultInst' + ) + + if hfault_info: + l3out_info['faultRecord'] = self.get_l3out_id_fault( + l3out_info['tenant'], + l3out_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + l3out_info['eventLog'] = self.get_l3out_id_event( + l3out_info['tenant'], + l3out_info['name'], + event_filter=event_filter + ) + + if audit_info: + l3out_info['auditLog'] = self.get_l3out_id_audit( + l3out_info['tenant'], + l3out_info['name'], + audit_filter=audit_filter + ) + + l3outs.append(l3out_info) + + l3outs = sorted( + l3outs, + key=lambda i: i['nameTenant'].lower() + ) + + return l3outs diff --git a/lib/aci/l3out/logical_node_profile/api.py b/lib/aci/l3out/logical_node_profile/api.py new file mode 100644 index 00000000..21f55da6 --- /dev/null +++ b/lib/aci/l3out/logical_node_profile/api.py @@ -0,0 +1,88 @@ +from lib import filter_helper + + +class L3OutLogicalNodeProfileApi(): + def __init__(self): + self.l3out_logical_node_profile_mo = None + + def get_l3out_logical_node_profile_mo(self): + if self.l3out_logical_node_profile_mo is not None: + return self.l3out_logical_node_profile_mo + + cache = self.get_object_cache( + 'l3extLNodeP' + ) + if cache is not None: + self.l3out_logical_node_profile_mo = cache + self.log.apic_mo( + 'l3extLNodeP', + self.l3out_logical_node_profile_mo + ) + return self.l3out_logical_node_profile_mo + + children = [ + 'l3extRsNodeL3OutAtt', + 'l3extLIfP' + ] + query = 'rsp-subtree=children&rsp-subtree-class=%s' % (','.join(children)) + managed_objects = self.get_class( + 'l3extLNodeP', + query=query + ) + if managed_objects is None: + return None + + node_children = [ + 'bgpLocalAsnP', + 'bgpAsP', + 'ospfIfP', + 'eigrpIfP', + 'bgpPeerP', + 'bfdIfP', + 'bfdMhIfP', + 'hsrpIfP', + 'dhcpLbl' + ] + node_query = 'target-subtree-class=%s&query-target=subtree' % (','.join(node_children)) + node_managed_objects = self.get_class( + 'l3extLNodeP', + query=node_query, + node_class=True + ) + if node_managed_objects is None: + return None + + self.l3out_logical_node_profile_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3extLNodeP']['attributes'] + for child_name in children: + attributes[child_name] = self.get_mo_children_attributes( + 'l3extLNodeP', + managed_object, + child_name + ) + + for node_child_name in node_children: + attributes[node_child_name] = [] + for node_managed_object in node_managed_objects['imdata']: + if node_child_name in node_managed_object: + if node_managed_object[node_child_name]['attributes']['dn'].startswith(attributes['dn']): + attributes[node_child_name].append( + node_managed_object[node_child_name]['attributes'] + ) + + self.l3out_logical_node_profile_mo.append( + attributes + ) + + self.log.apic_mo( + 'l3extLNodeP', + self.l3out_logical_node_profile_mo + ) + + self.set_object_cache( + 'l3extLNodeP', + self.l3out_logical_node_profile_mo + ) + + return self.l3out_logical_node_profile_mo diff --git a/lib/aci/l3out/logical_node_profile/info.py b/lib/aci/l3out/logical_node_profile/info.py new file mode 100644 index 00000000..ddba5d52 --- /dev/null +++ b/lib/aci/l3out/logical_node_profile/info.py @@ -0,0 +1,226 @@ +from lib import filter_helper + + +class L3OutLogicalNodeProfileInfo(): + def __init__(self): + self.l3out_logical_node_profile = None + + def get_l3out_logical_node_profile_configured_node_info(self, managed_objects): + # https:///model-doc/#/objects/l3extRsNodeL3OutAtt/overview + info = [] + for managed_object in managed_objects: + node_info = {} + node_info['rtrId'] = managed_object['rtrId'] + node_info['rtrIdLoopBack'] = managed_object['rtrIdLoopBack'] + node_info['podId'] = managed_object['tDn'].split('/')[1].split('-')[1] + node_info['nodeId'] = managed_object['tDn'].split('/')[2].split('-')[1] + if managed_object['tDn'].split('/')[0] == 'topology': + node_info['nodeDn'] = '/'.join(managed_object['tDn'].split('/')[1:]) + else: + node_info['nodeDn'] = managed_object['tDn'] + + node_info['nodeT'] = '%s (%s)' % ( + node_info['nodeDn'], + node_info['rtrId'] + ) + info.append( + node_info + ) + + info = sorted( + info, + key=lambda i: i['nodeT'] + ) + + return info + + def get_l3out_logical_node_profile_bgp_peer_info(self, managed_objects, bgp_asn_objects, bgp_local_asn_objects): + info = [] + for managed_object in managed_objects: + # https:///model-doc/#/objects/bgpPeerP/overview + # Dn Format + # [0]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/vlifp-[{nodeDn}]-[{encap}]/peerP-[{addr}] + # [1]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/rspathL3OutAtt-[{tDn}]/peerP-[{addr}] + # [2]: uni/tn-{name}/out-{name}/lnodep-{name}/peerP-[{addr}] + # Examples + # dn: /uni/tn-common/out-Infra_L3out/lnodep-Infra_L3out_LNP/lifp-Infra_L3out_LIfP/rspathL3OutAtt-[topology/pod-1/paths-2205/pathep-[eth1/25]]/peerP-[] + # dn: /uni/tn-NSO_testvf/out-VNF_PRIVATE/lnodep-RIGHT/lifp-Floating_SVI/vlifp-[topology/pod-1/node-2206]-[vlan-936]/peerP-[/29] + # dn: uni/tn-vEPC_demo/out-ACC_L3out/lnodep-ACC-L3out_LNP/peerP-[/32] + keys = [ + 'addr', + 'addrTCtrl', + 'adminSt', + 'allowedSelfAsCnt', + 'capability', + 'connectivityType', + 'ctrl', + 'ctrlExt', + 'dn', + 'peerCtrl', + 'privateASctrl', + 'sessionT', + 'ttl', + 'weight' + ] + + bgp_peer_info = {} + bgp_peer_info['__Output'] = {} + + for key in keys: + bgp_peer_info[key] = None + if key in managed_object: + bgp_peer_info[key] = managed_object[key] + + if bgp_peer_info['adminSt'] == 'enabled': + bgp_peer_info['__Output']['enabledTick'] = 'Green' + bgp_peer_info['enabled'] = True + bgp_peer_info['enabledTick'] = '\u2713' + else: + bgp_peer_info['__Output']['enabledTick'] = 'Red' + bgp_peer_info['enabled'] = True + bgp_peer_info['enabledTick'] = '\u2713' + + if bgp_peer_info['peerCtrl'] == 'bfd': + bgp_peer_info['isBfd'] = True + bgp_peer_info['isBfdTick'] = '\u2713' + else: + bgp_peer_info['isBfd'] = False + bgp_peer_info['isBfdTick'] = '\u2717' + + if len(managed_object['dn'].split('/peerP-[')[0].split('/')) == 4: + bgp_peer_info['logical_interface_profile'] = None + bgp_peer_info['type'] = 'loopback' + bgp_peer_info['path'] = 'loopback' + + if len(managed_object['dn'].split('/rspathL3OutAtt-[')) == 2: + bgp_peer_info['logical_interface_profile'] = managed_object['dn'].split('/')[4][5:] + bgp_peer_info['type'] = 'rspathL3OutAtt' + bgp_peer_info['path'] = managed_object['dn'].split('/rspathL3OutAtt-[')[1].split('/peerP-')[0][:-1] + if bgp_peer_info['path'].split('/')[0] == 'topology': + bgp_peer_info['path'] = '/'.join(bgp_peer_info['path'].split('/')[1:]) + bgp_peer_info['path'] = bgp_peer_info['path'].replace('/pathep-[', ' ') + bgp_peer_info['path'] = bgp_peer_info['path'].replace('[', '') + bgp_peer_info['path'] = bgp_peer_info['path'].replace(']', '') + bgp_peer_info['path'] = bgp_peer_info['path'].replace('protpaths', 'nodes') + bgp_peer_info['path'] = bgp_peer_info['path'].replace('paths', 'node') + + if len(managed_object['dn'].split('/vlifp-[')) == 2: + bgp_peer_info['logical_interface_profile'] = managed_object['dn'].split('/')[4][5:] + bgp_peer_info['type'] = 'vlifp' + bgp_peer_info['path'] = managed_object['dn'].split('/vlifp-[')[1].split('/peerP-')[0] + if bgp_peer_info['path'].split('/')[0] == 'topology': + bgp_peer_info['path'] = '/'.join(bgp_peer_info['path'].split('/')[1:]) + bgp_peer_info['path'] = bgp_peer_info['path'].replace(']-[vlan-', ' vlan-') + bgp_peer_info['path'] = bgp_peer_info['path'].replace('[', '') + bgp_peer_info['path'] = bgp_peer_info['path'].replace(']', '') + bgp_peer_info['path'] = bgp_peer_info['path'].replace('protpaths', 'nodes') + bgp_peer_info['path'] = bgp_peer_info['path'].replace('paths', 'node') + + bgp_peer_info['asn'] = None + bgp_peer_info['local_asn'] = None + + for item in bgp_asn_objects: + if item['dn'] == '%s/as' % (managed_object['dn']): + bgp_peer_info['asn'] = item['asn'] + break + + for item in bgp_local_asn_objects: + if item['dn'] == '%s/localasn' % (managed_object['dn']): + bgp_peer_info['local_asn'] = item['localAsn'] + break + + info.append( + bgp_peer_info + ) + + return info + + def get_l3out_logical_node_profile_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name', + 'targetDscp', + 'userdom' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # uni/tn-SPIN_InnoLab/out-Calico_L3Out/lnodep-Calico_L3Out_nodeProfile + info['tenant'] = info['dn'].split('/')[1][3:] + info['l3out'] = info['dn'].split('/')[2][4:] + + info['configured_node'] = self.get_l3out_logical_node_profile_configured_node_info( + managed_object['l3extRsNodeL3OutAtt'] + ) + + info['bgp_peer_connectivity_profile'] = self.get_l3out_logical_node_profile_bgp_peer_info( + managed_object['bgpPeerP'], + managed_object['bgpAsP'], + managed_object['bgpLocalAsnP'] + ) + + return info + + def get_l3out_logical_node_profiles_info(self): + if self.l3out_logical_node_profile is not None: + return self.l3out_logical_node_profile + + managed_objects = self.get_l3out_logical_node_profile_mo() + if managed_objects is None: + return None + + self.l3out_logical_node_profile = [] + for managed_object in managed_objects: + self.l3out_logical_node_profile.append( + self.get_l3out_logical_node_profile_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l3extLNodeP.info', + self.l3out_logical_node_profile + ) + + return self.l3out_logical_node_profile + + def match_l3out_logical_node_profile(self, profile_info, profile_filter): + if profile_filter is None or len(profile_filter) == 0: + return True + + for aepg_rule in profile_filter: + (key, value) = aepg_rule.split(':') + + if key == 'tenant': + if not filter_helper.match_string(value, profile_info['tenant']): + return False + + if key == 'l3out': + if not filter_helper.match_string(value, profile_info['l3out']): + return False + + return True + + def get_l3out_logical_node_profiles(self, profile_filter=None): + all_profiles = self.get_l3out_logical_node_profiles_info() + if all_profiles is None: + return None + + node_profiles_info = [] + for profile_info in all_profiles: + if not self.match_l3out_logical_node_profile(profile_info, profile_filter): + continue + + node_profiles_info.append( + profile_info + ) + + return node_profiles_info diff --git a/lib/aci/l3out/logical_node_profile/main.py b/lib/aci/l3out/logical_node_profile/main.py new file mode 100644 index 00000000..83975b70 --- /dev/null +++ b/lib/aci/l3out/logical_node_profile/main.py @@ -0,0 +1,8 @@ +from lib.aci.l3out.logical_node_profile.api import L3OutLogicalNodeProfileApi +from lib.aci.l3out.logical_node_profile.info import L3OutLogicalNodeProfileInfo + + +class L3OutLogicalNodeProfile(L3OutLogicalNodeProfileApi, L3OutLogicalNodeProfileInfo): + def __init__(self): + L3OutLogicalNodeProfileApi.__init__(self) + L3OutLogicalNodeProfileInfo.__init__(self) diff --git a/lib/aci/l3out/main.py b/lib/aci/l3out/main.py new file mode 100644 index 00000000..27d8744a --- /dev/null +++ b/lib/aci/l3out/main.py @@ -0,0 +1,47 @@ +from lib.aci.l3out.api import L3OutApi +from lib.aci.l3out.bgp import L3OutBgp +from lib.aci.l3out.domain import L3OutDomain +from lib.aci.l3out.eigrp import L3OutEigrp +from lib.aci.l3out.epg import L3OutEpg +from lib.aci.l3out.info import L3OutInfo +from lib.aci.l3out.logical_node_profile.main import L3OutLogicalNodeProfile +from lib.aci.l3out.ospf import L3OutOspf +from lib.aci.l3out.pim import L3OutPim +from lib.aci.l3out.vrf import L3OutVrf +from lib.aci.l3out.audit.main import L3OutAudit +from lib.aci.l3out.event.main import L3OutEvent +from lib.aci.l3out.fault.main import L3OutFault +from lib.aci.l3out.node.main import L3OutNode + + +class L3Out( + L3OutApi, + L3OutBgp, + L3OutDomain, + L3OutEigrp, + L3OutEpg, + L3OutInfo, + L3OutLogicalNodeProfile, + L3OutOspf, + L3OutPim, + L3OutVrf, + L3OutAudit, + L3OutEvent, + L3OutFault, + L3OutNode + ): + def __init__(self): + L3OutApi.__init__(self) + L3OutBgp.__init__(self) + L3OutDomain.__init__(self) + L3OutEigrp.__init__(self) + L3OutEpg.__init__(self) + L3OutInfo.__init__(self) + L3OutLogicalNodeProfile.__init__(self) + L3OutOspf.__init__(self) + L3OutPim.__init__(self) + L3OutVrf.__init__(self) + L3OutAudit.__init__(self) + L3OutEvent.__init__(self) + L3OutFault.__init__(self) + L3OutNode.__init__(self) diff --git a/lib/aci/l3out/node/__init__.py b/lib/aci/l3out/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/l3out/node/api.py b/lib/aci/l3out/node/api.py new file mode 100644 index 00000000..8d9c68c4 --- /dev/null +++ b/lib/aci/l3out/node/api.py @@ -0,0 +1,61 @@ +class L3OutNodeApi(): + def __init__(self): + self.l3out_node_mo = {} + + def get_l3out_node_mo(self, tenant_name, l3out_name): + key = '%s.%s' % (tenant_name, l3out_name) + if key in self.l3out_node_mo: + return self.l3out_node_mo[key] + + cache = self.get_object_cache( + 'l3extOut.%s' % (key) + ) + if cache is not None: + self.l3out_node_mo[key] = cache + self.log.apic_mo( + 'l3extOut.%s' % (key), + self.l3out_node_mo[key] + ) + return self.l3out_node_mo[key] + + distinguished_name = 'uni/tn-%s/l3out-%s' % (tenant_name, l3out_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=L3ExtOutToNwIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_l3out_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_l3out_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l3extOut']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'l3extOut', + managed_object + ) + self.l3out_node_mo[key] = attributes + + self.log.apic_mo( + 'l3extOut.%s' % (key), + self.l3out_node_mo[key] + ) + + self.set_object_cache( + 'l3extOut.%s' % (key), + self.l3out_node_mo[key] + ) + + return self.l3out_node_mo[key] diff --git a/lib/aci/l3out/node/info.py b/lib/aci/l3out/node/info.py new file mode 100644 index 00000000..52d47568 --- /dev/null +++ b/lib/aci/l3out/node/info.py @@ -0,0 +1,82 @@ +class L3OutNodeInfo(): + def __init__(self): + self.l3out_node = {} + + def get_l3out_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-3301/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_l3out_node(self, tenant_name, l3out_name): + key = '%s.%s' % (tenant_name, l3out_name) + if key in self.l3out_node: + return self.l3out_node[key] + + # one object or None value is expected + nodes_mo = self.get_l3out_node_mo(tenant_name, l3out_name) + if nodes_mo is None: + return None + + self.l3out_node[key] = self.get_l3out_node_info( + nodes_mo + ) + + self.log.apic_mo( + 'l3extOut.%s.info' % (key), + self.l3out_node[key] + ) + + return self.l3out_node[key] diff --git a/lib/aci/l3out/node/main.py b/lib/aci/l3out/node/main.py new file mode 100644 index 00000000..55fafbdd --- /dev/null +++ b/lib/aci/l3out/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.l3out.node.api import L3OutNodeApi +from lib.aci.l3out.node.info import L3OutNodeInfo + + +class L3OutNode(L3OutNodeApi, L3OutNodeInfo): + def __init__(self): + L3OutNodeApi.__init__(self) + L3OutNodeInfo.__init__(self) diff --git a/lib/aci/l3out/ospf.py b/lib/aci/l3out/ospf.py new file mode 100644 index 00000000..661d145a --- /dev/null +++ b/lib/aci/l3out/ospf.py @@ -0,0 +1,56 @@ +class L3OutOspf(): + def __init__(self): + pass + + def get_l3out_ospf_info(self, managed_object): + info = {} + info['__Output'] = {} + + if managed_object is None: + info['enabled'] = False + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + return info + + info['enabled'] = True + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + + keys = [ + 'areaCost', + 'areaCtrl', + 'areaId', + 'areaType', + 'multipodInternal' + ] + for key in keys: + info[key] = managed_object[key] + + if 'redistribute' in info['areaCtrl'].split(','): + info['redistribute'] = True + info['redistributeTick'] = '\u2713' + info['__Output']['redistributeTick'] = 'Green' + else: + info['redistribute'] = False + info['redistributeTick'] = '\u2717' + info['__Output']['redistributeTick'] = 'Red' + + if 'summary' in info['areaCtrl'].split(','): + info['summary'] = True + info['summaryTick'] = '\u2713' + info['__Output']['summaryTick'] = 'Green' + else: + info['summary'] = False + info['summaryTick'] = '\u2717' + info['__Output']['summaryTick'] = 'Red' + + if 'suppress' in info['areaCtrl'].split(','): + info['suppress'] = True + info['suppressTick'] = '\u2713' + info['__Output']['suppressTick'] = 'Green' + else: + info['suppress'] = False + info['suppressTick'] = '\u2717' + info['__Output']['suppressTick'] = 'Red' + + return info diff --git a/lib/aci/l3out/output.py b/lib/aci/l3out/output.py new file mode 100644 index 00000000..e1b0d24d --- /dev/null +++ b/lib/aci/l3out/output.py @@ -0,0 +1,617 @@ +class L3OutOutput(): + def __init__(self): + pass + + def print_l3outs_bgp(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - BGP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'bgp_peer_connectivity_profile.enabledTick', + 'bgp_peer_connectivity_profile.local_asn', + 'bgp_peer_connectivity_profile.path', + 'bgp_peer_connectivity_profile.addr', + 'bgp_peer_connectivity_profile.asn', + 'bgp_peer_connectivity_profile.isBfdTick', + 'bgp_peer_connectivity_profile.ttl', + 'bgp_peer_connectivity_profile.weight', + 'bgp_peer_connectivity_profile.ctrl', + 'bgp_peer_connectivity_profile.capability', + 'bgp_peer_connectivity_profile.addrTCtrl' + ] + + headers = [ + 'Faults', + 'L3Out', + 'Enbld', + 'ASN', + 'Path', + 'Peer IP', + 'Peer ASN', + 'BFD', + 'TTL', + 'Weight', + 'BGP Ctrl', + 'Caps', + 'Address' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['bgp_peer_connectivity_profile'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + def print_l3outs_eigrp(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - EIGRP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'eigrpExtP.enabledTick', + 'l3extRsEctx.nameTenant', + 'configured_node.nodeDn', + 'configured_node.rtrId' + ] + + headers = [ + 'Faults', + 'L3Out', + 'EIGRP', + 'VRF', + 'Border Leaf', + 'Router ID' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['configured_node'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + def print_l3outs_ospf(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - OSPF [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'targetDscp', + 'ospfExtP.enabledTick', + 'ospfExtP.areaId', + 'ospfExtP.areaType', + 'ospfExtP.areaCost', + 'ospfExtP.redistributeTick', + 'ospfExtP.summaryTick', + 'ospfExtP.suppressTick', + 'configured_node.nodeDn', + 'configured_node.rtrId' + ] + + headers = [ + 'Faults', + 'L3Out', + 'Target DSCP', + 'OSPF', + 'Area ID', + 'Area Type', + 'Area Cost', + 'Redistribute LSA into NSSA', + 'Originate Summary LSA', + 'Suppress translated LSA', + 'Border Leaf', + 'Router ID' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['configured_node'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + def print_l3outs_mpls(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - MPLS [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'mplsEnabledTick', + 'bgpExtP.enabledTick', + 'l3extRsEctx.nameTenant', + 'configured_node.nodeDn', + 'configured_node.rtrId' + ] + + headers = [ + 'Faults', + 'L3Out', + 'Tenant', + 'PIM', + 'BGP', + 'VRF', + 'Border Leaf', + 'Router ID' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['configured_node'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + def print_l3outs_pim(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - PIM [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'pimExtP.enabledTick', + 'l3extRsEctx.nameTenant', + 'configured_node.nodeDn', + 'configured_node.rtrId' + ] + + headers = [ + 'Faults', + 'L3Out', + 'Tenant', + 'PIM', + 'VRF', + 'Border Leaf', + 'Router ID' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['configured_node'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + def print_l3outs_epg(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - EPG [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'l3extRsEctx.nameTenant', + 'l3extInstP.name', + 'l3extInstP.pcTag', + 'l3extInstP.prio', + 'l3extInstP.targetDscp', + 'l3extInstP.prefGrMemb', + 'l3extInstP.pcEnfPref', + ] + + headers = [ + 'Faults', + 'L3Out Name', + 'VRF', + 'External EPG', + 'pcTag', + 'QoS', + 'DSCP', + 'Pref Grp Member', + 'Isolation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l3extInstP'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + def print_l3outs(self, info, title=False): + if title: + self.my_output.default( + 'L3Out [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'faults', + 'nameTenant', + 'mplsEnabledTick', + 'pimExtP.enabledTick', + 'bgpExtP.enabledTick', + 'ospfExtP.enabledTick', + 'eigrpExtP.enabledTick', + 'l3extRsEctx.nameTenant', + 'l3extRsL3DomAtt.name', + 'configured_node.nodeT', + 'l3extInstP.name' + ] + + headers = [ + 'Faults', + 'L3Out', + 'MPLS', + 'PIM', + 'BGP', + 'OSPF', + 'EIGRP', + 'VRF', + 'L3 Domain', + 'Node', + 'External EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['configured_node', 'l3extInstP'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + merge=True, + remove_empty_columns=True, + table=True + ) + + # if verbose: + # for l3out in l3outs: + # for node_profile in l3out['logicalNodeProfile']: + # self.print_l3out_logical_node_profile(node_profile) + + def print_l3out_logical_node_profile(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - Node Profile [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'dn', + 'descr', + 'targetDscp' + ] + + headers = [ + 'Dn', + 'Description', + 'Target DSCP' + ] + + self.my_output.dictionary( + info, + title='Logical Node Profile: %s' % (info['name']), + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_l3outs_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L3Out - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L3Out - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'L3Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_l3outs_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'L3Out - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'L3Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_l3outs_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L3Out - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L3Out - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'L3Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_l3outs_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'L3Out - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'L3Out - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'L3Out', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/l3out/pim.py b/lib/aci/l3out/pim.py new file mode 100644 index 00000000..044e7097 --- /dev/null +++ b/lib/aci/l3out/pim.py @@ -0,0 +1,19 @@ +class L3OutPim(): + def __init__(self): + pass + + def get_l3out_pim_info(self, managed_object): + info = {} + info['__Output'] = {} + + if managed_object is None: + info['enabled'] = False + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + return info + + info['enabled'] = True + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + + return info diff --git a/lib/aci/l3out/vrf.py b/lib/aci/l3out/vrf.py new file mode 100644 index 00000000..b75a0953 --- /dev/null +++ b/lib/aci/l3out/vrf.py @@ -0,0 +1,27 @@ +class L3OutVrf(): + def __init__(self): + pass + + def get_l3out_vrf_info(self, managed_object): + info = {} + info['__Output'] = {} + + if managed_object is None: + info['enabled'] = False + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + return info + + info['enabled'] = True + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + + info['dn'] = managed_object['tDn'] + info['tenant'] = managed_object['tDn'].split('/')[1][3:] + info['name'] = managed_object['tDn'].split('/')[2][4:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + return info diff --git a/lib/aci/node/__init__.py b/lib/aci/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e0d60faa Binary files /dev/null and b/lib/aci/node/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/__pycache__/api.cpython-310.pyc b/lib/aci/node/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6692579b Binary files /dev/null and b/lib/aci/node/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/__pycache__/info.cpython-310.pyc b/lib/aci/node/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..cc2cffc0 Binary files /dev/null and b/lib/aci/node/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/__pycache__/main.cpython-310.pyc b/lib/aci/node/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b8ebff95 Binary files /dev/null and b/lib/aci/node/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/__pycache__/output.cpython-310.pyc b/lib/aci/node/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..fd7ad2ae Binary files /dev/null and b/lib/aci/node/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/node/api.py b/lib/aci/node/api.py new file mode 100644 index 00000000..45378f9d --- /dev/null +++ b/lib/aci/node/api.py @@ -0,0 +1,47 @@ +class NodeApi(): + def __init__(self): + self.node_mo = None + + def get_node_mo(self): + if self.node_mo is not None: + return self.node_mo + + cache = self.get_object_cache( + 'fabricNode' + ) + if cache is not None: + self.node_mo = cache + self.log.apic_mo( + 'fabricNode', + self.node_mo + ) + return self.node_mo + + managed_objects = self.get_class( + 'fabricNode' + ) + if managed_objects is None: + self.log.error( + 'get_node_mo', + 'API failed' + ) + return None + + self.node_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fabricNode']['attributes'] + self.node_mo.append( + attributes + ) + + self.log.apic_mo( + 'fabricNode', + self.node_mo + ) + + self.set_object_cache( + 'fabricNode', + self.node_mo + ) + + return self.node_mo diff --git a/lib/aci/node/bot_output.py b/lib/aci/node/bot_output.py new file mode 100644 index 00000000..dd6b976a --- /dev/null +++ b/lib/aci/node/bot_output.py @@ -0,0 +1,68 @@ +class NodeBotOutput(): + def __init__(self): + pass + + def print_nodes(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Node [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'full_name', + 'id', + 'address', + 'adSt', + 'fabricSt', + 'roleUi', + 'model', + 'serial', + 'version' + ] + + headers = [ + 'Node Name', + 'ID', + 'VTEP IP', + 'Admin', + 'Fabric', + 'Role', + 'Model', + 'Serial', + 'Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Node' + ) + + html_output = self.my_output.get_output() + + return output, html_output \ No newline at end of file diff --git a/lib/aci/node/info.py b/lib/aci/node/info.py new file mode 100644 index 00000000..05b0179c --- /dev/null +++ b/lib/aci/node/info.py @@ -0,0 +1,306 @@ +from lib import filter_helper +from lib import ip_helper + + +class NodeInfo(): + def __init__(self): + self.nodes = None + + def get_node_count(self, pod_id=None): + node_filter = None + if pod_id is not None: + node_filter = ['pod:%s' % (pod_id), 'role:!controller'] + else: + node_filter = ['role:!controller'] + + nodes = self.get_nodes( + node_filter=node_filter + ) + return len(nodes) + + def get_node_id(self, node_name, pod_id=None): + node_info = self.get_node( + pod_id=pod_id, + node_name=node_name + ) + if node_info is None: + return None + return node_info['id'] + + def get_node_name(self, node_id, pod_id=None): + node_info = self.get_node( + pod_id=pod_id, + node_id=node_id + ) + if node_info is None: + return None + return node_info['name'] + + def get_node_names(self, pod_id=None): + node_filter = None + if pod_id is not None: + node_filter = ['pod:%s' % (pod_id)] + + nodes = self.get_nodes( + node_filter=node_filter + ) + if nodes is None: + return None + + node_names = [] + for node in nodes: + node_names.append( + node['name'] + ) + + return node_names + + def get_node_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'address', + 'adSt', + 'apicType', + 'dn', + 'id', + 'fabricSt', + 'model', + 'name', + 'nodeType', + 'role', + 'serial', + 'userdom', + 'vendor', + 'version' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['podId'] = managed_object['dn'].split('/')[1][4:] + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['name'] + ) + info['full_name'] = '%s/%s' % ( + info['apic'], + info['pod_node_name'] + ) + + info['roleUi'] = info['role'] + if info['nodeType'] == 'remote-leaf-wan': + info['roleUi'] = 'r-leaf' + + if info['adSt'] == 'on': + info['__Output']['adSt'] = 'Green' + else: + info['__Output']['adSt'] = 'Red' + + if info['fabricSt'] in ['unknown', 'inactive']: + if info['role'] == 'controller': + info['fabricSt'] = 'N/A' + else: + info['__Output']['fabricSt'] = 'Red' + + if info['fabricSt'] == 'active': + info['__Output']['fabricSt'] = 'Green' + + if info['fabricSt'] == 'inactive': + info['__Output']['fabricSt'] = 'Red' + + return info + + def get_nodes_info(self): + if self.nodes is not None: + return self.nodes + + nodes_mo = self.get_node_mo() + if nodes_mo is not None: + self.nodes = [] + for node_mo in nodes_mo: + self.nodes.append( + self.get_node_info( + node_mo + ) + ) + + return self.nodes + + def get_node(self, pod_id=None, node_id=None, node_name=None, node_ip=None): + node_filter = [] + if pod_id is not None: + node_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_id is not None: + node_filter.append( + 'id:%s' % (node_id) + ) + + if node_name is not None: + node_filter.append( + 'name:%s' % (node_name) + ) + + if node_ip is not None: + node_filter.append( + 'ip:%s' % (node_ip) + ) + + nodes = self.get_nodes( + node_filter=node_filter + ) + + if nodes is None: + return None + + if len(nodes) == 1: + return nodes[0] + + return None + + def match_node(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, node_info['id']): + return False + + if key == 'name': + if not filter_helper.match_string(value, node_info['name']): + return False + + if key == 'names': + found = False + for name in value.split(','): + if filter_helper.match_string(name, node_info['name']): + found = True + break + + if not found: + return False + + if key == 'pod': + if not filter_helper.match_string(value, node_info['podId']): + return False + + if key == 'model': + if not filter_helper.match_string(value, node_info['model']): + return False + + if key == 'ip': + if 'system' in node_info: + found = False + + if filter_helper.match_string(value, node_info['address']): + found = True + + if not found and filter_helper.match_string(value, node_info['system']['inbMgmtAddr']): + found = True + + if not found and filter_helper.match_string(value, node_info['system']['oobMgmtAddr']): + found = True + + if not found: + return False + + if key == 'subnet': + if 'system' in node_info: + found = False + + if ip_helper.is_ipv4_in_cidr(node_info['address'], value): + found = True + + if not found and ip_helper.is_ipv4_in_cidr(node_info['system']['inbMgmtAddr'], value): + found = True + + if not found and ip_helper.is_ipv4_in_cidr(node_info['system']['oobMgmtAddr'], value): + found = True + + if not found: + return False + + if key == 'role': + if value == '!controller': + if node_info['role'] == 'controller': + return False + else: + if node_info['role'] != value: + return False + + return True + + def get_nodes(self, node_filter=None, interfaces_summary_info=False, power_info=False, psu_info=False, sensor_info=False, system_info=False, temp_info=False): + all_nodes = self.get_nodes_info() + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node(node_info, node_filter): + continue + + if interfaces_summary_info: + if node_info['role'] == 'controller': + node_info['interfaces_summary'] = '' + else: + node_info['interfaces_summary'] = self.get_interfaces_phy_summary( + node_info['podId'], + node_info['id'] + ) + + if power_info: + node_info['power'] = self.get_node_power( + node_info['podId'], + node_info['id'] + ) + + if psu_info: + node_info['psu'] = self.get_node_psu( + node_info['podId'], + node_info['id'] + ) + + if sensor_info: + node_info['sensor'] = self.get_node_sensor( + node_info['podId'], + node_info['id'] + ) + + if system_info: + node_info['system'] = self.get_node_system( + node_info['podId'], + node_info['id'] + ) + if not self.match_node(node_info, node_filter): + continue + + if temp_info: + node_info['temp'] = self.get_node_temp( + node_info['podId'], + node_info['id'] + ) + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: i['name'].lower() + ) + + return nodes diff --git a/lib/aci/node/main.py b/lib/aci/node/main.py new file mode 100644 index 00000000..6cfbd759 --- /dev/null +++ b/lib/aci/node/main.py @@ -0,0 +1,29 @@ +from lib.aci.node.api import NodeApi +from lib.aci.node.info import NodeInfo +from lib.aci.node.policy.profile.main import NodeInterfacePolicyProfile +from lib.aci.node.power.main import NodePower +from lib.aci.node.psu.main import NodePsu +from lib.aci.node.sensor.main import NodeSensor +from lib.aci.node.system.main import NodeSystem +from lib.aci.node.temp.main import NodeTemp + + +class Node( + NodeApi, + NodeInfo, + NodeInterfacePolicyProfile, + NodePower, + NodePsu, + NodeSensor, + NodeSystem, + NodeTemp + ): + def __init__(self): + NodeApi.__init__(self) + NodeInfo.__init__(self) + NodeInterfacePolicyProfile.__init__(self) + NodePower.__init__(self) + NodePsu.__init__(self) + NodeSensor.__init__(self) + NodeSystem.__init__(self) + NodeTemp.__init__(self) diff --git a/lib/aci/node/output.py b/lib/aci/node/output.py new file mode 100644 index 00000000..49cdfc87 --- /dev/null +++ b/lib/aci/node/output.py @@ -0,0 +1,396 @@ +class NodeOutput(): + def __init__(self): + pass + + def print_nodes(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - State [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['full_name'] + else: + order = ['pod_node_name'] + + order = order + [ + 'id', + 'address', + 'adSt', + 'fabricSt', + 'roleUi', + 'model', + 'serial', + 'version' + ] + + headers = [ + 'Node Name', + 'ID', + 'VTEP IP', + 'Admin', + 'Fabric', + 'Role', + 'Model', + 'Serial', + 'Version' + ] + + self.my_output.my_table( + nodes, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_nodes_power(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - Power [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + power = [] + for node in nodes: + power = power + node['power'] + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'slotId', + 'descr', + 'drawnAvg', + 'drawnLast', + 'drawnMax', + 'drawnMin', + 'suppliedAvg', + 'suppliedLast', + 'suppliedMax', + 'suppliedMin' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'PSU Slot ID', + 'Description', + 'Drawn Avg', + 'Drawn Last', + 'Drawn Max', + 'Drawn Min', + 'Supplied Avg', + 'Supplied Last', + 'Supplied Max', + 'Supplied Min' + ] + + self.my_output.my_table( + power, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_nodes_psu(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - PSU [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + psu = [] + for node in nodes: + psu = psu + node['psu'] + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'slotId', + 'descr', + 'model', + 'ser', + 'drawnCurr', + 'volt', + 'operSt' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'PSU Slot ID', + 'Description', + 'Model', + 'Serial Number', + 'Current', + 'Voltage', + 'Oper State' + ] + + self.my_output.my_table( + psu, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_nodes_sensor(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - Sensor [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + sensor = [] + for node in nodes: + sensor = sensor + node['sensor'] + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'descr', + 'type', + 'value', + 'minorThresh', + 'majorThresh', + 'operSt' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Sensor', + 'Type', + 'Value', + 'Min', + 'Max', + 'Oper State' + ] + + self.my_output.my_table( + sensor, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_nodes_system(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - System [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'address', + 'system.inbMgmtCidr', + 'system.inbMgmtGateway', + 'system.oobMgmtCidr', + 'system.oobMgmtGateway', + 'system.controlPlaneMTU', + 'system.tepPool' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node Name', + 'VTEP IP', + 'Inband IP', + 'Inband Gateway', + 'OOB IP', + 'OOB Gateway', + 'MTU', + 'TEP Pool' + ] + + self.my_output.my_table( + nodes, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_nodes_temp(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - Temperature [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + temp = [] + for node in nodes: + temp = temp + node['temp'] + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'sensorName', + 'currentAvg', + 'currentLast', + 'currentMax', + 'currentMax' + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node', + 'Sensor', + 'Avg', + 'Last', + 'Max', + 'Min' + ] + + self.my_output.my_table( + temp, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_nodes_intf(self, nodes, title=False): + if title: + self.my_output.default( + 'Node - Interface [#%s]' % (len(nodes)), + underline=True, + before_newline=True + ) + + if len(nodes) == 0: + if title: + self.my_output.default('None') + return + + order = [] + if self.is_apic: + order = ['apic'] + + order = order + [ + 'pod_node_name', + 'interfaces_summary.portSummary', + 'interfaces_summary.uplinkSummary', + 'interfaces_summary.downlinkSummary', + 'interfaces_summary.100MSummary', + 'interfaces_summary.1GSummary', + 'interfaces_summary.10GSummary', + 'interfaces_summary.25GSummary', + 'interfaces_summary.40GSummary', + 'interfaces_summary.100GSummary', + 'interfaces_summary.400GSummary', + ] + + headers = [] + if self.is_apic: + headers = ['Apic'] + + headers = headers + [ + 'Node Name', + 'Ports (Up/Down/Total)', + 'Uplink', + 'Downlink', + '100M', + '1G', + '10G', + '25G', + '40G', + '100G', + '400G' + ] + + self.my_output.my_table( + nodes, + order=order, + headers=headers, + merge=True, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) diff --git a/lib/aci/node/policy/__init__.py b/lib/aci/node/policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/policy/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/policy/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..957e7991 Binary files /dev/null and b/lib/aci/node/policy/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/policy/profile/__init__.py b/lib/aci/node/policy/profile/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/policy/profile/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/policy/profile/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2c68df4d Binary files /dev/null and b/lib/aci/node/policy/profile/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/policy/profile/__pycache__/api.cpython-310.pyc b/lib/aci/node/policy/profile/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..64b69fec Binary files /dev/null and b/lib/aci/node/policy/profile/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/policy/profile/__pycache__/info.cpython-310.pyc b/lib/aci/node/policy/profile/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..c204f5cc Binary files /dev/null and b/lib/aci/node/policy/profile/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/policy/profile/__pycache__/main.cpython-310.pyc b/lib/aci/node/policy/profile/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..43b0472d Binary files /dev/null and b/lib/aci/node/policy/profile/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/policy/profile/api.py b/lib/aci/node/policy/profile/api.py new file mode 100644 index 00000000..9e149cfd --- /dev/null +++ b/lib/aci/node/policy/profile/api.py @@ -0,0 +1,62 @@ +class NodeInterfacePolicyProfileApi(): + def __init__(self): + self.node_interface_policy_profile_mo = {} + + def get_node_interface_policy_profile_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.node_interface_policy_profile_mo: + return self.node_interface_policy_profile_mo[key] + + cache = self.get_object_cache( + 'infraRsInterfacePolProfile', + object_selector=key + ) + if cache is not None: + self.node_interface_policy_profile_mo[key] = cache + self.log.apic_mo( + 'infraRsInterfacePolProfile.%s' % (key), + self.node_interface_policy_profile_mo[key] + ) + return self.node_interface_policy_profile_mo[key] + + # https:///api/node/mo/uni/infra/nodecfgcont/node-205.json?query-target=subtree&target-subtree-class=infraRsInterfacePolProfile,infraRsFexGrp&_dc=1684139156603 + distinguished_name = 'uni/infra/nodecfgcont/node-%s' % ( + node_id + ) + query = 'query-target=subtree&target-subtree-class=infraRsInterfacePolProfile' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_node_interface_policy_profile_mo', + 'API failed' + ) + return None + + self.node_interface_policy_profile_mo[key] = [] + + for managed_object in managed_objects['imdata']: + if 'infraRsInterfacePolProfile' in managed_object: + self.node_interface_policy_profile_mo[key].append( + managed_object['infraRsInterfacePolProfile']['attributes'] + ) + + self.log.apic_mo( + 'infraRsInterfacePolProfile.%s' % (key), + self.node_interface_policy_profile_mo[key] + ) + + self.set_object_cache( + 'infraRsInterfacePolProfile', + self.node_interface_policy_profile_mo[key], + object_selector=key + ) + + return self.node_interface_policy_profile_mo[key] diff --git a/lib/aci/node/policy/profile/info.py b/lib/aci/node/policy/profile/info.py new file mode 100644 index 00000000..a7296588 --- /dev/null +++ b/lib/aci/node/policy/profile/info.py @@ -0,0 +1,56 @@ +class NodeInterfacePolicyProfileInfo(): + def __init__(self): + pass + + def get_node_interface_policy_profile_info(self, managed_object): + # "childAction": "deleteNonPresent", + # "deplSt": "delivered", + # "dn": "uni/infra/nodecfgcont/node-205/rsinterfacePolProfile-[uni/infra/accportprof-UCSB1-FI-A_IntProf]", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2021-12-09T23:30:56.576+02:00", + # "monPolDn": "", + # "rType": "mo", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "infraAccPortP", + # "tDn": "uni/infra/accportprof-UCSB1-FI-A_IntProf", + # "tType": "mo" + + keys = [ + 'tCl', + 'tDn' + ] + info = {} + for key in keys: + info[key] = managed_object[key] + + if info['tCl'] != 'infraAccPortP': + self.log.error( + 'get_node_interface_policy_profile_info', + 'Unsupported profile class: %s' % (info['tCl']) + ) + return None + + info['name'] = info['tDn'].split('/')[2][12:] + + return info + + def get_node_interface_policy_profiles(self, pod_id, node_id): + managed_objects = self.get_node_interface_policy_profile_mo(pod_id, node_id) + if managed_objects is None: + return None + + profiles = [] + for managed_object in managed_objects: + profile_info = self.get_node_interface_policy_profile_info( + managed_object + ) + + if profile_info is not None: + profiles.append( + profile_info + ) + + return profiles diff --git a/lib/aci/node/policy/profile/main.py b/lib/aci/node/policy/profile/main.py new file mode 100644 index 00000000..10b7a50e --- /dev/null +++ b/lib/aci/node/policy/profile/main.py @@ -0,0 +1,8 @@ +from lib.aci.node.policy.profile.api import NodeInterfacePolicyProfileApi +from lib.aci.node.policy.profile.info import NodeInterfacePolicyProfileInfo + + +class NodeInterfacePolicyProfile(NodeInterfacePolicyProfileApi, NodeInterfacePolicyProfileInfo): + def __init__(self): + NodeInterfacePolicyProfileApi.__init__(self) + NodeInterfacePolicyProfileInfo.__init__(self) diff --git a/lib/aci/node/power/__init__.py b/lib/aci/node/power/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/power/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/power/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8a802234 Binary files /dev/null and b/lib/aci/node/power/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/power/__pycache__/api.cpython-310.pyc b/lib/aci/node/power/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6ff201e0 Binary files /dev/null and b/lib/aci/node/power/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/power/__pycache__/info.cpython-310.pyc b/lib/aci/node/power/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..3d716c06 Binary files /dev/null and b/lib/aci/node/power/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/power/__pycache__/main.cpython-310.pyc b/lib/aci/node/power/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2fd0f2dc Binary files /dev/null and b/lib/aci/node/power/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/power/api.py b/lib/aci/node/power/api.py new file mode 100644 index 00000000..164a7d92 --- /dev/null +++ b/lib/aci/node/power/api.py @@ -0,0 +1,54 @@ +class NodePowerApi(): + def __init__(self): + self.node_power_mo = None + + def get_node_power_mo(self, deduplicate=True): + if self.node_power_mo is not None: + return self.node_power_mo + + cache = self.get_object_cache( + 'eqptPsPower' + ) + if cache is not None: + self.node_power_mo = cache + self.log.apic_mo( + 'eqptPsPower', + self.node_power_mo + ) + return self.node_power_mo + + managed_objects = self.get_class( + 'eqptPsPower' + ) + if managed_objects is None: + self.log.error( + 'get_node_power_mo', + 'API failed' + ) + return None + + self.node_power_mo = [] + dns = [] + for managed_object in managed_objects['imdata']: + if 'eqptPsPower15min' in managed_object: + if deduplicate and managed_object['eqptPsPower15min']['attributes']['dn'] in dns: + continue + + dns.append( + managed_object['eqptPsPower15min']['attributes']['dn'] + ) + self.node_power_mo.append( + managed_object['eqptPsPower15min']['attributes'] + ) + + self.log.apic_mo( + 'eqptPsPower', + self.node_power_mo + ) + + self.set_object_cache( + 'eqptPsPower', + self.node_power_mo + ) + + return self.node_power_mo diff --git a/lib/aci/node/power/info.py b/lib/aci/node/power/info.py new file mode 100644 index 00000000..d8212678 --- /dev/null +++ b/lib/aci/node/power/info.py @@ -0,0 +1,150 @@ +from lib import filter_helper + + +class NodePowerInfo(): + def __init__(self): + self.nodes_power = None + + def convert_node_power_value(self, value): + if len(value) == 0: + return None + + return round(float(value), 2) + + def get_node_power_info(self, managed_object): + # "childAction": "", + # "cnt": "1", + # "dn": "topology/pod-1/node-3/sys/ch/psuslot-5/psu/CDeqptPsPower15min", + # "drawnAvg": "64.000000", + # "drawnLast": "64.000000", + # "drawnMax": "64.000000", + # "drawnMin": "64.000000", + # "drawnSpct": "0", + # "drawnThr": "", + # "drawnTr": "0.000000", + # "drawnTrBase": "58.666667", + # "drawnTtl": "64.000000", + # "lastCollOffset": "300", + # "repIntvEnd": "2023-05-19T09:05:29.169+02:00", + # "repIntvStart": "2023-05-19T09:00:28.504+02:00", + # "status": "", + # "suppliedAvg": "72.000000", + # "suppliedLast": "72.000000", + # "suppliedMax": "72.000000", + # "suppliedMin": "72.000000", + # "suppliedSpct": "0", + # "suppliedThr": "", + # "suppliedTr": "0.000000", + # "suppliedTrBase": "66.666667", + # "suppliedTtl": "72.000000" + info = {} + info['__Output'] = {} + + for key in managed_object: + if key.startswith('drawn'): + info[key] = self.convert_node_power_value(managed_object[key]) + continue + + if key.startswith('supplied'): + info[key] = self.convert_node_power_value(managed_object[key]) + continue + + info[key] = managed_object[key] + + info['podId'] = managed_object['dn'].split('/')[1][4:] + info['nodeId'] = managed_object['dn'].split('/')[2][5:] + info['nodeName'] = self.get_node_name( + info['nodeId'] + ) + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + # "dn": "topology/pod-1/node-3/sys/ch/psuslot-5/psu/CDeqptPsPower15min" + info['slotId'] = info['dn'].split('/')[5][8:] + + return info + + def get_nodes_power_info(self): + if self.nodes_power is not None: + return self.nodes_power + + nodes_power_mo = self.get_node_power_mo() + if nodes_power_mo is not None: + self.nodes_power = [] + for node_power_mo in nodes_power_mo: + node_power_info = self.get_node_power_info( + node_power_mo + ) + + self.nodes_power.append( + node_power_info + ) + + return self.nodes_power + + def get_node_power(self, pod_id, node_id): + node_filter = [] + node_filter.append( + 'pod:%s' % (pod_id) + ) + + node_filter.append( + 'id:%s' % (node_id) + ) + + node_power = self.get_nodes_power( + node_filter=node_filter + ) + + return node_power + + def match_node_power(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, node_info['nodeId']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, node_info['podId']): + return False + + if key == 'serial': + if not filter_helper.match_string(value, node_info['ser']): + return False + + return True + + def get_nodes_power(self, node_filter=None): + all_nodes = self.get_nodes_power_info() + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node_power(node_info, node_filter): + continue + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: ( + i['pod_node_name'], + i['slotId'] + ) + ) + + return nodes diff --git a/lib/aci/node/power/main.py b/lib/aci/node/power/main.py new file mode 100644 index 00000000..6e164269 --- /dev/null +++ b/lib/aci/node/power/main.py @@ -0,0 +1,8 @@ +from lib.aci.node.power.api import NodePowerApi +from lib.aci.node.power.info import NodePowerInfo + + +class NodePower(NodePowerApi, NodePowerInfo): + def __init__(self): + NodePowerApi.__init__(self) + NodePowerInfo.__init__(self) diff --git a/lib/aci/node/psu/__init__.py b/lib/aci/node/psu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/psu/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/psu/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8a802234 Binary files /dev/null and b/lib/aci/node/psu/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/psu/__pycache__/api.cpython-310.pyc b/lib/aci/node/psu/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..ad1c77b9 Binary files /dev/null and b/lib/aci/node/psu/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/psu/__pycache__/info.cpython-310.pyc b/lib/aci/node/psu/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e16756c4 Binary files /dev/null and b/lib/aci/node/psu/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/psu/__pycache__/main.cpython-310.pyc b/lib/aci/node/psu/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..26691771 Binary files /dev/null and b/lib/aci/node/psu/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/psu/api.py b/lib/aci/node/psu/api.py new file mode 100644 index 00000000..49a1fe89 --- /dev/null +++ b/lib/aci/node/psu/api.py @@ -0,0 +1,46 @@ +class NodePsuApi(): + def __init__(self): + self.node_psu_mo = None + + def get_node_psu_mo(self): + if self.node_psu_mo is not None: + return self.node_psu_mo + + cache = self.get_object_cache( + 'eqptPsu' + ) + if cache is not None: + self.node_psu_mo = cache + self.log.apic_mo( + 'eqptPsu', + self.node_psu_mo + ) + return self.node_psu_mo + + managed_objects = self.get_class( + 'eqptPsu' + ) + if managed_objects is None: + self.log.error( + 'get_node_psu_mo', + 'API failed' + ) + return None + + self.node_psu_mo = [] + for managed_object in managed_objects['imdata']: + self.node_psu_mo.append( + managed_object['eqptPsu']['attributes'] + ) + + self.log.apic_mo( + 'eqptPsu', + self.node_psu_mo + ) + + self.set_object_cache( + 'eqptPsu', + self.node_psu_mo + ) + + return self.node_psu_mo diff --git a/lib/aci/node/psu/info.py b/lib/aci/node/psu/info.py new file mode 100644 index 00000000..48157f15 --- /dev/null +++ b/lib/aci/node/psu/info.py @@ -0,0 +1,167 @@ +from lib import filter_helper + + +class NodePsuInfo(): + def __init__(self): + self.nodes_psu = None + + def convert_node_psu_value(self, value): + if len(value) == 0: + return None + + return round(float(value), 2) + + def get_node_psu_info(self, managed_object): + # "almReg": "0", + # "cap": "4.000000", + # "childAction": "", + # "cimcVersion": "", + # "descr": "FRU_PSU1 (ID 4)", + # "dn": "topology/pod-1/node-1/sys/ch/psuslot-5/psu", + # "drawnCurr": "0.000000", + # "fanOpSt": "unknown", + # "hwVer": "A", + # "id": "1", + # "mfgTm": "not-applicable", + # "modTs": "2023-05-19T09:15:45.143+02:00", + # "model": "UCSC-PSU1-770W", + # "monPolDn": "uni/fabric/monfab-default", + # "operSt": "ok", + # "rev": "0", + # "ser": "APS234101KU", + # "status": "", + # "tc": "770", + # "vId": "", + # "vSrc": "unknown", + # "vendor": "Cisco Systems Inc", + # "volt": "12.000000" + info = {} + info['__Output'] = {} + + keys = [ + 'cap', + 'descr', + 'dn', + 'drawnCurr', + 'fanOpSt', + 'hwVer', + 'id', + 'model', + 'operSt', + 'rev', + 'ser', + 'tc', + 'vendor', + 'volt' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['podId'] = managed_object['dn'].split('/')[1][4:] + info['nodeId'] = managed_object['dn'].split('/')[2][5:] + info['nodeName'] = self.get_node_name( + info['nodeId'] + ) + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['volt'] = self.convert_node_psu_value(info['volt']) + info['drawnCurr'] = self.convert_node_psu_value(info['drawnCurr']) + + # "dn": "topology/pod-1/node-1/sys/ch/psuslot-5/psu" + info['slotId'] = info['dn'].split('/')[5][8:] + + if info['operSt'] == 'ok': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_nodes_psu_info(self): + if self.nodes_psu is not None: + return self.nodes_psu + + nodes_psu_mo = self.get_node_psu_mo() + if nodes_psu_mo is not None: + self.nodes_psu = [] + for node_psu_mo in nodes_psu_mo: + node_psu_info = self.get_node_psu_info( + node_psu_mo + ) + + self.nodes_psu.append( + node_psu_info + ) + + return self.nodes_psu + + def get_node_psu(self, pod_id, node_id): + node_filter = [] + node_filter.append( + 'pod:%s' % (pod_id) + ) + + node_filter.append( + 'id:%s' % (node_id) + ) + + node_psu = self.get_nodes_psu( + node_filter=node_filter + ) + + return node_psu + + def match_node_psu(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, node_info['nodeId']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, node_info['podId']): + return False + + if key == 'serial': + if not filter_helper.match_string(value, node_info['ser']): + return False + + return True + + def get_nodes_psu(self, node_filter=None): + all_nodes = self.get_nodes_psu_info() + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node_psu(node_info, node_filter): + continue + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: ( + i['pod_node_name'], + i['slotId'] + ) + ) + + return nodes diff --git a/lib/aci/node/psu/main.py b/lib/aci/node/psu/main.py new file mode 100644 index 00000000..83630279 --- /dev/null +++ b/lib/aci/node/psu/main.py @@ -0,0 +1,8 @@ +from lib.aci.node.psu.api import NodePsuApi +from lib.aci.node.psu.info import NodePsuInfo + + +class NodePsu(NodePsuApi, NodePsuInfo): + def __init__(self): + NodePsuApi.__init__(self) + NodePsuInfo.__init__(self) diff --git a/lib/aci/node/sensor/__init__.py b/lib/aci/node/sensor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/sensor/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/sensor/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8a802234 Binary files /dev/null and b/lib/aci/node/sensor/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/sensor/__pycache__/api.cpython-310.pyc b/lib/aci/node/sensor/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5ddcd837 Binary files /dev/null and b/lib/aci/node/sensor/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/sensor/__pycache__/info.cpython-310.pyc b/lib/aci/node/sensor/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ca8d305c Binary files /dev/null and b/lib/aci/node/sensor/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/sensor/__pycache__/main.cpython-310.pyc b/lib/aci/node/sensor/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..bed285e0 Binary files /dev/null and b/lib/aci/node/sensor/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/sensor/api.py b/lib/aci/node/sensor/api.py new file mode 100644 index 00000000..8403e3ad --- /dev/null +++ b/lib/aci/node/sensor/api.py @@ -0,0 +1,46 @@ +class NodeSensorApi(): + def __init__(self): + self.node_sensor_mo = None + + def get_node_sensor_mo(self): + if self.node_sensor_mo is not None: + return self.node_sensor_mo + + cache = self.get_object_cache( + 'eqptSensor' + ) + if cache is not None: + self.node_sensor_mo = cache + self.log.apic_mo( + 'eqptSensor', + self.node_sensor_mo + ) + return self.node_sensor_mo + + managed_objects = self.get_class( + 'eqptSensor' + ) + if managed_objects is None: + self.log.error( + 'get_node_sensor_mo', + 'API failed' + ) + return None + + self.node_sensor_mo = [] + for managed_object in managed_objects['imdata']: + self.node_sensor_mo.append( + managed_object['eqptSensor']['attributes'] + ) + + self.log.apic_mo( + 'eqptSensor', + self.node_sensor_mo + ) + + self.set_object_cache( + 'eqptSensor', + self.node_sensor_mo + ) + + return self.node_sensor_mo diff --git a/lib/aci/node/sensor/info.py b/lib/aci/node/sensor/info.py new file mode 100644 index 00000000..54d2e7c5 --- /dev/null +++ b/lib/aci/node/sensor/info.py @@ -0,0 +1,140 @@ +from lib import filter_helper + + +class NodeSensorInfo(): + def __init__(self): + self.nodes_sensor = None + + def get_node_sensor_info(self, managed_object): + # "childAction": "", + # "cimcVersion": "", + # "descr": "Inlet", + # "dn": "topology/pod-1/node-101/sys/ch/supslot-1/sup/sensor-1", + # "id": "1", + # "majorThresh": "70", + # "mfgTm": "not-applicable", + # "minorThresh": "42", + # "modTs": "2023-05-19T09:13:06.651+02:00", + # "model": "Inlet", + # "monPolDn": "uni/fabric/monfab-default", + # "operSt": "normal", + # "rev": "n/a", + # "ser": "n/a", + # "status": "", + # "type": "inlet", + # "value": "0", + # "vendor": "n/a" + info = {} + info['__Output'] = {} + + keys = [ + 'descr', + 'id', + 'majorThresh', + 'minorThresh', + 'model', + 'operSt', + 'type', + 'value' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['podId'] = managed_object['dn'].split('/')[1][4:] + info['nodeId'] = managed_object['dn'].split('/')[2][5:] + info['nodeName'] = self.get_node_name( + info['nodeId'] + ) + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + if info['operSt'] == 'normal': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_nodes_sensor_info(self): + if self.nodes_sensor is not None: + return self.nodes_sensor + + nodes_sensor_mo = self.get_node_sensor_mo() + if nodes_sensor_mo is not None: + self.nodes_sensor = [] + for node_sensor_mo in nodes_sensor_mo: + node_sensor_info = self.get_node_sensor_info( + node_sensor_mo + ) + + self.nodes_sensor.append( + node_sensor_info + ) + + return self.nodes_sensor + + def get_node_sensor(self, pod_id, node_id): + node_filter = [] + node_filter.append( + 'pod:%s' % (pod_id) + ) + + node_filter.append( + 'id:%s' % (node_id) + ) + + node_sensor = self.get_nodes_sensor( + node_filter=node_filter + ) + + return node_sensor + + def match_node_sensor(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, node_info['nodeId']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, node_info['podId']): + return False + + return True + + def get_nodes_sensor(self, node_filter=None): + all_nodes = self.get_nodes_sensor_info() + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node_sensor(node_info, node_filter): + continue + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: ( + i['pod_node_name'], + i['descr'] + ) + ) + + return nodes diff --git a/lib/aci/node/sensor/main.py b/lib/aci/node/sensor/main.py new file mode 100644 index 00000000..e358c685 --- /dev/null +++ b/lib/aci/node/sensor/main.py @@ -0,0 +1,8 @@ +from lib.aci.node.sensor.api import NodeSensorApi +from lib.aci.node.sensor.info import NodeSensorInfo + + +class NodeSensor(NodeSensorApi, NodeSensorInfo): + def __init__(self): + NodeSensorApi.__init__(self) + NodeSensorInfo.__init__(self) diff --git a/lib/aci/node/system/__init__.py b/lib/aci/node/system/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/system/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/system/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8a802234 Binary files /dev/null and b/lib/aci/node/system/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/system/__pycache__/api.cpython-310.pyc b/lib/aci/node/system/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..86580918 Binary files /dev/null and b/lib/aci/node/system/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/system/__pycache__/info.cpython-310.pyc b/lib/aci/node/system/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1295bce6 Binary files /dev/null and b/lib/aci/node/system/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/system/__pycache__/main.cpython-310.pyc b/lib/aci/node/system/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b788f912 Binary files /dev/null and b/lib/aci/node/system/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/system/api.py b/lib/aci/node/system/api.py new file mode 100644 index 00000000..cf256c30 --- /dev/null +++ b/lib/aci/node/system/api.py @@ -0,0 +1,46 @@ +class NodeSystemApi(): + def __init__(self): + self.node_system_mo = None + + def get_node_system_mo(self): + if self.node_system_mo is not None: + return self.node_system_mo + + cache = self.get_object_cache( + 'topSystem' + ) + if cache is not None: + self.node_system_mo = cache + self.log.apic_mo( + 'topSystem', + self.node_system_mo + ) + return self.node_system_mo + + managed_objects = self.get_class( + 'topSystem' + ) + if managed_objects is None: + self.log.error( + 'get_node_system_mo', + 'API failed' + ) + return None + + self.node_system_mo = [] + for managed_object in managed_objects['imdata']: + self.node_system_mo.append( + managed_object['topSystem']['attributes'] + ) + + self.log.apic_mo( + 'topSystem', + self.node_system_mo + ) + + self.set_object_cache( + 'topSystem', + self.node_system_mo + ) + + return self.node_system_mo diff --git a/lib/aci/node/system/info.py b/lib/aci/node/system/info.py new file mode 100644 index 00000000..6a2656f3 --- /dev/null +++ b/lib/aci/node/system/info.py @@ -0,0 +1,114 @@ +from lib import filter_helper + + +class NodeSystemInfo(): + def __init__(self): + self.nodes_system = None + + def get_node_system_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['podId'] = managed_object['dn'].split('/')[1][4:] + info['nodeId'] = managed_object['dn'].split('/')[2][5:] + info['nodeName'] = self.get_node_name( + info['nodeId'] + ) + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['inbMgmtCidr'] = '%s/%s' % ( + info['inbMgmtAddr'], + info['inbMgmtAddrMask'] + ) + + info['oobMgmtCidr'] = '%s/%s' % ( + info['oobMgmtAddr'], + info['oobMgmtAddrMask'] + ) + + return info + + def get_nodes_system_info(self): + if self.nodes_system is not None: + return self.nodes_system + + nodes_system_mo = self.get_node_system_mo() + if nodes_system_mo is not None: + self.nodes_system = [] + for node_system_mo in nodes_system_mo: + node_system_info = self.get_node_system_info( + node_system_mo + ) + + self.nodes_system.append( + node_system_info + ) + + return self.nodes_system + + def get_node_system(self, pod_id, node_id): + node_filter = [] + node_filter.append( + 'pod:%s' % (pod_id) + ) + + node_filter.append( + 'id:%s' % (node_id) + ) + + node_system = self.get_nodes_system( + node_filter=node_filter + ) + + if node_system is not None and len(node_system) == 1: + return node_system[0] + + return None + + def match_node_system(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, node_info['nodeId']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, node_info['podId']): + return False + + return True + + def get_nodes_system(self, node_filter=None): + all_nodes = self.get_nodes_system_info() + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node_system(node_info, node_filter): + continue + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: i['pod_node_name'] + ) + + return nodes diff --git a/lib/aci/node/system/main.py b/lib/aci/node/system/main.py new file mode 100644 index 00000000..208ea4bd --- /dev/null +++ b/lib/aci/node/system/main.py @@ -0,0 +1,8 @@ +from lib.aci.node.system.api import NodeSystemApi +from lib.aci.node.system.info import NodeSystemInfo + + +class NodeSystem(NodeSystemApi, NodeSystemInfo): + def __init__(self): + NodeSystemApi.__init__(self) + NodeSystemInfo.__init__(self) diff --git a/lib/aci/node/temp/__init__.py b/lib/aci/node/temp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/node/temp/__pycache__/__init__.cpython-310.pyc b/lib/aci/node/temp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8a802234 Binary files /dev/null and b/lib/aci/node/temp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/node/temp/__pycache__/api.cpython-310.pyc b/lib/aci/node/temp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..9ee876d4 Binary files /dev/null and b/lib/aci/node/temp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/node/temp/__pycache__/info.cpython-310.pyc b/lib/aci/node/temp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b4038941 Binary files /dev/null and b/lib/aci/node/temp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/node/temp/__pycache__/main.cpython-310.pyc b/lib/aci/node/temp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..15143830 Binary files /dev/null and b/lib/aci/node/temp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/node/temp/api.py b/lib/aci/node/temp/api.py new file mode 100644 index 00000000..4aa1be80 --- /dev/null +++ b/lib/aci/node/temp/api.py @@ -0,0 +1,54 @@ +class NodeTempApi(): + def __init__(self): + self.node_temp_mo = None + + def get_node_temp_mo(self, deduplicate=True): + if self.node_temp_mo is not None: + return self.node_temp_mo + + cache = self.get_object_cache( + 'eqptTemp' + ) + if cache is not None: + self.node_temp_mo = cache + self.log.apic_mo( + 'eqptTemp', + self.node_temp_mo + ) + return self.node_temp_mo + + managed_objects = self.get_class( + 'eqptTemp' + ) + if managed_objects is None: + self.log.error( + 'get_node_temp_mo', + 'API failed' + ) + return None + + self.node_temp_mo = [] + dns = [] + for managed_object in managed_objects['imdata']: + if 'eqptTemp15min' in managed_object: + if deduplicate and managed_object['eqptTemp15min']['attributes']['dn'] in dns: + continue + + dns.append( + managed_object['eqptTemp15min']['attributes']['dn'] + ) + self.node_temp_mo.append( + managed_object['eqptTemp15min']['attributes'] + ) + + self.log.apic_mo( + 'eqptTemp', + self.node_temp_mo + ) + + self.set_object_cache( + 'eqptTemp', + self.node_temp_mo + ) + + return self.node_temp_mo diff --git a/lib/aci/node/temp/info.py b/lib/aci/node/temp/info.py new file mode 100644 index 00000000..1bc3a2cc --- /dev/null +++ b/lib/aci/node/temp/info.py @@ -0,0 +1,134 @@ +from lib import filter_helper + + +class NodeTempInfo(): + def __init__(self): + self.nodes_temp = None + + def get_node_temp_info(self, managed_object): + # "childAction": "", + # "cnt": "2", + # "currentAvg": "25", + # "currentLast": "26", + # "currentMax": "26", + # "currentMin": "25", + # "currentSpct": "0", + # "currentThr": "", + # "currentTr": "0", + # "currentTrBase": "25", + # "currentTtl": "51", + # "dn": "topology/pod-1/node-101/sys/ch/supslot-1/sup/sensor-1/CDeqptTemp15min", + # "lastCollOffset": "590", + # "normalizedAvg": "36", + # "normalizedLast": "37", + # "normalizedMax": "37", + # "normalizedMin": "36", + # "normalizedSpct": "0", + # "normalizedThr": "", + # "normalizedTr": "0", + # "normalizedTrBase": "36", + # "normalizedTtl": "73", + # "repIntvEnd": "2023-05-19T09:09:46.634+02:00", + # "repIntvStart": "2023-05-19T08:59:56.582+02:00", + # "status": "" + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['sensorName'] = '%s.%s' % ( + managed_object['dn'].split('/')[5], + managed_object['dn'].split('/')[7] + ) + + info['podId'] = managed_object['dn'].split('/')[1][4:] + info['nodeId'] = managed_object['dn'].split('/')[2][5:] + info['nodeName'] = self.get_node_name( + info['nodeId'] + ) + + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + return info + + def get_nodes_temp_info(self): + if self.nodes_temp is not None: + return self.nodes_temp + + nodes_temp_mo = self.get_node_temp_mo() + if nodes_temp_mo is not None: + self.nodes_temp = [] + for node_temp_mo in nodes_temp_mo: + node_temp_info = self.get_node_temp_info( + node_temp_mo + ) + + self.nodes_temp.append( + node_temp_info + ) + + return self.nodes_temp + + def get_node_temp(self, pod_id, node_id): + node_filter = [] + node_filter.append( + 'pod:%s' % (pod_id) + ) + + node_filter.append( + 'id:%s' % (node_id) + ) + + node_temp = self.get_nodes_temp( + node_filter=node_filter + ) + + return node_temp + + def match_node_temp(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'id': + if not filter_helper.match_string(value, node_info['nodeId']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, node_info['podId']): + return False + + return True + + def get_nodes_temp(self, node_filter=None): + all_nodes = self.get_nodes_temp_info() + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node_temp(node_info, node_filter): + continue + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: ( + i['pod_node_name'], + i['sensorName'] + ) + ) + + return nodes diff --git a/lib/aci/node/temp/main.py b/lib/aci/node/temp/main.py new file mode 100644 index 00000000..4c208973 --- /dev/null +++ b/lib/aci/node/temp/main.py @@ -0,0 +1,8 @@ +from lib.aci.node.temp.api import NodeTempApi +from lib.aci.node.temp.info import NodeTempInfo + + +class NodeTemp(NodeTempApi, NodeTempInfo): + def __init__(self): + NodeTempApi.__init__(self) + NodeTempInfo.__init__(self) diff --git a/lib/aci/output.py b/lib/aci/output.py new file mode 100644 index 00000000..113bafb7 --- /dev/null +++ b/lib/aci/output.py @@ -0,0 +1,165 @@ +from lib import output_helper + +from lib.aci.ap.output import ApplicationProfileOutput +from lib.aci.bd.output import BridgeDomainOutput +from lib.aci.contract.output import ContractOutput +from lib.aci.domain.output import DomainOutput +from lib.aci.endpoint.output import EndpointOutput +from lib.aci.epg.output import EpgOutput +from lib.aci.intf.output import InterfaceOutput +from lib.aci.l2out.output import L2OutOutput +from lib.aci.l3out.output import L3OutOutput +from lib.aci.node.output import NodeOutput +from lib.aci.pg.output import PolicyGroupOutput +from lib.aci.policy.output import PolicyOutput +from lib.aci.pool.output import PoolOutput +from lib.aci.proto.output import ProtocolOutput +from lib.aci.system.output import SystemOutput +from lib.aci.tenant.output import TenantOutput +from lib.aci.vrf.output import VrfOutput + + +class ApicOutput( + ApplicationProfileOutput, + BridgeDomainOutput, + ContractOutput, + DomainOutput, + EndpointOutput, + EpgOutput, + InterfaceOutput, + L2OutOutput, + L3OutOutput, + NodeOutput, + PolicyGroupOutput, + PolicyOutput, + PoolOutput, + ProtocolOutput, + SystemOutput, + TenantOutput, + VrfOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.is_apic = True + + ApplicationProfileOutput.__init__(self) + BridgeDomainOutput.__init__(self) + ContractOutput.__init__(self) + DomainOutput.__init__(self) + EndpointOutput.__init__(self) + EpgOutput.__init__(self) + InterfaceOutput.__init__(self) + L2OutOutput.__init__(self) + L3OutOutput.__init__(self) + NodeOutput.__init__(self) + PolicyGroupOutput.__init__(self) + PolicyOutput.__init__(self) + PoolOutput.__init__(self) + ProtocolOutput.__init__(self) + SystemOutput.__init__(self) + TenantOutput.__init__(self) + VrfOutput.__init__(self) + + def set_apic_off(self): + self.is_apic = False + + def print_apic_controllers(self, controllers, show_password=False): + controllers = sorted( + controllers, + key=lambda i: i['name'] + ) + + for controller in controllers: + controller['__Output'] = {} + + if controller['online']: + controller['onlineTick'] = '\u2713' + controller['__Output']['onlineTick'] = 'Green' + else: + controller['onlineTick'] = '\u2717' + controller['__Output']['onlineTick'] = 'Red' + + if controller['cache']['enabled']: + controller['cache']['enabledTick'] = '\u2713' + controller['__Output']['cache.enabledTick'] = 'Green' + else: + controller['cache']['enabledTick'] = '\u2717' + controller['__Output']['cache.enabledTick'] = 'Red' + + if controller['cache']['enabled']: + if len(controller['cache']['object']): + controller['cache']['objectTick'] = '\u2713' + controller['__Output']['cache.objectTick'] = 'Green' + else: + controller['cache']['objectTick'] = '\u2717' + controller['__Output']['cache.objectTick'] = 'Red' + + if not controller['cache']['enabled']: + controller['cache']['ttlT'] = '--' + controller['cache']['objectTick'] = '--' + + if not show_password: + controller['password'] = '******' + + order = [ + 'name', + 'ip', + 'port', + 'username', + 'password', + 'domain', + 'onlineTick', + 'cache.enabledTick', + 'cache.ttlT', + 'cache.objectTick' + ] + + headers = [ + 'Name', + 'IP', + 'Port', + 'Username', + 'Password', + 'Domain', + 'Online', + 'Cache', + 'TTL', + 'TTL Overrides' + ] + + self.my_output.my_table( + controllers, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_cache_stats(self, info): + order = [ + 'object', + 'selector', + 'ttlT', + 'ageT', + 'validTick' + ] + + headers = [ + 'Object Name', + 'Object Key', + 'TTL', + 'Age', + 'Valid' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) diff --git a/lib/aci/path/__init__.py b/lib/aci/path/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/path/__pycache__/__init__.cpython-310.pyc b/lib/aci/path/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..69af83ba Binary files /dev/null and b/lib/aci/path/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/path/__pycache__/api.cpython-310.pyc b/lib/aci/path/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..afdf608e Binary files /dev/null and b/lib/aci/path/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/path/__pycache__/info.cpython-310.pyc b/lib/aci/path/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..4eece35f Binary files /dev/null and b/lib/aci/path/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/path/__pycache__/main.cpython-310.pyc b/lib/aci/path/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9dad45bb Binary files /dev/null and b/lib/aci/path/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/path/api.py b/lib/aci/path/api.py new file mode 100644 index 00000000..2e50b45f --- /dev/null +++ b/lib/aci/path/api.py @@ -0,0 +1,44 @@ +class FabricPathApi(): + def __init__(self): + self.fabric_path_mo = None + + def get_fabric_path_mo(self): + if self.fabric_path_mo is not None: + return self.fabric_path_mo + + cache = self.get_object_cache( + 'fabricPathEp' + ) + if cache is not None: + self.fabric_path_mo = cache + self.log.apic_mo( + 'fabricPathEp', + self.fabric_path_mo + ) + return self.fabric_path_mo + + managed_objects = self.get_class( + 'fabricPathEp' + ) + if managed_objects is None: + return None + + self.fabric_path_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fabricPathEp']['attributes'] + self.fabric_path_mo.append( + attributes + ) + + self.log.apic_mo( + 'fabricPathEp', + self.fabric_path_mo + ) + + self.set_object_cache( + 'fabricPathEp', + self.fabric_path_mo + ) + + return self.fabric_path_mo diff --git a/lib/aci/path/info.py b/lib/aci/path/info.py new file mode 100644 index 00000000..c2510f7b --- /dev/null +++ b/lib/aci/path/info.py @@ -0,0 +1,191 @@ +from lib import filter_helper + + +class FabricPathInfo(): + def __init__(self): + self.fabric_path = None + + def get_fabric_path_info(self, managed_object): + # + # Single Port + # + # "breakT": "nonbroken", + # "childAction": "", + # "descr": "", + # "dn": "topology/pod-1/paths-205/pathep-[eth1/14]", + # "lagT": "not-aggregated", + # "lcOwn": "local", + # "modTs": "2019-11-28T12:17:56.054+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "eth1/14", + # "pathT": "leaf", + # "status": "" + # + # Port Aggregation + # + # "breakT": "nonbroken", + # "childAction": "", + # "descr": "ACI1 UCSB1-FI-A Policy Group (Created by Ansible)", + # "dn": "topology/pod-1/paths-206/pathep-[UCSB1-FI-A_PolGrp]", + # "lagT": "node", + # "lcOwn": "local", + # "modTs": "2022-09-14T22:41:36.792+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "UCSB1-FI-A_PolGrp", + # "pathT": "leaf", + # "status": "" + info = {} + info['__Output'] = {} + + keys = [ + 'breakT', + 'dn', + 'lagT', + 'name', + 'pathT' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # External - not in scope and assumption is it will be not shown for local endpoint + # "topology/pod-{id}/protpaths-{nodeAId}-{nodeBId}/extprotpaths-{extChAId}-{extChBId}/pathep-[{name}]", + # "topology/pod-{id}/paths-{nodeId}/extpaths-{extChId}/pathep-[{name}]", + + # Internal + # "topology/pod-{id}/protpaths-{nodeAId}-{nodeBId}/pathep-[{name}]", + # "topology/pod-{id}/paths-{nodeId}/pathep-[{name}]" + + if info['lagT'] == 'not-aggregated': + # "topology/pod-{id}/paths-{nodeId}/pathep-[{name}]" + info['aggregate'] = False + info['resolved'] = True + info['policy_group_name'] = None + info['ports'] = [] + port_info = {} + port_info['pod_id'] = info['dn'].split('/')[1].split('-')[1] + port_info['node_id'] = info['dn'].split('/')[2].split('-')[1] + port_info['port_id'] = info['name'] + port_info['ep'] = 'pod-%s:node-%s:%s' % ( + port_info['pod_id'], + port_info['node_id'], + port_info['port_id'] + ) + info['ports'].append(port_info) + + else: + # While both options are possible for dn format, the name will be of the policy group + # "topology/pod-{id}/protpaths-{nodeAId}-{nodeBId}/pathep-[{name}]", + # "topology/pod-{id}/paths-{nodeId}/pathep-[{name}]" + info['aggregate'] = True + info['resolved'] = False + info['policy_group_name'] = info['name'] + info['ports'] = [] + port_info = {} + port_info['ep'] = '(%s)' % (info['policy_group_name']) + info['ports'].append(port_info) + + if info['lagT'] not in ['node', 'not-aggregated']: + self.log.error( + 'get_fabric_path_info', + 'Unsupported fabric path: %s' % (managed_object) + ) + + return info + + def get_fabric_paths_info(self): + if self.fabric_path is not None: + return self.fabric_path + + managed_objects = self.get_fabric_path_mo() + if managed_objects is None: + return None + + self.fabric_path = [] + for managed_object in managed_objects: + self.fabric_path.append( + self.get_fabric_path_info( + managed_object + ) + ) + + self.log.apic_mo( + 'fabricPathEp.info', + self.fabric_path + ) + + return self.fabric_path + + def match_fabric_path(self, fabric_path_info, fabric_path_filter): + if fabric_path_filter is None or len(fabric_path_filter) == 0: + return True + + for aepg_rule in fabric_path_filter: + (key, value) = aepg_rule.split(':') + + if key == 'dn': + if not filter_helper.match_string(value, fabric_path_info['dn']): + return False + + return True + + def get_fabric_paths(self, fabric_path_filter=None): + all_paths = self.get_fabric_paths_info() + + fabric_paths = [] + + for fabric_path_info in all_paths: + if not self.match_fabric_path(fabric_path_info, fabric_path_filter): + continue + + fabric_paths.append(fabric_path_info) + + return fabric_paths + + def get_fabric_path_by_dn(self, fabric_path_dn): + fabric_paths = self.get_fabric_paths( + fabric_path_filter=['dn:%s' % (fabric_path_dn)] + ) + if fabric_paths is None: + return None + + if len(fabric_paths) == 1: + return fabric_paths[0] + + return None + + def get_fabric_path_ports(self, fabric_path_dn, resolve=False, phy=False): + ports = [] + + fabric_path = self.get_fabric_path_by_dn(fabric_path_dn) + if fabric_path is not None: + if fabric_path['resolved']: + return fabric_path['ports'] + + policy_group_nodes = self.get_policy_group_access_interface_vpc_nodes() + for policy_group in policy_group_nodes: + if policy_group['name'] == fabric_path['policy_group_name']: + if resolve: + for node in policy_group['nodes']: + node_ports = self.get_policy_group_access_interface_vpc_ports( + policy_group['name'], + node['id'] + ) + if node_ports is not None: + ports = ports + node_ports + + if not resolve: + ports = [] + + for node in policy_group['nodes']: + port_info = {} + port_info['node_id'] = node['id'] + port_info['ep'] = '(p) node-%s (%s)' % ( + node['id'], + policy_group['name'] + ) + ports.append(port_info) + + return ports diff --git a/lib/aci/path/main.py b/lib/aci/path/main.py new file mode 100644 index 00000000..42401232 --- /dev/null +++ b/lib/aci/path/main.py @@ -0,0 +1,8 @@ +from lib.aci.path.api import FabricPathApi +from lib.aci.path.info import FabricPathInfo + + +class FabricPath(FabricPathApi, FabricPathInfo): + def __init__(self): + FabricPathApi.__init__(self) + FabricPathInfo.__init__(self) diff --git a/lib/aci/pg/__init__.py b/lib/aci/pg/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e6603678 Binary files /dev/null and b/lib/aci/pg/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/__pycache__/main.cpython-310.pyc b/lib/aci/pg/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..33a8b3d9 Binary files /dev/null and b/lib/aci/pg/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/__pycache__/output.cpython-310.pyc b/lib/aci/pg/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..810f0bbc Binary files /dev/null and b/lib/aci/pg/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pg/access/__init__.py b/lib/aci/pg/access/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..14776de3 Binary files /dev/null and b/lib/aci/pg/access/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/__pycache__/breakout.cpython-310.pyc b/lib/aci/pg/access/__pycache__/breakout.cpython-310.pyc new file mode 100644 index 00000000..db07494a Binary files /dev/null and b/lib/aci/pg/access/__pycache__/breakout.cpython-310.pyc differ diff --git a/lib/aci/pg/access/__pycache__/leaf.cpython-310.pyc b/lib/aci/pg/access/__pycache__/leaf.cpython-310.pyc new file mode 100644 index 00000000..778d27f9 Binary files /dev/null and b/lib/aci/pg/access/__pycache__/leaf.cpython-310.pyc differ diff --git a/lib/aci/pg/access/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9b5c205c Binary files /dev/null and b/lib/aci/pg/access/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/__pycache__/output.cpython-310.pyc b/lib/aci/pg/access/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..49b82f1b Binary files /dev/null and b/lib/aci/pg/access/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pg/access/__pycache__/spine.cpython-310.pyc b/lib/aci/pg/access/__pycache__/spine.cpython-310.pyc new file mode 100644 index 00000000..b95f41ef Binary files /dev/null and b/lib/aci/pg/access/__pycache__/spine.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/__init__.py b/lib/aci/pg/access/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2f546d3f Binary files /dev/null and b/lib/aci/pg/access/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..da3d43ab Binary files /dev/null and b/lib/aci/pg/access/intf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/__pycache__/output.cpython-310.pyc b/lib/aci/pg/access/intf/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..2074c7f5 Binary files /dev/null and b/lib/aci/pg/access/intf/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/breakout/__init__.py b/lib/aci/pg/access/intf/breakout/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/breakout/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/breakout/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e9bbac3e Binary files /dev/null and b/lib/aci/pg/access/intf/breakout/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/breakout/__pycache__/api.cpython-310.pyc b/lib/aci/pg/access/intf/breakout/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..98734b75 Binary files /dev/null and b/lib/aci/pg/access/intf/breakout/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/breakout/__pycache__/info.cpython-310.pyc b/lib/aci/pg/access/intf/breakout/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e5b6130f Binary files /dev/null and b/lib/aci/pg/access/intf/breakout/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/breakout/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/breakout/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..62965d42 Binary files /dev/null and b/lib/aci/pg/access/intf/breakout/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/breakout/__pycache__/output.cpython-310.pyc b/lib/aci/pg/access/intf/breakout/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..2c3474ac Binary files /dev/null and b/lib/aci/pg/access/intf/breakout/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/breakout/api.py b/lib/aci/pg/access/intf/breakout/api.py new file mode 100644 index 00000000..e80fca1e --- /dev/null +++ b/lib/aci/pg/access/intf/breakout/api.py @@ -0,0 +1,51 @@ +class PolicyGroupAccessInterfaceBreakoutApi(): + def __init__(self): + self.policy_group_access_interface_breakout_mo = None + + def get_policy_group_access_interface_breakout_mo(self): + if self.policy_group_access_interface_breakout_mo is not None: + return self.policy_group_access_interface_breakout_mo + + # url: https:///api/node/class/infraBrkoutPortGrp.json + + cache = self.get_object_cache( + 'infraBrkoutPortGrp' + ) + if cache is not None: + self.policy_group_access_interface_breakout_mo = cache + self.log.apic_mo( + 'infraBrkoutPortGrp', + self.policy_group_access_interface_breakout_mo + ) + return self.policy_group_access_interface_breakout_mo + + managed_objects = self.get_class( + 'infraBrkoutPortGrp', + node_class=True + ) + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_breakout_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_breakout_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraBrkoutPortGrp']['attributes'] + self.policy_group_access_interface_breakout_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraBrkoutPortGrp', + self.policy_group_access_interface_breakout_mo + ) + + self.set_object_cache( + 'infraBrkoutPortGrp', + self.policy_group_access_interface_breakout_mo + ) + + return self.policy_group_access_interface_port_mo diff --git a/lib/aci/pg/access/intf/breakout/info.py b/lib/aci/pg/access/intf/breakout/info.py new file mode 100644 index 00000000..c2f2f8b3 --- /dev/null +++ b/lib/aci/pg/access/intf/breakout/info.py @@ -0,0 +1,110 @@ +from lib import filter_helper + + +class PolicyGroupAccessInterfaceBreakoutInfo(): + def __init__(self): + self.policy_group_access_interface_breakout = None + + def get_policy_group_access_interface_breakout_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'annotation', + 'brkoutMap', + 'dn', + 'name' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info + + def get_policy_groups_access_interface_breakout_info(self): + if self.policy_group_access_interface_breakout is not None: + return self.policy_group_access_interface_breakout + + managed_objects = self.get_policy_group_access_interface_breakout_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_breakout = [] + + for managed_object in managed_objects: + policy_group_info = self.get_policy_group_access_interface_breakout_info( + managed_object + ) + self.policy_group_access_interface_breakout.append( + policy_group_info + ) + + self.policy_group_access_interface_breakout = sorted( + self.policy_group_access_interface_breakout, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'infraBrkoutPortGrp.info', + self.policy_group_access_interface_breakout + ) + + return self.policy_group_access_interface_breakout + + def match_policy_group_access_interface_breakout(self, policy_group_info, policy_group_filter): + if policy_group_filter is None or len(policy_group_filter) == 0: + return True + + for ap_rule in policy_group_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_group_info['name']): + return False + + return True + + def get_policy_groups_access_interface_breakout(self, policy_group_filter=None): + all_policy_groups = self.get_policy_groups_access_interface_breakout_info() + if all_policy_groups is None: + return None + + policy_groups = [] + + for policy_group_info in all_policy_groups: + if not self.match_policy_group_access_interface_breakout(policy_group_info, policy_group_filter): + continue + + policy_groups.append( + policy_group_info + ) + + policy_groups = sorted( + policy_groups, + key=lambda i: i['name'].lower() + ) + + return policy_groups + + def get_policy_group_access_interface_breakout(self, name): + policy_group_info = self.get_policy_groups_access_interface_breakout( + policy_group_filter=['name:%s' % (name)] + ) + + if policy_group_info is None: + return None + + if len(policy_group_info) == 0: + return None + + if len(policy_group_info) > 1: + self.log.error( + 'get_policy_group_access_interface_breakout', + 'Unexpected policy group count' + ) + return None + + return policy_group_info[0] diff --git a/lib/aci/pg/access/intf/breakout/main.py b/lib/aci/pg/access/intf/breakout/main.py new file mode 100644 index 00000000..6077ca0f --- /dev/null +++ b/lib/aci/pg/access/intf/breakout/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.breakout.api import PolicyGroupAccessInterfaceBreakoutApi +from lib.aci.pg.access.intf.breakout.info import PolicyGroupAccessInterfaceBreakoutInfo + + +class PolicyGroupAccessInterfaceBreakout(PolicyGroupAccessInterfaceBreakoutApi, PolicyGroupAccessInterfaceBreakoutInfo): + def __init__(self): + PolicyGroupAccessInterfaceBreakoutApi.__init__(self) + PolicyGroupAccessInterfaceBreakoutInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/breakout/output.py b/lib/aci/pg/access/intf/breakout/output.py new file mode 100644 index 00000000..6468d8e4 --- /dev/null +++ b/lib/aci/pg/access/intf/breakout/output.py @@ -0,0 +1,23 @@ +class PolicyGroupAccessInterfaceBreakoutOutput(): + def __init__(self): + pass + + def print_policy_groups_access_interface_breakout_policies(self, info): + order = [ + 'name', + 'brkoutMap' + ] + + headers = [ + 'Name', + 'Breakout Map' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/pg/access/intf/fc/__init__.py b/lib/aci/pg/access/intf/fc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/fc/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/fc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d99aac7c Binary files /dev/null and b/lib/aci/pg/access/intf/fc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/fc/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/fc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2f00d149 Binary files /dev/null and b/lib/aci/pg/access/intf/fc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/fc/main.py b/lib/aci/pg/access/intf/fc/main.py new file mode 100644 index 00000000..05b2288a --- /dev/null +++ b/lib/aci/pg/access/intf/fc/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessInterfaceFc(): + def __init__(self): + pass \ No newline at end of file diff --git a/lib/aci/pg/access/intf/fcpc/__init__.py b/lib/aci/pg/access/intf/fcpc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/fcpc/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/fcpc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..17c1e336 Binary files /dev/null and b/lib/aci/pg/access/intf/fcpc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/fcpc/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/fcpc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..34dc27a3 Binary files /dev/null and b/lib/aci/pg/access/intf/fcpc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/fcpc/main.py b/lib/aci/pg/access/intf/fcpc/main.py new file mode 100644 index 00000000..d3d52fd7 --- /dev/null +++ b/lib/aci/pg/access/intf/fcpc/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessInterfaceFcPc(): + def __init__(self): + pass diff --git a/lib/aci/pg/access/intf/main.py b/lib/aci/pg/access/intf/main.py new file mode 100644 index 00000000..cac6726e --- /dev/null +++ b/lib/aci/pg/access/intf/main.py @@ -0,0 +1,29 @@ +from lib.aci.pg.access.intf.breakout.main import PolicyGroupAccessInterfaceBreakout +from lib.aci.pg.access.intf.fc.main import PolicyGroupAccessInterfaceFc +from lib.aci.pg.access.intf.fcpc.main import PolicyGroupAccessInterfaceFcPc +from lib.aci.pg.access.intf.override.main import PolicyGroupAccessInterfaceOverride +from lib.aci.pg.access.intf.pc.main import PolicyGroupAccessInterfacePc +from lib.aci.pg.access.intf.port.main import PolicyGroupAccessInterfacePort +from lib.aci.pg.access.intf.spine.main import PolicyGroupAccessInterfaceSpine +from lib.aci.pg.access.intf.vpc.main import PolicyGroupAccessInterfaceVpc + + +class PolicyGroupAccessInterface( + PolicyGroupAccessInterfaceBreakout, + PolicyGroupAccessInterfaceFc, + PolicyGroupAccessInterfaceFcPc, + PolicyGroupAccessInterfaceOverride, + PolicyGroupAccessInterfacePc, + PolicyGroupAccessInterfacePort, + PolicyGroupAccessInterfaceSpine, + PolicyGroupAccessInterfaceVpc + ): + def __init__(self): + PolicyGroupAccessInterfaceBreakout.__init__(self) + PolicyGroupAccessInterfaceFc.__init__(self) + PolicyGroupAccessInterfaceFcPc.__init__(self) + PolicyGroupAccessInterfaceOverride.__init__(self) + PolicyGroupAccessInterfacePc.__init__(self) + PolicyGroupAccessInterfacePort.__init__(self) + PolicyGroupAccessInterfaceSpine.__init__(self) + PolicyGroupAccessInterfaceVpc.__init__(self) diff --git a/lib/aci/pg/access/intf/output.py b/lib/aci/pg/access/intf/output.py new file mode 100644 index 00000000..1c4d2c76 --- /dev/null +++ b/lib/aci/pg/access/intf/output.py @@ -0,0 +1,14 @@ +from lib.aci.pg.access.intf.port.output import PolicyGroupAccessInterfacePortOutput +from lib.aci.pg.access.intf.vpc.output import PolicyGroupAccessInterfaceVpcOutput +from lib.aci.pg.access.intf.breakout.output import PolicyGroupAccessInterfaceBreakoutOutput + + +class PolicyGroupAccessInterfaceOutput( + PolicyGroupAccessInterfacePortOutput, + PolicyGroupAccessInterfaceVpcOutput, + PolicyGroupAccessInterfaceBreakoutOutput + ): + def __init__(self): + PolicyGroupAccessInterfacePortOutput.__init__(self) + PolicyGroupAccessInterfaceVpcOutput.__init__(self) + PolicyGroupAccessInterfaceBreakoutOutput.__init__(self) diff --git a/lib/aci/pg/access/intf/override/__init__.py b/lib/aci/pg/access/intf/override/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/override/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/override/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..6d065e04 Binary files /dev/null and b/lib/aci/pg/access/intf/override/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/override/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/override/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..04a039b2 Binary files /dev/null and b/lib/aci/pg/access/intf/override/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/override/main.py b/lib/aci/pg/access/intf/override/main.py new file mode 100644 index 00000000..e0bc11aa --- /dev/null +++ b/lib/aci/pg/access/intf/override/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessInterfaceOverride(): + def __init__(self): + pass diff --git a/lib/aci/pg/access/intf/pc/__init__.py b/lib/aci/pg/access/intf/pc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/pc/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/pc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..52e8fa76 Binary files /dev/null and b/lib/aci/pg/access/intf/pc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/pc/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/pc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0fbbb294 Binary files /dev/null and b/lib/aci/pg/access/intf/pc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/pc/main.py b/lib/aci/pg/access/intf/pc/main.py new file mode 100644 index 00000000..3b3e518b --- /dev/null +++ b/lib/aci/pg/access/intf/pc/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessInterfacePc(): + def __init__(self): + pass \ No newline at end of file diff --git a/lib/aci/pg/access/intf/port/__init__.py b/lib/aci/pg/access/intf/port/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/port/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/port/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..abc846ed Binary files /dev/null and b/lib/aci/pg/access/intf/port/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/port/__pycache__/api.cpython-310.pyc b/lib/aci/pg/access/intf/port/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..24eed46e Binary files /dev/null and b/lib/aci/pg/access/intf/port/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/port/__pycache__/info.cpython-310.pyc b/lib/aci/pg/access/intf/port/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..352e652c Binary files /dev/null and b/lib/aci/pg/access/intf/port/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/port/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/port/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..df6949b6 Binary files /dev/null and b/lib/aci/pg/access/intf/port/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/port/__pycache__/output.cpython-310.pyc b/lib/aci/pg/access/intf/port/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e37cfeef Binary files /dev/null and b/lib/aci/pg/access/intf/port/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/port/api.py b/lib/aci/pg/access/intf/port/api.py new file mode 100644 index 00000000..3f25f4f8 --- /dev/null +++ b/lib/aci/pg/access/intf/port/api.py @@ -0,0 +1,86 @@ +class PolicyGroupAccessInterfacePortApi(): + def __init__(self): + self.policy_group_access_interface_port_mo = None + self.policy_group_access_interface_port_policies = [ + 'infraRsAttEntP', + 'infraRsCdpIfPol', + 'infraRsHIfPol', + 'infraRsLinkFlapPol', + 'infraRsLldpIfPol', + 'infraRsMonIfInfraPol', + 'infraRsStpIfPol', + 'infraRsMcpIfPol', + 'infraRsStormctrlIfPol' + ] + + def get_policy_group_access_interface_port_mo(self): + if self.policy_group_access_interface_port_mo is not None: + return self.policy_group_access_interface_port_mo + + cache = self.get_object_cache( + 'infraAccPortGrp' + ) + if cache is not None: + self.policy_group_access_interface_port_mo = cache + self.log.apic_mo( + 'infraAccPortGrp', + self.policy_group_access_interface_port_mo + ) + return self.policy_group_access_interface_port_mo + + # url: https:///api/node/mo/uni/infra/funcprof.json? + # query-target=subtree&target-subtree-class=infraAccPortGrp&query-target-filter=not(wcard(infraAccPortGrp.dn,"__ui_"))&rsp-subtree=children&rsp-subtree-class=infraRsCdpIfPol,infraRsHIfPol,infraRsLinkFlapPol,infraRsLldpIfPol,infraRsMonIfInfraPol,infraRsStpIfPol,infraRsMcpIfPol,infraRsStormctrlIfPol + # &subscription=yes&order-by=infraAccPortGrp.name|asc&page=0&page-size=15 + + distinguished_name = 'uni/infra/funcprof' + query = 'query-target=subtree&target-subtree-class=infraAccPortGrp&rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=%s' % ( + ','.join(self.policy_group_access_interface_port_policies) + ) + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_port_mo', + 'API failed' + ) + return None + + self.log.apic_mo( + 'infraAccPortGrp.mo', + managed_objects + ) + + self.policy_group_access_interface_port_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAccPortGrp']['attributes'] + attributes['faultCounts'] = self.get_mo_child_attributes( + 'infraAccPortGrp', + managed_object, + 'faultCounts' + ) + for policy_name in self.policy_group_access_interface_port_policies: + attributes[policy_name] = self.get_mo_child_attributes( + 'infraAccPortGrp', + managed_object, + policy_name + ) + + self.policy_group_access_interface_port_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccPortGrp', + self.policy_group_access_interface_port_mo + ) + + self.set_object_cache( + 'infraAccPortGrp', + self.policy_group_access_interface_port_mo + ) + + return self.policy_group_access_interface_port_mo diff --git a/lib/aci/pg/access/intf/port/audit/__init__.py b/lib/aci/pg/access/intf/port/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/port/audit/api.py b/lib/aci/pg/access/intf/port/audit/api.py new file mode 100644 index 00000000..1cab7b38 --- /dev/null +++ b/lib/aci/pg/access/intf/port/audit/api.py @@ -0,0 +1,48 @@ +class PolicyGroupAccessInterfacePortAuditApi(): + def __init__(self): + self.policy_group_access_interface_port_audit_mo = None + + def get_policy_group_access_interface_port_audit_mo(self): + cache = self.get_object_cache( + 'infraAccPortGrp.audit' + ) + if cache is not None: + self.policy_group_access_interface_port_audit_mo = cache + self.log.apic_mo( + 'infraAccPortGrp.audit', + self.policy_group_access_interface_port_audit_mo + ) + return self.policy_group_access_interface_port_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'infraAccPortGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_port_audit_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_port_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.policy_group_access_interface_port_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccPortGrp.audit', + self.policy_group_access_interface_port_audit_mo + ) + + self.set_object_cache( + 'infraAccPortGrp.audit', + self.policy_group_access_interface_port_audit_mo + ) + + return self.policy_group_access_interface_port_audit_mo diff --git a/lib/aci/pg/access/intf/port/audit/info.py b/lib/aci/pg/access/intf/port/audit/info.py new file mode 100644 index 00000000..7bd7d8c2 --- /dev/null +++ b/lib/aci/pg/access/intf/port/audit/info.py @@ -0,0 +1,98 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGroupAccessInterfacePortAuditInfo(): + def __init__(self): + self.policy_group_access_interface_port_audit = None + + def get_policy_group_access_interface_port_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "affected": "uni/infra/funcprof/accportgrp-ESX-R7DC_PolGrp/rsqosDppIfPol" + info['pgName'] = None + if 'uni/infra/funcprof/accportgrp-' in info['affected']: + info['pgName'] = info['affected'].split('uni/infra/funcprof/accportgrp-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_group_access_interface_port_audit(self): + if self.policy_group_access_interface_port_audit is not None: + return self.policy_group_access_interface_port_audit + + managed_objects = self.get_policy_group_access_interface_port_audit_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_port_audit = [] + for managed_object in managed_objects: + audit_info = self.get_policy_group_access_interface_port_audit_info( + managed_object + ) + self.policy_group_access_interface_port_audit.append( + audit_info + ) + + self.log.apic_mo( + 'infraAccPortGrp.auditRecord.info', + self.policy_group_access_interface_port_audit + ) + + return self.policy_group_access_interface_port_audit + + def get_policy_group_access_interface_port_id_audit(self, pg_name, audit_filter=None): + audits = [] + + all_audits = self.get_policy_group_access_interface_port_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['pgName'] is not None: + if audit_info['pgName'] == pg_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/pg/access/intf/port/audit/main.py b/lib/aci/pg/access/intf/port/audit/main.py new file mode 100644 index 00000000..f8d1dbf2 --- /dev/null +++ b/lib/aci/pg/access/intf/port/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.port.audit.api import PolicyGroupAccessInterfacePortAuditApi +from lib.aci.pg.access.intf.port.audit.info import PolicyGroupAccessInterfacePortAuditInfo + + +class PolicyGroupAccessInterfacePortAudit(PolicyGroupAccessInterfacePortAuditApi, PolicyGroupAccessInterfacePortAuditInfo): + def __init__(self): + PolicyGroupAccessInterfacePortAuditApi.__init__(self) + PolicyGroupAccessInterfacePortAuditInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/port/event/__init__.py b/lib/aci/pg/access/intf/port/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/port/event/api.py b/lib/aci/pg/access/intf/port/event/api.py new file mode 100644 index 00000000..3955d2f5 --- /dev/null +++ b/lib/aci/pg/access/intf/port/event/api.py @@ -0,0 +1,51 @@ +class PolicyGroupAccessInterfacePortEventApi(): + def __init__(self): + self.policy_group_access_interface_port_event_mo = None + + def get_policy_group_access_interface_port_event_mo(self): + if self.policy_group_access_interface_port_event_mo is not None: + return self.policy_group_access_interface_port_event_mo + + cache = self.get_object_cache( + 'infraAccPortGrp.eventLog' + ) + if cache is not None: + self.policy_group_access_interface_port_event_mo = cache + self.log.apic_mo( + 'infraAccPortGrp.eventLog', + self.policy_group_access_interface_port_event_mo + ) + return self.policy_group_access_interface_port_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'infraAccPortGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_port_event_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_port_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.policy_group_access_interface_port_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccPortGrp.eventLog', + self.policy_group_access_interface_port_event_mo + ) + + self.set_object_cache( + 'infraAccPortGrp.eventLog', + self.policy_group_access_interface_port_event_mo + ) + + return self.policy_group_access_interface_port_event_mo diff --git a/lib/aci/pg/access/intf/port/event/info.py b/lib/aci/pg/access/intf/port/event/info.py new file mode 100644 index 00000000..0bef0780 --- /dev/null +++ b/lib/aci/pg/access/intf/port/event/info.py @@ -0,0 +1,107 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGroupAccessInterfacePortEventInfo(): + def __init__(self): + self.policy_group_access_interface_port_event = None + + def get_policy_group_access_interface_port_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "affected": "uni/infra/funcprof/accportgrp-ESX-R7DC_PolGrp/rsqosDppIfPol" + info['pgName'] = None + if 'uni/infra/funcprof/accportgrp-' in info['affected']: + info['pgName'] = info['affected'].split('uni/infra/funcprof/accportgrp-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/infra/funcprof/accportgrp-' in info['dn']: + info['pgName'] = info['dn'].split('uni/infra/funcprof/accportgrp-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_group_access_interface_port_event(self, deduplicate=True): + if self.policy_group_access_interface_port_event is not None: + return self.policy_group_access_interface_port_event + + managed_objects = self.get_policy_group_access_interface_port_event_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_port_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_policy_group_access_interface_port_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.policy_group_access_interface_port_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'infraAccPortGrp.eventLog.info', + self.policy_group_access_interface_port_event + ) + + return self.policy_group_access_interface_port_event + + def get_policy_group_access_interface_port_id_event(self, pg_name, event_filter=None): + events = [] + + all_events = self.get_policy_group_access_interface_port_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['pgName'] is not None: + if event_info['pgName'] == pg_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/pg/access/intf/port/event/main.py b/lib/aci/pg/access/intf/port/event/main.py new file mode 100644 index 00000000..6d708f1a --- /dev/null +++ b/lib/aci/pg/access/intf/port/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.port.event.api import PolicyGroupAccessInterfacePortEventApi +from lib.aci.pg.access.intf.port.event.info import PolicyGroupAccessInterfacePortEventInfo + + +class PolicyGroupAccessInterfacePortEvent(PolicyGroupAccessInterfacePortEventApi, PolicyGroupAccessInterfacePortEventInfo): + def __init__(self): + PolicyGroupAccessInterfacePortEventApi.__init__(self) + PolicyGroupAccessInterfacePortEventInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/port/fault/__init__.py b/lib/aci/pg/access/intf/port/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/port/fault/api.py b/lib/aci/pg/access/intf/port/fault/api.py new file mode 100644 index 00000000..89747e6e --- /dev/null +++ b/lib/aci/pg/access/intf/port/fault/api.py @@ -0,0 +1,112 @@ +class PolicyGroupAccessInterfacePortFaultApi(): + def __init__(self): + self.policy_group_access_interface_port_fault_mo = None + self.policy_group_access_interface_port_fault_record_mo = None + + def get_policy_group_access_interface_port_fault_mo(self): + cache = self.get_object_cache( + 'infraAccPortGrp.fault' + ) + if cache is not None: + self.policy_group_access_interface_port_fault_mo = cache + self.log.apic_mo( + 'infraAccPortGrp.fault', + self.policy_group_access_interface_port_fault_mo + ) + return self.policy_group_access_interface_port_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'infraAccPortGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_port_fault_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_port_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.policy_group_access_interface_port_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccPortGrp.fault', + self.policy_group_access_interface_port_fault_mo + ) + + self.set_object_cache( + 'infraAccPortGrp.fault', + self.policy_group_access_interface_port_fault_mo + ) + + return self.policy_group_access_interface_port_fault_mo + + def get_policy_group_access_interface_port_fault_record_mo(self): + cache = self.get_object_cache( + 'infraAccPortGrp.faultRecord' + ) + if cache is not None: + self.policy_group_access_interface_port_fault_record_mo = cache + self.log.apic_mo( + 'infraAccPortGrp.faultRecord', + self.policy_group_access_interface_port_fault_record_mo + ) + return self.policy_group_access_interface_port_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'infraAccPortGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_port_fault_record_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_port_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.policy_group_access_interface_port_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccPortGrp.faultRecord', + self.policy_group_access_interface_port_fault_record_mo + ) + + self.set_object_cache( + 'infraAccPortGrp.faultRecord', + self.policy_group_access_interface_port_fault_record_mo + ) + + return self.policy_group_access_interface_port_fault_record_mo diff --git a/lib/aci/pg/access/intf/port/fault/info.py b/lib/aci/pg/access/intf/port/fault/info.py new file mode 100644 index 00000000..45c99e50 --- /dev/null +++ b/lib/aci/pg/access/intf/port/fault/info.py @@ -0,0 +1,138 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGroupAccessInterfacePortFaultInfo(): + def __init__(self): + self.policy_group_access_interface_port_fault = None + self.policy_group_access_interface_port_fault_record = None + + def get_policy_group_access_interface_port_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "affected": "uni/infra/funcprof/accportgrp-ESX-R7DC_PolGrp/rsqosDppIfPol" + info['pgName'] = None + + if not managed_object['delegated']: + if 'uni/infra/funcprof/accportgrp-' in info['affected']: + info['pgName'] = info['affected'].split('uni/infra/funcprof/accportgrp-')[1].split('/')[0] + + if info['pgName'] is None: + if 'uni/infra/funcprof/accportgrp-' in info['dn']: + info['pgName'] = info['dn'].split('uni/infra/funcprof/accportgrp-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_group_access_interface_port_fault(self): + if self.policy_group_access_interface_port_fault is not None: + return self.policy_group_access_interface_port_fault + + managed_objects = self.get_policy_group_access_interface_port_fault_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_port_fault = [] + for managed_object in managed_objects: + fault_info = self.get_policy_group_access_interface_port_fault_info( + managed_object + ) + self.policy_group_access_interface_port_fault.append( + fault_info + ) + + self.log.apic_mo( + 'infraAccPortGrp.fault.info', + self.policy_group_access_interface_port_fault + ) + + return self.policy_group_access_interface_port_fault + + def get_policy_group_access_interface_port_fault_record(self, deduplicate=True): + if self.policy_group_access_interface_port_fault_record is not None: + return self.policy_group_access_interface_port_fault_record + + managed_objects = self.get_policy_group_access_interface_port_fault_record_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_port_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_policy_group_access_interface_port_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.policy_group_access_interface_port_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'infraAccPortGrp.faultRecord.info', + self.policy_group_access_interface_port_fault_record + ) + + return self.policy_group_access_interface_port_fault_record + + def get_policy_group_access_interface_port_id_fault(self, pg_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_policy_group_access_interface_port_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_policy_group_access_interface_port_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['pgName'] is not None: + if fault_info['pgName'] == pg_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/pg/access/intf/port/fault/main.py b/lib/aci/pg/access/intf/port/fault/main.py new file mode 100644 index 00000000..a4c04b22 --- /dev/null +++ b/lib/aci/pg/access/intf/port/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.port.fault.api import PolicyGroupAccessInterfacePortFaultApi +from lib.aci.pg.access.intf.port.fault.info import PolicyGroupAccessInterfacePortFaultInfo + + +class PolicyGroupAccessInterfacePortFault(PolicyGroupAccessInterfacePortFaultApi, PolicyGroupAccessInterfacePortFaultInfo): + def __init__(self): + PolicyGroupAccessInterfacePortFaultApi.__init__(self) + PolicyGroupAccessInterfacePortFaultInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/port/info.py b/lib/aci/pg/access/intf/port/info.py new file mode 100644 index 00000000..12fffe51 --- /dev/null +++ b/lib/aci/pg/access/intf/port/info.py @@ -0,0 +1,248 @@ +from lib import filter_helper + + +class PolicyGroupAccessInterfacePortInfo(): + def __init__(self): + self.policy_group_access_interface_port = None + + def get_policy_group_access_interface_port_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'annotation', + 'descr', + 'dn', + 'name' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + for policy_name in self.policy_group_access_interface_port_policies: + info[policy_name] = self.get_policy_interface_reference_attributes( + managed_object[policy_name] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_policy_groups_access_interface_port_info(self): + if self.policy_group_access_interface_port is not None: + return self.policy_group_access_interface_port + + managed_objects = self.get_policy_group_access_interface_port_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_port = [] + + for managed_object in managed_objects: + policy_group_info = self.get_policy_group_access_interface_port_info( + managed_object + ) + self.policy_group_access_interface_port.append( + policy_group_info + ) + + self.policy_group_access_interface_port = sorted( + self.policy_group_access_interface_port, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'infraAccPortGrp.info', + self.policy_group_access_interface_port + ) + + return self.policy_group_access_interface_port + + def match_policy_group_access_interface_port(self, policy_group_info, policy_group_filter): + if policy_group_filter is None or len(policy_group_filter) == 0: + return True + + for ap_rule in policy_group_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_group_info['name']): + return False + + if key == 'aaep': + if not filter_helper.match_string(value, policy_group_info['infraRsAttEntP']['name']): + return False + + if key == 'policy': + found = False + for policy_name in self.policy_group_access_interface_port_policies: + if filter_helper.match_string(value, policy_group_info[policy_name]['name']): + found = True + break + + if not found: + return False + + if key == 'fault': + if value == 'any': + if not policy_group_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_policy_group_access_interface_port', + 'Unsupported fault filtering value: %s' % (value) + ) + + if key not in ['name', 'aaep', 'fault', 'policy']: + found = False + for policy_name in self.policy_group_access_interface_port_policies: + if key == policy_name: + if filter_helper.match_string(value, policy_group_info[policy_name]['name']): + found = True + break + + if not found: + return False + + return True + + def get_policy_groups_access_interface_port( + self, + policy_group_filter=None, + aaep_info=False, + node_info=False, + vlan_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_policy_groups = self.get_policy_groups_access_interface_port_info() + if all_policy_groups is None: + return None + + policy_groups = [] + + for policy_group_info in all_policy_groups: + if not self.match_policy_group_access_interface_port(policy_group_info, policy_group_filter): + continue + + if aaep_info: + policy_group_info['aaep'] = None + aaep = self.get_policy_global_aae( + policy_global_aae_filter=['name:%s' % (policy_group_info['infraRsAttEntP']['name'])], + domain_info=True + ) + if aaep is not None: + if len(aaep) == 1: + policy_group_info['aaep'] = aaep[0] + + if node_info: + policy_group_node_info = self.get_policy_group_access_interface_port_node( + policy_group_info['name'] + ) + policy_group_info['node'] = None + policy_group_info['interface'] = None + if policy_group_node_info is not None: + policy_group_info['node'] = policy_group_node_info['node'] + policy_group_info['interface'] = policy_group_node_info['interface'] + + if vlan_info: + if policy_group_info['interface'] is not None: + for interface in policy_group_info['interface']: + interface['vlan'] = [] + interface['operSt'] = '--' + interface['operMode'] = '--' + + if interface['intf_type'] == 'l1PhysIf': + interface_info = self.get_interface_phy( + interface['pod_id'], + interface['node_id'], + interface['intf_name'], + epg_stats_info=True + ) + if interface_info is not None: + interface['operSt'] = interface_info['stats']['operSt'] + interface['operMode'] = interface_info['stats']['operMode'] + for intf_epg_stats in interface_info['epg_stats']: + if intf_epg_stats['vlan'] is not None: + if intf_epg_stats['vlan']['evlan'] not in interface['vlan']: + interface['vlan'].append( + intf_epg_stats['vlan']['evlan'] + ) + + interface['vlan'] = sorted( + interface['vlan'] + ) + interface['vlans'] = ','.join( + interface['vlan'] + ) + + if fault_info: + policy_group_info['faultInst'] = self.get_policy_group_access_interface_port_id_fault( + policy_group_info['name'], + 'faultInst' + ) + + if hfault_info: + policy_group_info['faultRecord'] = self.get_policy_group_access_interface_port_id_fault( + policy_group_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + policy_group_info['eventLog'] = self.get_policy_group_access_interface_port_id_event( + policy_group_info['name'], + event_filter=event_filter + ) + + if audit_info: + policy_group_info['auditLog'] = self.get_policy_group_access_interface_port_id_audit( + policy_group_info['name'], + audit_filter=audit_filter + ) + + policy_groups.append( + policy_group_info + ) + + policy_groups = sorted( + policy_groups, + key=lambda i: i['name'].lower() + ) + + return policy_groups + + def get_policy_group_access_interface_port(self, name): + policy_group_info = self.get_policy_groups_access_interface_port( + policy_group_filter=['name:%s' % (name)] + ) + + if policy_group_info is None: + return None + + if len(policy_group_info) == 0: + return None + + if len(policy_group_info) > 1: + self.log.error( + 'get_policy_group_access_interface_port', + 'Unexpected policy group count' + ) + return None + + return policy_group_info[0] diff --git a/lib/aci/pg/access/intf/port/main.py b/lib/aci/pg/access/intf/port/main.py new file mode 100644 index 00000000..7947dd72 --- /dev/null +++ b/lib/aci/pg/access/intf/port/main.py @@ -0,0 +1,23 @@ +from lib.aci.pg.access.intf.port.api import PolicyGroupAccessInterfacePortApi +from lib.aci.pg.access.intf.port.info import PolicyGroupAccessInterfacePortInfo +from lib.aci.pg.access.intf.port.audit.main import PolicyGroupAccessInterfacePortAudit +from lib.aci.pg.access.intf.port.event.main import PolicyGroupAccessInterfacePortEvent +from lib.aci.pg.access.intf.port.fault.main import PolicyGroupAccessInterfacePortFault +from lib.aci.pg.access.intf.port.node.main import PolicyGroupAccessInterfacePortNode + + +class PolicyGroupAccessInterfacePort( + PolicyGroupAccessInterfacePortApi, + PolicyGroupAccessInterfacePortInfo, + PolicyGroupAccessInterfacePortAudit, + PolicyGroupAccessInterfacePortEvent, + PolicyGroupAccessInterfacePortFault, + PolicyGroupAccessInterfacePortNode + ): + def __init__(self): + PolicyGroupAccessInterfacePortApi.__init__(self) + PolicyGroupAccessInterfacePortInfo.__init__(self) + PolicyGroupAccessInterfacePortAudit.__init__(self) + PolicyGroupAccessInterfacePortEvent.__init__(self) + PolicyGroupAccessInterfacePortFault.__init__(self) + PolicyGroupAccessInterfacePortNode.__init__(self) diff --git a/lib/aci/pg/access/intf/port/node/__init__.py b/lib/aci/pg/access/intf/port/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/port/node/api.py b/lib/aci/pg/access/intf/port/node/api.py new file mode 100644 index 00000000..c37d93b9 --- /dev/null +++ b/lib/aci/pg/access/intf/port/node/api.py @@ -0,0 +1,61 @@ +class PolicyGroupAccessInterfacePortNodeApi(): + def __init__(self): + self.policy_group_access_interface_port_node_mo = {} + + def get_policy_group_access_interface_port_node_mo(self, policy_name): + if policy_name in self.policy_group_access_interface_port_node_mo: + return self.policy_group_access_interface_port_node_mo[policy_name] + + key = policy_name + cache = self.get_object_cache( + 'infraAccPortGrp.%s' % (key) + ) + if cache is not None: + self.policy_group_access_interface_port_node_mo[key] = cache + self.log.apic_mo( + 'infraAccPortGrp.%s' % (key), + self.policy_group_access_interface_port_node_mo[key] + ) + return self.policy_group_access_interface_port_node_mo[key] + + distinguished_name = 'uni/infra/funcprof/accportgrp-%s' % (policy_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=AccBaseGrpToEthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_port_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_policy_group_access_interface_port_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAccPortGrp']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'infraAccPortGrp', + managed_object + ) + self.policy_group_access_interface_port_node_mo[key] = attributes + + self.log.apic_mo( + 'infraAccPortGrp.%s' % (key), + self.policy_group_access_interface_port_node_mo[key] + ) + + self.set_object_cache( + 'infraAccPortGrp.%s' % (key), + self.policy_group_access_interface_port_node_mo[key] + ) + + return self.policy_group_access_interface_port_node_mo[key] diff --git a/lib/aci/pg/access/intf/port/node/info.py b/lib/aci/pg/access/intf/port/node/info.py new file mode 100644 index 00000000..41aff7c5 --- /dev/null +++ b/lib/aci/pg/access/intf/port/node/info.py @@ -0,0 +1,80 @@ +class PolicyGroupAccessInterfacePortNodeInfo(): + def __init__(self): + self.policy_group_access_interface_port_node = {} + + def get_policy_group_access_interface_port_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/phys-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_policy_group_access_interface_port_node(self, policy_name): + if policy_name in self.policy_group_access_interface_port_node: + return self.policy_group_access_interface_port_node[policy_name] + + # one object or None value is expected + domain_nodes_mo = self.get_policy_group_access_interface_port_node_mo(policy_name) + if domain_nodes_mo is None: + return None + + self.policy_group_access_interface_port_node[policy_name] = self.get_policy_group_access_interface_port_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'infraAccPortGrp.%s.info' % (policy_name), + self.policy_group_access_interface_port_node[policy_name] + ) + + return self.policy_group_access_interface_port_node[policy_name] diff --git a/lib/aci/pg/access/intf/port/node/main.py b/lib/aci/pg/access/intf/port/node/main.py new file mode 100644 index 00000000..f0bc4aed --- /dev/null +++ b/lib/aci/pg/access/intf/port/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.port.node.api import PolicyGroupAccessInterfacePortNodeApi +from lib.aci.pg.access.intf.port.node.info import PolicyGroupAccessInterfacePortNodeInfo + + +class PolicyGroupAccessInterfacePortNode(PolicyGroupAccessInterfacePortNodeApi, PolicyGroupAccessInterfacePortNodeInfo): + def __init__(self): + PolicyGroupAccessInterfacePortNodeApi.__init__(self) + PolicyGroupAccessInterfacePortNodeInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/port/output.py b/lib/aci/pg/access/intf/port/output.py new file mode 100644 index 00000000..a9d10eb4 --- /dev/null +++ b/lib/aci/pg/access/intf/port/output.py @@ -0,0 +1,460 @@ +class PolicyGroupAccessInterfacePortOutput(): + def __init__(self): + pass + + def print_policy_groups_access_interface_port(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'infraRsAttEntP.name', + 'infraRsHIfPol.name', + 'infraRsLinkFlapPol.name', + 'infraRsCdpIfPol.name', + 'infraRsMcpIfPol.name', + 'infraRsLldpIfPol.name', + 'infraRsStpIfPol.name', + 'infraRsStormctrlIfPol.name' + ] + + headers = [ + 'Faults', + 'Name', + 'AAEP', + 'Link Level', + 'Link Flap', + 'CDP', + 'MCP', + 'LLDP', + 'STP', + 'Storm Control' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_port_aaep(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface Port - AAEP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + order = [ + 'name', + 'infraRsAttEntP.name', + 'infraRsDomP.domainType', + 'infraRsDomP.domainName', + 'vlanPool', + 'vlanBlock' + ] + + headers = [ + 'Name', + 'AAEP', + 'Domain Type', + 'Domain Name', + 'VLAN Pool', + 'VLAN Range' + ] + + for item in info: + item['infraRsDomP'] = item['aaep']['infraRsDomP'] + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['infraRsDomP', 'vlanPool', 'vlanBlock'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_port_node(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface Port - Deployed Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + order = [ + 'name', + 'infraRsAttEntP.name', + 'vlanPool', + 'vlanBlock', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'PG Name', + 'AAEP', + 'VLAN Pool', + 'VLAN Range', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlanPool', 'vlanBlock', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_port_interface(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface Port - Deployed Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + order = [ + 'name', + 'infraRsAttEntP.name', + 'vlanPool', + 'vlanBlock', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'PG Name', + 'AAEP', + 'VLAN Pool', + 'VLAN Range', + 'Node', + 'Intf Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlanPool', 'vlanBlock', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_port_vlan(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface Port - Deployed Interfaces with State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + order = [ + 'name', + 'infraRsAttEntP.name', + 'vlanPool', + 'vlanBlock', + 'interface.node_name', + 'interface.intf_name', + 'interface.operSt', + 'interface.operMode', + 'interface.vlans' + ] + + headers = [ + 'PG Name', + 'AAEP', + 'VLAN Pool', + 'VLAN Range', + 'Node', + 'Intf Name', + 'State', + 'Mode', + 'VLANs' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlanPool', 'vlanBlock', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_port_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Policy Group - Access Interface Port - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Policy Group - Access Interface Port - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_port_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface Port - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_port_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Policy Group - Access Interface Port - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Policy Group - Access Interface Port - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_port_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Policy Group - Access Interface Port - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Policy Group - Access Interface Port - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/pg/access/intf/spine/__init__.py b/lib/aci/pg/access/intf/spine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/spine/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/spine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1ef2fdf6 Binary files /dev/null and b/lib/aci/pg/access/intf/spine/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/spine/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/spine/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7018dc90 Binary files /dev/null and b/lib/aci/pg/access/intf/spine/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/spine/main.py b/lib/aci/pg/access/intf/spine/main.py new file mode 100644 index 00000000..1f833f37 --- /dev/null +++ b/lib/aci/pg/access/intf/spine/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessInterfaceSpine(): + def __init__(self): + pass \ No newline at end of file diff --git a/lib/aci/pg/access/intf/vpc/__init__.py b/lib/aci/pg/access/intf/vpc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8f61950b Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/api.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..ef92b6f2 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/info.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..3337d184 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..765ccfdc Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/node.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/node.cpython-310.pyc new file mode 100644 index 00000000..e28fcb45 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/node.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/output.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..be469cca Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/policy.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/policy.cpython-310.pyc new file mode 100644 index 00000000..8cc97567 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/policy.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/__pycache__/port.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/__pycache__/port.cpython-310.pyc new file mode 100644 index 00000000..9cf81e51 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/__pycache__/port.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/api.py b/lib/aci/pg/access/intf/vpc/api.py new file mode 100644 index 00000000..7fc9c25c --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/api.py @@ -0,0 +1,91 @@ +class PolicyGroupAccessInterfaceVpcApi(): + def __init__(self): + self.policy_group_access_interface_vpc_mo = None + self.policy_group_access_interface_vpc_policies = [ + 'infraRsCdpIfPol', + 'infraRsMcpIfPol', + 'infraRsHIfPol', + 'infraRsLinkFlapPol', + 'infraRsLldpIfPol', + 'infraRsLacpPol', + 'infraRsMonIfInfraPol', + 'infraAccBndlSubgrp', + 'infraRsStpIfPol', + 'infraRsAttEntP', + 'infraRsSpanVSrcGrp', + 'infraRsSpanVDestGrp', + 'infraRsL2IfPol', + 'infraRsStormctrlIfPol', + 'infraRsQosEgressDppIfPol', + 'infraRsQosIngressDppIfPol', + 'infraRsQosSdIfPol', + 'infraRsQosPfcIfPol', + 'infraRsQosEgressDppIfPol', + 'infraRsL2PortSecurityPol', + 'infraRsFcIfPol', + 'infraRsMacsecIfPol' + ] + + def get_policy_group_access_interface_vpc_mo(self): + if self.policy_group_access_interface_vpc_mo is not None: + return self.policy_group_access_interface_vpc_mo + + cache = self.get_object_cache( + 'infraAccBndlGrp' + ) + if cache is not None: + self.policy_group_access_interface_vpc_mo = cache + self.log.apic_mo( + 'infraAccBndlGrp', + self.policy_group_access_interface_vpc_mo + ) + return self.policy_group_access_interface_vpc_mo + + distinguished_name = 'uni/infra/funcprof' + query = 'query-target=subtree&target-subtree-class=%s&rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=%s' % ( + 'infraAccBndlGrp', + ','.join(self.policy_group_access_interface_vpc_policies) + ) + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_vpc_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAccBndlGrp']['attributes'] + attributes['faultCounts'] = self.get_mo_child_attributes( + 'infraAccBndlGrp', + managed_object, + 'faultCounts' + ) + for policy_name in self.policy_group_access_interface_vpc_policies: + attributes[policy_name] = self.get_mo_child_attributes( + 'infraAccBndlGrp', + managed_object, + policy_name + ) + + self.policy_group_access_interface_vpc_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccBndlGrp', + self.policy_group_access_interface_vpc_mo + ) + + self.set_object_cache( + 'infraAccBndlGrp', + self.policy_group_access_interface_vpc_mo + ) + + return self.policy_group_access_interface_vpc_mo diff --git a/lib/aci/pg/access/intf/vpc/audit/__init__.py b/lib/aci/pg/access/intf/vpc/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/audit/api.py b/lib/aci/pg/access/intf/vpc/audit/api.py new file mode 100644 index 00000000..2ed29a10 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/audit/api.py @@ -0,0 +1,48 @@ +class PolicyGroupAccessInterfaceVpcAuditApi(): + def __init__(self): + self.policy_group_access_interface_vpc_audit_mo = None + + def get_policy_group_access_interface_vpc_audit_mo(self): + cache = self.get_object_cache( + 'infraAccBndlGrp.audit' + ) + if cache is not None: + self.policy_group_access_interface_vpc_audit_mo = cache + self.log.apic_mo( + 'infraAccBndlGrp.audit', + self.policy_group_access_interface_vpc_audit_mo + ) + return self.policy_group_access_interface_vpc_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'infraAccBndlGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_audit_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_vpc_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.policy_group_access_interface_vpc_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccBndlGrp.audit', + self.policy_group_access_interface_vpc_audit_mo + ) + + self.set_object_cache( + 'infraAccBndlGrp.audit', + self.policy_group_access_interface_vpc_audit_mo + ) + + return self.policy_group_access_interface_vpc_audit_mo diff --git a/lib/aci/pg/access/intf/vpc/audit/info.py b/lib/aci/pg/access/intf/vpc/audit/info.py new file mode 100644 index 00000000..80834f35 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/audit/info.py @@ -0,0 +1,98 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGroupAccessInterfaceVpcAuditInfo(): + def __init__(self): + self.policy_group_access_interface_vpc_audit = None + + def get_policy_group_access_interface_vpc_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "affected": "uni/infra/funcprof/accbundle-ESX-R7DC_PolGrp/rsqosDppIfPol" + info['pgName'] = None + if 'uni/infra/funcprof/accbundle-' in info['affected']: + info['pgName'] = info['affected'].split('uni/infra/funcprof/accbundle-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_group_access_interface_vpc_audit(self): + if self.policy_group_access_interface_vpc_audit is not None: + return self.policy_group_access_interface_vpc_audit + + managed_objects = self.get_policy_group_access_interface_vpc_audit_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc_audit = [] + for managed_object in managed_objects: + audit_info = self.get_policy_group_access_interface_vpc_audit_info( + managed_object + ) + self.policy_group_access_interface_vpc_audit.append( + audit_info + ) + + self.log.apic_mo( + 'infraAccBndlGrp.auditRecord.info', + self.policy_group_access_interface_vpc_audit + ) + + return self.policy_group_access_interface_vpc_audit + + def get_policy_group_access_interface_vpc_id_audit(self, pg_name, audit_filter=None): + audits = [] + + all_audits = self.get_policy_group_access_interface_vpc_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['pgName'] is not None: + if audit_info['pgName'] == pg_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/pg/access/intf/vpc/audit/main.py b/lib/aci/pg/access/intf/vpc/audit/main.py new file mode 100644 index 00000000..a2d2a4c0 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.vpc.audit.api import PolicyGroupAccessInterfaceVpcAuditApi +from lib.aci.pg.access.intf.vpc.audit.info import PolicyGroupAccessInterfaceVpcAuditInfo + + +class PolicyGroupAccessInterfaceVpcAudit(PolicyGroupAccessInterfaceVpcAuditApi, PolicyGroupAccessInterfaceVpcAuditInfo): + def __init__(self): + PolicyGroupAccessInterfaceVpcAuditApi.__init__(self) + PolicyGroupAccessInterfaceVpcAuditInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/vpc/event/__init__.py b/lib/aci/pg/access/intf/vpc/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/event/api.py b/lib/aci/pg/access/intf/vpc/event/api.py new file mode 100644 index 00000000..e339e7a5 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/event/api.py @@ -0,0 +1,51 @@ +class PolicyGroupAccessInterfaceVpcEventApi(): + def __init__(self): + self.policy_group_access_interface_vpc_event_mo = None + + def get_policy_group_access_interface_vpc_event_mo(self): + if self.policy_group_access_interface_vpc_event_mo is not None: + return self.policy_group_access_interface_vpc_event_mo + + cache = self.get_object_cache( + 'infraAccBndlGrp.eventLog' + ) + if cache is not None: + self.policy_group_access_interface_vpc_event_mo = cache + self.log.apic_mo( + 'infraAccBndlGrp.eventLog', + self.policy_group_access_interface_vpc_event_mo + ) + return self.policy_group_access_interface_vpc_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'infraAccBndlGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_event_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_vpc_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.policy_group_access_interface_vpc_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccBndlGrp.eventLog', + self.policy_group_access_interface_vpc_event_mo + ) + + self.set_object_cache( + 'infraAccBndlGrp.eventLog', + self.policy_group_access_interface_vpc_event_mo + ) + + return self.policy_group_access_interface_vpc_event_mo diff --git a/lib/aci/pg/access/intf/vpc/event/info.py b/lib/aci/pg/access/intf/vpc/event/info.py new file mode 100644 index 00000000..5b61dce9 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/event/info.py @@ -0,0 +1,107 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGroupAccessInterfaceVpcEventInfo(): + def __init__(self): + self.policy_group_access_interface_vpc_event = None + + def get_policy_group_access_interface_vpc_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "affected": "uni/infra/funcprof/accbundle-ESX-R7DC_PolGrp/rsqosDppIfPol" + info['pgName'] = None + if 'uni/infra/funcprof/accbundle-' in info['affected']: + info['pgName'] = info['affected'].split('uni/infra/funcprof/accbundle-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/infra/funcprof/accbundle-' in info['dn']: + info['pgName'] = info['dn'].split('uni/infra/funcprof/accbundle-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_group_access_interface_vpc_event(self, deduplicate=True): + if self.policy_group_access_interface_vpc_event is not None: + return self.policy_group_access_interface_vpc_event + + managed_objects = self.get_policy_group_access_interface_vpc_event_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_policy_group_access_interface_vpc_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.policy_group_access_interface_vpc_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'infraAccBndlGrp.eventLog.info', + self.policy_group_access_interface_vpc_event + ) + + return self.policy_group_access_interface_vpc_event + + def get_policy_group_access_interface_vpc_id_event(self, pg_name, event_filter=None): + events = [] + + all_events = self.get_policy_group_access_interface_vpc_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['pgName'] is not None: + if event_info['pgName'] == pg_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/pg/access/intf/vpc/event/main.py b/lib/aci/pg/access/intf/vpc/event/main.py new file mode 100644 index 00000000..e59adc96 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.vpc.event.api import PolicyGroupAccessInterfaceVpcEventApi +from lib.aci.pg.access.intf.vpc.event.info import PolicyGroupAccessInterfaceVpcEventInfo + + +class PolicyGroupAccessInterfaceVpcEvent(PolicyGroupAccessInterfaceVpcEventApi, PolicyGroupAccessInterfaceVpcEventInfo): + def __init__(self): + PolicyGroupAccessInterfaceVpcEventApi.__init__(self) + PolicyGroupAccessInterfaceVpcEventInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/vpc/fault/__init__.py b/lib/aci/pg/access/intf/vpc/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/fault/api.py b/lib/aci/pg/access/intf/vpc/fault/api.py new file mode 100644 index 00000000..05ee76d6 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/fault/api.py @@ -0,0 +1,112 @@ +class PolicyGroupAccessInterfaceVpcFaultApi(): + def __init__(self): + self.policy_group_access_interface_vpc_fault_mo = None + self.policy_group_access_interface_vpc_fault_record_mo = None + + def get_policy_group_access_interface_vpc_fault_mo(self): + cache = self.get_object_cache( + 'infraAccBndlGrp.fault' + ) + if cache is not None: + self.policy_group_access_interface_vpc_fault_mo = cache + self.log.apic_mo( + 'infraAccBndlGrp.fault', + self.policy_group_access_interface_vpc_fault_mo + ) + return self.policy_group_access_interface_vpc_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'infraAccBndlGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_fault_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_vpc_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.policy_group_access_interface_vpc_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccBndlGrp.fault', + self.policy_group_access_interface_vpc_fault_mo + ) + + self.set_object_cache( + 'infraAccBndlGrp.fault', + self.policy_group_access_interface_vpc_fault_mo + ) + + return self.policy_group_access_interface_vpc_fault_mo + + def get_policy_group_access_interface_vpc_fault_record_mo(self): + cache = self.get_object_cache( + 'infraAccBndlGrp.faultRecord' + ) + if cache is not None: + self.policy_group_access_interface_vpc_fault_record_mo = cache + self.log.apic_mo( + 'infraAccBndlGrp.faultRecord', + self.policy_group_access_interface_vpc_fault_record_mo + ) + return self.policy_group_access_interface_vpc_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'infraAccBndlGrp', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_fault_record_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_vpc_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.policy_group_access_interface_vpc_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAccBndlGrp.faultRecord', + self.policy_group_access_interface_vpc_fault_record_mo + ) + + self.set_object_cache( + 'infraAccBndlGrp.faultRecord', + self.policy_group_access_interface_vpc_fault_record_mo + ) + + return self.policy_group_access_interface_vpc_fault_record_mo diff --git a/lib/aci/pg/access/intf/vpc/fault/info.py b/lib/aci/pg/access/intf/vpc/fault/info.py new file mode 100644 index 00000000..c9cdb0f2 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGroupAccessInterfaceVpcFaultInfo(): + def __init__(self): + self.policy_group_access_interface_vpc_fault = None + self.policy_group_access_interface_vpc_fault_record = None + + def get_policy_group_access_interface_vpc_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "affected": "uni/infra/funcprof/accbundle-ESX-R7DC_PolGrp/rsqosDppIfPol" + info['pgName'] = None + if not managed_object['delegated']: + if 'uni/infra/funcprof/accbundle-' in info['affected']: + info['pgName'] = info['affected'].split('uni/infra/funcprof/accbundle-')[1].split('/')[0] + + if info['pgName'] is None: + if 'uni/infra/funcprof/accbundle-' in info['dn']: + info['pgName'] = info['dn'].split('uni/infra/funcprof/accbundle-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_group_access_interface_vpc_fault(self): + if self.policy_group_access_interface_vpc_fault is not None: + return self.policy_group_access_interface_vpc_fault + + managed_objects = self.get_policy_group_access_interface_vpc_fault_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc_fault = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_policy_group_access_interface_vpc_fault_info( + managed_object + ) + self.policy_group_access_interface_vpc_fault.append( + fault_info + ) + + self.log.apic_mo( + 'infraAccBndlGrp.fault.info', + self.policy_group_access_interface_vpc_fault + ) + + return self.policy_group_access_interface_vpc_fault + + def get_policy_group_access_interface_vpc_fault_record(self, deduplicate=True): + if self.policy_group_access_interface_vpc_fault_record is not None: + return self.policy_group_access_interface_vpc_fault_record + + managed_objects = self.get_policy_group_access_interface_vpc_fault_record_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_policy_group_access_interface_vpc_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.policy_group_access_interface_vpc_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'infraAccBndlGrp.faultRecord.info', + self.policy_group_access_interface_vpc_fault_record + ) + + return self.policy_group_access_interface_vpc_fault_record + + def get_policy_group_access_interface_vpc_id_fault(self, pg_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_policy_group_access_interface_vpc_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_policy_group_access_interface_vpc_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['pgName'] is not None: + if fault_info['pgName'] == pg_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/pg/access/intf/vpc/fault/main.py b/lib/aci/pg/access/intf/vpc/fault/main.py new file mode 100644 index 00000000..5b4808c2 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.vpc.fault.api import PolicyGroupAccessInterfaceVpcFaultApi +from lib.aci.pg.access.intf.vpc.fault.info import PolicyGroupAccessInterfaceVpcFaultInfo + + +class PolicyGroupAccessInterfaceVpcFault(PolicyGroupAccessInterfaceVpcFaultApi, PolicyGroupAccessInterfaceVpcFaultInfo): + def __init__(self): + PolicyGroupAccessInterfaceVpcFaultApi.__init__(self) + PolicyGroupAccessInterfaceVpcFaultInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/vpc/info.py b/lib/aci/pg/access/intf/vpc/info.py new file mode 100644 index 00000000..ef78b99a --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/info.py @@ -0,0 +1,309 @@ +from lib import filter_helper + + +class PolicyGroupAccessInterfaceVpcInfo(): + def __init__(self): + self.policy_group_access_interface_vpc = None + + def get_policy_group_access_interface_vpc_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "descr": "ACI2 vEPC CL2201-2202 to ESX20 Policy Group (Created by Ansible)", + # "dn": "uni/infra/funcprof/accbundle-ESX20-CDC-22_PolGrp", + # "extMngdBy": "", + # "lagT": "node", + # "lcOwn": "local", + # "modTs": "2022-07-08T15:21:38.449+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "ESX20-CDC-22_PolGrp", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:", + info = {} + info['__Output'] = {} + + keys = [ + 'annotation', + 'descr', + 'dn', + 'lagT', + 'name' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + for policy_name in self.policy_group_access_interface_vpc_policies: + info[policy_name] = self.get_policy_interface_reference_attributes( + managed_object[policy_name] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_policy_groups_access_interface_vpc_info(self): + if self.policy_group_access_interface_vpc is not None: + return self.policy_group_access_interface_vpc + + managed_objects = self.get_policy_group_access_interface_vpc_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc = [] + + for managed_object in managed_objects: + policy_group_info = self.get_policy_group_access_interface_vpc_info( + managed_object + ) + self.policy_group_access_interface_vpc.append( + policy_group_info + ) + + self.policy_group_access_interface_vpc = sorted( + self.policy_group_access_interface_vpc, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'infraAccBndlGrp.info', + self.policy_group_access_interface_vpc + ) + + return self.policy_group_access_interface_vpc + + def match_policy_group_access_interface_vpc(self, policy_group_info, policy_group_filter): + if policy_group_filter is None or len(policy_group_filter) == 0: + return True + + for ap_rule in policy_group_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_group_info['name']): + return False + + if key == 'aaep': + if not filter_helper.match_string(value, policy_group_info['infraRsAttEntP']['name']): + return False + + if key == 'policy': + found = False + for policy_name in self.policy_group_access_interface_vpc_policies: + if filter_helper.match_string(value, policy_group_info[policy_name]['name']): + found = True + break + + if not found: + return False + + if key == 'fault': + if value == 'any': + if not policy_group_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_policy_group_access_interface_vpc', + 'Unsupported fault filtering value: %s' % (value) + ) + + if key not in ['name', 'aaep', 'fault', 'policy']: + found = False + for policy_name in self.policy_group_access_interface_vpc_policies: + if key == policy_name: + if filter_helper.match_string(value, policy_group_info[policy_name]['name']): + found = True + break + + if not found: + return False + + # if key == 'policy': + # if len(value.split(':')) > 2: + # self.log.error( + # 'match_policy_group_access_interface_vpc', + # 'Unsupported policy filter rule: %s' % (ap_rule) + # ) + # return False + + # if len(value.split(':')) == 1: + # found = False + # for policy in policy_group_info['policies']: + # if policy['name'] is not None: + # if filter_helper.match_string(value, policy['name']): + # found = True + # break + + # if not found: + # return False + + # if len(value.split(':')) == 2: + # found = False + # for policy in policy_group_info['policies']: + # if policy['name'] is not None: + # if filter_helper.match_string(value.split(':', maxsplit=1)[0], policy['type']): + # if filter_helper.match_string(value.split(':')[1], policy['name']): + # found = True + # break + + # if not found: + # return False + + return True + + def get_policy_groups_access_interface_vpc( + self, + policy_group_filter=None, + aaep_info=False, + node_info=False, + vlan_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_policy_groups = self.get_policy_groups_access_interface_vpc_info() + if all_policy_groups is None: + return None + + policy_groups = [] + + for policy_group_info in all_policy_groups: + if not self.match_policy_group_access_interface_vpc(policy_group_info, policy_group_filter): + continue + + if aaep_info: + policy_group_info['aaep'] = None + aaep = self.get_policy_global_aae( + policy_global_aae_filter=['name:%s' % (policy_group_info['infraRsAttEntP']['name'])], + domain_info=True + ) + if aaep is not None: + if len(aaep) == 1: + policy_group_info['aaep'] = aaep[0] + + if node_info: + policy_group_node_info = self.get_policy_group_access_interface_vpc_node( + policy_group_info['name'] + ) + policy_group_info['node'] = None + policy_group_info['interface'] = None + if policy_group_node_info is not None: + policy_group_info['node'] = policy_group_node_info['node'] + policy_group_info['interface'] = policy_group_node_info['interface'] + + # if node_info: + # policy_group_info['nodes'] = [] + + # vpc_nodes = self.get_policy_group_access_interface_vpc_nodes( + # policy_group_filter=['name:%s' % (policy_group_info['name'])], + # port_info=port_info + # ) + # if vpc_nodes is not None: + # if len(vpc_nodes) == 1: + # policy_group_info['nodes'] = vpc_nodes[0]['nodes'] + # if port_info: + # policy_group_info['ports'] = vpc_nodes[0]['ports'] + + if vlan_info: + if policy_group_info['interface'] is not None: + for interface in policy_group_info['interface']: + interface['vlan'] = [] + interface['operSt'] = '--' + interface['operMode'] = '--' + + if interface['intf_type'] == 'l1PhysIf': + interface_info = self.get_interface_phy( + interface['pod_id'], + interface['node_id'], + interface['intf_name'], + epg_stats_info=True + ) + if interface_info is not None: + interface['operSt'] = interface_info['stats']['operSt'] + interface['operMode'] = interface_info['stats']['operMode'] + for intf_epg_stats in interface_info['epg_stats']: + if intf_epg_stats['vlan'] is not None: + if intf_epg_stats['vlan']['evlan'] not in interface['vlan']: + interface['vlan'].append( + intf_epg_stats['vlan']['evlan'] + ) + + interface['vlan'] = sorted( + interface['vlan'] + ) + interface['vlans'] = ','.join( + interface['vlan'] + ) + + if fault_info: + policy_group_info['faultInst'] = self.get_policy_group_access_interface_vpc_id_fault( + policy_group_info['name'], + 'faultInst' + ) + + if hfault_info: + policy_group_info['faultRecord'] = self.get_policy_group_access_interface_vpc_id_fault( + policy_group_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + policy_group_info['eventLog'] = self.get_policy_group_access_interface_vpc_id_event( + policy_group_info['name'], + event_filter=event_filter + ) + + if audit_info: + policy_group_info['auditLog'] = self.get_policy_group_access_interface_vpc_id_audit( + policy_group_info['name'], + audit_filter=audit_filter + ) + + policy_groups.append( + policy_group_info + ) + + policy_groups = sorted( + policy_groups, + key=lambda i: i['name'].lower() + ) + + return policy_groups + + def get_policy_group_access_interface_vpc(self, name): + policy_group_info = self.get_policy_groups_access_interface_vpc( + policy_group_filter=['name:%s' % (name)] + ) + + if policy_group_info is None: + return None + + if len(policy_group_info) == 0: + return None + + if len(policy_group_info) > 1: + self.log.error( + 'get_policy_group_access_interface_vpc', + 'Unexpected policy group count' + ) + return None + + return policy_group_info[0] diff --git a/lib/aci/pg/access/intf/vpc/main.py b/lib/aci/pg/access/intf/vpc/main.py new file mode 100644 index 00000000..d196efee --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/main.py @@ -0,0 +1,29 @@ +from lib.aci.pg.access.intf.vpc.api import PolicyGroupAccessInterfaceVpcApi +from lib.aci.pg.access.intf.vpc.info import PolicyGroupAccessInterfaceVpcInfo +from lib.aci.pg.access.intf.vpc.audit.main import PolicyGroupAccessInterfaceVpcAudit +from lib.aci.pg.access.intf.vpc.event.main import PolicyGroupAccessInterfaceVpcEvent +from lib.aci.pg.access.intf.vpc.fault.main import PolicyGroupAccessInterfaceVpcFault +from lib.aci.pg.access.intf.vpc.node.main import PolicyGroupAccessInterfaceVpcNode +from lib.aci.pg.access.intf.vpc.nodes.main import PolicyGroupAccessInterfaceVpcNodes +from lib.aci.pg.access.intf.vpc.ports.main import PolicyGroupAccessInterfaceVpcPort + + +class PolicyGroupAccessInterfaceVpc( + PolicyGroupAccessInterfaceVpcApi, + PolicyGroupAccessInterfaceVpcInfo, + PolicyGroupAccessInterfaceVpcAudit, + PolicyGroupAccessInterfaceVpcEvent, + PolicyGroupAccessInterfaceVpcFault, + PolicyGroupAccessInterfaceVpcNode, + PolicyGroupAccessInterfaceVpcNodes, + PolicyGroupAccessInterfaceVpcPort + ): + def __init__(self): + PolicyGroupAccessInterfaceVpcApi.__init__(self) + PolicyGroupAccessInterfaceVpcInfo.__init__(self) + PolicyGroupAccessInterfaceVpcNode.__init__(self) + PolicyGroupAccessInterfaceVpcNodes.__init__(self) + PolicyGroupAccessInterfaceVpcPort.__init__(self) + PolicyGroupAccessInterfaceVpcAudit.__init__(self) + PolicyGroupAccessInterfaceVpcEvent.__init__(self) + PolicyGroupAccessInterfaceVpcFault.__init__(self) diff --git a/lib/aci/pg/access/intf/vpc/node/__init__.py b/lib/aci/pg/access/intf/vpc/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/node/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/node/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..770fe715 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/node/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/node/__pycache__/api.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/node/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..700c2f96 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/node/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/node/__pycache__/info.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/node/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..35948063 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/node/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/node/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/intf/vpc/node/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9be9ac14 Binary files /dev/null and b/lib/aci/pg/access/intf/vpc/node/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/intf/vpc/node/api.py b/lib/aci/pg/access/intf/vpc/node/api.py new file mode 100644 index 00000000..5772707f --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/node/api.py @@ -0,0 +1,61 @@ +class PolicyGroupAccessInterfaceVpcNodeApi(): + def __init__(self): + self.policy_group_access_interface_vpc_node_mo = {} + + def get_policy_group_access_interface_vpc_node_mo(self, policy_name): + if policy_name in self.policy_group_access_interface_vpc_node_mo: + return self.policy_group_access_interface_vpc_node_mo[policy_name] + + key = policy_name + cache = self.get_object_cache( + 'infraAccBndlGrp.%s' % (key) + ) + if cache is not None: + self.policy_group_access_interface_vpc_node_mo[key] = cache + self.log.apic_mo( + 'infraAccBndlGrp.%s' % (key), + self.policy_group_access_interface_vpc_node_mo[key] + ) + return self.policy_group_access_interface_vpc_node_mo[key] + + distinguished_name = 'uni/infra/funcprof/accbundle-%s' % (policy_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=AccBaseGrpToEthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_policy_group_access_interface_vpc_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAccBndlGrp']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'infraAccBndlGrp', + managed_object + ) + self.policy_group_access_interface_vpc_node_mo[key] = attributes + + self.log.apic_mo( + 'infraAccBndlGrp.%s' % (key), + self.policy_group_access_interface_vpc_node_mo[key] + ) + + self.set_object_cache( + 'infraAccBndlGrp.%s' % (key), + self.policy_group_access_interface_vpc_node_mo[key] + ) + + return self.policy_group_access_interface_vpc_node_mo[key] diff --git a/lib/aci/pg/access/intf/vpc/node/info.py b/lib/aci/pg/access/intf/vpc/node/info.py new file mode 100644 index 00000000..903aec6e --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/node/info.py @@ -0,0 +1,80 @@ +class PolicyGroupAccessInterfaceVpcNodeInfo(): + def __init__(self): + self.policy_group_access_interface_vpc_node = {} + + def get_policy_group_access_interface_vpc_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/phys-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_policy_group_access_interface_vpc_node(self, policy_name): + if policy_name in self.policy_group_access_interface_vpc_node: + return self.policy_group_access_interface_vpc_node[policy_name] + + # one object or None value is expected + domain_nodes_mo = self.get_policy_group_access_interface_vpc_node_mo(policy_name) + if domain_nodes_mo is None: + return None + + self.policy_group_access_interface_vpc_node[policy_name] = self.get_policy_group_access_interface_vpc_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'infraAccBndlGrp.%s.info' % (policy_name), + self.policy_group_access_interface_vpc_node[policy_name] + ) + + return self.policy_group_access_interface_vpc_node[policy_name] diff --git a/lib/aci/pg/access/intf/vpc/node/main.py b/lib/aci/pg/access/intf/vpc/node/main.py new file mode 100644 index 00000000..2c994ecb --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.vpc.node.api import PolicyGroupAccessInterfaceVpcNodeApi +from lib.aci.pg.access.intf.vpc.node.info import PolicyGroupAccessInterfaceVpcNodeInfo + + +class PolicyGroupAccessInterfaceVpcNode(PolicyGroupAccessInterfaceVpcNodeApi, PolicyGroupAccessInterfaceVpcNodeInfo): + def __init__(self): + PolicyGroupAccessInterfaceVpcNodeApi.__init__(self) + PolicyGroupAccessInterfaceVpcNodeInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/vpc/nodes/__init__.py b/lib/aci/pg/access/intf/vpc/nodes/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/nodes/api.py b/lib/aci/pg/access/intf/vpc/nodes/api.py new file mode 100644 index 00000000..8c7f2508 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/nodes/api.py @@ -0,0 +1,62 @@ +class PolicyGroupAccessInterfaceVpcNodesApi(): + def __init__(self): + self.policy_group_access_interface_vpc_nodes_mo = None + + def get_policy_group_access_interface_vpc_nodes_mo(self): + if self.policy_group_access_interface_vpc_nodes_mo is not None: + return self.policy_group_access_interface_vpc_nodes_mo + + cache = self.get_object_cache( + 'AccBaseGrpToEthIf' + ) + if cache is not None: + self.policy_group_access_interface_vpc_nodes_mo = cache + self.log.apic_mo( + 'AccBaseGrpToEthIf', + self.policy_group_access_interface_vpc_nodes_mo + ) + return self.policy_group_access_interface_vpc_nodes_mo + + distinguished_name = 'uni/infra/funcprof' + query = 'query-target=subtree&target-subtree-class=infraAccBndlGrp&rsp-subtree-include=full-deployment&target-path=AccBaseGrpToEthIf' + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_nodes_mo', + 'API failed' + ) + return None + + self.policy_group_access_interface_vpc_nodes_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAccBndlGrp']['attributes'] + + attributes['pconsNodeDeployCtx'] = [] + if 'children' in managed_object['infraAccBndlGrp']: + for child in managed_object['infraAccBndlGrp']['children']: + if 'pconsNodeDeployCtx' in child: + node_attributes = child['pconsNodeDeployCtx']['attributes'] + attributes['pconsNodeDeployCtx'].append( + node_attributes + ) + + self.policy_group_access_interface_vpc_nodes_mo.append( + attributes + ) + + self.log.apic_mo( + 'AccBaseGrpToEthIf', + self.policy_group_access_interface_vpc_nodes_mo + ) + + self.set_object_cache( + 'AccBaseGrpToEthIf', + self.policy_group_access_interface_vpc_nodes_mo + ) + + return self.policy_group_access_interface_vpc_nodes_mo diff --git a/lib/aci/pg/access/intf/vpc/nodes/info.py b/lib/aci/pg/access/intf/vpc/nodes/info.py new file mode 100644 index 00000000..798317aa --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/nodes/info.py @@ -0,0 +1,143 @@ +from lib import filter_helper + + +class PolicyGroupAccessInterfaceVpcNodesInfo(): + def __init__(self): + self.policy_group_access_interface_vpc_nodes = None + + def get_policy_group_access_interface_vpc_nodes_info(self, managed_object): + # { + # "annotation": "orchestrator:terraform", + # "childAction": "", + # "descr": "k8s ESX72 vPC", + # "dn": "uni/infra/funcprof/accbundle-k8s_esx72_PolGrp", + # "extMngdBy": "", + # "lagT": "node", + # "lcOwn": "local", + # "modTs": "2022-12-12T20:45:32.634+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "k8s_esx72_PolGrp", + # "nameAlias": "kali", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:", + # "pconsNodeDeployCtx": [ + # { + # "childAction": "deleteNonPresent", + # "count": "0", + # "deployStatus": "deployed", + # "lcOwn": "local", + # "modTs": "never", + # "nodeId": "2208", + # "rn": "nctx-2208", + # "status": "" + # }, + # { + # "childAction": "deleteNonPresent", + # "count": "0", + # "deployStatus": "deployed", + # "lcOwn": "local", + # "modTs": "never", + # "nodeId": "2207", + # "rn": "nctx-2207", + # "status": "" + # } + # ] + # } + info = {} + info['__Output'] = {} + + keys = [ + 'annotation', + 'descr', + 'dn', + 'lagT', + 'name' + ] + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['nodes'] = [] + if 'pconsNodeDeployCtx' in managed_object: + for node in managed_object['pconsNodeDeployCtx']: + if node['deployStatus'] == 'deployed': + if node['nodeId'] not in info['nodes']: + node_info = {} + node_info['id'] = node['nodeId'] + node_info['name'] = self.get_node_name( + node['nodeId'] + ) + info['nodes'].append( + node_info + ) + + return info + + def get_policy_groups_access_interface_vpc_nodes_info(self): + if self.policy_group_access_interface_vpc_nodes is not None: + return self.policy_group_access_interface_vpc_nodes + + managed_objects = self.get_policy_group_access_interface_vpc_nodes_mo() + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc_nodes = [] + for managed_object in managed_objects: + self.policy_group_access_interface_vpc_nodes.append( + self.get_policy_group_access_interface_vpc_nodes_info( + managed_object + ) + ) + + return self.policy_group_access_interface_vpc_nodes + + def match_policy_group_access_interface_vpc_nodes(self, policy_group_info, policy_group_filter): + if policy_group_filter is None or len(policy_group_filter) == 0: + return True + + for ap_rule in policy_group_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_group_info['name']): + return False + + return True + + def get_policy_group_access_interface_vpc_nodes(self, policy_group_filter=None, port_info=False): + all_policy_groups = self.get_policy_groups_access_interface_vpc_nodes_info() + if all_policy_groups is None: + return None + + policy_groups = [] + + for policy_group_info in all_policy_groups: + if not self.match_policy_group_access_interface_vpc_nodes(policy_group_info, policy_group_filter): + continue + + if port_info: + policy_group_info['ports'] = [] + for node_info in policy_group_info['nodes']: + ports_info = self.get_policy_group_access_interface_vpc_ports( + policy_group_info['name'], + node_info['id'] + ) + if ports_info is not None: + policy_group_info['ports'] = policy_group_info['ports'] + ports_info + + policy_groups.append( + policy_group_info + ) + + policy_groups = sorted( + policy_groups, + key=lambda i: i['name'].lower() + ) + + return policy_groups diff --git a/lib/aci/pg/access/intf/vpc/nodes/main.py b/lib/aci/pg/access/intf/vpc/nodes/main.py new file mode 100644 index 00000000..bbf31a79 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/nodes/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.vpc.nodes.api import PolicyGroupAccessInterfaceVpcNodesApi +from lib.aci.pg.access.intf.vpc.nodes.info import PolicyGroupAccessInterfaceVpcNodesInfo + + +class PolicyGroupAccessInterfaceVpcNodes(PolicyGroupAccessInterfaceVpcNodesApi, PolicyGroupAccessInterfaceVpcNodesInfo): + def __init__(self): + PolicyGroupAccessInterfaceVpcNodesApi.__init__(self) + PolicyGroupAccessInterfaceVpcNodesInfo.__init__(self) diff --git a/lib/aci/pg/access/intf/vpc/output.py b/lib/aci/pg/access/intf/vpc/output.py new file mode 100644 index 00000000..560a375b --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/output.py @@ -0,0 +1,522 @@ +class PolicyGroupAccessInterfaceVpcOutput(): + def __init__(self): + pass + + def print_policy_groups_access_interface_vpc(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'infraRsAttEntP.name', + 'infraRsCdpIfPol.name', + 'infraRsHIfPol.name', + 'infraRsLldpIfPol.name', + 'infraRsLacpPol.name', + 'infraRsLinkFlapPol.name', + 'infraRsMcpIfPol.name', + 'infraRsStpIfPol.name', + 'infraRsL2IfPol.name', + 'infraRsStormctrlIfPol.name', + 'infraRsL2PortSecurityPol.name' + ] + + headers = [ + 'Faults', + 'Name', + 'AAEP', + 'CDP', + 'Link Level', + 'LLDP', + 'LACP', + 'Link Flap', + 'MCP', + 'STP', + 'L2', + 'Storm Ctrl', + 'Port Sec' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_aaep(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - AAEP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + order = [ + 'name', + 'infraRsAttEntP.name', + 'infraRsDomP.domainType', + 'infraRsDomP.domainName', + 'vlanPool', + 'vlanBlock' + ] + + headers = [ + 'Name', + 'AAEP', + 'Domain Type', + 'Domain Name', + 'VLAN Pool', + 'VLAN Range' + ] + + for item in info: + item['infraRsDomP'] = item['aaep']['infraRsDomP'] + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['infraRsDomP', 'vlanPool', 'vlanBlock'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_node(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Deployed Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + order = [ + 'name', + 'infraRsAttEntP.name', + 'vlanPool', + 'vlanBlock', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'PG Name', + 'AAEP', + 'VLAN Pool', + 'VLAN Range', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlanPool', 'vlanBlock', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_interface(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Deployed Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + order = [ + 'name', + 'infraRsAttEntP.name', + 'vlanPool', + 'vlanBlock', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'PG Name', + 'AAEP', + 'VLAN Pool', + 'VLAN Range', + 'Node', + 'Intf Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlanPool', 'vlanBlock', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_vlan(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Deployed Interfaces with State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['vlanPool'] = item['aaep']['vlanPool'] + item['vlanBlock'] = item['aaep']['vlanBlock'] + + order = [ + 'name', + 'infraRsAttEntP.name', + 'vlanPool', + 'vlanBlock', + 'interface.node_name', + 'interface.intf_name', + 'interface.operSt', + 'interface.operMode', + 'interface.vlans' + ] + + headers = [ + 'PG Name', + 'AAEP', + 'VLAN Pool', + 'VLAN Range', + 'Node', + 'Intf Name', + 'State', + 'Mode', + 'VLANs' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vlanPool', 'vlanBlock', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + # def print_policy_groups_access_interface_vpc_nodes(self, info): + # order = [ + # 'name', + # 'aaep_name', + # 'nodes.name' + # ] + + # headers = [ + # 'Name', + # 'Attached Entity Profile', + # 'Deployed Node Name' + # ] + + # self.my_output.my_table( + # self.my_output.expand_lists( + # info, + # order, + # ['nodes'] + # ), + # order=order, + # headers=headers, + # allow_order_subkeys=True, + # underline=True, + # row_separator=True, + # table=True + # ) + + # def print_policy_groups_access_interface_vpc_ports(self, info): + # order = [ + # 'name', + # 'aaep_name', + # 'ports.node_name', + # 'ports.port_id' + # ] + + # headers = [ + # 'Name', + # 'Attached Entity Profile', + # 'Deployed Node Name', + # 'Deployed Port' + # ] + + # self.my_output.my_table( + # self.my_output.expand_lists( + # info, + # order, + # ['ports'] + # ), + # order=order, + # headers=headers, + # allow_order_subkeys=True, + # underline=True, + # row_separator=True, + # table=True + # ) + + def print_policy_groups_access_interface_vpc_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_policy_groups_access_interface_vpc_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Policy Group - Access Interface PC/VPC - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pgName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'PG Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/pg/access/intf/vpc/ports/__init__.py b/lib/aci/pg/access/intf/vpc/ports/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/intf/vpc/ports/api.py b/lib/aci/pg/access/intf/vpc/ports/api.py new file mode 100644 index 00000000..93a3c2b7 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/ports/api.py @@ -0,0 +1,66 @@ +class PolicyGroupAccessInterfaceVpcPortApi(): + def __init__(self): + self.policy_group_access_interface_vpc_port_mo = {} + + def get_policy_group_access_interface_vpc_port_mo(self, policy_group_name, node_id): + key = '%s.%s' % ( + policy_group_name, + node_id + ) + if key in self.policy_group_access_interface_vpc_port_mo: + return self.policy_group_access_interface_vpc_port_mo[key] + + cache = self.get_object_cache( + 'AccBaseGrpToEthIf', + object_selector=key + ) + if cache is not None: + self.policy_group_access_interface_vpc_port_mo[key] = cache + self.log.apic_mo( + 'AccBaseGrpToEthIf.%s' % (key), + self.policy_group_access_interface_vpc_port_mo[key] + ) + return self.policy_group_access_interface_vpc_port_mo[key] + + distinguished_name = 'uni/infra/funcprof/accbundle-%s' % (policy_group_name) + query = 'rsp-subtree-include=full-deployment&target-node=%s&target-path=AccBaseGrpToEthIf' % (node_id) + + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + if managed_objects is None: + self.log.error( + 'get_policy_group_access_interface_vpc_port_mo', + 'API failed' + ) + return None + + self.log.apic_mo( + 'AccBaseGrpToEthIf.mo.%s' % (key), + managed_objects + ) + + self.policy_group_access_interface_vpc_port_mo[key] = [] + + for managed_object in managed_objects['imdata']: + for child in managed_object['infraAccBndlGrp']['children']: + if 'pconsNodeDeployCtx' in child: + for node_child in child['pconsNodeDeployCtx']['children']: + if 'pconsResourceCtx' in node_child: + self.policy_group_access_interface_vpc_port_mo[key].append( + node_child['pconsResourceCtx']['attributes'] + ) + + self.log.apic_mo( + 'AccBaseGrpToEthIf.%s' % (key), + self.policy_group_access_interface_vpc_port_mo[key] + ) + + self.set_object_cache( + 'AccBaseGrpToEthIf', + self.policy_group_access_interface_vpc_port_mo[key], + object_selector=key + ) + + return self.policy_group_access_interface_vpc_port_mo[key] diff --git a/lib/aci/pg/access/intf/vpc/ports/info.py b/lib/aci/pg/access/intf/vpc/ports/info.py new file mode 100644 index 00000000..d296b269 --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/ports/info.py @@ -0,0 +1,65 @@ +class PolicyGroupAccessInterfaceVpcPortInfo(): + def __init__(self): + self.policy_group_access_interface_vpc_port = {} + + def get_policy_group_access_interface_vpc_port_info(self, managed_object, policy_group_name, node_id): + port_info = {} + port_info['dn'] = managed_object['ctxDn'] + port_info['pod_id'] = managed_object['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = str(node_id) + port_info['node_name'] = self.get_node_name( + node_id, + pod_id=port_info['pod_id'] + ) + + if managed_object['ctxClass'] == 'l1PhysIf': + # topology/pod-1/node-2205/sys/phys-[eth1/11] + port_info['port_id'] = managed_object['ctxDn'].split('phys-[')[1].rstrip(']') + port_info['ep'] = 'pod-%s:node-%s:%s (%s)' % ( + port_info['pod_id'], + port_info['node_id'], + port_info['port_id'], + policy_group_name + ) + + if managed_object['ctxClass'] not in ['l1PhysIf']: + self.log.error( + 'get_policy_group_interface_vpc_info', + 'Unsupported port: %s' % (managed_object) + ) + + return port_info + + def get_policy_group_access_interface_vpc_ports_info(self, policy_group_name, node_id): + key = '%s.%s' % ( + policy_group_name, + node_id + ) + if key in self.policy_group_access_interface_vpc_port: + return self.policy_group_access_interface_vpc_port[key] + + managed_objects = self.get_policy_group_access_interface_vpc_port_mo( + policy_group_name, + node_id + ) + if managed_objects is None: + return None + + self.policy_group_access_interface_vpc_port[key] = [] + for managed_object in managed_objects: + self.policy_group_access_interface_vpc_port[key].append( + self.get_policy_group_access_interface_vpc_port_info( + managed_object, + policy_group_name, + node_id + ) + ) + + return self.policy_group_access_interface_vpc_port[key] + + def get_policy_group_access_interface_vpc_ports(self, policy_group_name, node_id): + all_ports = self.get_policy_group_access_interface_vpc_ports_info( + policy_group_name, + node_id + ) + return all_ports diff --git a/lib/aci/pg/access/intf/vpc/ports/main.py b/lib/aci/pg/access/intf/vpc/ports/main.py new file mode 100644 index 00000000..35d79b0f --- /dev/null +++ b/lib/aci/pg/access/intf/vpc/ports/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.vpc.ports.api import PolicyGroupAccessInterfaceVpcPortApi +from lib.aci.pg.access.intf.vpc.ports.info import PolicyGroupAccessInterfaceVpcPortInfo + + +class PolicyGroupAccessInterfaceVpcPort(PolicyGroupAccessInterfaceVpcPortApi, PolicyGroupAccessInterfaceVpcPortInfo): + def __init__(self): + PolicyGroupAccessInterfaceVpcPortApi.__init__(self) + PolicyGroupAccessInterfaceVpcPortInfo.__init__(self) diff --git a/lib/aci/pg/access/main.py b/lib/aci/pg/access/main.py new file mode 100644 index 00000000..e4ea258b --- /dev/null +++ b/lib/aci/pg/access/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.intf.main import PolicyGroupAccessInterface +from lib.aci.pg.access.switch.main import PolicyGroupAccessSwitch + + +class PolicyGroupAccess(PolicyGroupAccessInterface, PolicyGroupAccessSwitch): + def __init__(self): + PolicyGroupAccessInterface.__init__(self) + PolicyGroupAccessSwitch.__init__(self) diff --git a/lib/aci/pg/access/output.py b/lib/aci/pg/access/output.py new file mode 100644 index 00000000..407168b2 --- /dev/null +++ b/lib/aci/pg/access/output.py @@ -0,0 +1,6 @@ +from lib.aci.pg.access.intf.output import PolicyGroupAccessInterfaceOutput + + +class PolicyGroupAccessOutput(PolicyGroupAccessInterfaceOutput): + def __init__(self): + PolicyGroupAccessInterfaceOutput.__init__(self) diff --git a/lib/aci/pg/access/switch/__init__.py b/lib/aci/pg/access/switch/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/switch/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/switch/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..690c62e0 Binary files /dev/null and b/lib/aci/pg/access/switch/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/switch/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/switch/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e430e03b Binary files /dev/null and b/lib/aci/pg/access/switch/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/switch/leaf/__init__.py b/lib/aci/pg/access/switch/leaf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/switch/leaf/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/switch/leaf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d72159d3 Binary files /dev/null and b/lib/aci/pg/access/switch/leaf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/switch/leaf/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/switch/leaf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1f2d85f1 Binary files /dev/null and b/lib/aci/pg/access/switch/leaf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/switch/leaf/main.py b/lib/aci/pg/access/switch/leaf/main.py new file mode 100644 index 00000000..9103cfba --- /dev/null +++ b/lib/aci/pg/access/switch/leaf/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessSwitchLeaf(): + def __init__(self): + pass diff --git a/lib/aci/pg/access/switch/main.py b/lib/aci/pg/access/switch/main.py new file mode 100644 index 00000000..d81fdab3 --- /dev/null +++ b/lib/aci/pg/access/switch/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.access.switch.leaf.main import PolicyGroupAccessSwitchLeaf +from lib.aci.pg.access.switch.spine.main import PolicyGroupAccessSwitchSpine + + +class PolicyGroupAccessSwitch(PolicyGroupAccessSwitchLeaf, PolicyGroupAccessSwitchSpine): + def __init__(self): + PolicyGroupAccessSwitchLeaf.__init__(self) + PolicyGroupAccessSwitchSpine.__init__(self) diff --git a/lib/aci/pg/access/switch/spine/__init__.py b/lib/aci/pg/access/switch/spine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/access/switch/spine/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/access/switch/spine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..fb1a29f9 Binary files /dev/null and b/lib/aci/pg/access/switch/spine/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/access/switch/spine/__pycache__/main.cpython-310.pyc b/lib/aci/pg/access/switch/spine/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1e6ba90f Binary files /dev/null and b/lib/aci/pg/access/switch/spine/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/access/switch/spine/main.py b/lib/aci/pg/access/switch/spine/main.py new file mode 100644 index 00000000..dfd5ca39 --- /dev/null +++ b/lib/aci/pg/access/switch/spine/main.py @@ -0,0 +1,3 @@ +class PolicyGroupAccessSwitchSpine(): + def __init__(self): + pass diff --git a/lib/aci/pg/fabric/__init__.py b/lib/aci/pg/fabric/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d56cb4ec Binary files /dev/null and b/lib/aci/pg/fabric/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/__pycache__/leaf.cpython-310.pyc b/lib/aci/pg/fabric/__pycache__/leaf.cpython-310.pyc new file mode 100644 index 00000000..542c83f1 Binary files /dev/null and b/lib/aci/pg/fabric/__pycache__/leaf.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3dbf182b Binary files /dev/null and b/lib/aci/pg/fabric/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/__pycache__/spine.cpython-310.pyc b/lib/aci/pg/fabric/__pycache__/spine.cpython-310.pyc new file mode 100644 index 00000000..17ee565d Binary files /dev/null and b/lib/aci/pg/fabric/__pycache__/spine.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/__init__.py b/lib/aci/pg/fabric/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/intf/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..304f4a65 Binary files /dev/null and b/lib/aci/pg/fabric/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c307b23c Binary files /dev/null and b/lib/aci/pg/fabric/intf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/leaf/__init__.py b/lib/aci/pg/fabric/intf/leaf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/intf/leaf/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/intf/leaf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4d146194 Binary files /dev/null and b/lib/aci/pg/fabric/intf/leaf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/leaf/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/intf/leaf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b899933d Binary files /dev/null and b/lib/aci/pg/fabric/intf/leaf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/leaf/main.py b/lib/aci/pg/fabric/intf/leaf/main.py new file mode 100644 index 00000000..b4f25758 --- /dev/null +++ b/lib/aci/pg/fabric/intf/leaf/main.py @@ -0,0 +1,3 @@ +class PolicyGroupFabricInterfaceLeaf(): + def __init__(self): + pass diff --git a/lib/aci/pg/fabric/intf/main.py b/lib/aci/pg/fabric/intf/main.py new file mode 100644 index 00000000..a677f16b --- /dev/null +++ b/lib/aci/pg/fabric/intf/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.fabric.intf.leaf.main import PolicyGroupFabricInterfaceLeaf +from lib.aci.pg.fabric.intf.spine.main import PolicyGroupFabricInterfaceSpine + + +class PolicyGroupFabricInterface(PolicyGroupFabricInterfaceLeaf, PolicyGroupFabricInterfaceSpine): + def __init__(self): + PolicyGroupFabricInterfaceLeaf.__init__(self) + PolicyGroupFabricInterfaceSpine.__init__(self) diff --git a/lib/aci/pg/fabric/intf/spine/__init__.py b/lib/aci/pg/fabric/intf/spine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/intf/spine/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/intf/spine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0b88c29e Binary files /dev/null and b/lib/aci/pg/fabric/intf/spine/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/spine/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/intf/spine/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..26b531b2 Binary files /dev/null and b/lib/aci/pg/fabric/intf/spine/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/intf/spine/main.py b/lib/aci/pg/fabric/intf/spine/main.py new file mode 100644 index 00000000..b5143ac0 --- /dev/null +++ b/lib/aci/pg/fabric/intf/spine/main.py @@ -0,0 +1,3 @@ +class PolicyGroupFabricInterfaceSpine(): + def __init__(self): + pass diff --git a/lib/aci/pg/fabric/main.py b/lib/aci/pg/fabric/main.py new file mode 100644 index 00000000..52928d67 --- /dev/null +++ b/lib/aci/pg/fabric/main.py @@ -0,0 +1,10 @@ +from lib.aci.pg.fabric.intf.main import PolicyGroupFabricInterface +from lib.aci.pg.fabric.module.main import PolicyGroupFabricModule +from lib.aci.pg.fabric.switch.main import PolicyGroupFabricSwitch + + +class PolicyGroupFabric(PolicyGroupFabricInterface, PolicyGroupFabricModule, PolicyGroupFabricSwitch): + def __init__(self): + PolicyGroupFabricInterface.__init__(self) + PolicyGroupFabricModule.__init__(self) + PolicyGroupFabricSwitch.__init__(self) diff --git a/lib/aci/pg/fabric/module/__init__.py b/lib/aci/pg/fabric/module/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/module/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/module/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0f7ddd7a Binary files /dev/null and b/lib/aci/pg/fabric/module/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/module/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/module/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8f1cb109 Binary files /dev/null and b/lib/aci/pg/fabric/module/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/module/leaf/__init__.py b/lib/aci/pg/fabric/module/leaf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/module/leaf/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/module/leaf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f8212049 Binary files /dev/null and b/lib/aci/pg/fabric/module/leaf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/module/leaf/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/module/leaf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a9a9fe6b Binary files /dev/null and b/lib/aci/pg/fabric/module/leaf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/module/leaf/main.py b/lib/aci/pg/fabric/module/leaf/main.py new file mode 100644 index 00000000..f5068687 --- /dev/null +++ b/lib/aci/pg/fabric/module/leaf/main.py @@ -0,0 +1,3 @@ +class PolicyGroupFabricModuleLeaf(): + def __init__(self): + pass diff --git a/lib/aci/pg/fabric/module/main.py b/lib/aci/pg/fabric/module/main.py new file mode 100644 index 00000000..fee63923 --- /dev/null +++ b/lib/aci/pg/fabric/module/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.fabric.module.leaf.main import PolicyGroupFabricModuleLeaf +from lib.aci.pg.fabric.module.spine.main import PolicyGroupFabricModuleSpine + + +class PolicyGroupFabricModule(PolicyGroupFabricModuleLeaf, PolicyGroupFabricModuleSpine): + def __init__(self): + PolicyGroupFabricModuleLeaf.__init__(self) + PolicyGroupFabricModuleSpine.__init__(self) diff --git a/lib/aci/pg/fabric/module/spine/__init__.py b/lib/aci/pg/fabric/module/spine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/module/spine/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/module/spine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a024e5e3 Binary files /dev/null and b/lib/aci/pg/fabric/module/spine/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/module/spine/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/module/spine/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..cde7d144 Binary files /dev/null and b/lib/aci/pg/fabric/module/spine/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/module/spine/main.py b/lib/aci/pg/fabric/module/spine/main.py new file mode 100644 index 00000000..5c27b913 --- /dev/null +++ b/lib/aci/pg/fabric/module/spine/main.py @@ -0,0 +1,3 @@ +class PolicyGroupFabricModuleSpine(): + def __init__(self): + pass diff --git a/lib/aci/pg/fabric/switch/__init__.py b/lib/aci/pg/fabric/switch/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/switch/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/switch/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9c2d789f Binary files /dev/null and b/lib/aci/pg/fabric/switch/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/switch/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/switch/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f0dc246e Binary files /dev/null and b/lib/aci/pg/fabric/switch/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/switch/leaf/__init__.py b/lib/aci/pg/fabric/switch/leaf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/switch/leaf/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/switch/leaf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..874d64f9 Binary files /dev/null and b/lib/aci/pg/fabric/switch/leaf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/switch/leaf/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/switch/leaf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1da49ccc Binary files /dev/null and b/lib/aci/pg/fabric/switch/leaf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/switch/leaf/main.py b/lib/aci/pg/fabric/switch/leaf/main.py new file mode 100644 index 00000000..398fc4dc --- /dev/null +++ b/lib/aci/pg/fabric/switch/leaf/main.py @@ -0,0 +1,3 @@ +class PolicyGroupFabricSwitchLeaf(): + def __init__(self): + pass diff --git a/lib/aci/pg/fabric/switch/main.py b/lib/aci/pg/fabric/switch/main.py new file mode 100644 index 00000000..fb6bf65c --- /dev/null +++ b/lib/aci/pg/fabric/switch/main.py @@ -0,0 +1,8 @@ +from lib.aci.pg.fabric.switch.leaf.main import PolicyGroupFabricSwitchLeaf +from lib.aci.pg.fabric.switch.spine.main import PolicyGroupFabricSwitchSpine + + +class PolicyGroupFabricSwitch(PolicyGroupFabricSwitchLeaf, PolicyGroupFabricSwitchSpine): + def __init__(self): + PolicyGroupFabricSwitchLeaf.__init__(self) + PolicyGroupFabricSwitchSpine.__init__(self) diff --git a/lib/aci/pg/fabric/switch/spine/__init__.py b/lib/aci/pg/fabric/switch/spine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pg/fabric/switch/spine/__pycache__/__init__.cpython-310.pyc b/lib/aci/pg/fabric/switch/spine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a688a282 Binary files /dev/null and b/lib/aci/pg/fabric/switch/spine/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/switch/spine/__pycache__/main.cpython-310.pyc b/lib/aci/pg/fabric/switch/spine/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ed7a7331 Binary files /dev/null and b/lib/aci/pg/fabric/switch/spine/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pg/fabric/switch/spine/main.py b/lib/aci/pg/fabric/switch/spine/main.py new file mode 100644 index 00000000..fdb2f8de --- /dev/null +++ b/lib/aci/pg/fabric/switch/spine/main.py @@ -0,0 +1,3 @@ +class PolicyGroupFabricSwitchSpine(): + def __init__(self): + pass diff --git a/lib/aci/pg/main.py b/lib/aci/pg/main.py new file mode 100644 index 00000000..a8602e23 --- /dev/null +++ b/lib/aci/pg/main.py @@ -0,0 +1,11 @@ +from lib.aci.pg.access.main import PolicyGroupAccess +from lib.aci.pg.fabric.main import PolicyGroupFabric + + +class PolicyGroup( + PolicyGroupAccess, + PolicyGroupFabric + ): + def __init__(self): + PolicyGroupAccess.__init__(self) + PolicyGroupFabric.__init__(self) diff --git a/lib/aci/pg/output.py b/lib/aci/pg/output.py new file mode 100644 index 00000000..69df88e6 --- /dev/null +++ b/lib/aci/pg/output.py @@ -0,0 +1,6 @@ +from lib.aci.pg.access.output import PolicyGroupAccessOutput + + +class PolicyGroupOutput(PolicyGroupAccessOutput): + def __init__(self): + PolicyGroupAccessOutput.__init__(self) diff --git a/lib/aci/policy/__init__.py b/lib/aci/policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4710d831 Binary files /dev/null and b/lib/aci/policy/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/cdp.cpython-310.pyc b/lib/aci/policy/__pycache__/cdp.cpython-310.pyc new file mode 100644 index 00000000..1b655e99 Binary files /dev/null and b/lib/aci/policy/__pycache__/cdp.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/host_interface.cpython-310.pyc b/lib/aci/policy/__pycache__/host_interface.cpython-310.pyc new file mode 100644 index 00000000..3b30a98c Binary files /dev/null and b/lib/aci/policy/__pycache__/host_interface.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/igmp_snoop.cpython-310.pyc b/lib/aci/policy/__pycache__/igmp_snoop.cpython-310.pyc new file mode 100644 index 00000000..88732322 Binary files /dev/null and b/lib/aci/policy/__pycache__/igmp_snoop.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/link_flap.cpython-310.pyc b/lib/aci/policy/__pycache__/link_flap.cpython-310.pyc new file mode 100644 index 00000000..1b302100 Binary files /dev/null and b/lib/aci/policy/__pycache__/link_flap.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/lldp.cpython-310.pyc b/lib/aci/policy/__pycache__/lldp.cpython-310.pyc new file mode 100644 index 00000000..839e8534 Binary files /dev/null and b/lib/aci/policy/__pycache__/lldp.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/main.cpython-310.pyc b/lib/aci/policy/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..72bc4546 Binary files /dev/null and b/lib/aci/policy/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/mcp.cpython-310.pyc b/lib/aci/policy/__pycache__/mcp.cpython-310.pyc new file mode 100644 index 00000000..04224de6 Binary files /dev/null and b/lib/aci/policy/__pycache__/mcp.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/mld_snoop.cpython-310.pyc b/lib/aci/policy/__pycache__/mld_snoop.cpython-310.pyc new file mode 100644 index 00000000..75589a88 Binary files /dev/null and b/lib/aci/policy/__pycache__/mld_snoop.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/monitoring.cpython-310.pyc b/lib/aci/policy/__pycache__/monitoring.cpython-310.pyc new file mode 100644 index 00000000..9da6700c Binary files /dev/null and b/lib/aci/policy/__pycache__/monitoring.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/output.cpython-310.pyc b/lib/aci/policy/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..edd277ed Binary files /dev/null and b/lib/aci/policy/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/sn.cpython-310.pyc b/lib/aci/policy/__pycache__/sn.cpython-310.pyc new file mode 100644 index 00000000..39647f32 Binary files /dev/null and b/lib/aci/policy/__pycache__/sn.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/storm_control.cpython-310.pyc b/lib/aci/policy/__pycache__/storm_control.cpython-310.pyc new file mode 100644 index 00000000..2126b3f9 Binary files /dev/null and b/lib/aci/policy/__pycache__/storm_control.cpython-310.pyc differ diff --git a/lib/aci/policy/__pycache__/stp.cpython-310.pyc b/lib/aci/policy/__pycache__/stp.cpython-310.pyc new file mode 100644 index 00000000..0fb1ebf4 Binary files /dev/null and b/lib/aci/policy/__pycache__/stp.cpython-310.pyc differ diff --git a/lib/aci/policy/general/__init__.py b/lib/aci/policy/general/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/general/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/general/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ba389108 Binary files /dev/null and b/lib/aci/policy/general/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/general/__pycache__/main.cpython-310.pyc b/lib/aci/policy/general/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f4a47cdd Binary files /dev/null and b/lib/aci/policy/general/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/general/__pycache__/output.cpython-310.pyc b/lib/aci/policy/general/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..cf7d7693 Binary files /dev/null and b/lib/aci/policy/general/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/general/aae/__init__.py b/lib/aci/policy/general/aae/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/general/aae/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/general/aae/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..221045b6 Binary files /dev/null and b/lib/aci/policy/general/aae/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/general/aae/__pycache__/api.cpython-310.pyc b/lib/aci/policy/general/aae/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3d5baee6 Binary files /dev/null and b/lib/aci/policy/general/aae/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/general/aae/__pycache__/info.cpython-310.pyc b/lib/aci/policy/general/aae/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..a6d5de8f Binary files /dev/null and b/lib/aci/policy/general/aae/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/general/aae/__pycache__/main.cpython-310.pyc b/lib/aci/policy/general/aae/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ce9ef91e Binary files /dev/null and b/lib/aci/policy/general/aae/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/general/aae/__pycache__/output.cpython-310.pyc b/lib/aci/policy/general/aae/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..892dcff8 Binary files /dev/null and b/lib/aci/policy/general/aae/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/general/aae/api.py b/lib/aci/policy/general/aae/api.py new file mode 100644 index 00000000..47a28140 --- /dev/null +++ b/lib/aci/policy/general/aae/api.py @@ -0,0 +1,89 @@ +class PolicyGeneralAaeApi(): + def __init__(self): + self.policy_global_aae_mo = None + + def get_policy_global_aae_mo(self): + if self.policy_global_aae_mo is not None: + return self.policy_global_aae_mo + + cache = self.get_object_cache( + 'infraAttEntityP' + ) + if cache is not None: + self.policy_global_aae_mo = cache + self.log.apic_mo( + 'infraAttEntityP', + self.policy_global_aae_mo + ) + return self.policy_global_aae_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=infraProvAcc,infraRtAttEntP,infraRsDomP' + managed_objects = self.get_class( + 'infraAttEntityP', + query=query + ) + + if managed_objects is None: + return None + + self.policy_global_aae_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAttEntityP']['attributes'] + attributes['infraRtAttEntP'] = self.get_mo_children_attributes( + 'infraAttEntityP', + managed_object, + 'infraRtAttEntP' + ) + attributes['infraRsDomP'] = self.get_mo_children_attributes( + 'infraAttEntityP', + managed_object, + 'infraRsDomP' + ) + attributes['infraProvAcc'] = self.get_mo_child_attributes( + 'infraAttEntityP', + managed_object, + 'infraProvAcc' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'infraAttEntityP', + managed_object, + 'faultCounts' + ) + attributes['infraRsFuncToEpg'] = [] + + self.policy_global_aae_mo.append( + attributes + ) + + query = 'query-target=subtree&target-subtree-class=infraAttEntityP&target-subtree-class=infraRsFuncToEpg' + managed_objects = self.get_managed_object( + 'uni/infra', + query=query, + node_mo=True + ) + if managed_objects is None: + return None + + for managed_object in managed_objects['imdata']: + if 'infraRsFuncToEpg' in managed_object: + # "dn": "uni/infra/attentp-k8s_phys_AAEP/gen-default/rsfuncToEpg-[uni/tn-k8s/ap-k8s_ANP/epg-csr1_lan]" + ref_dn = '/'.join( + managed_object['infraRsFuncToEpg']['attributes']['dn'].split('/')[:3] + ) + for policy_mo in self.policy_global_aae_mo: + if policy_mo['dn'] == ref_dn: + policy_mo['infraRsFuncToEpg'].append( + managed_object['infraRsFuncToEpg']['attributes'] + ) + + self.log.apic_mo( + 'infraAttEntityP', + self.policy_global_aae_mo + ) + + self.set_object_cache( + 'infraAttEntityP', + self.policy_global_aae_mo + ) + + return self.policy_global_aae_mo diff --git a/lib/aci/policy/general/aae/audit/__init__.py b/lib/aci/policy/general/aae/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/general/aae/audit/api.py b/lib/aci/policy/general/aae/audit/api.py new file mode 100644 index 00000000..8728b655 --- /dev/null +++ b/lib/aci/policy/general/aae/audit/api.py @@ -0,0 +1,48 @@ +class PolicyGeneralAaeAuditApi(): + def __init__(self): + self.policy_global_aae_audit_mo = None + + def get_policy_global_aae_audit_mo(self): + cache = self.get_object_cache( + 'infraAttEntityP.audit' + ) + if cache is not None: + self.policy_global_aae_audit_mo = cache + self.log.apic_mo( + 'infraAttEntityP.audit', + self.policy_global_aae_audit_mo + ) + return self.policy_global_aae_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'infraAttEntityP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_global_aae_audit_mo', + 'API failed' + ) + return None + + self.policy_global_aae_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.policy_global_aae_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAttEntityP.audit', + self.policy_global_aae_audit_mo + ) + + self.set_object_cache( + 'infraAttEntityP.audit', + self.policy_global_aae_audit_mo + ) + + return self.policy_global_aae_audit_mo diff --git a/lib/aci/policy/general/aae/audit/info.py b/lib/aci/policy/general/aae/audit/info.py new file mode 100644 index 00000000..dd945ea0 --- /dev/null +++ b/lib/aci/policy/general/aae/audit/info.py @@ -0,0 +1,98 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGeneralAaeAuditInfo(): + def __init__(self): + self.policy_global_aae_audit = None + + def get_policy_global_aae_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # uni/infra/attentp-HX1_AAEP/rsdomP-[uni/phys-HX1_PhysDom] + info['policyName'] = None + if 'uni/infra/attentp-' in info['affected']: + info['policyName'] = info['affected'].split('uni/infra/attentp-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_global_aae_audit(self): + if self.policy_global_aae_audit is not None: + return self.policy_global_aae_audit + + managed_objects = self.get_policy_global_aae_audit_mo() + if managed_objects is None: + return None + + self.policy_global_aae_audit = [] + for managed_object in managed_objects: + audit_info = self.get_policy_global_aae_audit_info( + managed_object + ) + self.policy_global_aae_audit.append( + audit_info + ) + + self.log.apic_mo( + 'infraAttEntityP.auditRecord.info', + self.policy_global_aae_audit + ) + + return self.policy_global_aae_audit + + def get_policy_global_aae_id_audit(self, policy_name, audit_filter=None): + audits = [] + + all_audits = self.get_policy_global_aae_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['policyName'] is not None: + if audit_info['policyName'] == policy_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/policy/general/aae/audit/main.py b/lib/aci/policy/general/aae/audit/main.py new file mode 100644 index 00000000..a0f37fa0 --- /dev/null +++ b/lib/aci/policy/general/aae/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.general.aae.audit.api import PolicyGeneralAaeAuditApi +from lib.aci.policy.general.aae.audit.info import PolicyGeneralAaeAuditInfo + + +class PolicyGeneralAaeAudit(PolicyGeneralAaeAuditApi, PolicyGeneralAaeAuditInfo): + def __init__(self): + PolicyGeneralAaeAuditApi.__init__(self) + PolicyGeneralAaeAuditInfo.__init__(self) diff --git a/lib/aci/policy/general/aae/event/__init__.py b/lib/aci/policy/general/aae/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/general/aae/event/api.py b/lib/aci/policy/general/aae/event/api.py new file mode 100644 index 00000000..60eed1e6 --- /dev/null +++ b/lib/aci/policy/general/aae/event/api.py @@ -0,0 +1,51 @@ +class PolicyGeneralAaeEventApi(): + def __init__(self): + self.policy_global_aae_event_mo = None + + def get_policy_global_aae_event_mo(self): + if self.policy_global_aae_event_mo is not None: + return self.policy_global_aae_event_mo + + cache = self.get_object_cache( + 'infraAttEntityP.eventLog' + ) + if cache is not None: + self.policy_global_aae_event_mo = cache + self.log.apic_mo( + 'infraAttEntityP.eventLog', + self.policy_global_aae_event_mo + ) + return self.policy_global_aae_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'infraAttEntityP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_global_aae_event_mo', + 'API failed' + ) + return None + + self.policy_global_aae_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.policy_global_aae_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAttEntityP.eventLog', + self.policy_global_aae_event_mo + ) + + self.set_object_cache( + 'infraAttEntityP.eventLog', + self.policy_global_aae_event_mo + ) + + return self.policy_global_aae_event_mo diff --git a/lib/aci/policy/general/aae/event/info.py b/lib/aci/policy/general/aae/event/info.py new file mode 100644 index 00000000..bbf4bc11 --- /dev/null +++ b/lib/aci/policy/general/aae/event/info.py @@ -0,0 +1,109 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGeneralAaeEventInfo(): + def __init__(self): + self.policy_global_aae_event = None + + def get_policy_global_aae_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # uni/infra/attentp-HX1_AAEP/rsdomP-[uni/phys-HX1_PhysDom] + info['policyName'] = None + + if 'affected' in info: + if 'uni/infra/attentp-' in info['affected']: + info['policyName'] = info['affected'].split('uni/infra/attentp-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/infra/attentp-' in info['dn']: + info['policyName'] = info['dn'].split('uni/infra/attentp-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_global_aae_event(self, deduplicate=True): + if self.policy_global_aae_event is not None: + return self.policy_global_aae_event + + managed_objects = self.get_policy_global_aae_event_mo() + if managed_objects is None: + return None + + self.policy_global_aae_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_policy_global_aae_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.policy_global_aae_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'infraAttEntityP.eventLog.info', + self.policy_global_aae_event + ) + + return self.policy_global_aae_event + + def get_policy_global_aae_id_event(self, policy_name, event_filter=None): + events = [] + + all_events = self.get_policy_global_aae_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['policyName'] is not None: + if event_info['policyName'] == policy_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/policy/general/aae/event/main.py b/lib/aci/policy/general/aae/event/main.py new file mode 100644 index 00000000..18934aa0 --- /dev/null +++ b/lib/aci/policy/general/aae/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.general.aae.event.api import PolicyGeneralAaeEventApi +from lib.aci.policy.general.aae.event.info import PolicyGeneralAaeEventInfo + + +class PolicyGeneralAaeEvent(PolicyGeneralAaeEventApi, PolicyGeneralAaeEventInfo): + def __init__(self): + PolicyGeneralAaeEventApi.__init__(self) + PolicyGeneralAaeEventInfo.__init__(self) diff --git a/lib/aci/policy/general/aae/fault/__init__.py b/lib/aci/policy/general/aae/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/general/aae/fault/api.py b/lib/aci/policy/general/aae/fault/api.py new file mode 100644 index 00000000..3b71154a --- /dev/null +++ b/lib/aci/policy/general/aae/fault/api.py @@ -0,0 +1,112 @@ +class PolicyGeneralAaeFaultApi(): + def __init__(self): + self.policy_global_aae_fault_mo = None + self.policy_global_aae_fault_record_mo = None + + def get_policy_global_aae_fault_mo(self): + cache = self.get_object_cache( + 'infraAttEntityP.fault' + ) + if cache is not None: + self.policy_global_aae_fault_mo = cache + self.log.apic_mo( + 'infraAttEntityP.fault', + self.policy_global_aae_fault_mo + ) + return self.policy_global_aae_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'infraAttEntityP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_global_aae_fault_mo', + 'API failed' + ) + return None + + self.policy_global_aae_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.policy_global_aae_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAttEntityP.fault', + self.policy_global_aae_fault_mo + ) + + self.set_object_cache( + 'infraAttEntityP.fault', + self.policy_global_aae_fault_mo + ) + + return self.policy_global_aae_fault_mo + + def get_policy_global_aae_fault_record_mo(self): + cache = self.get_object_cache( + 'infraAttEntityP.faultRecord' + ) + if cache is not None: + self.policy_global_aae_fault_record_mo = cache + self.log.apic_mo( + 'infraAttEntityP.faultRecord', + self.policy_global_aae_fault_record_mo + ) + return self.policy_global_aae_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'infraAttEntityP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_global_aae_fault_record_mo', + 'API failed' + ) + return None + + self.policy_global_aae_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.policy_global_aae_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'infraAttEntityP.faultRecord', + self.policy_global_aae_fault_record_mo + ) + + self.set_object_cache( + 'infraAttEntityP.faultRecord', + self.policy_global_aae_fault_record_mo + ) + + return self.policy_global_aae_fault_record_mo diff --git a/lib/aci/policy/general/aae/fault/info.py b/lib/aci/policy/general/aae/fault/info.py new file mode 100644 index 00000000..db2f000f --- /dev/null +++ b/lib/aci/policy/general/aae/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PolicyGeneralAaeFaultInfo(): + def __init__(self): + self.policy_global_aae_fault = None + self.policy_global_aae_fault_record = None + + def get_policy_global_aae_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # uni/infra/attentp-HX1_AAEP/rsdomP-[uni/phys-HX1_PhysDom] + info['policyName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/infra/attentp-' in info['affected']: + info['policyName'] = info['affected'].split('uni/infra/attentp-')[1].split('/')[0] + + if info['policyName'] is None: + if 'uni/infra/attentp-' in info['dn']: + info['policyName'] = info['dn'].split('uni/infra/attentp-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_policy_global_aae_fault(self, deduplicate=True): + if self.policy_global_aae_fault is not None: + return self.policy_global_aae_fault + + managed_objects = self.get_policy_global_aae_fault_mo() + if managed_objects is None: + return None + + self.policy_global_aae_fault = [] + for managed_object in managed_objects: + fault_info = self.get_policy_global_aae_fault_info( + managed_object + ) + self.policy_global_aae_fault.append( + fault_info + ) + + self.log.apic_mo( + 'infraAttEntityP.fault.info', + self.policy_global_aae_fault + ) + + return self.policy_global_aae_fault + + def get_policy_global_aae_fault_record(self, deduplicate=True): + if self.policy_global_aae_fault_record is not None: + return self.policy_global_aae_fault_record + + managed_objects = self.get_policy_global_aae_fault_record_mo() + if managed_objects is None: + return None + + self.policy_global_aae_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_policy_global_aae_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.policy_global_aae_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'infraAttEntityP.faultRecord.info', + self.policy_global_aae_fault_record + ) + + return self.policy_global_aae_fault_record + + def get_policy_global_aae_id_fault(self, policy_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_policy_global_aae_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_policy_global_aae_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['policyName'] is not None: + if fault_info['policyName'] == policy_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/policy/general/aae/fault/main.py b/lib/aci/policy/general/aae/fault/main.py new file mode 100644 index 00000000..6c5378ad --- /dev/null +++ b/lib/aci/policy/general/aae/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.general.aae.fault.api import PolicyGeneralAaeFaultApi +from lib.aci.policy.general.aae.fault.info import PolicyGeneralAaeFaultInfo + + +class PolicyGeneralAaeFault(PolicyGeneralAaeFaultApi, PolicyGeneralAaeFaultInfo): + def __init__(self): + PolicyGeneralAaeFaultApi.__init__(self) + PolicyGeneralAaeFaultInfo.__init__(self) diff --git a/lib/aci/policy/general/aae/info.py b/lib/aci/policy/general/aae/info.py new file mode 100644 index 00000000..448e1f05 --- /dev/null +++ b/lib/aci/policy/general/aae/info.py @@ -0,0 +1,345 @@ +from lib import filter_helper + + +class PolicyGeneralAaeInfo(): + def __init__(self): + pass + + def get_policy_global_aae_domain_info(self, managed_object): + keys = [ + 'forceResolve', + 'state', + 'tCl', + 'tDn' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['domainType'] = self.get_domain_type_from_tcl( + managed_object['tCl'] + ) + + info['domainName'] = managed_object['tDn'] + if info['tCl'] == 'vmmDomP': + # "tDn": "uni/vmmp-VMware/dom-EU-SPDC-CDC-22" + info['domainName'] = managed_object['tDn'].split('/')[2][4:] + + if info['tCl'] == 'l3extDomP': + # "tDn": "uni/l3dom-vEPC_ESX" + info['domainName'] = managed_object['tDn'].split('/')[1][6:] + + if info['tCl'] == 'physDomP': + # "tDn": "uni/phys-ESX-CDC-22_PhysDom" + info['domainName'] = managed_object['tDn'].split('/')[1][5:] + + if info['tCl'] == 'l2extDomP': + # "tDn": "uni/l2dom-Infra_L2dom" + info['domainName'] = managed_object['tDn'].split('/')[1][6:] + + return info + + def extend_policy_global_aae_domain_info(self, policy_global_aae_info): + for domain_info in policy_global_aae_info['infraRsDomP']: + if domain_info['tCl'] == 'physDomP': + domain_info['info'] = self.get_domain_phy( + domain_info['domainName'], + vlan_info=True + ) + continue + + if domain_info['tCl'] == 'vmmDomP': + domain_info['info'] = self.get_domain_vmm( + domain_info['domainName'], + vlan_info=True + ) + continue + + if domain_info['tCl'] == 'l2extDomP': + domain_info['info'] = self.get_domain_l2( + domain_info['domainName'], + vlan_info=True + ) + continue + + if domain_info['tCl'] == 'l3extDomP': + domain_info['info'] = self.get_domain_l3( + domain_info['domainName'], + vlan_info=True + ) + continue + + domain_info['info'] = None + self.log.error( + 'extend_policy_global_aae_domain_info', + 'Unsupported domain: %s' % (domain_info['tCl']) + ) + + policy_global_aae_info['vlanPool'] = [] + policy_global_aae_info['vlanBlock'] = [] + for domain_info in policy_global_aae_info['infraRsDomP']: + if domain_info['info'] is not None: + if domain_info['info']['vlan'] not in policy_global_aae_info['vlanPool']: + policy_global_aae_info['vlanPool'].append( + domain_info['info']['vlan'] + ) + if domain_info['info']['vlan_info'] is not None: + for vlan_range in domain_info['info']['vlan_info']['fvnsEncapBlk']: + policy_global_aae_info['vlanBlock'].append( + vlan_range['blockInfo'] + ) + + policy_global_aae_info['vlanPool'] = sorted( + policy_global_aae_info['vlanPool'] + ) + policy_global_aae_info['vlanBlock'] = sorted( + policy_global_aae_info['vlanBlock'] + ) + + return policy_global_aae_info + + def get_policy_global_aae_epg_info(self, managed_object): + keys = [ + 'dn', + 'encap', + 'mode', + 'primaryEncap', + 'state', + 'tCl', + 'tDn' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['epgName'] = None + if info['tCl'] == 'fvAEPg': + info['epgName'] = self.get_epg_name_from_dn( + managed_object['tDn'] + ) + + info['epgEncap'] = None + if info['epgName'] is not None: + if info['encap'] is not None and len(info['encap']) > 0: + info['epgEncap'] = '%s (%s)' % ( + info['epgName'], + info['encap'] + ) + + return info + + def get_policy_global_aae_policy_group_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['dn'] = managed_object['tDn'] + info['type'] = managed_object['tCl'] + info['typeName'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + + info['name'] = managed_object['tDn'] + if info['type'] == 'infraSpAccPortGrp': + # "tDn": "uni/infra/funcprof/spaccportgrp-multipodL3Out_policyGroup" + info['name'] = managed_object['tDn'].split('/')[3][13:] + + if info['type'] == 'infraAccPortGrp': + # "tDn": "uni/infra/funcprof/accportgrp-ESX-CDC-22_PolGrp" + info['name'] = managed_object['tDn'].split('/')[3][11:] + + if info['type'] == 'infraAccBndlGrp': + # "tDn": "uni/infra/funcprof/accbundle-k8s_esx72_PolGrp" + info['name'] = managed_object['tDn'].split('/')[3][10:] + + if info['type'] not in ['infraSpAccPortGrp', 'infraAccPortGrp', 'infraAccBndlGrp']: + self.log.error( + 'get_policy_global_aae_policy_group_info', + 'Unsupported: %s' % (managed_object['tDn']) + ) + + return info + + def get_policy_global_aae_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['infraRtAttEntP'] = [] + for policy_group_mo in managed_object['infraRtAttEntP']: + info['infraRtAttEntP'].append( + self.get_policy_global_aae_policy_group_info( + policy_group_mo + ) + ) + info['infraRtAttEntP'] = sorted( + info['infraRtAttEntP'], + key=lambda i: i['name'] + ) + + info['infraRsDomP'] = [] + for domain_mo in managed_object['infraRsDomP']: + info['infraRsDomP'].append( + self.get_policy_global_aae_domain_info( + domain_mo + ) + ) + + info['infraRsDomP'] = sorted( + info['infraRsDomP'], + key=lambda i: i['domainName'] + ) + + info['infraRsFuncToEpg'] = [] + for epg_mo in managed_object['infraRsFuncToEpg']: + info['infraRsFuncToEpg'].append( + self.get_policy_global_aae_epg_info( + epg_mo + ) + ) + + if managed_object['infraProvAcc'] is None: + info['infraVlanEnabled'] = False + info['infraVlanEnabledTick'] = '\u2717' + info['__Output']['infraVlanEnabledTick'] = 'Red' + else: + info['infraVlanEnabled'] = True + info['infraVlanEnabledTick'] = '\u2713' + info['__Output']['infraVlanEnabledTick'] = 'Green' + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def match_policy_global_aae(self, policy_global_aae_info, policy_global_aae_filter): + if policy_global_aae_filter is None or len(policy_global_aae_filter) == 0: + return True + + for aepg_rule in policy_global_aae_filter: + (key, value) = aepg_rule.split(':') + if key == 'name': + if not filter_helper.match_string(value, policy_global_aae_info['name']): + return False + + if key == 'dn': + if not filter_helper.match_string(value, policy_global_aae_info['dn']): + return False + + if key == 'fault': + if value == 'any': + if not policy_global_aae_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_policy_global_aae', + 'Unsupported fault filtering value: %s' % (value) + ) + + return True + + def get_policy_global_aae( + self, + policy_global_aae_filter=None, + domain_info=False, + node_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_policies = self.get_policy_global_aae_mo() + if all_policies is None: + return None + + policy_global_aae = [] + + for managed_object in all_policies: + policy_global_aae_info = self.get_policy_global_aae_info( + managed_object + ) + + if not self.match_policy_global_aae(policy_global_aae_info, policy_global_aae_filter): + continue + + if domain_info: + policy_global_aae_info = self.extend_policy_global_aae_domain_info( + policy_global_aae_info + ) + + if node_info: + domain_node_info = self.get_policy_global_aae_node( + policy_global_aae_info['name'] + ) + policy_global_aae_info['node'] = None + policy_global_aae_info['interface'] = None + if domain_node_info is not None: + policy_global_aae_info['node'] = domain_node_info['node'] + policy_global_aae_info['interface'] = domain_node_info['interface'] + + if fault_info: + policy_global_aae_info['faultInst'] = self.get_policy_global_aae_id_fault( + policy_global_aae_info['name'], + 'faultInst' + ) + + if hfault_info: + policy_global_aae_info['faultRecord'] = self.get_policy_global_aae_id_fault( + policy_global_aae_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + policy_global_aae_info['eventLog'] = self.get_policy_global_aae_id_event( + policy_global_aae_info['name'], + event_filter=event_filter + ) + + if audit_info: + policy_global_aae_info['auditLog'] = self.get_policy_global_aae_id_audit( + policy_global_aae_info['name'], + audit_filter=audit_filter + ) + + policy_global_aae.append(policy_global_aae_info) + + policy_global_aae = sorted( + policy_global_aae, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'infraAttEntityP.info', + policy_global_aae + ) + + return policy_global_aae diff --git a/lib/aci/policy/general/aae/main.py b/lib/aci/policy/general/aae/main.py new file mode 100644 index 00000000..a8af413e --- /dev/null +++ b/lib/aci/policy/general/aae/main.py @@ -0,0 +1,23 @@ +from lib.aci.policy.general.aae.api import PolicyGeneralAaeApi +from lib.aci.policy.general.aae.info import PolicyGeneralAaeInfo +from lib.aci.policy.general.aae.audit.main import PolicyGeneralAaeAudit +from lib.aci.policy.general.aae.event.main import PolicyGeneralAaeEvent +from lib.aci.policy.general.aae.fault.main import PolicyGeneralAaeFault +from lib.aci.policy.general.aae.node.main import PolicyGeneralAaeNode + + +class PolicyGeneralAae( + PolicyGeneralAaeApi, + PolicyGeneralAaeInfo, + PolicyGeneralAaeAudit, + PolicyGeneralAaeEvent, + PolicyGeneralAaeFault, + PolicyGeneralAaeNode + ): + def __init__(self): + PolicyGeneralAaeApi.__init__(self) + PolicyGeneralAaeInfo.__init__(self) + PolicyGeneralAaeAudit.__init__(self) + PolicyGeneralAaeEvent.__init__(self) + PolicyGeneralAaeFault.__init__(self) + PolicyGeneralAaeNode.__init__(self) diff --git a/lib/aci/policy/general/aae/node/__init__.py b/lib/aci/policy/general/aae/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/general/aae/node/api.py b/lib/aci/policy/general/aae/node/api.py new file mode 100644 index 00000000..3a8c2acf --- /dev/null +++ b/lib/aci/policy/general/aae/node/api.py @@ -0,0 +1,54 @@ +class PolicyGeneralAaeNodeApi(): + def __init__(self): + self.policy_global_aae_node_mo = {} + + def get_policy_global_aae_node_mo(self, policy_name): + if policy_name in self.policy_global_aae_node_mo: + return self.policy_global_aae_node_mo[policy_name] + + key = policy_name + cache = self.get_object_cache( + 'infraAttEntityP.%s' % (key) + ) + if cache is not None: + self.policy_global_aae_node_mo[key] = cache + self.log.apic_mo( + 'infraAttEntityP.%s' % (key), + self.policy_global_aae_node_mo[key] + ) + return self.policy_global_aae_node_mo[key] + + distinguished_name = 'uni/infra/attentp-%s' % (policy_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=AttEntityPToPthIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_policy_global_aae_node_mo', + 'API failed' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['infraAttEntityP']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'infraAttEntityP', + managed_object + ) + self.policy_global_aae_node_mo[key] = attributes + + self.log.apic_mo( + 'infraAttEntityP.%s' % (key), + self.policy_global_aae_node_mo[key] + ) + + self.set_object_cache( + 'infraAttEntityP.%s' % (key), + self.policy_global_aae_node_mo[key] + ) + + return self.policy_global_aae_node_mo[key] diff --git a/lib/aci/policy/general/aae/node/info.py b/lib/aci/policy/general/aae/node/info.py new file mode 100644 index 00000000..53c7a201 --- /dev/null +++ b/lib/aci/policy/general/aae/node/info.py @@ -0,0 +1,79 @@ +class PolicyGeneralAaeNodeInfo(): + def __init__(self): + self.policy_global_aae_node = {} + + def get_policy_global_aae_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/phys-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_policy_global_aae_node(self, domain_name): + if domain_name in self.policy_global_aae_node: + return self.policy_global_aae_node[domain_name] + + # one object or None value is expected + domain_nodes_mo = self.get_policy_global_aae_node_mo(domain_name) + if domain_nodes_mo is None: + return None + + self.policy_global_aae_node[domain_name] = self.get_policy_global_aae_node_info( + domain_nodes_mo + ) + + self.log.apic_mo( + 'infraAttEntityP.%s.info' % (domain_name), + self.policy_global_aae_node[domain_name] + ) + + return self.policy_global_aae_node[domain_name] diff --git a/lib/aci/policy/general/aae/node/main.py b/lib/aci/policy/general/aae/node/main.py new file mode 100644 index 00000000..39e913f8 --- /dev/null +++ b/lib/aci/policy/general/aae/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.general.aae.node.api import PolicyGeneralAaeNodeApi +from lib.aci.policy.general.aae.node.info import PolicyGeneralAaeNodeInfo + + +class PolicyGeneralAaeNode(PolicyGeneralAaeNodeApi, PolicyGeneralAaeNodeInfo): + def __init__(self): + PolicyGeneralAaeNodeApi.__init__(self) + PolicyGeneralAaeNodeInfo.__init__(self) diff --git a/lib/aci/policy/general/aae/output.py b/lib/aci/policy/general/aae/output.py new file mode 100644 index 00000000..26e1836a --- /dev/null +++ b/lib/aci/policy/general/aae/output.py @@ -0,0 +1,445 @@ +class PolicyGeneralAaeOutput(): + def __init__(self): + pass + + def print_policies_global_aae(self, info, title=False): + if title: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + if len(item['infraRsFuncToEpg']) == 0: + item['infraRsFuncToEpg'].append( + dict( + epgName='--' + ) + ) + + order = [ + 'faults', + 'name', + 'infraVlanEnabledTick', + 'infraRsDomP.domainType', + 'infraRsDomP.domainName', + 'infraRsDomP.state', + 'infraRsFuncToEpg.epgEncap', + 'infraRtAttEntP.typeName', + 'infraRtAttEntP.name' + ] + + headers = [ + 'Faults', + 'Name', + 'Infra VLAN', + 'Domain Type', + 'Domain Name', + 'Domain State', + 'EPG', + 'PG Interface Type', + 'PG Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['infraRsDomP', 'infraRtAttEntP', 'infraRsFuncToEpg'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policies_global_aae_epg(self, info, title=False): + if title: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - EPG Usage [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['epg'] = [] + if 'vlan_info' in item: + if item['vlan_info'] is not None: + item['epg'] = item['vlan_info']['epg'] + + order = [ + 'faults', + 'name', + 'aaep_names', + 'vlan', + 'epg.vlanId', + 'epg.tenantAppEpg' + ] + + headers = [ + 'Faults', + 'Domain', + 'AAEP', + 'VLAN Pool', + 'Vlan', + 'EPG' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'epg'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policies_global_aae_node(self, info, title=False): + if title: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Faults', + 'Name', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policies_global_aae_reln(self, info, title=False): + if title: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Relationships [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'reln.type', + 'reln.name' + ] + + headers = [ + 'Faults', + 'Domain', + 'Policy Type', + 'Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['reln'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policies_global_aae_interface(self, info, title=False): + if title: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'interface.node_name', + 'interface.intf_type', + 'interface.intf_name' + ] + + headers = [ + 'Faults', + 'Name', + 'Node', + 'Intf Type', + 'Intf Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['aaep_names', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_policies_global_aae_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'policyName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_policies_global_aae_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'policyName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_policies_global_aae_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'policyName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_policies_global_aae_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Attachable Access Entity Profile (AAEP) - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'policyName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/general/main.py b/lib/aci/policy/general/main.py new file mode 100644 index 00000000..66f7e434 --- /dev/null +++ b/lib/aci/policy/general/main.py @@ -0,0 +1,6 @@ +from lib.aci.policy.general.aae.main import PolicyGeneralAae + + +class PolicyGeneral(PolicyGeneralAae): + def __init__(self): + PolicyGeneralAae.__init__(self) diff --git a/lib/aci/policy/general/output.py b/lib/aci/policy/general/output.py new file mode 100644 index 00000000..0fab0e76 --- /dev/null +++ b/lib/aci/policy/general/output.py @@ -0,0 +1,6 @@ +from lib.aci.policy.general.aae.output import PolicyGeneralAaeOutput + + +class PolicyGeneralOutput(PolicyGeneralAaeOutput): + def __init__(self): + PolicyGeneralAaeOutput.__init__(self) diff --git a/lib/aci/policy/interface/__init__.py b/lib/aci/policy/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0f0e5246 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/cdp.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/cdp.cpython-310.pyc new file mode 100644 index 00000000..a23cc21d Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/cdp.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..3e632e4d Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/fc.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/fc.cpython-310.pyc new file mode 100644 index 00000000..ee49ea25 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/fc.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/l2.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/l2.cpython-310.pyc new file mode 100644 index 00000000..12ce9821 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/l2.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/link_flap.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/link_flap.cpython-310.pyc new file mode 100644 index 00000000..aee4445f Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/link_flap.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/link_level.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/link_level.cpython-310.pyc new file mode 100644 index 00000000..2fe61e06 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/link_level.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/lldp.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/lldp.cpython-310.pyc new file mode 100644 index 00000000..14448445 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/lldp.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/macsec.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/macsec.cpython-310.pyc new file mode 100644 index 00000000..ab569ff1 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/macsec.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7aa1d0eb Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/mcp.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/mcp.cpython-310.pyc new file mode 100644 index 00000000..f63a9edc Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/mcp.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..7e4af86f Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/port_channel.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/port_channel.cpython-310.pyc new file mode 100644 index 00000000..f5b71d9a Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/port_channel.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/port_security.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/port_security.cpython-310.pyc new file mode 100644 index 00000000..3019c7ce Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/port_security.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/storm_control.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/storm_control.cpython-310.pyc new file mode 100644 index 00000000..8027930e Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/storm_control.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/__pycache__/stp.cpython-310.pyc b/lib/aci/policy/interface/__pycache__/stp.cpython-310.pyc new file mode 100644 index 00000000..bd604cc8 Binary files /dev/null and b/lib/aci/policy/interface/__pycache__/stp.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__init__.py b/lib/aci/policy/interface/auth/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/auth/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95be65e6 Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..24fc78f0 Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..d1cc36fc Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..a1e174d0 Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..d058b39e Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8a4f05f5 Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..9739d7d6 Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/__pycache__/vmm.cpython-310.pyc b/lib/aci/policy/interface/auth/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..2edf8688 Binary files /dev/null and b/lib/aci/policy/interface/auth/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/api.py b/lib/aci/policy/interface/auth/api.py new file mode 100644 index 00000000..ccb22807 --- /dev/null +++ b/lib/aci/policy/interface/auth/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceAuthApi(): + def __init__(self): + self.policy_interface_auth_mo = None + + def get_policy_interface_auth_mo(self): + if self.policy_interface_auth_mo is not None: + return self.policy_interface_auth_mo + + cache = self.get_object_cache( + 'l2PortAuthPol' + ) + if cache is not None: + self.policy_interface_auth_mo = cache + self.log.apic_mo( + 'l2PortAuthPol', + self.policy_interface_auth_mo + ) + return self.policy_interface_auth_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'l2PortAuthPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_auth_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2PortAuthPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'l2PortAuthPol' + ) + + self.policy_interface_auth_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2PortAuthPol', + self.policy_interface_auth_mo + ) + + self.set_object_cache( + 'l2PortAuthPol', + self.policy_interface_auth_mo + ) + + return self.policy_interface_auth_mo diff --git a/lib/aci/policy/interface/auth/attachment/__init__.py b/lib/aci/policy/interface/auth/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/auth/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/auth/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/auth/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/auth/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..29df975c Binary files /dev/null and b/lib/aci/policy/interface/auth/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/auth/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..dffcaf7d Binary files /dev/null and b/lib/aci/policy/interface/auth/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/auth/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..81ae8898 Binary files /dev/null and b/lib/aci/policy/interface/auth/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/auth/attachment/api.py b/lib/aci/policy/interface/auth/attachment/api.py new file mode 100644 index 00000000..9e499c9f --- /dev/null +++ b/lib/aci/policy/interface/auth/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceAuthAttachmentApi(): + def __init__(self): + self.policy_interface_auth_attachment_mo = None + + def get_policy_interface_auth_attachment_mo(self): + if self.policy_interface_auth_attachment_mo is not None: + return self.policy_interface_auth_attachment_mo + + cache = self.get_object_cache( + 'l1RsL2PortAuthCons' + ) + if cache is not None: + self.policy_interface_auth_attachment_mo = cache + self.log.apic_mo( + 'l1RsL2PortAuthCons', + self.policy_interface_auth_attachment_mo + ) + return self.policy_interface_auth_attachment_mo + + managed_objects = self.get_class( + 'l1RsL2PortAuthCons' + ) + if managed_objects is None: + return None + + self.policy_interface_auth_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_auth_attachment_mo.append( + managed_object['l1RsL2PortAuthCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsL2PortAuthCons', + self.policy_interface_auth_attachment_mo + ) + + self.set_object_cache( + 'l1RsL2PortAuthCons', + self.policy_interface_auth_attachment_mo + ) + + return self.policy_interface_auth_attachment_mo diff --git a/lib/aci/policy/interface/auth/attachment/info.py b/lib/aci/policy/interface/auth/attachment/info.py new file mode 100644 index 00000000..01b2a9a6 --- /dev/null +++ b/lib/aci/policy/interface/auth/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceAuthAttachmentInfo(): + def __init__(self): + self.policy_interface_auth_attachment = None + + def get_policy_interface_auth_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rscdpIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "cdpIfPol", + # "tDn": "uni/infra/cdpIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_auth_attachments_info(self): + if self.policy_interface_auth_attachment is not None: + return self.policy_interface_auth_attachment + + managed_objects = self.get_policy_interface_auth_attachment_mo() + if managed_objects is not None: + self.policy_interface_auth_attachment = [] + for managed_object in managed_objects: + self.policy_interface_auth_attachment.append( + self.get_policy_interface_auth_attachment_info( + managed_object + ) + ) + + return self.policy_interface_auth_attachment + + def match_policy_interface_auth_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_auth_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_auth_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_auth_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_auth_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/auth/attachment/main.py b/lib/aci/policy/interface/auth/attachment/main.py new file mode 100644 index 00000000..3ae8f46b --- /dev/null +++ b/lib/aci/policy/interface/auth/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.auth.attachment.api import PolicyInterfaceAuthAttachmentApi +from lib.aci.policy.interface.auth.attachment.info import PolicyInterfaceAuthAttachmentInfo + + +class PolicyInterfaceAuthAttachment(PolicyInterfaceAuthAttachmentApi, PolicyInterfaceAuthAttachmentInfo): + def __init__(self): + PolicyInterfaceAuthAttachmentApi.__init__(self) + PolicyInterfaceAuthAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/auth/context.py b/lib/aci/policy/interface/auth/context.py new file mode 100644 index 00000000..94042ffe --- /dev/null +++ b/lib/aci/policy/interface/auth/context.py @@ -0,0 +1,63 @@ +class PolicyInterfaceAuthContext(): + def __init__(self): + pass + + def set_policy_interface_auth_context(self, policies): + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsL2PortAuthCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-auth-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_auth_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_auth_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/auth/info.py b/lib/aci/policy/interface/auth/info.py new file mode 100644 index 00000000..8f957829 --- /dev/null +++ b/lib/aci/policy/interface/auth/info.py @@ -0,0 +1,207 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceAuthInfo(): + def __init__(self): + self.policy_interface_auth = None + + def get_policy_interface_auth_reln_info(self, managed_object): + info = {} + info['class'] = 'l2PortAuthPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_auth_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/portauthpol-default", + # "extMngdBy": "", + # "hostMode": "single-host", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'adminSt', + 'annotation', + 'dn', + 'hostMode', + 'name' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_auth_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_auth_info(self): + if self.policy_interface_auth is not None: + return self.policy_interface_auth + + managed_objects = self.get_policy_interface_auth_mo() + if managed_objects is not None: + self.policy_interface_auth = [] + for managed_object in managed_objects: + self.policy_interface_auth.append( + self.get_policy_interface_auth_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l2PortAuthPol.info', + self.policy_interface_auth + ) + + return self.policy_interface_auth + + def match_policy_interface_auth(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsL2PortAuthCons' in policy_info: + if len(policy_info['l1RsL2PortAuthCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + return True + + def match_policy_interface_auth_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_auth(self, policy_filter=None, attachment_info=False): + all_policies = self.get_policies_interface_auth_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_auth(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_auth_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_auth(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsL2PortAuthCons'] = self.get_policy_interface_auth_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsL2PortAuthCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsL2PortAuthCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_auth_attachments_node_summary( + policy_info['l1RsL2PortAuthCons'] + ) + + if not self.match_policy_interface_auth(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/auth/main.py b/lib/aci/policy/interface/auth/main.py new file mode 100644 index 00000000..75abbd89 --- /dev/null +++ b/lib/aci/policy/interface/auth/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.auth.attachment.main import PolicyInterfaceAuthAttachment +from lib.aci.policy.interface.auth.api import PolicyInterfaceAuthApi +from lib.aci.policy.interface.auth.context import PolicyInterfaceAuthContext +from lib.aci.policy.interface.auth.info import PolicyInterfaceAuthInfo + + +class PolicyInterfaceAuth(PolicyInterfaceAuthAttachment, PolicyInterfaceAuthApi, PolicyInterfaceAuthContext, PolicyInterfaceAuthInfo): + def __init__(self): + PolicyInterfaceAuthAttachment.__init__(self) + PolicyInterfaceAuthApi.__init__(self) + PolicyInterfaceAuthContext.__init__(self) + PolicyInterfaceAuthInfo.__init__(self) diff --git a/lib/aci/policy/interface/auth/output.py b/lib/aci/policy/interface/auth/output.py new file mode 100644 index 00000000..0368b35e --- /dev/null +++ b/lib/aci/policy/interface/auth/output.py @@ -0,0 +1,185 @@ +class PolicyInterfaceAuthOutput(): + def __init__(self): + pass + + def print_policy_interface_auth(self, info): + self.print_policy_interface_auth_properties( + info + ) + + self.print_policy_interface_auth_interfaces( + info['l1RsL2PortAuthCons'] + ) + + self.print_policy_interface_auth_references( + info['relnFrom'] + ) + + def print_policy_interface_auth_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt', + 'hostMode' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Host Mode' + ] + + self.my_output.dictionary( + info, + title='802.1x Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_auth_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_auth_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_auth_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'hostMode', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Host Mode', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_auth_usage(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'hostMode', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Host Mode', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_auth_interfaces(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'hostMode', + 'l1RsL2PortAuthCons.pod_node_name', + 'l1RsL2PortAuthCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Host Mode', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsL2PortAuthCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/cdp/__init__.py b/lib/aci/policy/interface/cdp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/cdp/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95be65e6 Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8d588fff Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..848ebf74 Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..9a8072c6 Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..65ce6341 Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2e36235e Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..57ec675f Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/__pycache__/vmm.cpython-310.pyc b/lib/aci/policy/interface/cdp/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..2edf8688 Binary files /dev/null and b/lib/aci/policy/interface/cdp/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/api.py b/lib/aci/policy/interface/cdp/api.py new file mode 100644 index 00000000..f89a19c0 --- /dev/null +++ b/lib/aci/policy/interface/cdp/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceCdpApi(): + def __init__(self): + self.policy_interface_cdp_mo = None + + def get_policy_interface_cdp_mo(self): + if self.policy_interface_cdp_mo is not None: + return self.policy_interface_cdp_mo + + cache = self.get_object_cache( + 'cdpIfPol' + ) + if cache is not None: + self.policy_interface_cdp_mo = cache + self.log.apic_mo( + 'cdpIfPol', + self.policy_interface_cdp_mo + ) + return self.policy_interface_cdp_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'cdpIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_cdp_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['cdpIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'cdpIfPol' + ) + + self.policy_interface_cdp_mo.append( + attributes + ) + + self.log.apic_mo( + 'cdpIfPol', + self.policy_interface_cdp_mo + ) + + self.set_object_cache( + 'cdpIfPol', + self.policy_interface_cdp_mo + ) + + return self.policy_interface_cdp_mo diff --git a/lib/aci/policy/interface/cdp/attachment/__init__.py b/lib/aci/policy/interface/cdp/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/cdp/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/cdp/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/cdp/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/cdp/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..fcdd0075 Binary files /dev/null and b/lib/aci/policy/interface/cdp/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/cdp/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..24f2d9a1 Binary files /dev/null and b/lib/aci/policy/interface/cdp/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/cdp/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f260bcf1 Binary files /dev/null and b/lib/aci/policy/interface/cdp/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/cdp/attachment/api.py b/lib/aci/policy/interface/cdp/attachment/api.py new file mode 100644 index 00000000..1dd1f7bb --- /dev/null +++ b/lib/aci/policy/interface/cdp/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceCdpAttachmentApi(): + def __init__(self): + self.policy_interface_cdp_attachment_mo = None + + def get_policy_interface_cdp_attachment_mo(self): + if self.policy_interface_cdp_attachment_mo is not None: + return self.policy_interface_cdp_attachment_mo + + cache = self.get_object_cache( + 'l1RsCdpIfPolCons' + ) + if cache is not None: + self.policy_interface_cdp_attachment_mo = cache + self.log.apic_mo( + 'l1RsCdpIfPolCons', + self.policy_interface_cdp_attachment_mo + ) + return self.policy_interface_cdp_attachment_mo + + managed_objects = self.get_class( + 'l1RsCdpIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_cdp_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_cdp_attachment_mo.append( + managed_object['l1RsCdpIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsCdpIfPolCons', + self.policy_interface_cdp_attachment_mo + ) + + self.set_object_cache( + 'l1RsCdpIfPolCons', + self.policy_interface_cdp_attachment_mo + ) + + return self.policy_interface_cdp_attachment_mo diff --git a/lib/aci/policy/interface/cdp/attachment/info.py b/lib/aci/policy/interface/cdp/attachment/info.py new file mode 100644 index 00000000..eeb05735 --- /dev/null +++ b/lib/aci/policy/interface/cdp/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceCdpAttachmentInfo(): + def __init__(self): + self.policy_interface_cdp_attachment = None + + def get_policy_interface_cdp_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rscdpIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "cdpIfPol", + # "tDn": "uni/infra/cdpIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_cdp_attachments_info(self): + if self.policy_interface_cdp_attachment is not None: + return self.policy_interface_cdp_attachment + + managed_objects = self.get_policy_interface_cdp_attachment_mo() + if managed_objects is not None: + self.policy_interface_cdp_attachment = [] + for managed_object in managed_objects: + self.policy_interface_cdp_attachment.append( + self.get_policy_interface_cdp_attachment_info( + managed_object + ) + ) + + return self.policy_interface_cdp_attachment + + def match_policy_interface_cdp_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_cdp_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_cdp_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_cdp_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_cdp_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/cdp/attachment/main.py b/lib/aci/policy/interface/cdp/attachment/main.py new file mode 100644 index 00000000..fd2f0941 --- /dev/null +++ b/lib/aci/policy/interface/cdp/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.cdp.attachment.api import PolicyInterfaceCdpAttachmentApi +from lib.aci.policy.interface.cdp.attachment.info import PolicyInterfaceCdpAttachmentInfo + + +class PolicyInterfaceCdpAttachment(PolicyInterfaceCdpAttachmentApi, PolicyInterfaceCdpAttachmentInfo): + def __init__(self): + PolicyInterfaceCdpAttachmentApi.__init__(self) + PolicyInterfaceCdpAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/cdp/context.py b/lib/aci/policy/interface/cdp/context.py new file mode 100644 index 00000000..17dd839d --- /dev/null +++ b/lib/aci/policy/interface/cdp/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceCdpContext(): + def __init__(self): + pass + + def set_policy_interface_cdp_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "cdpIfPol", + # "policyDn": "uni/infra/cdpIfP-k8s_cdp_enable", + # "policyName": "k8s_cdp_enable" + # + # Context + # "cdp": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsCdpIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-cdp-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_cdp_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_cdp_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/cdp/info.py b/lib/aci/policy/interface/cdp/info.py new file mode 100644 index 00000000..86009782 --- /dev/null +++ b/lib/aci/policy/interface/cdp/info.py @@ -0,0 +1,224 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceCdpInfo(): + def __init__(self): + self.policy_interface_cdp = None + + def get_policy_interface_cdp_reln_info(self, managed_object): + info = {} + info['class'] = 'cdpIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_cdp_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/portcdppol-default", + # "extMngdBy": "", + # "hostMode": "single-host", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'adminSt', + 'annotation', + 'dn', + 'hostMode', + 'name' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_cdp_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_cdp_info(self): + if self.policy_interface_cdp is not None: + return self.policy_interface_cdp + + managed_objects = self.get_policy_interface_cdp_mo() + if managed_objects is not None: + self.policy_interface_cdp = [] + for managed_object in managed_objects: + self.policy_interface_cdp.append( + self.get_policy_interface_cdp_info( + managed_object + ) + ) + + self.log.apic_mo( + 'cdpIfPol.info', + self.policy_interface_cdp + ) + + return self.policy_interface_cdp + + def match_policy_interface_cdp(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsCdpIfPolCons' in policy_info: + if len(policy_info['l1RsCdpIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsCdpIfPolCons' in policy_info: + if len(policy_info['l1RsCdpIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsCdpIfPolCons' in policy_info: + if len(policy_info['l1RsCdpIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_cdp_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_cdp(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_cdp_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_cdp(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_cdp_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_cdp(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsCdpIfPolCons'] = self.get_policy_interface_cdp_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsCdpIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsCdpIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_cdp_attachments_node_summary( + policy_info['l1RsCdpIfPolCons'] + ) + + if not self.match_policy_interface_cdp(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/cdp/main.py b/lib/aci/policy/interface/cdp/main.py new file mode 100644 index 00000000..c482eefe --- /dev/null +++ b/lib/aci/policy/interface/cdp/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.cdp.attachment.main import PolicyInterfaceCdpAttachment +from lib.aci.policy.interface.cdp.api import PolicyInterfaceCdpApi +from lib.aci.policy.interface.cdp.context import PolicyInterfaceCdpContext +from lib.aci.policy.interface.cdp.info import PolicyInterfaceCdpInfo + + +class PolicyInterfaceCdp(PolicyInterfaceCdpAttachment, PolicyInterfaceCdpApi, PolicyInterfaceCdpContext, PolicyInterfaceCdpInfo): + def __init__(self): + PolicyInterfaceCdpAttachment.__init__(self) + PolicyInterfaceCdpApi.__init__(self) + PolicyInterfaceCdpContext.__init__(self) + PolicyInterfaceCdpInfo.__init__(self) diff --git a/lib/aci/policy/interface/cdp/output.py b/lib/aci/policy/interface/cdp/output.py new file mode 100644 index 00000000..a5871f85 --- /dev/null +++ b/lib/aci/policy/interface/cdp/output.py @@ -0,0 +1,169 @@ +class PolicyInterfaceCdpOutput(): + def __init__(self): + pass + + def print_policy_interface_cdp(self, info): + self.print_policy_interface_cdp_properties( + info + ) + + self.print_policy_interface_cdp_interfaces( + info['l1RsCdpIfPolCons'] + ) + + self.print_policy_interface_cdp_references( + info['relnFrom'] + ) + + def print_policy_interface_cdp_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State' + ] + + self.my_output.dictionary( + info, + title='CDP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_cdp_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_cdp_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_cdp_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_cdp_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_cdp_interfaces(self, info): + order = [ + 'name', + 'l1RsCdpIfPolCons.pod_node_name', + 'l1RsCdpIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsCdpIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/copp/__init__.py b/lib/aci/policy/interface/copp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/copp/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95be65e6 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..23d82e5b Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..fd92a986 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..0f91eaf7 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..77d1367d Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..28fd3242 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..2d227c56 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/protocol.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/protocol.cpython-310.pyc new file mode 100644 index 00000000..4a9b35b8 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/protocol.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/__pycache__/vmm.cpython-310.pyc b/lib/aci/policy/interface/copp/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..2edf8688 Binary files /dev/null and b/lib/aci/policy/interface/copp/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/api.py b/lib/aci/policy/interface/copp/api.py new file mode 100644 index 00000000..e01f8aad --- /dev/null +++ b/lib/aci/policy/interface/copp/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceCoppApi(): + def __init__(self): + self.policy_interface_copp_mo = None + + def get_policy_interface_copp_mo(self): + if self.policy_interface_copp_mo is not None: + return self.policy_interface_copp_mo + + cache = self.get_object_cache( + 'coppIfPol' + ) + if cache is not None: + self.policy_interface_copp_mo = cache + self.log.apic_mo( + 'coppIfPol', + self.policy_interface_copp_mo + ) + return self.policy_interface_copp_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'coppIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_copp_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['coppIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'coppIfPol' + ) + + self.policy_interface_copp_mo.append( + attributes + ) + + self.log.apic_mo( + 'coppIfPol', + self.policy_interface_copp_mo + ) + + self.set_object_cache( + 'coppIfPol', + self.policy_interface_copp_mo + ) + + return self.policy_interface_copp_mo diff --git a/lib/aci/policy/interface/copp/attachment/__init__.py b/lib/aci/policy/interface/copp/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/copp/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/copp/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/copp/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/copp/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..aee18dce Binary files /dev/null and b/lib/aci/policy/interface/copp/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/copp/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..8bbba285 Binary files /dev/null and b/lib/aci/policy/interface/copp/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/copp/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..baf1ab5c Binary files /dev/null and b/lib/aci/policy/interface/copp/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/attachment/api.py b/lib/aci/policy/interface/copp/attachment/api.py new file mode 100644 index 00000000..1125b6d1 --- /dev/null +++ b/lib/aci/policy/interface/copp/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceCoppAttachmentApi(): + def __init__(self): + self.policy_interface_copp_attachment_mo = None + + def get_policy_interface_copp_attachment_mo(self): + if self.policy_interface_copp_attachment_mo is not None: + return self.policy_interface_copp_attachment_mo + + cache = self.get_object_cache( + 'l1RsCoppIfPolCons' + ) + if cache is not None: + self.policy_interface_copp_attachment_mo = cache + self.log.apic_mo( + 'l1RsCoppIfPolCons', + self.policy_interface_copp_attachment_mo + ) + return self.policy_interface_copp_attachment_mo + + managed_objects = self.get_class( + 'l1RsCoppIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_copp_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_copp_attachment_mo.append( + managed_object['l1RsCoppIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsCoppIfPolCons', + self.policy_interface_copp_attachment_mo + ) + + self.set_object_cache( + 'l1RsCoppIfPolCons', + self.policy_interface_copp_attachment_mo + ) + + return self.policy_interface_copp_attachment_mo diff --git a/lib/aci/policy/interface/copp/attachment/info.py b/lib/aci/policy/interface/copp/attachment/info.py new file mode 100644 index 00000000..791ee114 --- /dev/null +++ b/lib/aci/policy/interface/copp/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceCoppAttachmentInfo(): + def __init__(self): + self.policy_interface_copp_attachment = None + + def get_policy_interface_copp_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rscoppIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "coppIfPol", + # "tDn": "uni/infra/coppIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_copp_attachments_info(self): + if self.policy_interface_copp_attachment is not None: + return self.policy_interface_copp_attachment + + managed_objects = self.get_policy_interface_copp_attachment_mo() + if managed_objects is not None: + self.policy_interface_copp_attachment = [] + for managed_object in managed_objects: + self.policy_interface_copp_attachment.append( + self.get_policy_interface_copp_attachment_info( + managed_object + ) + ) + + return self.policy_interface_copp_attachment + + def match_policy_interface_copp_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_copp_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_copp_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_copp_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_copp_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/copp/attachment/main.py b/lib/aci/policy/interface/copp/attachment/main.py new file mode 100644 index 00000000..8e5b30f9 --- /dev/null +++ b/lib/aci/policy/interface/copp/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.copp.attachment.api import PolicyInterfaceCoppAttachmentApi +from lib.aci.policy.interface.copp.attachment.info import PolicyInterfaceCoppAttachmentInfo + + +class PolicyInterfaceCoppAttachment(PolicyInterfaceCoppAttachmentApi, PolicyInterfaceCoppAttachmentInfo): + def __init__(self): + PolicyInterfaceCoppAttachmentApi.__init__(self) + PolicyInterfaceCoppAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/copp/context.py b/lib/aci/policy/interface/copp/context.py new file mode 100644 index 00000000..fc8faac8 --- /dev/null +++ b/lib/aci/policy/interface/copp/context.py @@ -0,0 +1,63 @@ +class PolicyInterfaceCoppContext(): + def __init__(self): + pass + + def set_policy_interface_copp_context(self, policies): + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsCoppIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-copp-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_copp_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_copp_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/copp/info.py b/lib/aci/policy/interface/copp/info.py new file mode 100644 index 00000000..a138d01b --- /dev/null +++ b/lib/aci/policy/interface/copp/info.py @@ -0,0 +1,227 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceCoppInfo(): + def __init__(self): + self.policy_interface_copp = None + + def get_policy_interface_copp_reln_info(self, managed_object): + info = {} + info['class'] = 'coppIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_copp_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/portcopppol-default", + # "extMngdBy": "", + # "hostMode": "single-host", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'adminSt', + 'annotation', + 'dn', + 'hostMode', + 'name' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_copp_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_copp_info(self): + if self.policy_interface_copp is not None: + return self.policy_interface_copp + + managed_objects = self.get_policy_interface_copp_mo() + if managed_objects is not None: + self.policy_interface_copp = [] + for managed_object in managed_objects: + self.policy_interface_copp.append( + self.get_policy_interface_copp_info( + managed_object + ) + ) + + self.log.apic_mo( + 'coppIfPol.info', + self.policy_interface_copp + ) + + return self.policy_interface_copp + + def match_policy_interface_copp(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsCoppIfPolCons' in policy_info: + if len(policy_info['l1RsCoppIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsCoppIfPolCons' in policy_info: + if len(policy_info['l1RsCoppIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsCoppIfPolCons' in policy_info: + if len(policy_info['l1RsCoppIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_copp_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_copp(self, policy_filter=None, attachment_info=False): + all_policies = self.get_policies_interface_copp_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_copp(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_copp_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_copp(policy_info, policy_filter): + continue + + policy_info['protocol'] = self.get_policy_interface_copp_protocols() + policy_info['protocolCount'] = len(policy_info['protocol']) + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsCoppIfPolCons'] = self.get_policy_interface_copp_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsCoppIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsCoppIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_copp_attachments_node_summary( + policy_info['l1RsCoppIfPolCons'] + ) + + if not self.match_policy_interface_copp(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/copp/main.py b/lib/aci/policy/interface/copp/main.py new file mode 100644 index 00000000..64a1abac --- /dev/null +++ b/lib/aci/policy/interface/copp/main.py @@ -0,0 +1,14 @@ +from lib.aci.policy.interface.copp.attachment.main import PolicyInterfaceCoppAttachment +from lib.aci.policy.interface.copp.api import PolicyInterfaceCoppApi +from lib.aci.policy.interface.copp.context import PolicyInterfaceCoppContext +from lib.aci.policy.interface.copp.info import PolicyInterfaceCoppInfo +from lib.aci.policy.interface.copp.protocol.main import PolicyInterfaceCoppProtocol + + +class PolicyInterfaceCopp(PolicyInterfaceCoppAttachment, PolicyInterfaceCoppApi, PolicyInterfaceCoppContext, PolicyInterfaceCoppInfo, PolicyInterfaceCoppProtocol): + def __init__(self): + PolicyInterfaceCoppAttachment.__init__(self) + PolicyInterfaceCoppApi.__init__(self) + PolicyInterfaceCoppContext.__init__(self) + PolicyInterfaceCoppInfo.__init__(self) + PolicyInterfaceCoppProtocol.__init__(self) diff --git a/lib/aci/policy/interface/copp/output.py b/lib/aci/policy/interface/copp/output.py new file mode 100644 index 00000000..40538bb8 --- /dev/null +++ b/lib/aci/policy/interface/copp/output.py @@ -0,0 +1,177 @@ +class PolicyInterfaceCoppOutput(): + def __init__(self): + pass + + def print_policy_interface_copp(self, info): + self.print_policy_interface_copp_properties( + info + ) + + self.print_policy_interface_copp_interfaces( + info['l1RsCoppIfPolCons'] + ) + + self.print_policy_interface_copp_references( + info['relnFrom'] + ) + + def print_policy_interface_copp_properties(self, info): + order = [ + 'name', + 'tf', + 'protocolCount' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Protocol Count' + ] + + self.my_output.dictionary( + info, + title='CoPP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_copp_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_copp_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_copp_summary(self, info): + order = [ + 'name', + 'tfTick', + 'protocolCount', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Protocols', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_copp_usage(self, info): + order = [ + 'name', + 'tfTick', + 'protocolCount', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Protocols', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_copp_interfaces(self, info): + order = [ + 'name', + 'tfTick', + 'protocolCount', + 'l1RsCoppIfPolCons.pod_node_name', + 'l1RsCoppIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Protocols', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsCoppIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/copp/protocol/__init__.py b/lib/aci/policy/interface/copp/protocol/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/copp/protocol/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/copp/protocol/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/copp/protocol/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/protocol/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/copp/protocol/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..0d2f5b11 Binary files /dev/null and b/lib/aci/policy/interface/copp/protocol/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/protocol/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/copp/protocol/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..d35a83ef Binary files /dev/null and b/lib/aci/policy/interface/copp/protocol/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/protocol/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/copp/protocol/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..00eca6b4 Binary files /dev/null and b/lib/aci/policy/interface/copp/protocol/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/copp/protocol/api.py b/lib/aci/policy/interface/copp/protocol/api.py new file mode 100644 index 00000000..3425541e --- /dev/null +++ b/lib/aci/policy/interface/copp/protocol/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceCoppProtocolApi(): + def __init__(self): + self.policy_interface_copp_protocol_mo = None + + def get_policy_interface_copp_protocol_mo(self): + if self.policy_interface_copp_protocol_mo is not None: + return self.policy_interface_copp_protocol_mo + + cache = self.get_object_cache( + 'coppProtoClassP' + ) + if cache is not None: + self.policy_interface_copp_protocol_mo = cache + self.log.apic_mo( + 'coppProtoClassP', + self.policy_interface_copp_protocol_mo + ) + return self.policy_interface_copp_protocol_mo + + managed_objects = self.get_class( + 'coppProtoClassP' + ) + if managed_objects is None: + return None + + self.policy_interface_copp_protocol_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_copp_protocol_mo.append( + managed_object['coppProtoClassP']['attributes'] + ) + + self.log.apic_mo( + 'coppProtoClassP', + self.policy_interface_copp_protocol_mo + ) + + self.set_object_cache( + 'coppProtoClassP', + self.policy_interface_copp_protocol_mo + ) + + return self.policy_interface_copp_protocol_mo diff --git a/lib/aci/policy/interface/copp/protocol/info.py b/lib/aci/policy/interface/copp/protocol/info.py new file mode 100644 index 00000000..daefb706 --- /dev/null +++ b/lib/aci/policy/interface/copp/protocol/info.py @@ -0,0 +1,32 @@ +class PolicyInterfaceCoppProtocolInfo(): + def __init__(self): + self.policy_interface_copp_protocol = None + + def get_policy_interface_copp_protocol_info(self, managed_object): + info = {} + for key in managed_object: + info[key] = managed_object[key] + return info + + def get_policy_interface_copp_protocols_info(self): + if self.policy_interface_copp_protocol is not None: + return self.policy_interface_copp_protocol + + managed_objects = self.get_policy_interface_copp_protocol_mo() + if managed_objects is not None: + self.policy_interface_copp_protocol = [] + for managed_object in managed_objects: + self.policy_interface_copp_protocol.append( + self.get_policy_interface_copp_protocol_info( + managed_object + ) + ) + + return self.policy_interface_copp_protocol + + def get_policy_interface_copp_protocols(self): + all_protocols = self.get_policy_interface_copp_protocols_info() + if all_protocols is None: + return None + + return all_protocols diff --git a/lib/aci/policy/interface/copp/protocol/main.py b/lib/aci/policy/interface/copp/protocol/main.py new file mode 100644 index 00000000..7ada3006 --- /dev/null +++ b/lib/aci/policy/interface/copp/protocol/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.copp.protocol.api import PolicyInterfaceCoppProtocolApi +from lib.aci.policy.interface.copp.protocol.info import PolicyInterfaceCoppProtocolInfo + + +class PolicyInterfaceCoppProtocol(PolicyInterfaceCoppProtocolApi, PolicyInterfaceCoppProtocolInfo): + def __init__(self): + PolicyInterfaceCoppProtocolApi.__init__(self) + PolicyInterfaceCoppProtocolInfo.__init__(self) diff --git a/lib/aci/policy/interface/dpp/__init__.py b/lib/aci/policy/interface/dpp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/dpp/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95be65e6 Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..19957747 Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..9b64bd8f Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..ea22cdbd Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..0ce291d1 Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5b52ed18 Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..ea2713c3 Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/__pycache__/vmm.cpython-310.pyc b/lib/aci/policy/interface/dpp/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..2edf8688 Binary files /dev/null and b/lib/aci/policy/interface/dpp/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/api.py b/lib/aci/policy/interface/dpp/api.py new file mode 100644 index 00000000..96389de5 --- /dev/null +++ b/lib/aci/policy/interface/dpp/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceDppApi(): + def __init__(self): + self.policy_interface_dpp_mo = None + + def get_policy_interface_dpp_mo(self): + if self.policy_interface_dpp_mo is not None: + return self.policy_interface_dpp_mo + + cache = self.get_object_cache( + 'qosDppPol' + ) + if cache is not None: + self.policy_interface_dpp_mo = cache + self.log.apic_mo( + 'qosDppPol', + self.policy_interface_dpp_mo + ) + return self.policy_interface_dpp_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'qosDppPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_dpp_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['qosDppPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'qosDppPol' + ) + + self.policy_interface_dpp_mo.append( + attributes + ) + + self.log.apic_mo( + 'qosDppPol', + self.policy_interface_dpp_mo + ) + + self.set_object_cache( + 'qosDppPol', + self.policy_interface_dpp_mo + ) + + return self.policy_interface_dpp_mo diff --git a/lib/aci/policy/interface/dpp/attachment/__init__.py b/lib/aci/policy/interface/dpp/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/dpp/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/dpp/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/dpp/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/dpp/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4abbaf0b Binary files /dev/null and b/lib/aci/policy/interface/dpp/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/dpp/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..332d5a91 Binary files /dev/null and b/lib/aci/policy/interface/dpp/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/dpp/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..66ff3af8 Binary files /dev/null and b/lib/aci/policy/interface/dpp/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/dpp/attachment/api.py b/lib/aci/policy/interface/dpp/attachment/api.py new file mode 100644 index 00000000..fb84f4e4 --- /dev/null +++ b/lib/aci/policy/interface/dpp/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceDppAttachmentApi(): + def __init__(self): + self.policy_interface_dpp_attachment_mo = None + + def get_policy_interface_dpp_attachment_mo(self): + if self.policy_interface_dpp_attachment_mo is not None: + return self.policy_interface_dpp_attachment_mo + + cache = self.get_object_cache( + 'l1RsQosEgressDppIfPolCons' + ) + if cache is not None: + self.policy_interface_dpp_attachment_mo = cache + self.log.apic_mo( + 'l1RsQosEgressDppIfPolCons', + self.policy_interface_dpp_attachment_mo + ) + return self.policy_interface_dpp_attachment_mo + + managed_objects = self.get_class( + 'l1RsQosEgressDppIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_dpp_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_dpp_attachment_mo.append( + managed_object['l1RsQosEgressDppIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsQosEgressDppIfPolCons', + self.policy_interface_dpp_attachment_mo + ) + + self.set_object_cache( + 'l1RsQosEgressDppIfPolCons', + self.policy_interface_dpp_attachment_mo + ) + + return self.policy_interface_dpp_attachment_mo diff --git a/lib/aci/policy/interface/dpp/attachment/info.py b/lib/aci/policy/interface/dpp/attachment/info.py new file mode 100644 index 00000000..e21ee528 --- /dev/null +++ b/lib/aci/policy/interface/dpp/attachment/info.py @@ -0,0 +1,117 @@ +from lib import filter_helper + + +class PolicyInterfaceDppAttachmentInfo(): + def __init__(self): + self.policy_interface_dpp_attachment = None + + def get_policy_interface_dpp_attachment_info(self, managed_object): + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_dpp_attachments_info(self): + if self.policy_interface_dpp_attachment is not None: + return self.policy_interface_dpp_attachment + + managed_objects = self.get_policy_interface_dpp_attachment_mo() + if managed_objects is not None: + self.policy_interface_dpp_attachment = [] + for managed_object in managed_objects: + self.policy_interface_dpp_attachment.append( + self.get_policy_interface_dpp_attachment_info( + managed_object + ) + ) + + return self.policy_interface_dpp_attachment + + def match_policy_interface_dpp_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_dpp_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_dpp_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_dpp_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_dpp_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/dpp/attachment/main.py b/lib/aci/policy/interface/dpp/attachment/main.py new file mode 100644 index 00000000..e3c9b65e --- /dev/null +++ b/lib/aci/policy/interface/dpp/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.dpp.attachment.api import PolicyInterfaceDppAttachmentApi +from lib.aci.policy.interface.dpp.attachment.info import PolicyInterfaceDppAttachmentInfo + + +class PolicyInterfaceDppAttachment(PolicyInterfaceDppAttachmentApi, PolicyInterfaceDppAttachmentInfo): + def __init__(self): + PolicyInterfaceDppAttachmentApi.__init__(self) + PolicyInterfaceDppAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/dpp/context.py b/lib/aci/policy/interface/dpp/context.py new file mode 100644 index 00000000..56a8c40f --- /dev/null +++ b/lib/aci/policy/interface/dpp/context.py @@ -0,0 +1,63 @@ +class PolicyInterfaceDppContext(): + def __init__(self): + pass + + def set_policy_interface_dpp_context(self, policies): + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsQosEgressDppIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-dpp-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_dpp_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_dpp_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/dpp/info.py b/lib/aci/policy/interface/dpp/info.py new file mode 100644 index 00000000..60000d30 --- /dev/null +++ b/lib/aci/policy/interface/dpp/info.py @@ -0,0 +1,289 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceDppInfo(): + def __init__(self): + self.policy_interface_dpp = None + + def get_policy_interface_dpp_reln_info(self, managed_object): + info = {} + info['class'] = 'dppIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_dpp_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "be": "unspecified", + # "beUnit": "unspecified", + # "burst": "unspecified", + # "burstUnit": "unspecified", + # "childAction": "", + # "conformAction": "transmit", + # "conformMarkCos": "unspecified", + # "conformMarkDscp": "unspecified", + # "descr": "", + # "dn": "uni/infra/qosdpppol-default", + # "exceedAction": "drop", + # "exceedMarkCos": "unspecified", + # "exceedMarkDscp": "unspecified", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "mode": "bit", + # "monPolDn": "", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "pir": "0", + # "pirUnit": "unspecified", + # "rate": "0", + # "rateUnit": "unspecified", + # "sharingMode": "dedicated", + # "status": "", + # "type": "1R2C", + # "uid": "0", + # "userdom": "", + # "violateAction": "drop", + # "violateMarkCos": "unspecified", + # "violateMarkDscp": "unspecified" + keys = [ + 'adminSt', + 'annotation', + 'be', + 'beUnit', + 'burst', + 'burstUnit', + 'conformAction', + 'conformMarkCos', + 'conformMarkDscp', + 'dn', + 'exceedAction', + 'exceedMarkCos', + 'exceedMarkDscp', + 'mode', + 'name', + 'pir', + 'pirUnit', + 'rate', + 'rateUnit', + 'sharingMode', + 'type', + 'violateAction', + 'violateMarkCos', + 'violateMarkDscp', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['burst'] == 'unspecified': + info['burstT'] = 'unspecified' + else: + info['burstT'] = '%s %s' % ( + info['burst'], + info['burstUnit'] + ) + + if info['be'] == 'unspecified': + info['beT'] = 'unspecified' + else: + info['beT'] = '%s %s' % ( + info['be'], + info['beUnit'] + ) + + if info['rate'] == 'unspecified': + info['rateT'] = 'unspecified' + else: + if info['rateUnit'] == 'unspecified': + info['rateT'] = '%s pps' % ( + info['rate'] + ) + else: + info['rateT'] = '%s %s' % ( + info['rate'], + info['rateUnit'] + ) + + if info['pir'] == 'unspecified': + info['pirT'] = 'unspecified' + else: + if info['pirUnit'] == 'unspecified': + info['pirT'] = '%s pps' % ( + info['pir'] + ) + else: + info['pirT'] = '%s %s' % ( + info['pir'], + info['pirUnit'] + ) + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['references'] = len( + info['relnFrom'] + ) + return info + + def get_policies_interface_dpp_info(self): + if self.policy_interface_dpp is not None: + return self.policy_interface_dpp + + managed_objects = self.get_policy_interface_dpp_mo() + if managed_objects is not None: + self.policy_interface_dpp = [] + for managed_object in managed_objects: + self.policy_interface_dpp.append( + self.get_policy_interface_dpp_info( + managed_object + ) + ) + + self.log.apic_mo( + 'dppIfPol.info', + self.policy_interface_dpp + ) + + return self.policy_interface_dpp + + def match_policy_interface_dpp(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsQosEgressDppIfPolCons' in policy_info: + if len(policy_info['l1RsQosEgressDppIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsQosEgressDppIfPolCons' in policy_info: + if len(policy_info['l1RsQosEgressDppIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsQosEgressDppIfPolCons' in policy_info: + if len(policy_info['l1RsQosEgressDppIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_dpp_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_dpp(self, policy_filter=None, attachment_info=False): + all_policies = self.get_policies_interface_dpp_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_dpp(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_dpp_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_dpp(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsQosEgressDppIfPolCons'] = self.get_policy_interface_dpp_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsQosEgressDppIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsQosEgressDppIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_dpp_attachments_node_summary( + policy_info['l1RsQosEgressDppIfPolCons'] + ) + + if not self.match_policy_interface_dpp(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/dpp/main.py b/lib/aci/policy/interface/dpp/main.py new file mode 100644 index 00000000..833c8c3c --- /dev/null +++ b/lib/aci/policy/interface/dpp/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.dpp.attachment.main import PolicyInterfaceDppAttachment +from lib.aci.policy.interface.dpp.api import PolicyInterfaceDppApi +from lib.aci.policy.interface.dpp.context import PolicyInterfaceDppContext +from lib.aci.policy.interface.dpp.info import PolicyInterfaceDppInfo + + +class PolicyInterfaceDpp(PolicyInterfaceDppAttachment, PolicyInterfaceDppApi, PolicyInterfaceDppContext, PolicyInterfaceDppInfo): + def __init__(self): + PolicyInterfaceDppAttachment.__init__(self) + PolicyInterfaceDppApi.__init__(self) + PolicyInterfaceDppContext.__init__(self) + PolicyInterfaceDppInfo.__init__(self) diff --git a/lib/aci/policy/interface/dpp/output.py b/lib/aci/policy/interface/dpp/output.py new file mode 100644 index 00000000..f37140e9 --- /dev/null +++ b/lib/aci/policy/interface/dpp/output.py @@ -0,0 +1,205 @@ +class PolicyInterfaceDppOutput(): + def __init__(self): + pass + + def print_policy_interface_dpp(self, info): + self.print_policy_interface_dpp_properties( + info + ) + + self.print_policy_interface_dpp_interfaces( + info['l1RsQosEgressDppIfPolCons'] + ) + + self.print_policy_interface_dpp_references( + info['relnFrom'] + ) + + def print_policy_interface_dpp_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt', + 'type', + 'conformAction', + 'violateAction', + 'sharingMode', + 'burstT', + 'beT', + 'rateT', + 'pirT', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Type', + 'Conform Action', + 'Violate Action', + 'Sharing Mode', + 'Burst', + 'Excessive Burst', + 'Rate', + 'Peak Rate', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Data Plane Policing Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_dpp_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_dpp_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_dpp_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'type', + 'conformAction', + 'violateAction', + 'sharingMode', + 'burstT', + 'beT', + 'rateT', + 'pirT', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Type', + 'Conform Action', + 'Violate Action', + 'Sharing Mode', + 'Burst', + 'Excessive Burst', + 'Rate', + 'Peak Rate', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_dpp_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_dpp_interfaces(self, info): + order = [ + 'name', + 'l1RsQosEgressDppIfPolCons.pod_node_name', + 'l1RsQosEgressDppIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsQosEgressDppIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/fc/__init__.py b/lib/aci/policy/interface/fc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/fc/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..55bb324d Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e6a03f9e Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..2d1de066 Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..5af8cfc3 Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..2db91064 Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..06856fb9 Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/fc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..c0465862 Binary files /dev/null and b/lib/aci/policy/interface/fc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/api.py b/lib/aci/policy/interface/fc/api.py new file mode 100644 index 00000000..34dbd710 --- /dev/null +++ b/lib/aci/policy/interface/fc/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceFcApi(): + def __init__(self): + self.policy_interface_fc_mo = None + + def get_policy_interface_fc_mo(self): + if self.policy_interface_fc_mo is not None: + return self.policy_interface_fc_mo + + cache = self.get_object_cache( + 'fcIfPol' + ) + if cache is not None: + self.policy_interface_fc_mo = cache + self.log.apic_mo( + 'fcIfPol', + self.policy_interface_fc_mo + ) + return self.policy_interface_fc_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'fcIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_fc_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fcIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'fcIfPol' + ) + + self.policy_interface_fc_mo.append( + attributes + ) + + self.log.apic_mo( + 'fcIfPol', + self.policy_interface_fc_mo + ) + + self.set_object_cache( + 'fcIfPol', + self.policy_interface_fc_mo + ) + + return self.policy_interface_fc_mo diff --git a/lib/aci/policy/interface/fc/attachment/__init__.py b/lib/aci/policy/interface/fc/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/fc/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/fc/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/fc/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/fc/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..7fc01561 Binary files /dev/null and b/lib/aci/policy/interface/fc/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/fc/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f7ff2693 Binary files /dev/null and b/lib/aci/policy/interface/fc/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/fc/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..40dd1c7f Binary files /dev/null and b/lib/aci/policy/interface/fc/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/fc/attachment/api.py b/lib/aci/policy/interface/fc/attachment/api.py new file mode 100644 index 00000000..9579cd18 --- /dev/null +++ b/lib/aci/policy/interface/fc/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceFcAttachmentApi(): + def __init__(self): + self.policy_interface_fc_attachment_mo = None + + def get_policy_interface_fc_attachment_mo(self): + if self.policy_interface_fc_attachment_mo is not None: + return self.policy_interface_fc_attachment_mo + + cache = self.get_object_cache( + 'l1RsFcIfPolCons' + ) + if cache is not None: + self.policy_interface_fc_attachment_mo = cache + self.log.apic_mo( + 'l1RsFcIfPolCons', + self.policy_interface_fc_attachment_mo + ) + return self.policy_interface_fc_attachment_mo + + managed_objects = self.get_class( + 'l1RsFcIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_fc_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_fc_attachment_mo.append( + managed_object['l1RsFcIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsFcIfPolCons', + self.policy_interface_fc_attachment_mo + ) + + self.set_object_cache( + 'l1RsFcIfPolCons', + self.policy_interface_fc_attachment_mo + ) + + return self.policy_interface_fc_attachment_mo diff --git a/lib/aci/policy/interface/fc/attachment/info.py b/lib/aci/policy/interface/fc/attachment/info.py new file mode 100644 index 00000000..92439952 --- /dev/null +++ b/lib/aci/policy/interface/fc/attachment/info.py @@ -0,0 +1,117 @@ +from lib import filter_helper + + +class PolicyInterfaceFcAttachmentInfo(): + def __init__(self): + self.policy_interface_fc_attachment = None + + def get_policy_interface_fc_attachment_info(self, managed_object): + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_fc_attachments_info(self): + if self.policy_interface_fc_attachment is not None: + return self.policy_interface_fc_attachment + + managed_objects = self.get_policy_interface_fc_attachment_mo() + if managed_objects is not None: + self.policy_interface_fc_attachment = [] + for managed_object in managed_objects: + self.policy_interface_fc_attachment.append( + self.get_policy_interface_fc_attachment_info( + managed_object + ) + ) + + return self.policy_interface_fc_attachment + + def match_policy_interface_fc_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_fc_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_fc_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_fc_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_fc_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/fc/attachment/main.py b/lib/aci/policy/interface/fc/attachment/main.py new file mode 100644 index 00000000..82421079 --- /dev/null +++ b/lib/aci/policy/interface/fc/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.fc.attachment.api import PolicyInterfaceFcAttachmentApi +from lib.aci.policy.interface.fc.attachment.info import PolicyInterfaceFcAttachmentInfo + + +class PolicyInterfaceFcAttachment(PolicyInterfaceFcAttachmentApi, PolicyInterfaceFcAttachmentInfo): + def __init__(self): + PolicyInterfaceFcAttachmentApi.__init__(self) + PolicyInterfaceFcAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/fc/context.py b/lib/aci/policy/interface/fc/context.py new file mode 100644 index 00000000..31ca30e8 --- /dev/null +++ b/lib/aci/policy/interface/fc/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceFcContext(): + def __init__(self): + pass + + def set_policy_interface_fc_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "fcIfPol", + # "policyDn": "uni/infra/fcIfP-k8s_fc_enable", + # "policyName": "k8s_fc_enable" + # + # Context + # "phy": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsFcIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-fc-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_fc_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_fc_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/fc/info.py b/lib/aci/policy/interface/fc/info.py new file mode 100644 index 00000000..951f6cce --- /dev/null +++ b/lib/aci/policy/interface/fc/info.py @@ -0,0 +1,228 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceFcInfo(): + def __init__(self): + self.policy_interface_fc = None + + def get_policy_interface_fc_reln_info(self, managed_object): + info = {} + info['class'] = 'fcIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_fc_info(self, managed_object): + # "annotation": "", + # "automaxspeed": "32G", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/fcIfPol-default", + # "extMngdBy": "", + # "fillPattern": "IDLE", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "portMode": "f", + # "rxBBCredit": "64", + # "speed": "auto", + # "status": "", + # "trunkMode": "trunk-off", + # "uid": "0", + # "userdom": "" + keys = [ + 'annotation', + 'automaxspeed', + 'dn', + 'fillPattern', + 'name', + 'portMode', + 'rxBBCredit', + 'speed', + 'trunkMode', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_fc_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_fc_info(self): + if self.policy_interface_fc is not None: + return self.policy_interface_fc + + managed_objects = self.get_policy_interface_fc_mo() + if managed_objects is not None: + self.policy_interface_fc = [] + for managed_object in managed_objects: + self.policy_interface_fc.append( + self.get_policy_interface_fc_info( + managed_object + ) + ) + + self.log.apic_mo( + 'fcIfPol.info', + self.policy_interface_fc + ) + + return self.policy_interface_fc + + def match_policy_interface_fc(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsFcIfPolCons' in policy_info: + if len(policy_info['l1RsFcIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsFcIfPolCons' in policy_info: + if len(policy_info['l1RsFcIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsFcIfPolCons' in policy_info: + if len(policy_info['l1RsFcIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_fc_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_fc(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_fc_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_fc(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_fc_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_fc(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsFcIfPolCons'] = self.get_policy_interface_fc_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsFcIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsFcIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_fc_attachments_node_summary( + policy_info['l1RsFcIfPolCons'] + ) + + if not self.match_policy_interface_fc(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/fc/main.py b/lib/aci/policy/interface/fc/main.py new file mode 100644 index 00000000..58bc75e0 --- /dev/null +++ b/lib/aci/policy/interface/fc/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.fc.attachment.main import PolicyInterfaceFcAttachment +from lib.aci.policy.interface.fc.api import PolicyInterfaceFcApi +from lib.aci.policy.interface.fc.context import PolicyInterfaceFcContext +from lib.aci.policy.interface.fc.info import PolicyInterfaceFcInfo + + +class PolicyInterfaceFc(PolicyInterfaceFcAttachment, PolicyInterfaceFcApi, PolicyInterfaceFcContext, PolicyInterfaceFcInfo): + def __init__(self): + PolicyInterfaceFcAttachment.__init__(self) + PolicyInterfaceFcApi.__init__(self) + PolicyInterfaceFcContext.__init__(self) + PolicyInterfaceFcInfo.__init__(self) diff --git a/lib/aci/policy/interface/fc/output.py b/lib/aci/policy/interface/fc/output.py new file mode 100644 index 00000000..6f52bea7 --- /dev/null +++ b/lib/aci/policy/interface/fc/output.py @@ -0,0 +1,189 @@ +class PolicyInterfaceFcOutput(): + def __init__(self): + pass + + def print_policy_interface_fc(self, info): + self.print_policy_interface_fc_properties( + info + ) + + self.print_policy_interface_fc_interfaces( + info['l1RsFcIfPolCons'] + ) + + self.print_policy_interface_fc_references( + info['relnFrom'] + ) + + def print_policy_interface_fc_properties(self, info): + order = [ + 'name', + 'tf', + 'portMode', + 'trunkMode', + 'speed', + 'fillPattern', + 'rxBBCredit', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Port Mode', + 'Trunk Mode', + 'Speed', + 'Fill Pattern', + 'Receive Buffer Credit', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='FC Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_fc_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_fc_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_fc_summary(self, info): + order = [ + 'name', + 'tf', + 'portMode', + 'trunkMode', + 'speed', + 'fillPattern', + 'rxBBCredit', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Port Mode', + 'Trunk Mode', + 'Speed', + 'Fill Pattern', + 'Receive Buffer Credit', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_fc_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_fc_interfaces(self, info): + order = [ + 'name', + 'l1RsFcIfPolCons.pod_node_name', + 'l1RsFcIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsFcIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/l2/__init__.py b/lib/aci/policy/interface/l2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/l2/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..bb62a0d5 Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..fbe512be Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..a4e9e55d Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..309c2c3b Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..531e2f0e Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..818de579 Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/l2/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..b77d01d8 Binary files /dev/null and b/lib/aci/policy/interface/l2/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/api.py b/lib/aci/policy/interface/l2/api.py new file mode 100644 index 00000000..fcfbf5e6 --- /dev/null +++ b/lib/aci/policy/interface/l2/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceL2Api(): + def __init__(self): + self.policy_interface_l2_mo = None + + def get_policy_interface_l2_mo(self): + if self.policy_interface_l2_mo is not None: + return self.policy_interface_l2_mo + + cache = self.get_object_cache( + 'l2IfPol' + ) + if cache is not None: + self.policy_interface_l2_mo = cache + self.log.apic_mo( + 'l2IfPol', + self.policy_interface_l2_mo + ) + return self.policy_interface_l2_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'l2IfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_l2_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2IfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'l2IfPol' + ) + + self.policy_interface_l2_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2IfPol', + self.policy_interface_l2_mo + ) + + self.set_object_cache( + 'l2IfPol', + self.policy_interface_l2_mo + ) + + return self.policy_interface_l2_mo diff --git a/lib/aci/policy/interface/l2/attachment/__init__.py b/lib/aci/policy/interface/l2/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/l2/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/l2/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/l2/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/l2/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..0eed2566 Binary files /dev/null and b/lib/aci/policy/interface/l2/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/l2/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..c7fe7311 Binary files /dev/null and b/lib/aci/policy/interface/l2/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/l2/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5d6b723b Binary files /dev/null and b/lib/aci/policy/interface/l2/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/l2/attachment/api.py b/lib/aci/policy/interface/l2/attachment/api.py new file mode 100644 index 00000000..b87fec30 --- /dev/null +++ b/lib/aci/policy/interface/l2/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceL2AttachmentApi(): + def __init__(self): + self.policy_interface_l2_attachment_mo = None + + def get_policy_interface_l2_attachment_mo(self): + if self.policy_interface_l2_attachment_mo is not None: + return self.policy_interface_l2_attachment_mo + + cache = self.get_object_cache( + 'l1RsL2IfPolCons' + ) + if cache is not None: + self.policy_interface_l2_attachment_mo = cache + self.log.apic_mo( + 'l1RsL2IfPolCons', + self.policy_interface_l2_attachment_mo + ) + return self.policy_interface_l2_attachment_mo + + managed_objects = self.get_class( + 'l1RsL2IfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_l2_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_l2_attachment_mo.append( + managed_object['l1RsL2IfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsL2IfPolCons', + self.policy_interface_l2_attachment_mo + ) + + self.set_object_cache( + 'l1RsL2IfPolCons', + self.policy_interface_l2_attachment_mo + ) + + return self.policy_interface_l2_attachment_mo diff --git a/lib/aci/policy/interface/l2/attachment/info.py b/lib/aci/policy/interface/l2/attachment/info.py new file mode 100644 index 00000000..0ba7aa45 --- /dev/null +++ b/lib/aci/policy/interface/l2/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceL2AttachmentInfo(): + def __init__(self): + self.policy_interface_l2_attachment = None + + def get_policy_interface_l2_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsl2IfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "l2IfPol", + # "tDn": "uni/infra/l2IfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_l2_attachments_info(self): + if self.policy_interface_l2_attachment is not None: + return self.policy_interface_l2_attachment + + managed_objects = self.get_policy_interface_l2_attachment_mo() + if managed_objects is not None: + self.policy_interface_l2_attachment = [] + for managed_object in managed_objects: + self.policy_interface_l2_attachment.append( + self.get_policy_interface_l2_attachment_info( + managed_object + ) + ) + + return self.policy_interface_l2_attachment + + def match_policy_interface_l2_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_l2_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_l2_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_l2_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_l2_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/l2/attachment/main.py b/lib/aci/policy/interface/l2/attachment/main.py new file mode 100644 index 00000000..3370e7b8 --- /dev/null +++ b/lib/aci/policy/interface/l2/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.l2.attachment.api import PolicyInterfaceL2AttachmentApi +from lib.aci.policy.interface.l2.attachment.info import PolicyInterfaceL2AttachmentInfo + + +class PolicyInterfaceL2Attachment(PolicyInterfaceL2AttachmentApi, PolicyInterfaceL2AttachmentInfo): + def __init__(self): + PolicyInterfaceL2AttachmentApi.__init__(self) + PolicyInterfaceL2AttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/l2/context.py b/lib/aci/policy/interface/l2/context.py new file mode 100644 index 00000000..a5756c70 --- /dev/null +++ b/lib/aci/policy/interface/l2/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceL2Context(): + def __init__(self): + pass + + def set_policy_interface_l2_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "l2IfPol", + # "policyDn": "uni/infra/l2IfP-k8s_l2_enable", + # "policyName": "k8s_l2_enable" + # + # Context + # "l2": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsL2IfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-l2-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_l2_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_l2_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/l2/info.py b/lib/aci/policy/interface/l2/info.py new file mode 100644 index 00000000..5bbbf64c --- /dev/null +++ b/lib/aci/policy/interface/l2/info.py @@ -0,0 +1,238 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceL2Info(): + def __init__(self): + self.policy_interface_l2 = None + + def get_policy_interface_l2_reln_info(self, managed_object): + info = {} + info['class'] = 'l2IfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_l2_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/l2IfP-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "qinq": "disabled", + # "status": "", + # "uid": "0", + # "userdom": "", + # "vepa": "disabled", + # "vlanScope": "global" + keys = [ + 'annotation', + 'dn', + 'name', + 'qinq', + 'relnFrom', + 'vepa', + 'vlanScope' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + if info['qinq'] == 'enabled': + info['__Output']['qinq'] = 'Green' + else: + info['__Output']['qinq'] = 'Red' + + if info['vepa'] == 'enabled': + info['__Output']['vepa'] = 'Green' + else: + info['__Output']['vepa'] = 'Red' + + info['vlanScopeT'] = '' + if info['vlanScope'] == 'global': + info['vlanScopeT'] = 'Global scope' + if info['vlanScope'] == 'portlocal': + info['vlanScopeT'] = 'Port Local scope' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_l2_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_l2_info(self): + if self.policy_interface_l2 is not None: + return self.policy_interface_l2 + + managed_objects = self.get_policy_interface_l2_mo() + if managed_objects is not None: + self.policy_interface_l2 = [] + for managed_object in managed_objects: + self.policy_interface_l2.append( + self.get_policy_interface_l2_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l2IfPol.info', + self.policy_interface_l2 + ) + + return self.policy_interface_l2 + + def match_policy_interface_l2(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsL2IfPolCons' in policy_info: + if len(policy_info['l1RsL2IfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsL2IfPolCons' in policy_info: + if len(policy_info['l1RsL2IfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsL2IfPolCons' in policy_info: + if len(policy_info['l1RsL2IfPolCons']) > 0: + return False + + return True + + def match_policy_interface_l2_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_l2(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_l2_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_l2(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_l2_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_l2(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsL2IfPolCons'] = self.get_policy_interface_l2_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsL2IfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsL2IfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_l2_attachments_node_summary( + policy_info['l1RsL2IfPolCons'] + ) + + if not self.match_policy_interface_l2(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/l2/main.py b/lib/aci/policy/interface/l2/main.py new file mode 100644 index 00000000..4e3bac03 --- /dev/null +++ b/lib/aci/policy/interface/l2/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.l2.attachment.main import PolicyInterfaceL2Attachment +from lib.aci.policy.interface.l2.api import PolicyInterfaceL2Api +from lib.aci.policy.interface.l2.context import PolicyInterfaceL2Context +from lib.aci.policy.interface.l2.info import PolicyInterfaceL2Info + + +class PolicyInterfaceL2(PolicyInterfaceL2Attachment, PolicyInterfaceL2Api, PolicyInterfaceL2Context, PolicyInterfaceL2Info): + def __init__(self): + PolicyInterfaceL2Attachment.__init__(self) + PolicyInterfaceL2Api.__init__(self) + PolicyInterfaceL2Context.__init__(self) + PolicyInterfaceL2Info.__init__(self) diff --git a/lib/aci/policy/interface/l2/output.py b/lib/aci/policy/interface/l2/output.py new file mode 100644 index 00000000..d9d44b52 --- /dev/null +++ b/lib/aci/policy/interface/l2/output.py @@ -0,0 +1,181 @@ +class PolicyInterfaceL2Output(): + def __init__(self): + pass + + def print_policy_interface_l2(self, info): + self.print_policy_interface_l2_properties( + info + ) + + self.print_policy_interface_l2_interfaces( + info['l1RsL2IfPolCons'] + ) + + self.print_policy_interface_l2_references( + info['relnFrom'] + ) + + def print_policy_interface_l2_properties(self, info): + order = [ + 'name', + 'tf', + 'qinq', + 'vepa', + 'vlanScopeT', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'QinQ', + '802.1Qbg', + 'VLAN Scope', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='CDP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_l2_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_l2_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_l2_summary(self, info): + order = [ + 'name', + 'tfTick', + 'qinq', + 'vepa', + 'vlanScopeT', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'QinQ', + '802.1Qbg', + 'VLAN Scope', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_l2_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_l2_interfaces(self, info): + order = [ + 'name', + 'l1RsL2IfPolCons.pod_node_name', + 'l1RsL2IfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsL2IfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/link_flap/__init__.py b/lib/aci/policy/interface/link_flap/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/link_flap/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d6867171 Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..a9e34864 Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..fc68cbe4 Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..611546dc Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..df366dab Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/link_flap/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..0be6662d Binary files /dev/null and b/lib/aci/policy/interface/link_flap/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/api.py b/lib/aci/policy/interface/link_flap/api.py new file mode 100644 index 00000000..f34936ad --- /dev/null +++ b/lib/aci/policy/interface/link_flap/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceLinkFlapApi(): + def __init__(self): + self.policy_interface_link_flap_mo = None + + def get_policy_interface_link_flap_mo(self): + if self.policy_interface_link_flap_mo is not None: + return self.policy_interface_link_flap_mo + + cache = self.get_object_cache( + 'fabricLinkFlapPol' + ) + if cache is not None: + self.policy_interface_link_flap_mo = cache + self.log.apic_mo( + 'fabricLinkFlapPol', + self.policy_interface_link_flap_mo + ) + return self.policy_interface_link_flap_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'fabricLinkFlapPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_link_flap_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fabricLinkFlapPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'fabricLinkFlapPol' + ) + + self.policy_interface_link_flap_mo.append( + attributes + ) + + self.log.apic_mo( + 'fabricLinkFlapPol', + self.policy_interface_link_flap_mo + ) + + self.set_object_cache( + 'fabricLinkFlapPol', + self.policy_interface_link_flap_mo + ) + + return self.policy_interface_link_flap_mo diff --git a/lib/aci/policy/interface/link_flap/attachment/__init__.py b/lib/aci/policy/interface/link_flap/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/link_flap/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/link_flap/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/link_flap/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/link_flap/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..0f660229 Binary files /dev/null and b/lib/aci/policy/interface/link_flap/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/link_flap/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e30e96b7 Binary files /dev/null and b/lib/aci/policy/interface/link_flap/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/link_flap/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5943f9e9 Binary files /dev/null and b/lib/aci/policy/interface/link_flap/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_flap/attachment/api.py b/lib/aci/policy/interface/link_flap/attachment/api.py new file mode 100644 index 00000000..3a65fc2e --- /dev/null +++ b/lib/aci/policy/interface/link_flap/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceLinkFlapAttachmentApi(): + def __init__(self): + self.policy_interface_link_flap_attachment_mo = None + + def get_policy_interface_link_flap_attachment_mo(self): + if self.policy_interface_link_flap_attachment_mo is not None: + return self.policy_interface_link_flap_attachment_mo + + cache = self.get_object_cache( + 'l1RsLinkFlapPolCons' + ) + if cache is not None: + self.policy_interface_link_flap_attachment_mo = cache + self.log.apic_mo( + 'l1RsLinkFlapPolCons', + self.policy_interface_link_flap_attachment_mo + ) + return self.policy_interface_link_flap_attachment_mo + + managed_objects = self.get_class( + 'l1RsLinkFlapPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_link_flap_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_link_flap_attachment_mo.append( + managed_object['l1RsLinkFlapPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsLinkFlapPolCons', + self.policy_interface_link_flap_attachment_mo + ) + + self.set_object_cache( + 'l1RsLinkFlapPolCons', + self.policy_interface_link_flap_attachment_mo + ) + + return self.policy_interface_link_flap_attachment_mo diff --git a/lib/aci/policy/interface/link_flap/attachment/info.py b/lib/aci/policy/interface/link_flap/attachment/info.py new file mode 100644 index 00000000..a15f53e7 --- /dev/null +++ b/lib/aci/policy/interface/link_flap/attachment/info.py @@ -0,0 +1,117 @@ +from lib import filter_helper + + +class PolicyInterfaceLinkFlapAttachmentInfo(): + def __init__(self): + self.policy_interface_link_flap_attachment = None + + def get_policy_interface_link_flap_attachment_info(self, managed_object): + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_link_flap_attachments_info(self): + if self.policy_interface_link_flap_attachment is not None: + return self.policy_interface_link_flap_attachment + + managed_objects = self.get_policy_interface_link_flap_attachment_mo() + if managed_objects is not None: + self.policy_interface_link_flap_attachment = [] + for managed_object in managed_objects: + self.policy_interface_link_flap_attachment.append( + self.get_policy_interface_link_flap_attachment_info( + managed_object + ) + ) + + return self.policy_interface_link_flap_attachment + + def match_policy_interface_link_flap_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_link_flap_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_link_flap_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_link_flap_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_link_flap_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/link_flap/attachment/main.py b/lib/aci/policy/interface/link_flap/attachment/main.py new file mode 100644 index 00000000..92eb026f --- /dev/null +++ b/lib/aci/policy/interface/link_flap/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.link_flap.attachment.api import PolicyInterfaceLinkFlapAttachmentApi +from lib.aci.policy.interface.link_flap.attachment.info import PolicyInterfaceLinkFlapAttachmentInfo + + +class PolicyInterfaceLinkFlapAttachment(PolicyInterfaceLinkFlapAttachmentApi, PolicyInterfaceLinkFlapAttachmentInfo): + def __init__(self): + PolicyInterfaceLinkFlapAttachmentApi.__init__(self) + PolicyInterfaceLinkFlapAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/link_flap/context.py b/lib/aci/policy/interface/link_flap/context.py new file mode 100644 index 00000000..4b1c09d3 --- /dev/null +++ b/lib/aci/policy/interface/link_flap/context.py @@ -0,0 +1,63 @@ +class PolicyInterfaceLinkFlapContext(): + def __init__(self): + pass + + def set_policy_interface_link_flap_context(self, policies): + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsLinkFlapPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-link_flap-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_link_flap_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_link_flap_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/link_flap/info.py b/lib/aci/policy/interface/link_flap/info.py new file mode 100644 index 00000000..7c99254c --- /dev/null +++ b/lib/aci/policy/interface/link_flap/info.py @@ -0,0 +1,221 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceLinkFlapInfo(): + def __init__(self): + self.policy_interface_link_flap = None + + def get_policy_interface_link_flap_reln_info(self, managed_object): + info = {} + info['class'] = 'fabricLinkFlapPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_link_flap_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/linkflappol-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "linkFlapErrorMax": "30", + # "linkFlapErrorSeconds": "420", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'annotation', + 'dn', + 'linkFlapErrorMax', + 'linkFlapErrorSeconds', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_link_flap_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_link_flap_info(self): + if self.policy_interface_link_flap is not None: + return self.policy_interface_link_flap + + managed_objects = self.get_policy_interface_link_flap_mo() + if managed_objects is not None: + self.policy_interface_link_flap = [] + for managed_object in managed_objects: + self.policy_interface_link_flap.append( + self.get_policy_interface_link_flap_info( + managed_object + ) + ) + + self.log.apic_mo( + 'fabricLinkFlapPol.info', + self.policy_interface_link_flap + ) + + return self.policy_interface_link_flap + + def match_policy_interface_link_flap(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsLinkFlapPolCons' in policy_info: + if len(policy_info['l1RsLinkFlapPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsLinkFlapPolCons' in policy_info: + if len(policy_info['l1RsLinkFlapPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsLinkFlapPolCons' in policy_info: + if len(policy_info['l1RsLinkFlapPolCons']) > 0: + return False + + return True + + def match_policy_interface_link_flap_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_link_flap(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_link_flap_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_link_flap(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_link_flap_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_link_flap(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsLinkFlapPolCons'] = self.get_policy_interface_link_flap_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsLinkFlapPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsLinkFlapPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_link_flap_attachments_node_summary( + policy_info['l1RsLinkFlapPolCons'] + ) + + if not self.match_policy_interface_link_flap(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/link_flap/main.py b/lib/aci/policy/interface/link_flap/main.py new file mode 100644 index 00000000..94db1807 --- /dev/null +++ b/lib/aci/policy/interface/link_flap/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.link_flap.attachment.main import PolicyInterfaceLinkFlapAttachment +from lib.aci.policy.interface.link_flap.api import PolicyInterfaceLinkFlapApi +from lib.aci.policy.interface.link_flap.context import PolicyInterfaceLinkFlapContext +from lib.aci.policy.interface.link_flap.info import PolicyInterfaceLinkFlapInfo + + +class PolicyInterfaceLinkFlap(PolicyInterfaceLinkFlapAttachment, PolicyInterfaceLinkFlapApi, PolicyInterfaceLinkFlapContext, PolicyInterfaceLinkFlapInfo): + def __init__(self): + PolicyInterfaceLinkFlapAttachment.__init__(self) + PolicyInterfaceLinkFlapApi.__init__(self) + PolicyInterfaceLinkFlapContext.__init__(self) + PolicyInterfaceLinkFlapInfo.__init__(self) diff --git a/lib/aci/policy/interface/link_flap/output.py b/lib/aci/policy/interface/link_flap/output.py new file mode 100644 index 00000000..6123849a --- /dev/null +++ b/lib/aci/policy/interface/link_flap/output.py @@ -0,0 +1,177 @@ +class PolicyInterfaceLinkFlapOutput(): + def __init__(self): + pass + + def print_policy_interface_link_flap(self, info): + self.print_policy_interface_link_flap_properties( + info + ) + + self.print_policy_interface_link_flap_interfaces( + info['l1RsLinkFlapPolCons'] + ) + + self.print_policy_interface_link_flap_references( + info['relnFrom'] + ) + + def print_policy_interface_link_flap_properties(self, info): + order = [ + 'name', + 'tf', + 'linkFlapErrorMax', + 'linkFlapErrorSeconds', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Max Flaps', + 'Max Flaps Duration [sec]', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Link Flap Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_link_flap_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_link_flap_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_flap_summary(self, info): + order = [ + 'name', + 'tfTick', + 'linkFlapErrorMax', + 'linkFlapErrorSeconds', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Max Flaps', + 'Max Flaps Duration [sec]', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_flap_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_flap_interfaces(self, info): + order = [ + 'name', + 'l1RsLinkFlapPolCons.pod_node_name', + 'l1RsLinkFlapPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsLinkFlapPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/link_level/__init__.py b/lib/aci/policy/interface/link_level/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/link_level/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c4a43a33 Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..0c233a24 Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..401b9f6e Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..0eeae0f9 Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c1715351 Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/link_level/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..4587d27c Binary files /dev/null and b/lib/aci/policy/interface/link_level/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/api.py b/lib/aci/policy/interface/link_level/api.py new file mode 100644 index 00000000..a0552026 --- /dev/null +++ b/lib/aci/policy/interface/link_level/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceLinkLevelApi(): + def __init__(self): + self.policy_interface_link_level_mo = None + + def get_policy_interface_link_level_mo(self): + if self.policy_interface_link_level_mo is not None: + return self.policy_interface_link_level_mo + + cache = self.get_object_cache( + 'fabricHIfPol' + ) + if cache is not None: + self.policy_interface_link_level_mo = cache + self.log.apic_mo( + 'fabricHIfPol', + self.policy_interface_link_level_mo + ) + return self.policy_interface_link_level_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'fabricHIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_link_level_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fabricHIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'fabricHIfPol' + ) + + self.policy_interface_link_level_mo.append( + attributes + ) + + self.log.apic_mo( + 'fabricHIfPol', + self.policy_interface_link_level_mo + ) + + self.set_object_cache( + 'fabricHIfPol', + self.policy_interface_link_level_mo + ) + + return self.policy_interface_link_level_mo diff --git a/lib/aci/policy/interface/link_level/attachment/__init__.py b/lib/aci/policy/interface/link_level/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/link_level/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/link_level/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/link_level/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/link_level/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e25ca044 Binary files /dev/null and b/lib/aci/policy/interface/link_level/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/link_level/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..0a8392ae Binary files /dev/null and b/lib/aci/policy/interface/link_level/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/link_level/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f52ac8ea Binary files /dev/null and b/lib/aci/policy/interface/link_level/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level/attachment/api.py b/lib/aci/policy/interface/link_level/attachment/api.py new file mode 100644 index 00000000..5e931d27 --- /dev/null +++ b/lib/aci/policy/interface/link_level/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceLinkLevelAttachmentApi(): + def __init__(self): + self.policy_interface_link_level_attachment_mo = None + + def get_policy_interface_link_level_attachment_mo(self): + if self.policy_interface_link_level_attachment_mo is not None: + return self.policy_interface_link_level_attachment_mo + + cache = self.get_object_cache( + 'l1RsHIfPolCons' + ) + if cache is not None: + self.policy_interface_link_level_attachment_mo = cache + self.log.apic_mo( + 'l1RsHIfPolCons', + self.policy_interface_link_level_attachment_mo + ) + return self.policy_interface_link_level_attachment_mo + + managed_objects = self.get_class( + 'l1RsHIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_link_level_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_link_level_attachment_mo.append( + managed_object['l1RsHIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsHIfPolCons', + self.policy_interface_link_level_attachment_mo + ) + + self.set_object_cache( + 'l1RsHIfPolCons', + self.policy_interface_link_level_attachment_mo + ) + + return self.policy_interface_link_level_attachment_mo diff --git a/lib/aci/policy/interface/link_level/attachment/info.py b/lib/aci/policy/interface/link_level/attachment/info.py new file mode 100644 index 00000000..c643e60e --- /dev/null +++ b/lib/aci/policy/interface/link_level/attachment/info.py @@ -0,0 +1,117 @@ +from lib import filter_helper + + +class PolicyInterfaceLinkLevelAttachmentInfo(): + def __init__(self): + self.policy_interface_link_level_attachment = None + + def get_policy_interface_link_level_attachment_info(self, managed_object): + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_link_level_attachments_info(self): + if self.policy_interface_link_level_attachment is not None: + return self.policy_interface_link_level_attachment + + managed_objects = self.get_policy_interface_link_level_attachment_mo() + if managed_objects is not None: + self.policy_interface_link_level_attachment = [] + for managed_object in managed_objects: + self.policy_interface_link_level_attachment.append( + self.get_policy_interface_link_level_attachment_info( + managed_object + ) + ) + + return self.policy_interface_link_level_attachment + + def match_policy_interface_link_level_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_link_level_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_link_level_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_link_level_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_link_level_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/link_level/attachment/main.py b/lib/aci/policy/interface/link_level/attachment/main.py new file mode 100644 index 00000000..36532ec7 --- /dev/null +++ b/lib/aci/policy/interface/link_level/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.link_level.attachment.api import PolicyInterfaceLinkLevelAttachmentApi +from lib.aci.policy.interface.link_level.attachment.info import PolicyInterfaceLinkLevelAttachmentInfo + + +class PolicyInterfaceLinkLevelAttachment(PolicyInterfaceLinkLevelAttachmentApi, PolicyInterfaceLinkLevelAttachmentInfo): + def __init__(self): + PolicyInterfaceLinkLevelAttachmentApi.__init__(self) + PolicyInterfaceLinkLevelAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/link_level/context.py b/lib/aci/policy/interface/link_level/context.py new file mode 100644 index 00000000..a70dd570 --- /dev/null +++ b/lib/aci/policy/interface/link_level/context.py @@ -0,0 +1,63 @@ +class PolicyInterfaceLinkLevelContext(): + def __init__(self): + pass + + def set_policy_interface_link_level_context(self, policies): + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsHIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-link_level-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_link_level_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_link_level_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/link_level/info.py b/lib/aci/policy/interface/link_level/info.py new file mode 100644 index 00000000..b32a2eb1 --- /dev/null +++ b/lib/aci/policy/interface/link_level/info.py @@ -0,0 +1,234 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceLinkLevelInfo(): + def __init__(self): + self.policy_interface_link_level = None + + def get_policy_interface_link_level_reln_info(self, managed_object): + info = {} + info['class'] = 'fabricHIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_link_level_info(self, managed_object): + # "annotation": "", + # "autoNeg": "on", + # "childAction": "", + # "creator": "USER", + # "descr": "Auto Speed and Auto FEC", + # "dfeDelayMs": "0", + # "dn": "uni/infra/hintfpol-25G-auto", + # "emiRetrain": "disable", + # "extMngdBy": "", + # "fecMode": "auto-fec", + # "lcOwn": "local", + # "linkDebounce": "100", + # "modTs": "2022-01-28T14:41:55.292+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "25G-auto", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "portPhyMediaType": "auto", + # "speed": "inherit", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:" + keys = [ + 'annotation', + 'autoNeg', + 'creator', + 'descr', + 'dfeDelayMs', + 'dn', + 'emiRetrain', + 'fecMode', + 'linkDebounce', + 'name', + 'portPhyMediaType', + 'speed', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_link_level_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_link_level_info(self): + if self.policy_interface_link_level is not None: + return self.policy_interface_link_level + + managed_objects = self.get_policy_interface_link_level_mo() + if managed_objects is not None: + self.policy_interface_link_level = [] + for managed_object in managed_objects: + self.policy_interface_link_level.append( + self.get_policy_interface_link_level_info( + managed_object + ) + ) + + self.log.apic_mo( + 'fabricHIfPol.info', + self.policy_interface_link_level + ) + + return self.policy_interface_link_level + + def match_policy_interface_link_level(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsHIfPolCons' in policy_info: + if len(policy_info['l1RsHIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsHIfPolCons' in policy_info: + if len(policy_info['l1RsHIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsHIfPolCons' in policy_info: + if len(policy_info['l1RsHIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_link_level_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_link_level(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_link_level_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_link_level(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_link_level_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_link_level(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsHIfPolCons'] = self.get_policy_interface_link_level_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsHIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsHIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_link_level_attachments_node_summary( + policy_info['l1RsHIfPolCons'] + ) + + if not self.match_policy_interface_link_level(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/link_level/main.py b/lib/aci/policy/interface/link_level/main.py new file mode 100644 index 00000000..e5cf16fa --- /dev/null +++ b/lib/aci/policy/interface/link_level/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.link_level.attachment.main import PolicyInterfaceLinkLevelAttachment +from lib.aci.policy.interface.link_level.api import PolicyInterfaceLinkLevelApi +from lib.aci.policy.interface.link_level.context import PolicyInterfaceLinkLevelContext +from lib.aci.policy.interface.link_level.info import PolicyInterfaceLinkLevelInfo + + +class PolicyInterfaceLinkLevel(PolicyInterfaceLinkLevelAttachment, PolicyInterfaceLinkLevelApi, PolicyInterfaceLinkLevelContext, PolicyInterfaceLinkLevelInfo): + def __init__(self): + PolicyInterfaceLinkLevelAttachment.__init__(self) + PolicyInterfaceLinkLevelApi.__init__(self) + PolicyInterfaceLinkLevelContext.__init__(self) + PolicyInterfaceLinkLevelInfo.__init__(self) diff --git a/lib/aci/policy/interface/link_level/output.py b/lib/aci/policy/interface/link_level/output.py new file mode 100644 index 00000000..c4cd23bc --- /dev/null +++ b/lib/aci/policy/interface/link_level/output.py @@ -0,0 +1,197 @@ +class PolicyInterfaceLinkLevelOutput(): + def __init__(self): + pass + + def print_policy_interface_link_level(self, info): + self.print_policy_interface_link_level_properties( + info + ) + + self.print_policy_interface_link_level_interfaces( + info['l1RsHIfPolCons'] + ) + + self.print_policy_interface_link_level_references( + info['relnFrom'] + ) + + def print_policy_interface_link_level_properties(self, info): + order = [ + 'name', + 'tf', + 'portPhyMediaType', + 'autoNeg', + 'speed', + 'dfeDelayMs', + 'linkDebounce', + 'fecMode', + 'emiRetrain', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'PHY Type', + 'Auto Neg', + 'Speed', + 'Delay [msec]', + 'Link Debounce [msec]', + 'FEC Mode', + 'EMI Retrain', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Link Level Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_link_level_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_link_level_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_level_summary(self, info): + order = [ + 'name', + 'tfTick', + 'portPhyMediaType', + 'autoNeg', + 'speed', + 'dfeDelayMs', + 'linkDebounce', + 'fecMode', + 'emiRetrain', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'PHY Type', + 'Auto Neg', + 'Speed', + 'Delay [msec]', + 'Link Debounce [msec]', + 'FEC Mode', + 'EMI Retrain', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_level_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_level_interfaces(self, info): + order = [ + 'name', + 'l1RsHIfPolCons.pod_node_name', + 'l1RsHIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsHIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/link_level_fc/__init__.py b/lib/aci/policy/interface/link_level_fc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d268a167 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..e7bca004 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..34910709 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..50c0a9b7 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8914527e Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..b9829e62 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/api.py b/lib/aci/policy/interface/link_level_fc/api.py new file mode 100644 index 00000000..c91f75ec --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceLinkLevelFcApi(): + def __init__(self): + self.policy_interface_link_level_fc_mo = None + + def get_policy_interface_link_level_fc_mo(self): + if self.policy_interface_link_level_fc_mo is not None: + return self.policy_interface_link_level_fc_mo + + cache = self.get_object_cache( + 'qosLlfcIfPol' + ) + if cache is not None: + self.policy_interface_link_level_fc_mo = cache + self.log.apic_mo( + 'qosLlfcIfPol', + self.policy_interface_link_level_fc_mo + ) + return self.policy_interface_link_level_fc_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'qosLlfcIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_link_level_fc_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['qosLlfcIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'qosLlfcIfPol' + ) + + self.policy_interface_link_level_fc_mo.append( + attributes + ) + + self.log.apic_mo( + 'qosLlfcIfPol', + self.policy_interface_link_level_fc_mo + ) + + self.set_object_cache( + 'qosLlfcIfPol', + self.policy_interface_link_level_fc_mo + ) + + return self.policy_interface_link_level_fc_mo diff --git a/lib/aci/policy/interface/link_level_fc/attachment/__init__.py b/lib/aci/policy/interface/link_level_fc/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..280eba67 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1ed4ebd9 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2fce9997 Binary files /dev/null and b/lib/aci/policy/interface/link_level_fc/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/link_level_fc/attachment/api.py b/lib/aci/policy/interface/link_level_fc/attachment/api.py new file mode 100644 index 00000000..ccfb9216 --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceLinkLevelFcAttachmentApi(): + def __init__(self): + self.policy_interface_link_level_fc_attachment_mo = None + + def get_policy_interface_link_level_fc_attachment_mo(self): + if self.policy_interface_link_level_fc_attachment_mo is not None: + return self.policy_interface_link_level_fc_attachment_mo + + cache = self.get_object_cache( + 'l1RsQosLlfcIfPolCons' + ) + if cache is not None: + self.policy_interface_link_level_fc_attachment_mo = cache + self.log.apic_mo( + 'l1RsQosLlfcIfPolCons', + self.policy_interface_link_level_fc_attachment_mo + ) + return self.policy_interface_link_level_fc_attachment_mo + + managed_objects = self.get_class( + 'l1RsQosLlfcIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_link_level_fc_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_link_level_fc_attachment_mo.append( + managed_object['l1RsQosLlfcIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsQosLlfcIfPolCons', + self.policy_interface_link_level_fc_attachment_mo + ) + + self.set_object_cache( + 'l1RsQosLlfcIfPolCons', + self.policy_interface_link_level_fc_attachment_mo + ) + + return self.policy_interface_link_level_fc_attachment_mo diff --git a/lib/aci/policy/interface/link_level_fc/attachment/info.py b/lib/aci/policy/interface/link_level_fc/attachment/info.py new file mode 100644 index 00000000..6c97e7e9 --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/attachment/info.py @@ -0,0 +1,117 @@ +from lib import filter_helper + + +class PolicyInterfaceLinkLevelFcAttachmentInfo(): + def __init__(self): + self.policy_interface_link_level_fc_attachment = None + + def get_policy_interface_link_level_fc_attachment_info(self, managed_object): + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_link_level_fc_attachments_info(self): + if self.policy_interface_link_level_fc_attachment is not None: + return self.policy_interface_link_level_fc_attachment + + managed_objects = self.get_policy_interface_link_level_fc_attachment_mo() + if managed_objects is not None: + self.policy_interface_link_level_fc_attachment = [] + for managed_object in managed_objects: + self.policy_interface_link_level_fc_attachment.append( + self.get_policy_interface_link_level_fc_attachment_info( + managed_object + ) + ) + + return self.policy_interface_link_level_fc_attachment + + def match_policy_interface_link_level_fc_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_link_level_fc_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_link_level_fc_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_link_level_fc_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_link_level_fc_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/link_level_fc/attachment/main.py b/lib/aci/policy/interface/link_level_fc/attachment/main.py new file mode 100644 index 00000000..da413ab8 --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.link_level_fc.attachment.api import PolicyInterfaceLinkLevelFcAttachmentApi +from lib.aci.policy.interface.link_level_fc.attachment.info import PolicyInterfaceLinkLevelFcAttachmentInfo + + +class PolicyInterfaceLinkLevelFcAttachment(PolicyInterfaceLinkLevelFcAttachmentApi, PolicyInterfaceLinkLevelFcAttachmentInfo): + def __init__(self): + PolicyInterfaceLinkLevelFcAttachmentApi.__init__(self) + PolicyInterfaceLinkLevelFcAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/link_level_fc/context.py b/lib/aci/policy/interface/link_level_fc/context.py new file mode 100644 index 00000000..5e5d114e --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/context.py @@ -0,0 +1,63 @@ +class PolicyInterfaceLinkLevelFcContext(): + def __init__(self): + pass + + def set_policy_interface_link_level_fc_context(self, policies): + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsQosLlfcIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-link_level_fc-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_link_level_fc_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_link_level_fc_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/link_level_fc/info.py b/lib/aci/policy/interface/link_level_fc/info.py new file mode 100644 index 00000000..2789d4df --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/info.py @@ -0,0 +1,220 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceLinkLevelFcInfo(): + def __init__(self): + self.policy_interface_link_level_fc = None + + def get_policy_interface_link_level_fc_reln_info(self, managed_object): + info = {} + info['class'] = 'qosLlfcIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_link_level_fc_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/llfc-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "llfcRcvAdminSt": "off", + # "llfcSendAdminSt": "off", + # "modTs": "2021-03-17T04:02:25.117+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "all" + keys = [ + 'annotation', + 'dn', + 'llfcRcvAdminSt', + 'llfcSendAdminSt', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_link_level_fc_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_link_level_fc_info(self): + if self.policy_interface_link_level_fc is not None: + return self.policy_interface_link_level_fc + + managed_objects = self.get_policy_interface_link_level_fc_mo() + if managed_objects is not None: + self.policy_interface_link_level_fc = [] + for managed_object in managed_objects: + self.policy_interface_link_level_fc.append( + self.get_policy_interface_link_level_fc_info( + managed_object + ) + ) + + self.log.apic_mo( + 'qosLlfcIfPol.info', + self.policy_interface_link_level_fc + ) + + return self.policy_interface_link_level_fc + + def match_policy_interface_link_level_fc(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsQosLlfcIfPolCons' in policy_info: + if len(policy_info['l1RsQosLlfcIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsQosLlfcIfPolCons' in policy_info: + if len(policy_info['l1RsQosLlfcIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsQosLlfcIfPolCons' in policy_info: + if len(policy_info['l1RsQosLlfcIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_link_level_fc_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_link_level_fc(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_link_level_fc_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_link_level_fc(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_link_level_fc_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_link_level_fc(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsQosLlfcIfPolCons'] = self.get_policy_interface_link_level_fc_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsQosLlfcIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsQosLlfcIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_link_level_fc_attachments_node_summary( + policy_info['l1RsQosLlfcIfPolCons'] + ) + + if not self.match_policy_interface_link_level_fc(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/link_level_fc/main.py b/lib/aci/policy/interface/link_level_fc/main.py new file mode 100644 index 00000000..5365ff69 --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.link_level_fc.attachment.main import PolicyInterfaceLinkLevelFcAttachment +from lib.aci.policy.interface.link_level_fc.api import PolicyInterfaceLinkLevelFcApi +from lib.aci.policy.interface.link_level_fc.context import PolicyInterfaceLinkLevelFcContext +from lib.aci.policy.interface.link_level_fc.info import PolicyInterfaceLinkLevelFcInfo + + +class PolicyInterfaceLinkLevelFc(PolicyInterfaceLinkLevelFcAttachment, PolicyInterfaceLinkLevelFcApi, PolicyInterfaceLinkLevelFcContext, PolicyInterfaceLinkLevelFcInfo): + def __init__(self): + PolicyInterfaceLinkLevelFcAttachment.__init__(self) + PolicyInterfaceLinkLevelFcApi.__init__(self) + PolicyInterfaceLinkLevelFcContext.__init__(self) + PolicyInterfaceLinkLevelFcInfo.__init__(self) diff --git a/lib/aci/policy/interface/link_level_fc/output.py b/lib/aci/policy/interface/link_level_fc/output.py new file mode 100644 index 00000000..d61fdeb7 --- /dev/null +++ b/lib/aci/policy/interface/link_level_fc/output.py @@ -0,0 +1,177 @@ +class PolicyInterfaceLinkLevelFcOutput(): + def __init__(self): + pass + + def print_policy_interface_link_level_fc(self, info): + self.print_policy_interface_link_level_fc_properties( + info + ) + + self.print_policy_interface_link_level_fc_interfaces( + info['l1RsQosLlfcIfPolCons'] + ) + + self.print_policy_interface_link_level_fc_references( + info['relnFrom'] + ) + + def print_policy_interface_link_level_fc_properties(self, info): + order = [ + 'name', + 'tf', + 'llfcRcvAdminSt', + 'llfcSendAdminSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Receive Flow Control', + 'Send Flow Control', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Link Level Flow Control Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_link_level_fc_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_link_level_fc_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_level_fc_summary(self, info): + order = [ + 'name', + 'tfTick', + 'llfcRcvAdminSt', + 'llfcSendAdminSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Receive Flow Control', + 'Send Flow Control', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_level_fc_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_link_level_fc_interfaces(self, info): + order = [ + 'name', + 'l1RsQosLlfcIfPolCons.pod_node_name', + 'l1RsQosLlfcIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsQosLlfcIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/lldp/__init__.py b/lib/aci/policy/interface/lldp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/lldp/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..55bb324d Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..cee88daf Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..143ef6b7 Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..6d2b96ae Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..d06bfde6 Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2963e05b Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/lldp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..b3d875f8 Binary files /dev/null and b/lib/aci/policy/interface/lldp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/api.py b/lib/aci/policy/interface/lldp/api.py new file mode 100644 index 00000000..68c6be0d --- /dev/null +++ b/lib/aci/policy/interface/lldp/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceLldpApi(): + def __init__(self): + self.policy_interface_lldp_mo = None + + def get_policy_interface_lldp_mo(self): + if self.policy_interface_lldp_mo is not None: + return self.policy_interface_lldp_mo + + cache = self.get_object_cache( + 'lldpIfPol' + ) + if cache is not None: + self.policy_interface_lldp_mo = cache + self.log.apic_mo( + 'lldpIfPol', + self.policy_interface_lldp_mo + ) + return self.policy_interface_lldp_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'lldpIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_lldp_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['lldpIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'lldpIfPol' + ) + + self.policy_interface_lldp_mo.append( + attributes + ) + + self.log.apic_mo( + 'lldpIfPol', + self.policy_interface_lldp_mo + ) + + self.set_object_cache( + 'lldpIfPol', + self.policy_interface_lldp_mo + ) + + return self.policy_interface_lldp_mo diff --git a/lib/aci/policy/interface/lldp/attachment/__init__.py b/lib/aci/policy/interface/lldp/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/lldp/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/lldp/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/lldp/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/lldp/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8f22b7b8 Binary files /dev/null and b/lib/aci/policy/interface/lldp/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/lldp/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..5ecbe321 Binary files /dev/null and b/lib/aci/policy/interface/lldp/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/lldp/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0995bfc7 Binary files /dev/null and b/lib/aci/policy/interface/lldp/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/lldp/attachment/api.py b/lib/aci/policy/interface/lldp/attachment/api.py new file mode 100644 index 00000000..49b53d65 --- /dev/null +++ b/lib/aci/policy/interface/lldp/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceLldpAttachmentApi(): + def __init__(self): + self.policy_interface_lldp_attachment_mo = None + + def get_policy_interface_lldp_attachment_mo(self): + if self.policy_interface_lldp_attachment_mo is not None: + return self.policy_interface_lldp_attachment_mo + + cache = self.get_object_cache( + 'l1RsLldpIfPolCons' + ) + if cache is not None: + self.policy_interface_lldp_attachment_mo = cache + self.log.apic_mo( + 'l1RsLldpIfPolCons', + self.policy_interface_lldp_attachment_mo + ) + return self.policy_interface_lldp_attachment_mo + + managed_objects = self.get_class( + 'l1RsLldpIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_lldp_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_lldp_attachment_mo.append( + managed_object['l1RsLldpIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsLldpIfPolCons', + self.policy_interface_lldp_attachment_mo + ) + + self.set_object_cache( + 'l1RsLldpIfPolCons', + self.policy_interface_lldp_attachment_mo + ) + + return self.policy_interface_lldp_attachment_mo diff --git a/lib/aci/policy/interface/lldp/attachment/info.py b/lib/aci/policy/interface/lldp/attachment/info.py new file mode 100644 index 00000000..d3b3fb81 --- /dev/null +++ b/lib/aci/policy/interface/lldp/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceLldpAttachmentInfo(): + def __init__(self): + self.policy_interface_lldp_attachment = None + + def get_policy_interface_lldp_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rslldpIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "lldpIfPol", + # "tDn": "uni/infra/lldpIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_lldp_attachments_info(self): + if self.policy_interface_lldp_attachment is not None: + return self.policy_interface_lldp_attachment + + managed_objects = self.get_policy_interface_lldp_attachment_mo() + if managed_objects is not None: + self.policy_interface_lldp_attachment = [] + for managed_object in managed_objects: + self.policy_interface_lldp_attachment.append( + self.get_policy_interface_lldp_attachment_info( + managed_object + ) + ) + + return self.policy_interface_lldp_attachment + + def match_policy_interface_lldp_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_lldp_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_lldp_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_lldp_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_lldp_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/lldp/attachment/main.py b/lib/aci/policy/interface/lldp/attachment/main.py new file mode 100644 index 00000000..2503d33e --- /dev/null +++ b/lib/aci/policy/interface/lldp/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.lldp.attachment.api import PolicyInterfaceLldpAttachmentApi +from lib.aci.policy.interface.lldp.attachment.info import PolicyInterfaceLldpAttachmentInfo + + +class PolicyInterfaceLldpAttachment(PolicyInterfaceLldpAttachmentApi, PolicyInterfaceLldpAttachmentInfo): + def __init__(self): + PolicyInterfaceLldpAttachmentApi.__init__(self) + PolicyInterfaceLldpAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/lldp/context.py b/lib/aci/policy/interface/lldp/context.py new file mode 100644 index 00000000..3d36a10d --- /dev/null +++ b/lib/aci/policy/interface/lldp/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceLldpContext(): + def __init__(self): + pass + + def set_policy_interface_lldp_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "lldpIfPol", + # "policyDn": "uni/infra/lldpIfP-k8s_lldp_enable", + # "policyName": "k8s_lldp_enable" + # + # Context + # "lldp": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsLldpIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-lldp-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_lldp_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_lldp_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/lldp/info.py b/lib/aci/policy/interface/lldp/info.py new file mode 100644 index 00000000..a46918cd --- /dev/null +++ b/lib/aci/policy/interface/lldp/info.py @@ -0,0 +1,232 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceLldpInfo(): + def __init__(self): + self.policy_interface_lldp = None + + def get_policy_interface_lldp_reln_info(self, managed_object): + info = {} + info['class'] = 'lldpIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_lldp_info(self, managed_object): + # "adminRxSt": "enabled", + # "adminTxSt": "enabled", + # "annotation": "", + # "childAction": "", + # "creator": "USER", + # "descr": "", + # "dn": "uni/fabric/lldpIfP-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.320+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'adminRxSt', + 'adminTxSt', + 'annotation', + 'dn', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + if info['adminRxSt'] == 'enabled': + info['__Output']['adminRxSt'] = 'Green' + else: + info['__Output']['adminRxSt'] = 'Red' + + if info['adminTxSt'] == 'enabled': + info['__Output']['adminTxSt'] = 'Green' + else: + info['__Output']['adminTxSt'] = 'Red' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_lldp_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_lldp_info(self): + if self.policy_interface_lldp is not None: + return self.policy_interface_lldp + + managed_objects = self.get_policy_interface_lldp_mo() + if managed_objects is not None: + self.policy_interface_lldp = [] + for managed_object in managed_objects: + self.policy_interface_lldp.append( + self.get_policy_interface_lldp_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lldpIfPol.info', + self.policy_interface_lldp + ) + + return self.policy_interface_lldp + + def match_policy_interface_lldp(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsLldpIfPolCons' in policy_info: + if len(policy_info['l1RsLldpIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsLldpIfPolCons' in policy_info: + if len(policy_info['l1RsLldpIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsLldpIfPolCons' in policy_info: + if len(policy_info['l1RsLldpIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_lldp_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_lldp(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_lldp_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_lldp(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_lldp_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_lldp(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsLldpIfPolCons'] = self.get_policy_interface_lldp_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsLldpIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsLldpIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_lldp_attachments_node_summary( + policy_info['l1RsLldpIfPolCons'] + ) + + if not self.match_policy_interface_lldp(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/lldp/main.py b/lib/aci/policy/interface/lldp/main.py new file mode 100644 index 00000000..ab65d842 --- /dev/null +++ b/lib/aci/policy/interface/lldp/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.lldp.attachment.main import PolicyInterfaceLldpAttachment +from lib.aci.policy.interface.lldp.api import PolicyInterfaceLldpApi +from lib.aci.policy.interface.lldp.context import PolicyInterfaceLldpContext +from lib.aci.policy.interface.lldp.info import PolicyInterfaceLldpInfo + + +class PolicyInterfaceLldp(PolicyInterfaceLldpAttachment, PolicyInterfaceLldpApi, PolicyInterfaceLldpContext, PolicyInterfaceLldpInfo): + def __init__(self): + PolicyInterfaceLldpAttachment.__init__(self) + PolicyInterfaceLldpApi.__init__(self) + PolicyInterfaceLldpContext.__init__(self) + PolicyInterfaceLldpInfo.__init__(self) diff --git a/lib/aci/policy/interface/lldp/output.py b/lib/aci/policy/interface/lldp/output.py new file mode 100644 index 00000000..97fb42d0 --- /dev/null +++ b/lib/aci/policy/interface/lldp/output.py @@ -0,0 +1,177 @@ +class PolicyInterfaceLldpOutput(): + def __init__(self): + pass + + def print_policy_interface_lldp(self, info): + self.print_policy_interface_lldp_properties( + info + ) + + self.print_policy_interface_lldp_interfaces( + info['l1RsLldpIfPolCons'] + ) + + self.print_policy_interface_lldp_references( + info['relnFrom'] + ) + + def print_policy_interface_lldp_properties(self, info): + order = [ + 'name', + 'tf', + 'adminRxSt', + 'adminTxSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Receive State', + 'Transmit State', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='LLDP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_lldp_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_lldp_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_lldp_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminRxSt', + 'adminTxSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Receive State', + 'Transmit State', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_lldp_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_lldp_interfaces(self, info): + order = [ + 'name', + 'l1RsLldpIfPolCons.pod_node_name', + 'l1RsLldpIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsLldpIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/main.py b/lib/aci/policy/interface/main.py new file mode 100644 index 00000000..6793693b --- /dev/null +++ b/lib/aci/policy/interface/main.py @@ -0,0 +1,139 @@ +from lib.aci.policy.interface.auth.main import PolicyInterfaceAuth +from lib.aci.policy.interface.cdp.main import PolicyInterfaceCdp +from lib.aci.policy.interface.copp.main import PolicyInterfaceCopp +from lib.aci.policy.interface.dpp.main import PolicyInterfaceDpp +from lib.aci.policy.interface.fc.main import PolicyInterfaceFc +from lib.aci.policy.interface.l2.main import PolicyInterfaceL2 +from lib.aci.policy.interface.link_flap.main import PolicyInterfaceLinkFlap +from lib.aci.policy.interface.link_level.main import PolicyInterfaceLinkLevel +from lib.aci.policy.interface.link_level_fc.main import PolicyInterfaceLinkLevelFc +from lib.aci.policy.interface.lldp.main import PolicyInterfaceLldp +from lib.aci.policy.interface.mcp.main import PolicyInterfaceMcp +from lib.aci.policy.interface.pfc.main import PolicyInterfacePfc +from lib.aci.policy.interface.port_channel.main import PolicyInterfacePortChannel +from lib.aci.policy.interface.port_channel_member.main import PolicyInterfacePortChannelMember +from lib.aci.policy.interface.port_security.main import PolicyInterfacePortSecurity +from lib.aci.policy.interface.slow_drain.main import PolicyInterfaceSlowDrain +from lib.aci.policy.interface.storm_control.main import PolicyInterfaceStormControl +from lib.aci.policy.interface.stp.main import PolicyInterfaceStp +from lib.aci.policy.interface.synce.main import PolicyInterfaceSynce +from lib.aci.policy.interface.transceiver.main import PolicyInterfaceTransceiver + + +class PolicyInterface( + PolicyInterfaceAuth, + PolicyInterfaceCdp, + PolicyInterfaceCopp, + PolicyInterfaceDpp, + PolicyInterfaceFc, + PolicyInterfaceL2, + PolicyInterfaceLinkFlap, + PolicyInterfaceLinkLevel, + PolicyInterfaceLinkLevelFc, + PolicyInterfaceLldp, + PolicyInterfaceMcp, + PolicyInterfacePfc, + PolicyInterfacePortChannel, + PolicyInterfacePortChannelMember, + PolicyInterfacePortSecurity, + PolicyInterfaceSlowDrain, + PolicyInterfaceStormControl, + PolicyInterfaceStp, + PolicyInterfaceSynce, + PolicyInterfaceTransceiver + ): + def __init__(self): + PolicyInterfaceAuth.__init__(self) + PolicyInterfaceCdp.__init__(self) + PolicyInterfaceCopp.__init__(self) + PolicyInterfaceDpp.__init__(self) + PolicyInterfaceFc.__init__(self) + PolicyInterfaceL2.__init__(self) + PolicyInterfaceLinkFlap.__init__(self) + PolicyInterfaceLinkLevel.__init__(self) + PolicyInterfaceLinkLevelFc.__init__(self) + PolicyInterfaceLldp.__init__(self) + PolicyInterfaceMcp.__init__(self) + PolicyInterfacePfc.__init__(self) + PolicyInterfacePortChannel.__init__(self) + PolicyInterfacePortChannelMember.__init__(self) + PolicyInterfacePortSecurity.__init__(self) + PolicyInterfaceSlowDrain.__init__(self) + PolicyInterfaceStormControl.__init__(self) + PolicyInterfaceStp.__init__(self) + PolicyInterfaceSynce.__init__(self) + PolicyInterfaceTransceiver.__init__(self) + + def get_policy_interface_reln(self, managed_object, interface_class_name): + attributes = [] + if 'children' in managed_object[interface_class_name]: + for child in managed_object[interface_class_name]['children']: + for class_name in child: + entry = {} + entry['class'] = class_name + entry['rn'] = child[class_name]['attributes']['rn'] + entry['tCl'] = child[class_name]['attributes']['tCl'] + entry['tDn'] = child[class_name]['attributes']['tDn'] + entry['policyType'] = self.get_policy_type_from_tcl( + child[class_name]['attributes']['tCl'] + ) + entry['policyName'] = self.get_policy_name_from_tdn( + child[class_name]['attributes']['tDn'] + ) + attributes.append( + entry + ) + + attributes = sorted( + attributes, + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + return attributes + + def get_policy_interface_reference_attributes(self, managed_object): + # "annotation": "", + # "childAction": "", + # "extMngdBy": "", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2021-05-19T18:26:53.317+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "rType": "mo", + # "rn": "rsstormctrlIfPol", + # "state": "formed", + # "stateQual": "default-target", + # "status": "", + # "tCl": "stormctrlIfPol", + # "tContextDn": "", + # "tDn": "uni/infra/stormctrlifp-default", + # "tRn": "stormctrlifp-default", + # "tType": "name", + # "tnStormctrlIfPolName": "", + # "uid": "0", + # "userdom": "all" + keys = [ + 'state', + 'tDn', + 'tRn' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if managed_object is not None and key in managed_object: + info[key] = managed_object[key] + + info['name'] = '--' + if managed_object is not None: + if 'tType' in managed_object: + if managed_object['tType'] == 'name': + info['name'] = '-'.join(info['tRn'].split('-')[1:]) + if managed_object['tType'] == 'mo': + info['name'] = '-'.join(info['tDn'].split('-')[1:]) + + return info diff --git a/lib/aci/policy/interface/mcp/__init__.py b/lib/aci/policy/interface/mcp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/mcp/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95be65e6 Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d689ce26 Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..7681d1a3 Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..b6cfcc00 Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ff328d5f Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7d3c0a7f Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..5e9a3cf2 Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/__pycache__/vmm.cpython-310.pyc b/lib/aci/policy/interface/mcp/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..2edf8688 Binary files /dev/null and b/lib/aci/policy/interface/mcp/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/api.py b/lib/aci/policy/interface/mcp/api.py new file mode 100644 index 00000000..0b4114f1 --- /dev/null +++ b/lib/aci/policy/interface/mcp/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceMcpApi(): + def __init__(self): + self.policy_interface_mcp_mo = None + + def get_policy_interface_mcp_mo(self): + if self.policy_interface_mcp_mo is not None: + return self.policy_interface_mcp_mo + + cache = self.get_object_cache( + 'mcpIfPol' + ) + if cache is not None: + self.policy_interface_mcp_mo = cache + self.log.apic_mo( + 'mcpIfPol', + self.policy_interface_mcp_mo + ) + return self.policy_interface_mcp_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'mcpIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_mcp_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['mcpIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'mcpIfPol' + ) + + self.policy_interface_mcp_mo.append( + attributes + ) + + self.log.apic_mo( + 'mcpIfPol', + self.policy_interface_mcp_mo + ) + + self.set_object_cache( + 'mcpIfPol', + self.policy_interface_mcp_mo + ) + + return self.policy_interface_mcp_mo diff --git a/lib/aci/policy/interface/mcp/attachment/__init__.py b/lib/aci/policy/interface/mcp/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/mcp/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/mcp/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/mcp/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/mcp/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8bb55bff Binary files /dev/null and b/lib/aci/policy/interface/mcp/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/mcp/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..7edb9c9f Binary files /dev/null and b/lib/aci/policy/interface/mcp/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/mcp/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7532fc85 Binary files /dev/null and b/lib/aci/policy/interface/mcp/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/mcp/attachment/api.py b/lib/aci/policy/interface/mcp/attachment/api.py new file mode 100644 index 00000000..96cef5f4 --- /dev/null +++ b/lib/aci/policy/interface/mcp/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceMcpAttachmentApi(): + def __init__(self): + self.policy_interface_mcp_attachment_mo = None + + def get_policy_interface_mcp_attachment_mo(self): + if self.policy_interface_mcp_attachment_mo is not None: + return self.policy_interface_mcp_attachment_mo + + cache = self.get_object_cache( + 'l1RsMcpIfPolCons' + ) + if cache is not None: + self.policy_interface_mcp_attachment_mo = cache + self.log.apic_mo( + 'l1RsMcpIfPolCons', + self.policy_interface_mcp_attachment_mo + ) + return self.policy_interface_mcp_attachment_mo + + managed_objects = self.get_class( + 'l1RsMcpIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_mcp_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_mcp_attachment_mo.append( + managed_object['l1RsMcpIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsMcpIfPolCons', + self.policy_interface_mcp_attachment_mo + ) + + self.set_object_cache( + 'l1RsMcpIfPolCons', + self.policy_interface_mcp_attachment_mo + ) + + return self.policy_interface_mcp_attachment_mo diff --git a/lib/aci/policy/interface/mcp/attachment/info.py b/lib/aci/policy/interface/mcp/attachment/info.py new file mode 100644 index 00000000..e4c62f3e --- /dev/null +++ b/lib/aci/policy/interface/mcp/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceMcpAttachmentInfo(): + def __init__(self): + self.policy_interface_mcp_attachment = None + + def get_policy_interface_mcp_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsmcpIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "mcpIfPol", + # "tDn": "uni/infra/mcpIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_mcp_attachments_info(self): + if self.policy_interface_mcp_attachment is not None: + return self.policy_interface_mcp_attachment + + managed_objects = self.get_policy_interface_mcp_attachment_mo() + if managed_objects is not None: + self.policy_interface_mcp_attachment = [] + for managed_object in managed_objects: + self.policy_interface_mcp_attachment.append( + self.get_policy_interface_mcp_attachment_info( + managed_object + ) + ) + + return self.policy_interface_mcp_attachment + + def match_policy_interface_mcp_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_mcp_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_mcp_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_mcp_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_mcp_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/mcp/attachment/main.py b/lib/aci/policy/interface/mcp/attachment/main.py new file mode 100644 index 00000000..0cc1abd9 --- /dev/null +++ b/lib/aci/policy/interface/mcp/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.mcp.attachment.api import PolicyInterfaceMcpAttachmentApi +from lib.aci.policy.interface.mcp.attachment.info import PolicyInterfaceMcpAttachmentInfo + + +class PolicyInterfaceMcpAttachment(PolicyInterfaceMcpAttachmentApi, PolicyInterfaceMcpAttachmentInfo): + def __init__(self): + PolicyInterfaceMcpAttachmentApi.__init__(self) + PolicyInterfaceMcpAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/mcp/context.py b/lib/aci/policy/interface/mcp/context.py new file mode 100644 index 00000000..ddc42657 --- /dev/null +++ b/lib/aci/policy/interface/mcp/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceMcpContext(): + def __init__(self): + pass + + def set_policy_interface_mcp_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "mcpIfPol", + # "policyDn": "uni/infra/mcpIfP-k8s_mcp_enable", + # "policyName": "k8s_mcp_enable" + # + # Context + # "mcp": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsMcpIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-mcp-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_mcp_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_mcp_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/mcp/info.py b/lib/aci/policy/interface/mcp/info.py new file mode 100644 index 00000000..b2945566 --- /dev/null +++ b/lib/aci/policy/interface/mcp/info.py @@ -0,0 +1,245 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceMcpInfo(): + def __init__(self): + self.policy_interface_mcp = None + + def get_policy_interface_mcp_reln_info(self, managed_object): + info = {} + info['class'] = 'mcpIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_mcp_info(self, managed_object): + # "adminSt": "enabled", + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/mcpIfP-default", + # "extMngdBy": "", + # "gracePeriod": "3", + # "gracePeriodMsec": "0", + # "lcOwn": "local", + # "mcpMode": "off", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "strictInitDelayTime": "0", + # "strictTxFreq": "0", + # "strictTxFreqMsec": "500", + # "uid": "0", + # "userdom": "" + keys = [ + 'adminSt', + 'annotation', + 'dn', + 'gracePeriod', + 'gracePeriodMsec', + 'mcpMode', + 'name', + 'strictInitDelayTime', + 'strictTxFreq', + 'strictTxFreqMsec', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + if info['mcpMode'] == 'off': + info['mcpModeT'] = 'Non strict' + info['strictInitDelayTime'] = '' + info['strictTxFreq'] = '' + info['strictTxFreqMsec'] = '' + info['gracePeriod'] = '' + info['gracePeriodMsec'] = '' + else: + info['mcpModeT'] = 'Strict' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_mcp_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_mcp_info(self): + if self.policy_interface_mcp is not None: + return self.policy_interface_mcp + + managed_objects = self.get_policy_interface_mcp_mo() + if managed_objects is not None: + self.policy_interface_mcp = [] + for managed_object in managed_objects: + self.policy_interface_mcp.append( + self.get_policy_interface_mcp_info( + managed_object + ) + ) + + self.log.apic_mo( + 'mcpIfPol.info', + self.policy_interface_mcp + ) + + return self.policy_interface_mcp + + def match_policy_interface_mcp(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsMcpIfPolCons' in policy_info: + if len(policy_info['l1RsMcpIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsMcpIfPolCons' in policy_info: + if len(policy_info['l1RsMcpIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsMcpIfPolCons' in policy_info: + if len(policy_info['l1RsMcpIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_mcp_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_mcp(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_mcp_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_mcp(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_mcp_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_mcp(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsMcpIfPolCons'] = self.get_policy_interface_mcp_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsMcpIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsMcpIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_mcp_attachments_node_summary( + policy_info['l1RsMcpIfPolCons'] + ) + + if not self.match_policy_interface_mcp(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/mcp/main.py b/lib/aci/policy/interface/mcp/main.py new file mode 100644 index 00000000..1d76b8f8 --- /dev/null +++ b/lib/aci/policy/interface/mcp/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.mcp.attachment.main import PolicyInterfaceMcpAttachment +from lib.aci.policy.interface.mcp.api import PolicyInterfaceMcpApi +from lib.aci.policy.interface.mcp.context import PolicyInterfaceMcpContext +from lib.aci.policy.interface.mcp.info import PolicyInterfaceMcpInfo + + +class PolicyInterfaceMcp(PolicyInterfaceMcpAttachment, PolicyInterfaceMcpApi, PolicyInterfaceMcpContext, PolicyInterfaceMcpInfo): + def __init__(self): + PolicyInterfaceMcpAttachment.__init__(self) + PolicyInterfaceMcpApi.__init__(self) + PolicyInterfaceMcpContext.__init__(self) + PolicyInterfaceMcpInfo.__init__(self) diff --git a/lib/aci/policy/interface/mcp/output.py b/lib/aci/policy/interface/mcp/output.py new file mode 100644 index 00000000..0bddb881 --- /dev/null +++ b/lib/aci/policy/interface/mcp/output.py @@ -0,0 +1,177 @@ +class PolicyInterfaceMcpOutput(): + def __init__(self): + pass + + def print_policy_interface_mcp(self, info): + self.print_policy_interface_mcp_properties( + info + ) + + self.print_policy_interface_mcp_interfaces( + info['l1RsMcpIfPolCons'] + ) + + self.print_policy_interface_mcp_references( + info['relnFrom'] + ) + + def print_policy_interface_mcp_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State' + ] + + self.my_output.dictionary( + info, + title='CDP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_mcp_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_mcp_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_mcp_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_mcp_usage(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_mcp_interfaces(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'l1RsMcpIfPolCons.pod_node_name', + 'l1RsMcpIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsMcpIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/output.py b/lib/aci/policy/interface/output.py new file mode 100644 index 00000000..b6d3b278 --- /dev/null +++ b/lib/aci/policy/interface/output.py @@ -0,0 +1,274 @@ +import copy + +from lib.aci.policy.interface.auth.output import PolicyInterfaceAuthOutput +from lib.aci.policy.interface.cdp.output import PolicyInterfaceCdpOutput +from lib.aci.policy.interface.copp.output import PolicyInterfaceCoppOutput +from lib.aci.policy.interface.dpp.output import PolicyInterfaceDppOutput +from lib.aci.policy.interface.fc.output import PolicyInterfaceFcOutput +from lib.aci.policy.interface.l2.output import PolicyInterfaceL2Output +from lib.aci.policy.interface.link_flap.output import PolicyInterfaceLinkFlapOutput +from lib.aci.policy.interface.link_level.output import PolicyInterfaceLinkLevelOutput +from lib.aci.policy.interface.link_level_fc.output import PolicyInterfaceLinkLevelFcOutput +from lib.aci.policy.interface.lldp.output import PolicyInterfaceLldpOutput +from lib.aci.policy.interface.mcp.output import PolicyInterfaceMcpOutput +from lib.aci.policy.interface.pfc.output import PolicyInterfacePfcOutput +from lib.aci.policy.interface.port_channel.output import PolicyInterfacePortChannelOutput +from lib.aci.policy.interface.port_channel_member.output import PolicyInterfacePortChannelMemberOutput +from lib.aci.policy.interface.port_security.output import PolicyInterfacePortSecurityOutput +from lib.aci.policy.interface.slow_drain.output import PolicyInterfaceSlowDrainOutput +from lib.aci.policy.interface.storm_control.output import PolicyInterfaceStormControlOutput +from lib.aci.policy.interface.stp.output import PolicyInterfaceStpOutput +from lib.aci.policy.interface.synce.output import PolicyInterfaceSynceOutput +from lib.aci.policy.interface.transceiver.output import PolicyInterfaceTransceiverOutput + + +class PolicyInterfaceOutput( + PolicyInterfaceAuthOutput, + PolicyInterfaceCdpOutput, + PolicyInterfaceCoppOutput, + PolicyInterfaceDppOutput, + PolicyInterfaceFcOutput, + PolicyInterfaceL2Output, + PolicyInterfaceLinkFlapOutput, + PolicyInterfaceLinkLevelOutput, + PolicyInterfaceLinkLevelFcOutput, + PolicyInterfaceLldpOutput, + PolicyInterfaceMcpOutput, + PolicyInterfacePfcOutput, + PolicyInterfacePortChannelOutput, + PolicyInterfacePortChannelMemberOutput, + PolicyInterfacePortSecurityOutput, + PolicyInterfaceSlowDrainOutput, + PolicyInterfaceStormControlOutput, + PolicyInterfaceStpOutput, + PolicyInterfaceSynceOutput, + PolicyInterfaceTransceiverOutput + ): + def __init__(self): + PolicyInterfaceAuthOutput.__init__(self) + PolicyInterfaceCdpOutput.__init__(self) + PolicyInterfaceCoppOutput.__init__(self) + PolicyInterfaceDppOutput.__init__(self) + PolicyInterfaceFcOutput.__init__(self) + PolicyInterfaceL2Output.__init__(self) + PolicyInterfaceLinkFlapOutput.__init__(self) + PolicyInterfaceLinkLevelOutput.__init__(self) + PolicyInterfaceLinkLevelFcOutput.__init__(self) + PolicyInterfaceLldpOutput.__init__(self) + PolicyInterfaceMcpOutput.__init__(self) + PolicyInterfacePfcOutput.__init__(self) + PolicyInterfacePortChannelOutput.__init__(self) + PolicyInterfacePortChannelMemberOutput.__init__(self) + PolicyInterfacePortSecurityOutput.__init__(self) + PolicyInterfaceSlowDrainOutput.__init__(self) + PolicyInterfaceStormControlOutput.__init__(self) + PolicyInterfaceStpOutput.__init__(self) + PolicyInterfaceSynceOutput.__init__(self) + PolicyInterfaceTransceiverOutput.__init__(self) + + def print_policy_interface_reln_from(self, info): + order = [ + 'policyType', + 'policyName' + ] + + headers = [ + 'Policy Type', + 'Policy Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_node_interfaces(self, info, verbose): + if verbose: + node_ports = [] + for node in info: + node_ports = node_ports + node['interfaces'] + + order = [ + 'port.podId', + 'port.nodeName', + 'port.id', + 'port.adminSt', + 'port.stats.operSt', + 'port.portT', + 'port.stats.bundleIndex' + ] + + headers = [ + 'Pod', + 'Node', + 'Port', + 'Admin State', + 'Oper State', + 'Port Type', + 'Port Channel' + ] + + self.my_output.my_table( + node_ports, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if not verbose: + order = [ + 'pod_id', + 'node_name', + 'interfacesCount' + ] + + headers = [ + 'Pod', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface(self, info, title, order, headers, verbose): + self.my_output.dictionary( + info, + title=title, + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + if 'relnFrom' in info: + self.print_policy_interface_reln_from(info['relnFrom']) + + if 'nodeInterfaces' in info: + self.print_policy_interface_node_interfaces(info['nodeInterfaces'], verbose) + + def print_policies_interface(self, info, order, headers, verbose, expand_lists=None): + if not verbose: + order.append('interfaces') + headers.append('Interfaces') + order.append('references') + headers.append('Ref Policies') + + if expand_lists is not None: + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + expand_lists + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + else: + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if verbose: + order.append('nodeInterfaces.node_name') + headers.append('Node Name') + order.append('nodeInterfaces.interfacesCount') + headers.append('Interfaces') + order.append('relnFrom.policyType') + headers.append('Ref Policy Type') + order.append('relnFrom.policyName') + headers.append('Ref Policy Name') + + if expand_lists is not None: + expand_lists = expand_lists + ['relnFrom', 'nodeInterfaces'] + else: + expand_lists = ['relnFrom', 'nodeInterfaces'] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + expand_lists + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_node(self, info, order, headers, include_no_policy=False, expand_lists=None): + if not include_no_policy: + info_filtered = [] + for item in info: + if 'policy' not in item: + continue + + if len(item['policy']) == 0: + continue + + info_filtered.append(item) + + info = copy.deepcopy(info_filtered) + + base_order = [ + 'port.id', + 'port.adminSt', + 'port.stats.operSt', + 'port.portT', + 'port.stats.bundleIndex' + ] + order = base_order + order + + base_headers = [ + 'Port', + 'Admin State', + 'Oper State', + 'Port Type', + 'Port Channel' + ] + headers = base_headers + headers + + if expand_lists is not None: + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + expand_lists + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + else: + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/pfc/__init__.py b/lib/aci/policy/interface/pfc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/pfc/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95be65e6 Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c642d04d Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..bb52a4a8 Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..c43fe000 Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..190b6721 Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f4598b30 Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..955d8aed Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/__pycache__/vmm.cpython-310.pyc b/lib/aci/policy/interface/pfc/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..2edf8688 Binary files /dev/null and b/lib/aci/policy/interface/pfc/__pycache__/vmm.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/api.py b/lib/aci/policy/interface/pfc/api.py new file mode 100644 index 00000000..0fdf6cbf --- /dev/null +++ b/lib/aci/policy/interface/pfc/api.py @@ -0,0 +1,51 @@ +class PolicyInterfacePfcApi(): + def __init__(self): + self.policy_interface_pfc_mo = None + + def get_policy_interface_pfc_mo(self): + if self.policy_interface_pfc_mo is not None: + return self.policy_interface_pfc_mo + + cache = self.get_object_cache( + 'qosPfcIfPol' + ) + if cache is not None: + self.policy_interface_pfc_mo = cache + self.log.apic_mo( + 'qosPfcIfPol', + self.policy_interface_pfc_mo + ) + return self.policy_interface_pfc_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'qosPfcIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_pfc_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['qosPfcIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'qosPfcIfPol' + ) + + self.policy_interface_pfc_mo.append( + attributes + ) + + self.log.apic_mo( + 'qosPfcIfPol', + self.policy_interface_pfc_mo + ) + + self.set_object_cache( + 'qosPfcIfPol', + self.policy_interface_pfc_mo + ) + + return self.policy_interface_pfc_mo diff --git a/lib/aci/policy/interface/pfc/attachment/__init__.py b/lib/aci/policy/interface/pfc/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/pfc/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/pfc/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/pfc/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/pfc/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d364fdde Binary files /dev/null and b/lib/aci/policy/interface/pfc/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/pfc/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ee08b7d8 Binary files /dev/null and b/lib/aci/policy/interface/pfc/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/pfc/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..cae3e9d4 Binary files /dev/null and b/lib/aci/policy/interface/pfc/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/pfc/attachment/api.py b/lib/aci/policy/interface/pfc/attachment/api.py new file mode 100644 index 00000000..84bec4e9 --- /dev/null +++ b/lib/aci/policy/interface/pfc/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfacePfcAttachmentApi(): + def __init__(self): + self.policy_interface_pfc_attachment_mo = None + + def get_policy_interface_pfc_attachment_mo(self): + if self.policy_interface_pfc_attachment_mo is not None: + return self.policy_interface_pfc_attachment_mo + + cache = self.get_object_cache( + 'l1RsQosPfcIfPolCons' + ) + if cache is not None: + self.policy_interface_pfc_attachment_mo = cache + self.log.apic_mo( + 'l1RsQosPfcIfPolCons', + self.policy_interface_pfc_attachment_mo + ) + return self.policy_interface_pfc_attachment_mo + + managed_objects = self.get_class( + 'l1RsQosPfcIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_pfc_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_pfc_attachment_mo.append( + managed_object['l1RsQosPfcIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsQosPfcIfPolCons', + self.policy_interface_pfc_attachment_mo + ) + + self.set_object_cache( + 'l1RsQosPfcIfPolCons', + self.policy_interface_pfc_attachment_mo + ) + + return self.policy_interface_pfc_attachment_mo diff --git a/lib/aci/policy/interface/pfc/attachment/info.py b/lib/aci/policy/interface/pfc/attachment/info.py new file mode 100644 index 00000000..95dca099 --- /dev/null +++ b/lib/aci/policy/interface/pfc/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfacePfcAttachmentInfo(): + def __init__(self): + self.policy_interface_pfc_attachment = None + + def get_policy_interface_pfc_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsqosPfcIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "qosPfcIfPol", + # "tDn": "uni/infra/pfcIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_pfc_attachments_info(self): + if self.policy_interface_pfc_attachment is not None: + return self.policy_interface_pfc_attachment + + managed_objects = self.get_policy_interface_pfc_attachment_mo() + if managed_objects is not None: + self.policy_interface_pfc_attachment = [] + for managed_object in managed_objects: + self.policy_interface_pfc_attachment.append( + self.get_policy_interface_pfc_attachment_info( + managed_object + ) + ) + + return self.policy_interface_pfc_attachment + + def match_policy_interface_pfc_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_pfc_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_pfc_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_pfc_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_pfc_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/pfc/attachment/main.py b/lib/aci/policy/interface/pfc/attachment/main.py new file mode 100644 index 00000000..12ec1f33 --- /dev/null +++ b/lib/aci/policy/interface/pfc/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.pfc.attachment.api import PolicyInterfacePfcAttachmentApi +from lib.aci.policy.interface.pfc.attachment.info import PolicyInterfacePfcAttachmentInfo + + +class PolicyInterfacePfcAttachment(PolicyInterfacePfcAttachmentApi, PolicyInterfacePfcAttachmentInfo): + def __init__(self): + PolicyInterfacePfcAttachmentApi.__init__(self) + PolicyInterfacePfcAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/pfc/context.py b/lib/aci/policy/interface/pfc/context.py new file mode 100644 index 00000000..cc91c897 --- /dev/null +++ b/lib/aci/policy/interface/pfc/context.py @@ -0,0 +1,93 @@ +class PolicyInterfacePfcContext(): + def __init__(self): + pass + + def set_policy_interface_pfc_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "qosPfcIfPol", + # "policyDn": "uni/infra/pfcIfP-k8s_pfc_enable", + # "policyName": "k8s_pfc_enable" + # + # Context + # "pfc": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsQosPfcIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-pfc-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_pfc_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_pfc_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/pfc/info.py b/lib/aci/policy/interface/pfc/info.py new file mode 100644 index 00000000..2e116a19 --- /dev/null +++ b/lib/aci/policy/interface/pfc/info.py @@ -0,0 +1,223 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfacePfcInfo(): + def __init__(self): + self.policy_interface_pfc = None + + def get_policy_interface_pfc_reln_info(self, managed_object): + info = {} + info['class'] = 'qosPfcIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_pfc_info(self, managed_object): + # "adminSt": "auto", + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/pfc-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'adminSt', + 'annotation', + 'dn', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['adminSt'] in ['auto', 'on']: + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_pfc_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_pfc_info(self): + if self.policy_interface_pfc is not None: + return self.policy_interface_pfc + + managed_objects = self.get_policy_interface_pfc_mo() + if managed_objects is not None: + self.policy_interface_pfc = [] + for managed_object in managed_objects: + self.policy_interface_pfc.append( + self.get_policy_interface_pfc_info( + managed_object + ) + ) + + self.log.apic_mo( + 'qosPfcIfPol.info', + self.policy_interface_pfc + ) + + return self.policy_interface_pfc + + def match_policy_interface_pfc(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsQosPfcIfPolCons' in policy_info: + if len(policy_info['l1RsQosPfcIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsQosPfcIfPolCons' in policy_info: + if len(policy_info['l1RsQosPfcIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsQosPfcIfPolCons' in policy_info: + if len(policy_info['l1RsQosPfcIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_pfc_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_pfc(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_pfc_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_pfc(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_pfc_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_pfc(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsQosPfcIfPolCons'] = self.get_policy_interface_pfc_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsQosPfcIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsQosPfcIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_pfc_attachments_node_summary( + policy_info['l1RsQosPfcIfPolCons'] + ) + + if not self.match_policy_interface_pfc(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/pfc/main.py b/lib/aci/policy/interface/pfc/main.py new file mode 100644 index 00000000..18de69ef --- /dev/null +++ b/lib/aci/policy/interface/pfc/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.pfc.attachment.main import PolicyInterfacePfcAttachment +from lib.aci.policy.interface.pfc.api import PolicyInterfacePfcApi +from lib.aci.policy.interface.pfc.context import PolicyInterfacePfcContext +from lib.aci.policy.interface.pfc.info import PolicyInterfacePfcInfo + + +class PolicyInterfacePfc(PolicyInterfacePfcAttachment, PolicyInterfacePfcApi, PolicyInterfacePfcContext, PolicyInterfacePfcInfo): + def __init__(self): + PolicyInterfacePfcAttachment.__init__(self) + PolicyInterfacePfcApi.__init__(self) + PolicyInterfacePfcContext.__init__(self) + PolicyInterfacePfcInfo.__init__(self) diff --git a/lib/aci/policy/interface/pfc/output.py b/lib/aci/policy/interface/pfc/output.py new file mode 100644 index 00000000..ce40ce75 --- /dev/null +++ b/lib/aci/policy/interface/pfc/output.py @@ -0,0 +1,177 @@ +class PolicyInterfacePfcOutput(): + def __init__(self): + pass + + def print_policy_interface_pfc(self, info): + self.print_policy_interface_pfc_properties( + info + ) + + self.print_policy_interface_pfc_interfaces( + info['l1RsQosPfcIfPolCons'] + ) + + self.print_policy_interface_pfc_references( + info['relnFrom'] + ) + + def print_policy_interface_pfc_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State' + ] + + self.my_output.dictionary( + info, + title='Priority Flow Control Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_pfc_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_pfc_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_pfc_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_pfc_usage(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_pfc_interfaces(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'l1RsQosPfcIfPolCons.pod_node_name', + 'l1RsQosPfcIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsQosPfcIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/port_channel/__init__.py b/lib/aci/policy/interface/port_channel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/port_channel/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5c4c62f9 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..96ee16d9 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..3b31390e Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..605e1422 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c70e6d44 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/port_channel/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..1f766d3f Binary files /dev/null and b/lib/aci/policy/interface/port_channel/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/api.py b/lib/aci/policy/interface/port_channel/api.py new file mode 100644 index 00000000..25c447b8 --- /dev/null +++ b/lib/aci/policy/interface/port_channel/api.py @@ -0,0 +1,56 @@ +class PolicyInterfacePortChannelApi(): + def __init__(self): + self.policy_interface_port_channel_mo = None + + def get_policy_interface_port_channel_mo(self): + if self.policy_interface_port_channel_mo is not None: + return self.policy_interface_port_channel_mo + + cache = self.get_object_cache( + 'lacpLagPol' + ) + if cache is not None: + self.policy_interface_port_channel_mo = cache + self.log.apic_mo( + 'lacpLagPol', + self.policy_interface_port_channel_mo + ) + return self.policy_interface_port_channel_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'lacpLagPol', + query=query + ) + if managed_objects is None: + return None + + self.log.apic_mo( + 'lacpLagPol.raw', + managed_objects + ) + + self.policy_interface_port_channel_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['lacpLagPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'lacpLagPol' + ) + + self.policy_interface_port_channel_mo.append( + attributes + ) + + self.log.apic_mo( + 'lacpLagPol', + self.policy_interface_port_channel_mo + ) + + self.set_object_cache( + 'lacpLagPol', + self.policy_interface_port_channel_mo + ) + + return self.policy_interface_port_channel_mo diff --git a/lib/aci/policy/interface/port_channel/attachment/__init__.py b/lib/aci/policy/interface/port_channel/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/port_channel/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/port_channel/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/port_channel/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/port_channel/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..7a08a828 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/port_channel/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..333c2105 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/port_channel/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1fcc2545 Binary files /dev/null and b/lib/aci/policy/interface/port_channel/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel/attachment/api.py b/lib/aci/policy/interface/port_channel/attachment/api.py new file mode 100644 index 00000000..929c2b6d --- /dev/null +++ b/lib/aci/policy/interface/port_channel/attachment/api.py @@ -0,0 +1,92 @@ +import copy + + +class PolicyInterfacePortChannelAttachmentApi(): + def __init__(self): + self.policy_interface_port_channel_attachment_mo = None + self.policy_interface_port_channel_nodes = None + + def get_policy_interface_port_channel_attachment_mo(self): + if self.policy_interface_port_channel_attachment_mo is not None: + return self.policy_interface_port_channel_attachment_mo + + cache = self.get_object_cache( + 'L2IfPolToEthIf' + ) + if cache is not None: + self.policy_interface_port_channel_attachment_mo = cache + self.log.apic_mo( + 'L2IfPolToEthIf', + self.policy_interface_port_channel_attachment_mo + ) + return self.policy_interface_port_channel_attachment_mo + + self.policy_interface_port_channel_attachment_mo = [] + self.policy_interface_port_channel_nodes = [] + + for port_channel_info in self.policy_interface_port_channel: + port_channel_name = port_channel_info['name'] + managed_objects = self.get_managed_object( + 'uni/infra/lacplagp-%s' % (port_channel_name), + query='rsp-subtree-include=full-deployment&target-path=L2IfPolToEthIf' + ) + if managed_objects is not None: + for item in managed_objects['imdata']: + if 'lacpLagPol' in item and 'children' in item['lacpLagPol']: + for child in item['lacpLagPol']['children']: + if 'pconsNodeDeployCtx' in child: + info = {} + info['tDn'] = port_channel_info['dn'] + info['tName'] = port_channel_name + info['tCl'] = 'lacpLagPol' + info['nodeId'] = child['pconsNodeDeployCtx']['attributes']['nodeId'] + info['profiles'] = [] + if 'children' in child['pconsNodeDeployCtx']: + for subchild in child['pconsNodeDeployCtx']['children']: + if 'pconsDependencyCtx' in subchild: + profile = {} + profile['class'] = subchild['pconsDependencyCtx']['attributes']['ctxClass'] + profile['dn'] = subchild['pconsDependencyCtx']['attributes']['ctxDn'] + info['profiles'].append( + profile + ) + + self.policy_interface_port_channel_nodes.append(info) + + self.log.apic_mo( + 'L2IfPolToEthIf.nodes', + self.policy_interface_port_channel_nodes + ) + + for port_channel_node in self.policy_interface_port_channel_nodes: + managed_objects = self.get_managed_object( + 'uni/infra/lacplagp-%s' % (port_channel_node['tName']), + query='rsp-subtree-include=full-deployment&target-node=%s&target-path=L2IfPolToEthIf' % (port_channel_node['nodeId']) + ) + self.log.apic_mo( + 'L2IfPolToEthIf.%s.%s' % (port_channel_node['nodeId'], port_channel_node['tName']), + managed_objects + ) + if managed_objects is not None: + for item in managed_objects['imdata']: + if 'lacpLagPol' in item and 'children' in item['lacpLagPol']: + for child in item['lacpLagPol']['children']: + if 'pconsNodeDeployCtx' in child: + if 'children' in child['pconsNodeDeployCtx']: + for deploy_child in child['pconsNodeDeployCtx']['children']: + if 'pconsResourceCtx' in deploy_child: + info = copy.deepcopy(port_channel_node) + info['dn'] = deploy_child['pconsResourceCtx']['attributes']['ctxDn'] + self.policy_interface_port_channel_attachment_mo.append(info) + + self.log.apic_mo( + 'L2IfPolToEthIf', + self.policy_interface_port_channel_attachment_mo + ) + + self.set_object_cache( + 'L2IfPolToEthIf', + self.policy_interface_port_channel_attachment_mo + ) + + return self.policy_interface_port_channel_attachment_mo diff --git a/lib/aci/policy/interface/port_channel/attachment/info.py b/lib/aci/policy/interface/port_channel/attachment/info.py new file mode 100644 index 00000000..e9810a8d --- /dev/null +++ b/lib/aci/policy/interface/port_channel/attachment/info.py @@ -0,0 +1,128 @@ +from lib import filter_helper + + +class PolicyInterfacePortChannelAttachmentInfo(): + def __init__(self): + self.policy_interface_port_channel_attachment = None + + def get_policy_interface_port_channel_attachment_info(self, managed_object): + # "tDn": "uni/infra/lacplagp-k8s_lacp_active", + # "tName": "k8s_lacp_active", + # "tCl": "lacpLagPol", + # "nodeId": "2208", + # "profiles": [ + # { + # "class": "infraAccPortP", + # "dn": "uni/infra/accportprof-k8s_CL2208_IntProf" + # } + # ], + # "dn": "topology/pod-1/node-2208/sys/aggr-[po8]" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['dn'].split('aggr-[')[1].split(']')[0] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][9:] + + return info + + def get_policy_interface_port_channel_attachments_info(self): + if self.policy_interface_port_channel_attachment is not None: + return self.policy_interface_port_channel_attachment + + managed_objects = self.get_policy_interface_port_channel_attachment_mo() + if managed_objects is not None: + self.policy_interface_port_channel_attachment = [] + for managed_object in managed_objects: + self.policy_interface_port_channel_attachment.append( + self.get_policy_interface_port_channel_attachment_info( + managed_object + ) + ) + + return self.policy_interface_port_channel_attachment + + def match_policy_interface_port_channel_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_port_channel_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_port_channel_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_port_channel_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_port_channel_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/port_channel/attachment/main.py b/lib/aci/policy/interface/port_channel/attachment/main.py new file mode 100644 index 00000000..cdd65685 --- /dev/null +++ b/lib/aci/policy/interface/port_channel/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.port_channel.attachment.api import PolicyInterfacePortChannelAttachmentApi +from lib.aci.policy.interface.port_channel.attachment.info import PolicyInterfacePortChannelAttachmentInfo + + +class PolicyInterfacePortChannelAttachment(PolicyInterfacePortChannelAttachmentApi, PolicyInterfacePortChannelAttachmentInfo): + def __init__(self): + PolicyInterfacePortChannelAttachmentApi.__init__(self) + PolicyInterfacePortChannelAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/port_channel/context.py b/lib/aci/policy/interface/port_channel/context.py new file mode 100644 index 00000000..f496b5d4 --- /dev/null +++ b/lib/aci/policy/interface/port_channel/context.py @@ -0,0 +1,93 @@ +class PolicyInterfacePortChannelContext(): + def __init__(self): + pass + + def set_policy_interface_port_channel_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "port_channelIfPol", + # "policyDn": "uni/infra/port_channelIfP-k8s_port_channel_enable", + # "policyName": "k8s_port_channel_enable" + # + # Context + # "port_channel": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsLacpIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-port_channel-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_port_channel_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_port_channel_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/port_channel/info.py b/lib/aci/policy/interface/port_channel/info.py new file mode 100644 index 00000000..e93ee865 --- /dev/null +++ b/lib/aci/policy/interface/port_channel/info.py @@ -0,0 +1,234 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfacePortChannelInfo(): + def __init__(self): + self.policy_interface_port_channel = None + + def get_policy_interface_port_channel_reln_info(self, managed_object): + info = {} + info['class'] = 'lacpLagPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_port_channel_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "creator": "USER", + # "ctrl": "fast-sel-hot-stdby,graceful-conv,susp-individual", + # "descr": "", + # "dn": "uni/infra/lacplagp-LACP-passive", + # "extMngdBy": "", + # "lcOwn": "local", + # "maxLinks": "16", + # "minLinks": "1", + # "modTs": "2020-12-22T18:45:43.441+01:00", + # "mode": "passive", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "LACP-passive", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:" + keys = [ + 'annotation', + 'ctrl', + 'dn', + 'maxLinks', + 'minLinks', + 'mode', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['ctrlT'] = [] + if 'fast-sel-hot-stdby' in info['ctrl'].split(','): + info['ctrlT'].append('Fast Select Hot Standby Ports') + if 'graceful-conv' in info['ctrl'].split(','): + info['ctrlT'].append('Graceful Convergence') + if 'susp-individual' in info['ctrl'].split(','): + info['ctrlT'].append('Suspend Individual Ports') + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_port_channel_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_port_channel_info(self): + if self.policy_interface_port_channel is not None: + return self.policy_interface_port_channel + + managed_objects = self.get_policy_interface_port_channel_mo() + if managed_objects is not None: + self.policy_interface_port_channel = [] + for managed_object in managed_objects: + self.policy_interface_port_channel.append( + self.get_policy_interface_port_channel_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lacpLagPol.info', + self.policy_interface_port_channel + ) + + return self.policy_interface_port_channel + + def match_policy_interface_port_channel(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsLacpIfPolCons' in policy_info: + if len(policy_info['l1RsLacpIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsLacpIfPolCons' in policy_info: + if len(policy_info['l1RsLacpIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsLacpIfPolCons' in policy_info: + if len(policy_info['l1RsLacpIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_port_channel_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_port_channel(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_port_channel_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_port_channel(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_port_channel_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_port_channel(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsLacpIfPolCons'] = self.get_policy_interface_port_channel_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsLacpIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsLacpIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_port_channel_attachments_node_summary( + policy_info['l1RsLacpIfPolCons'] + ) + + if not self.match_policy_interface_port_channel(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/port_channel/main.py b/lib/aci/policy/interface/port_channel/main.py new file mode 100644 index 00000000..6e35e228 --- /dev/null +++ b/lib/aci/policy/interface/port_channel/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.port_channel.attachment.main import PolicyInterfacePortChannelAttachment +from lib.aci.policy.interface.port_channel.api import PolicyInterfacePortChannelApi +from lib.aci.policy.interface.port_channel.context import PolicyInterfacePortChannelContext +from lib.aci.policy.interface.port_channel.info import PolicyInterfacePortChannelInfo + + +class PolicyInterfacePortChannel(PolicyInterfacePortChannelAttachment, PolicyInterfacePortChannelApi, PolicyInterfacePortChannelContext, PolicyInterfacePortChannelInfo): + def __init__(self): + PolicyInterfacePortChannelAttachment.__init__(self) + PolicyInterfacePortChannelApi.__init__(self) + PolicyInterfacePortChannelContext.__init__(self) + PolicyInterfacePortChannelInfo.__init__(self) diff --git a/lib/aci/policy/interface/port_channel/output.py b/lib/aci/policy/interface/port_channel/output.py new file mode 100644 index 00000000..df575f25 --- /dev/null +++ b/lib/aci/policy/interface/port_channel/output.py @@ -0,0 +1,189 @@ +class PolicyInterfacePortChannelOutput(): + def __init__(self): + pass + + def print_policy_interface_port_channel(self, info): + self.print_policy_interface_port_channel_properties( + info + ) + + self.print_policy_interface_port_channel_interfaces( + info['l1RsLacpIfPolCons'] + ) + + self.print_policy_interface_port_channel_references( + info['relnFrom'] + ) + + def print_policy_interface_port_channel_properties(self, info): + order = [ + 'name', + 'tf', + 'mode', + 'ctrlT', + 'minLinks', + 'maxLinks', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Mode', + 'Control', + 'Min Links', + 'Max Links', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Port Channel Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_port_channel_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_port_channel_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_channel_summary(self, info): + order = [ + 'name', + 'tfTick', + 'mode', + 'ctrlT', + 'minLinks', + 'maxLinks', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Mode', + 'Control', + 'Min Links', + 'Max Links', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ctrlT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_channel_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_channel_interfaces(self, info): + order = [ + 'name', + 'l1RsLacpIfPolCons.pod_node_name', + 'l1RsLacpIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsLacpIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/port_channel_member/__init__.py b/lib/aci/policy/interface/port_channel_member/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..f868bbcf Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..aae374e0 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..37abc331 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..06d11f36 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9e1d1e29 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..6f746366 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/api.py b/lib/aci/policy/interface/port_channel_member/api.py new file mode 100644 index 00000000..3bd1d731 --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/api.py @@ -0,0 +1,51 @@ +class PolicyInterfacePortChannelMemberApi(): + def __init__(self): + self.policy_interface_port_channel_member_mo = None + + def get_policy_interface_port_channel_member_mo(self): + if self.policy_interface_port_channel_member_mo is not None: + return self.policy_interface_port_channel_member_mo + + cache = self.get_object_cache( + 'lacpIfPol' + ) + if cache is not None: + self.policy_interface_port_channel_member_mo = cache + self.log.apic_mo( + 'lacpIfPol', + self.policy_interface_port_channel_member_mo + ) + return self.policy_interface_port_channel_member_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'lacpIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_port_channel_member_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['lacpIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'lacpIfPol' + ) + + self.policy_interface_port_channel_member_mo.append( + attributes + ) + + self.log.apic_mo( + 'lacpIfPol', + self.policy_interface_port_channel_member_mo + ) + + self.set_object_cache( + 'lacpIfPol', + self.policy_interface_port_channel_member_mo + ) + + return self.policy_interface_port_channel_member_mo diff --git a/lib/aci/policy/interface/port_channel_member/attachment/__init__.py b/lib/aci/policy/interface/port_channel_member/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6542d2f5 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..46fa1940 Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..73323eec Binary files /dev/null and b/lib/aci/policy/interface/port_channel_member/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_channel_member/attachment/api.py b/lib/aci/policy/interface/port_channel_member/attachment/api.py new file mode 100644 index 00000000..40a81b97 --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfacePortChannelMemberAttachmentApi(): + def __init__(self): + self.policy_interface_port_channel_member_attachment_mo = None + + def get_policy_interface_port_channel_member_attachment_mo(self): + if self.policy_interface_port_channel_member_attachment_mo is not None: + return self.policy_interface_port_channel_member_attachment_mo + + cache = self.get_object_cache( + 'l1RsLacpIfPolCons' + ) + if cache is not None: + self.policy_interface_port_channel_member_attachment_mo = cache + self.log.apic_mo( + 'l1RsLacpIfPolCons', + self.policy_interface_port_channel_member_attachment_mo + ) + return self.policy_interface_port_channel_member_attachment_mo + + managed_objects = self.get_class( + 'l1RsLacpIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_port_channel_member_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_port_channel_member_attachment_mo.append( + managed_object['l1RsLacpIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsLacpIfPolCons', + self.policy_interface_port_channel_member_attachment_mo + ) + + self.set_object_cache( + 'l1RsLacpIfPolCons', + self.policy_interface_port_channel_member_attachment_mo + ) + + return self.policy_interface_port_channel_member_attachment_mo diff --git a/lib/aci/policy/interface/port_channel_member/attachment/info.py b/lib/aci/policy/interface/port_channel_member/attachment/info.py new file mode 100644 index 00000000..beeab870 --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfacePortChannelMemberAttachmentInfo(): + def __init__(self): + self.policy_interface_port_channel_member_attachment = None + + def get_policy_interface_port_channel_member_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rslacpIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "lacpIfPol", + # "tDn": "uni/infra/port_channel_memberIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_port_channel_member_attachments_info(self): + if self.policy_interface_port_channel_member_attachment is not None: + return self.policy_interface_port_channel_member_attachment + + managed_objects = self.get_policy_interface_port_channel_member_attachment_mo() + if managed_objects is not None: + self.policy_interface_port_channel_member_attachment = [] + for managed_object in managed_objects: + self.policy_interface_port_channel_member_attachment.append( + self.get_policy_interface_port_channel_member_attachment_info( + managed_object + ) + ) + + return self.policy_interface_port_channel_member_attachment + + def match_policy_interface_port_channel_member_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_port_channel_member_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_port_channel_member_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_port_channel_member_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_port_channel_member_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/port_channel_member/attachment/main.py b/lib/aci/policy/interface/port_channel_member/attachment/main.py new file mode 100644 index 00000000..3e06fe19 --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.port_channel_member.attachment.api import PolicyInterfacePortChannelMemberAttachmentApi +from lib.aci.policy.interface.port_channel_member.attachment.info import PolicyInterfacePortChannelMemberAttachmentInfo + + +class PolicyInterfacePortChannelMemberAttachment(PolicyInterfacePortChannelMemberAttachmentApi, PolicyInterfacePortChannelMemberAttachmentInfo): + def __init__(self): + PolicyInterfacePortChannelMemberAttachmentApi.__init__(self) + PolicyInterfacePortChannelMemberAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/port_channel_member/context.py b/lib/aci/policy/interface/port_channel_member/context.py new file mode 100644 index 00000000..e2efb8d8 --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/context.py @@ -0,0 +1,93 @@ +class PolicyInterfacePortChannelMemberContext(): + def __init__(self): + pass + + def set_policy_interface_port_channel_member_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "lacpIfPol", + # "policyDn": "uni/infra/port_channel_memberIfP-k8s_port_channel_member_enable", + # "policyName": "k8s_port_channel_member_enable" + # + # Context + # "port_channel_member": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsLacpIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-port_channel_member-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_port_channel_member_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_port_channel_member_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/port_channel_member/info.py b/lib/aci/policy/interface/port_channel_member/info.py new file mode 100644 index 00000000..9bff3061 --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/info.py @@ -0,0 +1,222 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfacePortChannelMemberInfo(): + def __init__(self): + self.policy_interface_port_channel_member = None + + def get_policy_interface_port_channel_member_reln_info(self, managed_object): + info = {} + info['class'] = 'lacpIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_port_channel_member_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/lacpifp-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "prio": "32768", + # "status": "", + # "txRate": "normal", + # "uid": "0", + # "userdom": "" + keys = [ + 'annotation', + 'dn', + 'name', + 'dn', + 'prio', + 'txRate', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_port_channel_member_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_port_channel_member_info(self): + if self.policy_interface_port_channel_member is not None: + return self.policy_interface_port_channel_member + + managed_objects = self.get_policy_interface_port_channel_member_mo() + if managed_objects is not None: + self.policy_interface_port_channel_member = [] + for managed_object in managed_objects: + self.policy_interface_port_channel_member.append( + self.get_policy_interface_port_channel_member_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lacpIfPol.info', + self.policy_interface_port_channel_member + ) + + return self.policy_interface_port_channel_member + + def match_policy_interface_port_channel_member(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsLacpIfPolCons' in policy_info: + if len(policy_info['l1RsLacpIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsLacpIfPolCons' in policy_info: + if len(policy_info['l1RsLacpIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsLacpIfPolCons' in policy_info: + if len(policy_info['l1RsLacpIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_port_channel_member_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_port_channel_member(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_port_channel_member_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_port_channel_member(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_port_channel_member_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_port_channel_member(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsLacpIfPolCons'] = self.get_policy_interface_port_channel_member_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsLacpIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsLacpIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_port_channel_member_attachments_node_summary( + policy_info['l1RsLacpIfPolCons'] + ) + + if not self.match_policy_interface_port_channel_member(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/port_channel_member/main.py b/lib/aci/policy/interface/port_channel_member/main.py new file mode 100644 index 00000000..9df5823c --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.port_channel_member.attachment.main import PolicyInterfacePortChannelMemberAttachment +from lib.aci.policy.interface.port_channel_member.api import PolicyInterfacePortChannelMemberApi +from lib.aci.policy.interface.port_channel_member.context import PolicyInterfacePortChannelMemberContext +from lib.aci.policy.interface.port_channel_member.info import PolicyInterfacePortChannelMemberInfo + + +class PolicyInterfacePortChannelMember(PolicyInterfacePortChannelMemberAttachment, PolicyInterfacePortChannelMemberApi, PolicyInterfacePortChannelMemberContext, PolicyInterfacePortChannelMemberInfo): + def __init__(self): + PolicyInterfacePortChannelMemberAttachment.__init__(self) + PolicyInterfacePortChannelMemberApi.__init__(self) + PolicyInterfacePortChannelMemberContext.__init__(self) + PolicyInterfacePortChannelMemberInfo.__init__(self) diff --git a/lib/aci/policy/interface/port_channel_member/output.py b/lib/aci/policy/interface/port_channel_member/output.py new file mode 100644 index 00000000..2a680adc --- /dev/null +++ b/lib/aci/policy/interface/port_channel_member/output.py @@ -0,0 +1,177 @@ +class PolicyInterfacePortChannelMemberOutput(): + def __init__(self): + pass + + def print_policy_interface_port_channel_member(self, info): + self.print_policy_interface_port_channel_member_properties( + info + ) + + self.print_policy_interface_port_channel_member_interfaces( + info['l1RsLacpIfPolCons'] + ) + + self.print_policy_interface_port_channel_member_references( + info['relnFrom'] + ) + + def print_policy_interface_port_channel_member_properties(self, info): + order = [ + 'name', + 'tf', + 'prio', + 'txRate', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Priority', + 'Transmit Rate', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Port Channel Member Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_port_channel_member_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_port_channel_member_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_channel_member_summary(self, info): + order = [ + 'name', + 'tfTick', + 'prio', + 'txRate', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Priority', + 'Transmit Rate', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_channel_member_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_channel_member_interfaces(self, info): + order = [ + 'name', + 'l1RsLacpIfPolCons.pod_node_name', + 'l1RsLacpIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsLacpIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/port_security/__init__.py b/lib/aci/policy/interface/port_security/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/port_security/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..195a15de Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..d12ee24c Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..8278e8db Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..4fc1a52b Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..50fd1d98 Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/port_security/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..2667af75 Binary files /dev/null and b/lib/aci/policy/interface/port_security/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/api.py b/lib/aci/policy/interface/port_security/api.py new file mode 100644 index 00000000..b940137a --- /dev/null +++ b/lib/aci/policy/interface/port_security/api.py @@ -0,0 +1,51 @@ +class PolicyInterfacePortSecurityApi(): + def __init__(self): + self.policy_interface_port_security_mo = None + + def get_policy_interface_port_security_mo(self): + if self.policy_interface_port_security_mo is not None: + return self.policy_interface_port_security_mo + + cache = self.get_object_cache( + 'l2PortSecurityPol' + ) + if cache is not None: + self.policy_interface_port_security_mo = cache + self.log.apic_mo( + 'l2PortSecurityPol', + self.policy_interface_port_security_mo + ) + return self.policy_interface_port_security_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'l2PortSecurityPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_port_security_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['l2PortSecurityPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'l2PortSecurityPol' + ) + + self.policy_interface_port_security_mo.append( + attributes + ) + + self.log.apic_mo( + 'l2PortSecurityPol', + self.policy_interface_port_security_mo + ) + + self.set_object_cache( + 'l2PortSecurityPol', + self.policy_interface_port_security_mo + ) + + return self.policy_interface_port_security_mo diff --git a/lib/aci/policy/interface/port_security/attachment/__init__.py b/lib/aci/policy/interface/port_security/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/port_security/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/port_security/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/port_security/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/port_security/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5449dadf Binary files /dev/null and b/lib/aci/policy/interface/port_security/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/port_security/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..4f3a9896 Binary files /dev/null and b/lib/aci/policy/interface/port_security/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/port_security/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..37749cc4 Binary files /dev/null and b/lib/aci/policy/interface/port_security/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/port_security/attachment/api.py b/lib/aci/policy/interface/port_security/attachment/api.py new file mode 100644 index 00000000..6238f30c --- /dev/null +++ b/lib/aci/policy/interface/port_security/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfacePortSecurityAttachmentApi(): + def __init__(self): + self.policy_interface_port_security_attachment_mo = None + + def get_policy_interface_port_security_attachment_mo(self): + if self.policy_interface_port_security_attachment_mo is not None: + return self.policy_interface_port_security_attachment_mo + + cache = self.get_object_cache( + 'l1RsL2PortSecurityCons' + ) + if cache is not None: + self.policy_interface_port_security_attachment_mo = cache + self.log.apic_mo( + 'l1RsL2PortSecurityCons', + self.policy_interface_port_security_attachment_mo + ) + return self.policy_interface_port_security_attachment_mo + + managed_objects = self.get_class( + 'l1RsL2PortSecurityCons' + ) + if managed_objects is None: + return None + + self.policy_interface_port_security_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_port_security_attachment_mo.append( + managed_object['l1RsL2PortSecurityCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsL2PortSecurityCons', + self.policy_interface_port_security_attachment_mo + ) + + self.set_object_cache( + 'l1RsL2PortSecurityCons', + self.policy_interface_port_security_attachment_mo + ) + + return self.policy_interface_port_security_attachment_mo diff --git a/lib/aci/policy/interface/port_security/attachment/info.py b/lib/aci/policy/interface/port_security/attachment/info.py new file mode 100644 index 00000000..49be8189 --- /dev/null +++ b/lib/aci/policy/interface/port_security/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfacePortSecurityAttachmentInfo(): + def __init__(self): + self.policy_interface_port_security_attachment = None + + def get_policy_interface_port_security_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsl2PortSecurityPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "l2PortSecurityPol", + # "tDn": "uni/infra/port_securityIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_port_security_attachments_info(self): + if self.policy_interface_port_security_attachment is not None: + return self.policy_interface_port_security_attachment + + managed_objects = self.get_policy_interface_port_security_attachment_mo() + if managed_objects is not None: + self.policy_interface_port_security_attachment = [] + for managed_object in managed_objects: + self.policy_interface_port_security_attachment.append( + self.get_policy_interface_port_security_attachment_info( + managed_object + ) + ) + + return self.policy_interface_port_security_attachment + + def match_policy_interface_port_security_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_port_security_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_port_security_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_port_security_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_port_security_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/port_security/attachment/main.py b/lib/aci/policy/interface/port_security/attachment/main.py new file mode 100644 index 00000000..58b05bf6 --- /dev/null +++ b/lib/aci/policy/interface/port_security/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.port_security.attachment.api import PolicyInterfacePortSecurityAttachmentApi +from lib.aci.policy.interface.port_security.attachment.info import PolicyInterfacePortSecurityAttachmentInfo + + +class PolicyInterfacePortSecurityAttachment(PolicyInterfacePortSecurityAttachmentApi, PolicyInterfacePortSecurityAttachmentInfo): + def __init__(self): + PolicyInterfacePortSecurityAttachmentApi.__init__(self) + PolicyInterfacePortSecurityAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/port_security/context.py b/lib/aci/policy/interface/port_security/context.py new file mode 100644 index 00000000..05c25214 --- /dev/null +++ b/lib/aci/policy/interface/port_security/context.py @@ -0,0 +1,93 @@ +class PolicyInterfacePortSecurityContext(): + def __init__(self): + pass + + def set_policy_interface_port_security_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "l2PortSecurityPol", + # "policyDn": "uni/infra/port_securityIfP-k8s_port_security_enable", + # "policyName": "k8s_port_security_enable" + # + # Context + # "port_security": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsL2PortSecurityCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-port_security-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_port_security_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_port_security_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/port_security/info.py b/lib/aci/policy/interface/port_security/info.py new file mode 100644 index 00000000..7ad489db --- /dev/null +++ b/lib/aci/policy/interface/port_security/info.py @@ -0,0 +1,222 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfacePortSecurityInfo(): + def __init__(self): + self.policy_interface_port_security = None + + def get_policy_interface_port_security_reln_info(self, managed_object): + info = {} + info['class'] = 'l2PortSecurityPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_port_security_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/portsecurityP-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "maximum": "0", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "timeout": "60", + # "uid": "0", + # "userdom": "", + # "violation": "protect" + keys = [ + 'annotation', + 'dn', + 'maximum', + 'name', + 'timeout', + 'violation', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_port_security_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_port_security_info(self): + if self.policy_interface_port_security is not None: + return self.policy_interface_port_security + + managed_objects = self.get_policy_interface_port_security_mo() + if managed_objects is not None: + self.policy_interface_port_security = [] + for managed_object in managed_objects: + self.policy_interface_port_security.append( + self.get_policy_interface_port_security_info( + managed_object + ) + ) + + self.log.apic_mo( + 'l2PortSecurityPol.info', + self.policy_interface_port_security + ) + + return self.policy_interface_port_security + + def match_policy_interface_port_security(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsL2PortSecurityCons' in policy_info: + if len(policy_info['l1RsL2PortSecurityCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsL2PortSecurityCons' in policy_info: + if len(policy_info['l1RsL2PortSecurityCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsL2PortSecurityCons' in policy_info: + if len(policy_info['l1RsL2PortSecurityCons']) > 0: + return False + + return True + + def match_policy_interface_port_security_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_port_security(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_port_security_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_port_security(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_port_security_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_port_security(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsL2PortSecurityCons'] = self.get_policy_interface_port_security_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsL2PortSecurityCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsL2PortSecurityCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_port_security_attachments_node_summary( + policy_info['l1RsL2PortSecurityCons'] + ) + + if not self.match_policy_interface_port_security(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/port_security/main.py b/lib/aci/policy/interface/port_security/main.py new file mode 100644 index 00000000..5e1991b8 --- /dev/null +++ b/lib/aci/policy/interface/port_security/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.port_security.attachment.main import PolicyInterfacePortSecurityAttachment +from lib.aci.policy.interface.port_security.api import PolicyInterfacePortSecurityApi +from lib.aci.policy.interface.port_security.context import PolicyInterfacePortSecurityContext +from lib.aci.policy.interface.port_security.info import PolicyInterfacePortSecurityInfo + + +class PolicyInterfacePortSecurity(PolicyInterfacePortSecurityAttachment, PolicyInterfacePortSecurityApi, PolicyInterfacePortSecurityContext, PolicyInterfacePortSecurityInfo): + def __init__(self): + PolicyInterfacePortSecurityAttachment.__init__(self) + PolicyInterfacePortSecurityApi.__init__(self) + PolicyInterfacePortSecurityContext.__init__(self) + PolicyInterfacePortSecurityInfo.__init__(self) diff --git a/lib/aci/policy/interface/port_security/output.py b/lib/aci/policy/interface/port_security/output.py new file mode 100644 index 00000000..e95f27ff --- /dev/null +++ b/lib/aci/policy/interface/port_security/output.py @@ -0,0 +1,181 @@ +class PolicyInterfacePortSecurityOutput(): + def __init__(self): + pass + + def print_policy_interface_port_security(self, info): + self.print_policy_interface_port_security_properties( + info + ) + + self.print_policy_interface_port_security_interfaces( + info['l1RsL2PortSecurityCons'] + ) + + self.print_policy_interface_port_security_references( + info['relnFrom'] + ) + + def print_policy_interface_port_security_properties(self, info): + order = [ + 'name', + 'tf', + 'timeout', + 'maximum', + 'violation', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Timeout', + 'Maximum Endpoints', + 'Violation Action', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='CDP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_port_security_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_port_security_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_security_summary(self, info): + order = [ + 'name', + 'tfTick', + 'timeout', + 'maximum', + 'violation', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Timeout', + 'Maximum Endpoints', + 'Violation Action', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_security_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_port_security_interfaces(self, info): + order = [ + 'name', + 'l1RsL2PortSecurityCons.pod_node_name', + 'l1RsL2PortSecurityCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsL2PortSecurityCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/slow_drain/__init__.py b/lib/aci/policy/interface/slow_drain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..dae6ef9e Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..e9813481 Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..380f9544 Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f54101ed Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f555fd56 Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..9a702e50 Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/api.py b/lib/aci/policy/interface/slow_drain/api.py new file mode 100644 index 00000000..fe176413 --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceSlowDrainApi(): + def __init__(self): + self.policy_interface_slow_drain_mo = None + + def get_policy_interface_slow_drain_mo(self): + if self.policy_interface_slow_drain_mo is not None: + return self.policy_interface_slow_drain_mo + + cache = self.get_object_cache( + 'qosSdIfPol' + ) + if cache is not None: + self.policy_interface_slow_drain_mo = cache + self.log.apic_mo( + 'qosSdIfPol', + self.policy_interface_slow_drain_mo + ) + return self.policy_interface_slow_drain_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'qosSdIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_slow_drain_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['qosSdIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'qosSdIfPol' + ) + + self.policy_interface_slow_drain_mo.append( + attributes + ) + + self.log.apic_mo( + 'qosSdIfPol', + self.policy_interface_slow_drain_mo + ) + + self.set_object_cache( + 'qosSdIfPol', + self.policy_interface_slow_drain_mo + ) + + return self.policy_interface_slow_drain_mo diff --git a/lib/aci/policy/interface/slow_drain/attachment/__init__.py b/lib/aci/policy/interface/slow_drain/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/slow_drain/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2133741f Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..581f79e8 Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..924def4c Binary files /dev/null and b/lib/aci/policy/interface/slow_drain/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/slow_drain/attachment/api.py b/lib/aci/policy/interface/slow_drain/attachment/api.py new file mode 100644 index 00000000..0b0709ce --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceSlowDrainAttachmentApi(): + def __init__(self): + self.policy_interface_slow_drain_attachment_mo = None + + def get_policy_interface_slow_drain_attachment_mo(self): + if self.policy_interface_slow_drain_attachment_mo is not None: + return self.policy_interface_slow_drain_attachment_mo + + cache = self.get_object_cache( + 'l1RsQosSdIfPolCons' + ) + if cache is not None: + self.policy_interface_slow_drain_attachment_mo = cache + self.log.apic_mo( + 'l1RsQosSdIfPolCons', + self.policy_interface_slow_drain_attachment_mo + ) + return self.policy_interface_slow_drain_attachment_mo + + managed_objects = self.get_class( + 'l1RsQosSdIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_slow_drain_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_slow_drain_attachment_mo.append( + managed_object['l1RsQosSdIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsQosSdIfPolCons', + self.policy_interface_slow_drain_attachment_mo + ) + + self.set_object_cache( + 'l1RsQosSdIfPolCons', + self.policy_interface_slow_drain_attachment_mo + ) + + return self.policy_interface_slow_drain_attachment_mo diff --git a/lib/aci/policy/interface/slow_drain/attachment/info.py b/lib/aci/policy/interface/slow_drain/attachment/info.py new file mode 100644 index 00000000..bb58e2cc --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceSlowDrainAttachmentInfo(): + def __init__(self): + self.policy_interface_slow_drain_attachment = None + + def get_policy_interface_slow_drain_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsqosSdIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "qosSdIfPol", + # "tDn": "uni/infra/slow_drainIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_slow_drain_attachments_info(self): + if self.policy_interface_slow_drain_attachment is not None: + return self.policy_interface_slow_drain_attachment + + managed_objects = self.get_policy_interface_slow_drain_attachment_mo() + if managed_objects is not None: + self.policy_interface_slow_drain_attachment = [] + for managed_object in managed_objects: + self.policy_interface_slow_drain_attachment.append( + self.get_policy_interface_slow_drain_attachment_info( + managed_object + ) + ) + + return self.policy_interface_slow_drain_attachment + + def match_policy_interface_slow_drain_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_slow_drain_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_slow_drain_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_slow_drain_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_slow_drain_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/slow_drain/attachment/main.py b/lib/aci/policy/interface/slow_drain/attachment/main.py new file mode 100644 index 00000000..7fbf7382 --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.slow_drain.attachment.api import PolicyInterfaceSlowDrainAttachmentApi +from lib.aci.policy.interface.slow_drain.attachment.info import PolicyInterfaceSlowDrainAttachmentInfo + + +class PolicyInterfaceSlowDrainAttachment(PolicyInterfaceSlowDrainAttachmentApi, PolicyInterfaceSlowDrainAttachmentInfo): + def __init__(self): + PolicyInterfaceSlowDrainAttachmentApi.__init__(self) + PolicyInterfaceSlowDrainAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/slow_drain/context.py b/lib/aci/policy/interface/slow_drain/context.py new file mode 100644 index 00000000..467bb3cf --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceSlowDrainContext(): + def __init__(self): + pass + + def set_policy_interface_slow_drain_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "qosSdIfPol", + # "policyDn": "uni/infra/slow_drainIfP-k8s_slow_drain_enable", + # "policyName": "k8s_slow_drain_enable" + # + # Context + # "slow_drain": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsQosSdIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-slow_drain-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_slow_drain_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_slow_drain_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/slow_drain/info.py b/lib/aci/policy/interface/slow_drain/info.py new file mode 100644 index 00000000..8bc487d8 --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/info.py @@ -0,0 +1,229 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceSlowDrainInfo(): + def __init__(self): + self.policy_interface_slow_drain = None + + def get_policy_interface_slow_drain_reln_info(self, managed_object): + info = {} + info['class'] = 'qosSdIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_slow_drain_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "congClearAction": "off", + # "congDetectMult": "10", + # "descr": "", + # "dn": "uni/infra/qossdpol-default", + # "extMngdBy": "", + # "flushAdminSt": "disabled", + # "flushIntvl": "500", + # "lcOwn": "local", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "0", + # "userdom": "" + keys = [ + 'annotation', + 'congClearAction', + 'congDetectMult', + 'dn', + 'flushAdminSt', + 'flushIntvl', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + if info['flushAdminSt'] == 'enabled': + info['__Output']['flushAdminSt'] = 'Green' + else: + info['__Output']['flushAdminSt'] = 'Red' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_slow_drain_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_slow_drain_info(self): + if self.policy_interface_slow_drain is not None: + return self.policy_interface_slow_drain + + managed_objects = self.get_policy_interface_slow_drain_mo() + if managed_objects is not None: + self.policy_interface_slow_drain = [] + for managed_object in managed_objects: + self.policy_interface_slow_drain.append( + self.get_policy_interface_slow_drain_info( + managed_object + ) + ) + + self.log.apic_mo( + 'qosSdIfPol.info', + self.policy_interface_slow_drain + ) + + return self.policy_interface_slow_drain + + def match_policy_interface_slow_drain(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsQosSdIfPolCons' in policy_info: + if len(policy_info['l1RsQosSdIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsQosSdIfPolCons' in policy_info: + if len(policy_info['l1RsQosSdIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsQosSdIfPolCons' in policy_info: + if len(policy_info['l1RsQosSdIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_slow_drain_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_slow_drain(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_slow_drain_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_slow_drain(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_slow_drain_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_slow_drain(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsQosSdIfPolCons'] = self.get_policy_interface_slow_drain_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsQosSdIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsQosSdIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_slow_drain_attachments_node_summary( + policy_info['l1RsQosSdIfPolCons'] + ) + + if not self.match_policy_interface_slow_drain(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/slow_drain/main.py b/lib/aci/policy/interface/slow_drain/main.py new file mode 100644 index 00000000..4ed225ff --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.slow_drain.attachment.main import PolicyInterfaceSlowDrainAttachment +from lib.aci.policy.interface.slow_drain.api import PolicyInterfaceSlowDrainApi +from lib.aci.policy.interface.slow_drain.context import PolicyInterfaceSlowDrainContext +from lib.aci.policy.interface.slow_drain.info import PolicyInterfaceSlowDrainInfo + + +class PolicyInterfaceSlowDrain(PolicyInterfaceSlowDrainAttachment, PolicyInterfaceSlowDrainApi, PolicyInterfaceSlowDrainContext, PolicyInterfaceSlowDrainInfo): + def __init__(self): + PolicyInterfaceSlowDrainAttachment.__init__(self) + PolicyInterfaceSlowDrainApi.__init__(self) + PolicyInterfaceSlowDrainContext.__init__(self) + PolicyInterfaceSlowDrainInfo.__init__(self) diff --git a/lib/aci/policy/interface/slow_drain/output.py b/lib/aci/policy/interface/slow_drain/output.py new file mode 100644 index 00000000..98d4561a --- /dev/null +++ b/lib/aci/policy/interface/slow_drain/output.py @@ -0,0 +1,185 @@ +class PolicyInterfaceSlowDrainOutput(): + def __init__(self): + pass + + def print_policy_interface_slow_drain(self, info): + self.print_policy_interface_slow_drain_properties( + info + ) + + self.print_policy_interface_slow_drain_interfaces( + info['l1RsQosSdIfPolCons'] + ) + + self.print_policy_interface_slow_drain_references( + info['relnFrom'] + ) + + def print_policy_interface_slow_drain_properties(self, info): + order = [ + 'name', + 'tf', + 'congClearAction', + 'congDetectMult', + 'flushAdminSt', + 'flushIntvl', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Congestion Clear Action', + 'Congestion Detect Multiplier', + 'Flush Admin State', + 'Flush Timeout [msec]', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='Slow Drain Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_slow_drain_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_slow_drain_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_slow_drain_summary(self, info): + order = [ + 'name', + 'tfTick', + 'congClearAction', + 'congDetectMult', + 'flushAdminSt', + 'flushIntvl', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Congestion Clear Action', + 'Congestion Detect Multiplier', + 'Flush Admin State', + 'Flush Timeout [msec]', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_slow_drain_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_slow_drain_interfaces(self, info): + order = [ + 'name', + 'l1RsQosSdIfPolCons.pod_node_name', + 'l1RsQosSdIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsQosSdIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/storm_control/__init__.py b/lib/aci/policy/interface/storm_control/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/storm_control/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f343b200 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8e9eabae Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..7c3c8121 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..3fdb6334 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..36cbcdc5 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..57f83377 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/storm_control/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..67b45501 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/api.py b/lib/aci/policy/interface/storm_control/api.py new file mode 100644 index 00000000..928deddd --- /dev/null +++ b/lib/aci/policy/interface/storm_control/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceStormControlApi(): + def __init__(self): + self.policy_interface_storm_control_mo = None + + def get_policy_interface_storm_control_mo(self): + if self.policy_interface_storm_control_mo is not None: + return self.policy_interface_storm_control_mo + + cache = self.get_object_cache( + 'stormctrlIfPol' + ) + if cache is not None: + self.policy_interface_storm_control_mo = cache + self.log.apic_mo( + 'stormctrlIfPol', + self.policy_interface_storm_control_mo + ) + return self.policy_interface_storm_control_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'stormctrlIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_storm_control_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['stormctrlIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'stormctrlIfPol' + ) + + self.policy_interface_storm_control_mo.append( + attributes + ) + + self.log.apic_mo( + 'stormctrlIfPol', + self.policy_interface_storm_control_mo + ) + + self.set_object_cache( + 'stormctrlIfPol', + self.policy_interface_storm_control_mo + ) + + return self.policy_interface_storm_control_mo diff --git a/lib/aci/policy/interface/storm_control/attachment/__init__.py b/lib/aci/policy/interface/storm_control/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/storm_control/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/storm_control/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/storm_control/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/storm_control/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4ed6f740 Binary files /dev/null and b/lib/aci/policy/interface/storm_control/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/storm_control/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..c096f80d Binary files /dev/null and b/lib/aci/policy/interface/storm_control/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/storm_control/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3b74d0ad Binary files /dev/null and b/lib/aci/policy/interface/storm_control/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/storm_control/attachment/api.py b/lib/aci/policy/interface/storm_control/attachment/api.py new file mode 100644 index 00000000..2624cbea --- /dev/null +++ b/lib/aci/policy/interface/storm_control/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceStormControlAttachmentApi(): + def __init__(self): + self.policy_interface_storm_control_attachment_mo = None + + def get_policy_interface_storm_control_attachment_mo(self): + if self.policy_interface_storm_control_attachment_mo is not None: + return self.policy_interface_storm_control_attachment_mo + + cache = self.get_object_cache( + 'l1RsStormctrlIfPolCons' + ) + if cache is not None: + self.policy_interface_storm_control_attachment_mo = cache + self.log.apic_mo( + 'l1RsStormctrlIfPolCons', + self.policy_interface_storm_control_attachment_mo + ) + return self.policy_interface_storm_control_attachment_mo + + managed_objects = self.get_class( + 'l1RsStormctrlIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_storm_control_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_storm_control_attachment_mo.append( + managed_object['l1RsStormctrlIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsStormctrlIfPolCons', + self.policy_interface_storm_control_attachment_mo + ) + + self.set_object_cache( + 'l1RsStormctrlIfPolCons', + self.policy_interface_storm_control_attachment_mo + ) + + return self.policy_interface_storm_control_attachment_mo diff --git a/lib/aci/policy/interface/storm_control/attachment/info.py b/lib/aci/policy/interface/storm_control/attachment/info.py new file mode 100644 index 00000000..8e86ec61 --- /dev/null +++ b/lib/aci/policy/interface/storm_control/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceStormControlAttachmentInfo(): + def __init__(self): + self.policy_interface_storm_control_attachment = None + + def get_policy_interface_storm_control_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsstormctrlIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "stormctrlIfPol", + # "tDn": "uni/infra/storm_controlIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_storm_control_attachments_info(self): + if self.policy_interface_storm_control_attachment is not None: + return self.policy_interface_storm_control_attachment + + managed_objects = self.get_policy_interface_storm_control_attachment_mo() + if managed_objects is not None: + self.policy_interface_storm_control_attachment = [] + for managed_object in managed_objects: + self.policy_interface_storm_control_attachment.append( + self.get_policy_interface_storm_control_attachment_info( + managed_object + ) + ) + + return self.policy_interface_storm_control_attachment + + def match_policy_interface_storm_control_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_storm_control_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_storm_control_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_storm_control_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_storm_control_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/storm_control/attachment/main.py b/lib/aci/policy/interface/storm_control/attachment/main.py new file mode 100644 index 00000000..e1ee6450 --- /dev/null +++ b/lib/aci/policy/interface/storm_control/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.storm_control.attachment.api import PolicyInterfaceStormControlAttachmentApi +from lib.aci.policy.interface.storm_control.attachment.info import PolicyInterfaceStormControlAttachmentInfo + + +class PolicyInterfaceStormControlAttachment(PolicyInterfaceStormControlAttachmentApi, PolicyInterfaceStormControlAttachmentInfo): + def __init__(self): + PolicyInterfaceStormControlAttachmentApi.__init__(self) + PolicyInterfaceStormControlAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/storm_control/context.py b/lib/aci/policy/interface/storm_control/context.py new file mode 100644 index 00000000..ed9e2801 --- /dev/null +++ b/lib/aci/policy/interface/storm_control/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceStormControlContext(): + def __init__(self): + pass + + def set_policy_interface_storm_control_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "stormctrlIfPol", + # "policyDn": "uni/infra/storm_controlIfP-k8s_storm_control_enable", + # "policyName": "k8s_storm_control_enable" + # + # Context + # "storm_control": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsStormctrlIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-storm_control-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_storm_control_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_storm_control_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/storm_control/info.py b/lib/aci/policy/interface/storm_control/info.py new file mode 100644 index 00000000..be9c963c --- /dev/null +++ b/lib/aci/policy/interface/storm_control/info.py @@ -0,0 +1,281 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceStormControlInfo(): + def __init__(self): + self.policy_interface_storm_control = None + + def get_policy_interface_storm_control_reln_info(self, managed_object): + info = {} + info['class'] = 'stormctrlIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_storm_control_info(self, managed_object): + # "annotation": "", + # "bcBurstPps": "unspecified", + # "bcBurstRate": "100.000000", + # "bcRate": "100.000000", + # "bcRatePps": "unspecified", + # "burstPps": "unspecified", + # "burstRate": "100.000000", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/stormctrlifp-default", + # "extMngdBy": "", + # "isUcMcBcStormPktCfgValid": "Invalid", + # "lcOwn": "local", + # "mcBurstPps": "unspecified", + # "mcBurstRate": "100.000000", + # "mcRate": "100.000000", + # "mcRatePps": "unspecified", + # "modTs": "2020-12-09T19:07:28.202+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "rate": "100.000000", + # "ratePps": "unspecified", + # "status": "", + # "stormCtrlAction": "drop", + # "stormCtrlSoakInstCount": "3", + # "type": "all", + # "uid": "0", + # "userdom": "", + # "uucBurstPps": "unspecified", + # "uucBurstRate": "100.000000", + # "uucRate": "100.000000", + # "uucRatePps": "unspecified" + keys = [ + 'annotation', + 'dn', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['packetType'] = [] + + if managed_object['isUcMcBcStormPktCfgValid'] == 'Valid': + packet_type_info = {} + packet_type_info['type'] = 'unicast' + packet_type_info['burstPps'] = managed_object['uucBurstPps'] + packet_type_info['burstRate'] = managed_object['uucBurstRate'] + packet_type_info['rate'] = managed_object['uucRate'] + packet_type_info['ratePps'] = managed_object['uucRatePps'] + packet_type_info['stormCtrlAction'] = managed_object['stormCtrlAction'] + packet_type_info['stormCtrlSoakInstCount'] = managed_object['stormCtrlSoakInstCount'] + info['packetType'].append(packet_type_info) + + packet_type_info = {} + packet_type_info['type'] = 'broadcast' + packet_type_info['burstPps'] = managed_object['bcBurstPps'] + packet_type_info['burstRate'] = managed_object['bcBurstRate'] + packet_type_info['rate'] = managed_object['bcRate'] + packet_type_info['ratePps'] = managed_object['bcRatePps'] + packet_type_info['stormCtrlAction'] = managed_object['stormCtrlAction'] + packet_type_info['stormCtrlSoakInstCount'] = managed_object['stormCtrlSoakInstCount'] + info['packetType'].append(packet_type_info) + + packet_type_info = {} + packet_type_info['type'] = 'multicast' + packet_type_info['burstPps'] = managed_object['mcBurstPps'] + packet_type_info['burstRate'] = managed_object['mcBurstRate'] + packet_type_info['rate'] = managed_object['mcRate'] + packet_type_info['ratePps'] = managed_object['mcRatePps'] + packet_type_info['stormCtrlAction'] = managed_object['stormCtrlAction'] + packet_type_info['stormCtrlSoakInstCount'] = managed_object['stormCtrlSoakInstCount'] + info['packetType'].append(packet_type_info) + + if managed_object['isUcMcBcStormPktCfgValid'] == 'Invalid': + packet_type_info = {} + packet_type_info['type'] = 'all' + packet_type_info['burstPps'] = managed_object['burstPps'] + packet_type_info['burstRate'] = managed_object['burstRate'] + packet_type_info['rate'] = managed_object['rate'] + packet_type_info['ratePps'] = managed_object['ratePps'] + packet_type_info['stormCtrlAction'] = managed_object['stormCtrlAction'] + packet_type_info['stormCtrlSoakInstCount'] = managed_object['stormCtrlSoakInstCount'] + info['packetType'].append(packet_type_info) + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_storm_control_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_storm_control_info(self): + if self.policy_interface_storm_control is not None: + return self.policy_interface_storm_control + + managed_objects = self.get_policy_interface_storm_control_mo() + if managed_objects is not None: + self.policy_interface_storm_control = [] + for managed_object in managed_objects: + self.policy_interface_storm_control.append( + self.get_policy_interface_storm_control_info( + managed_object + ) + ) + + self.log.apic_mo( + 'stormctrlIfPol.info', + self.policy_interface_storm_control + ) + + return self.policy_interface_storm_control + + def match_policy_interface_storm_control(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsStormctrlIfPolCons' in policy_info: + if len(policy_info['l1RsStormctrlIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsStormctrlIfPolCons' in policy_info: + if len(policy_info['l1RsStormctrlIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsStormctrlIfPolCons' in policy_info: + if len(policy_info['l1RsStormctrlIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_storm_control_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_storm_control(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_storm_control_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_storm_control(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_storm_control_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_storm_control(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsStormctrlIfPolCons'] = self.get_policy_interface_storm_control_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsStormctrlIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsStormctrlIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_storm_control_attachments_node_summary( + policy_info['l1RsStormctrlIfPolCons'] + ) + + if not self.match_policy_interface_storm_control(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/storm_control/main.py b/lib/aci/policy/interface/storm_control/main.py new file mode 100644 index 00000000..76a915de --- /dev/null +++ b/lib/aci/policy/interface/storm_control/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.storm_control.attachment.main import PolicyInterfaceStormControlAttachment +from lib.aci.policy.interface.storm_control.api import PolicyInterfaceStormControlApi +from lib.aci.policy.interface.storm_control.context import PolicyInterfaceStormControlContext +from lib.aci.policy.interface.storm_control.info import PolicyInterfaceStormControlInfo + + +class PolicyInterfaceStormControl(PolicyInterfaceStormControlAttachment, PolicyInterfaceStormControlApi, PolicyInterfaceStormControlContext, PolicyInterfaceStormControlInfo): + def __init__(self): + PolicyInterfaceStormControlAttachment.__init__(self) + PolicyInterfaceStormControlApi.__init__(self) + PolicyInterfaceStormControlContext.__init__(self) + PolicyInterfaceStormControlInfo.__init__(self) diff --git a/lib/aci/policy/interface/storm_control/output.py b/lib/aci/policy/interface/storm_control/output.py new file mode 100644 index 00000000..8c7ab1f7 --- /dev/null +++ b/lib/aci/policy/interface/storm_control/output.py @@ -0,0 +1,204 @@ +class PolicyInterfaceStormControlOutput(): + def __init__(self): + pass + + def print_policy_interface_storm_control(self, info): + self.print_policy_interface_storm_control_properties( + info + ) + + self.print_policy_interface_storm_control_interfaces( + info['l1RsStormctrlIfPolCons'] + ) + + self.print_policy_interface_storm_control_references( + info['relnFrom'] + ) + + def print_policy_interface_storm_control_properties(self, info): + order = [ + 'name', + 'tf', + 'packetType.type', + 'packetType.rate', + 'packetType.burstRate', + 'packetType.ratePps', + 'packetType.burstPps', + 'packetType.stormCtrlAction', + 'packetType.stormCtrlSoakInstCount', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Packet Type', + 'Rate [%]', + 'Burst Rate [%]', + 'Rate [pps]', + 'Burst Rate [pps]', + 'Storm Control Action', + 'Storm Soak', + 'Instances', + 'Ref Policies' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + [info], + order, + ['packetType'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_storm_control_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_storm_control_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_storm_control_summary(self, info): + order = [ + 'name', + 'tf', + 'packetType.type', + 'packetType.rate', + 'packetType.burstRate', + 'packetType.ratePps', + 'packetType.burstPps', + 'packetType.stormCtrlAction', + 'packetType.stormCtrlSoakInstCount', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Packet Type', + 'Rate [%]', + 'Burst Rate [%]', + 'Rate [pps]', + 'Burst Rate [pps]', + 'Storm Control Action', + 'Storm Soak', + 'Instances', + 'Ref Policies' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['packetType'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_storm_control_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_storm_control_interfaces(self, info): + order = [ + 'name', + 'l1RsStormctrlIfPolCons.pod_node_name', + 'l1RsStormctrlIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsStormctrlIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/stp/__init__.py b/lib/aci/policy/interface/stp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/stp/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..61fa9738 Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..467b347a Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..aee75630 Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..abe0764c Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..09907e74 Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d6a911c5 Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/stp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e9979a5b Binary files /dev/null and b/lib/aci/policy/interface/stp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/api.py b/lib/aci/policy/interface/stp/api.py new file mode 100644 index 00000000..af66e9cf --- /dev/null +++ b/lib/aci/policy/interface/stp/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceStpApi(): + def __init__(self): + self.policy_interface_stp_mo = None + + def get_policy_interface_stp_mo(self): + if self.policy_interface_stp_mo is not None: + return self.policy_interface_stp_mo + + cache = self.get_object_cache( + 'stpIfPol' + ) + if cache is not None: + self.policy_interface_stp_mo = cache + self.log.apic_mo( + 'stpIfPol', + self.policy_interface_stp_mo + ) + return self.policy_interface_stp_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'stpIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_stp_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['stpIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'stpIfPol' + ) + + self.policy_interface_stp_mo.append( + attributes + ) + + self.log.apic_mo( + 'stpIfPol', + self.policy_interface_stp_mo + ) + + self.set_object_cache( + 'stpIfPol', + self.policy_interface_stp_mo + ) + + return self.policy_interface_stp_mo diff --git a/lib/aci/policy/interface/stp/attachment/__init__.py b/lib/aci/policy/interface/stp/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/stp/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/stp/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/stp/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/stp/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..b5d7d1a2 Binary files /dev/null and b/lib/aci/policy/interface/stp/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/stp/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..75d63283 Binary files /dev/null and b/lib/aci/policy/interface/stp/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/stp/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a24d2aef Binary files /dev/null and b/lib/aci/policy/interface/stp/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/stp/attachment/api.py b/lib/aci/policy/interface/stp/attachment/api.py new file mode 100644 index 00000000..5f11bb59 --- /dev/null +++ b/lib/aci/policy/interface/stp/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceStpAttachmentApi(): + def __init__(self): + self.policy_interface_stp_attachment_mo = None + + def get_policy_interface_stp_attachment_mo(self): + if self.policy_interface_stp_attachment_mo is not None: + return self.policy_interface_stp_attachment_mo + + cache = self.get_object_cache( + 'l1RsStpIfPolCons' + ) + if cache is not None: + self.policy_interface_stp_attachment_mo = cache + self.log.apic_mo( + 'l1RsStpIfPolCons', + self.policy_interface_stp_attachment_mo + ) + return self.policy_interface_stp_attachment_mo + + managed_objects = self.get_class( + 'l1RsStpIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_stp_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_stp_attachment_mo.append( + managed_object['l1RsStpIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsStpIfPolCons', + self.policy_interface_stp_attachment_mo + ) + + self.set_object_cache( + 'l1RsStpIfPolCons', + self.policy_interface_stp_attachment_mo + ) + + return self.policy_interface_stp_attachment_mo diff --git a/lib/aci/policy/interface/stp/attachment/info.py b/lib/aci/policy/interface/stp/attachment/info.py new file mode 100644 index 00000000..fb862070 --- /dev/null +++ b/lib/aci/policy/interface/stp/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceStpAttachmentInfo(): + def __init__(self): + self.policy_interface_stp_attachment = None + + def get_policy_interface_stp_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rsstpIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "stpIfPol", + # "tDn": "uni/infra/stpIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_stp_attachments_info(self): + if self.policy_interface_stp_attachment is not None: + return self.policy_interface_stp_attachment + + managed_objects = self.get_policy_interface_stp_attachment_mo() + if managed_objects is not None: + self.policy_interface_stp_attachment = [] + for managed_object in managed_objects: + self.policy_interface_stp_attachment.append( + self.get_policy_interface_stp_attachment_info( + managed_object + ) + ) + + return self.policy_interface_stp_attachment + + def match_policy_interface_stp_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_stp_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_stp_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_stp_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_stp_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/stp/attachment/main.py b/lib/aci/policy/interface/stp/attachment/main.py new file mode 100644 index 00000000..55a57362 --- /dev/null +++ b/lib/aci/policy/interface/stp/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.stp.attachment.api import PolicyInterfaceStpAttachmentApi +from lib.aci.policy.interface.stp.attachment.info import PolicyInterfaceStpAttachmentInfo + + +class PolicyInterfaceStpAttachment(PolicyInterfaceStpAttachmentApi, PolicyInterfaceStpAttachmentInfo): + def __init__(self): + PolicyInterfaceStpAttachmentApi.__init__(self) + PolicyInterfaceStpAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/stp/context.py b/lib/aci/policy/interface/stp/context.py new file mode 100644 index 00000000..bf398fd4 --- /dev/null +++ b/lib/aci/policy/interface/stp/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceStpContext(): + def __init__(self): + pass + + def set_policy_interface_stp_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "stpIfPol", + # "policyDn": "uni/infra/stpIfP-k8s_stp_enable", + # "policyName": "k8s_stp_enable" + # + # Context + # "stp": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsStpIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-stp-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_stp_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_stp_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/stp/info.py b/lib/aci/policy/interface/stp/info.py new file mode 100644 index 00000000..b70dbc1c --- /dev/null +++ b/lib/aci/policy/interface/stp/info.py @@ -0,0 +1,233 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceStpInfo(): + def __init__(self): + self.policy_interface_stp = None + + def get_policy_interface_stp_reln_info(self, managed_object): + info = {} + info['class'] = 'stpIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_stp_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "ctrl": "bpdu-filter,bpdu-guard", + # "descr": "", + # "dn": "uni/infra/ifPol-test", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2023-02-06T14:52:55.014+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "test", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:" + keys = [ + 'annotation', + 'ctrl', + 'dn', + 'name', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['bpduFilter'] = False + info['bpduFilterTick'] = '\u2717' + info['bpduGuard'] = False + info['bpduGuardTick'] = '\u2717' + + if info['ctrl'] is not None: + if 'bpdu-filter' in info['ctrl'].split(','): + info['bpduFilter'] = True + info['bpduFilterTick'] = '\u2713' + + if 'bpdu-guard' in info['ctrl'].split(','): + info['bpduGuard'] = True + info['bpduGuardTick'] = '\u2713' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_stp_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_stp_info(self): + if self.policy_interface_stp is not None: + return self.policy_interface_stp + + managed_objects = self.get_policy_interface_stp_mo() + if managed_objects is not None: + self.policy_interface_stp = [] + for managed_object in managed_objects: + self.policy_interface_stp.append( + self.get_policy_interface_stp_info( + managed_object + ) + ) + + self.log.apic_mo( + 'stpIfPol.info', + self.policy_interface_stp + ) + + return self.policy_interface_stp + + def match_policy_interface_stp(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsStpIfPolCons' in policy_info: + if len(policy_info['l1RsStpIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsStpIfPolCons' in policy_info: + if len(policy_info['l1RsStpIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsStpIfPolCons' in policy_info: + if len(policy_info['l1RsStpIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_stp_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_stp(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_stp_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_stp(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_stp_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_stp(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsStpIfPolCons'] = self.get_policy_interface_stp_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsStpIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsStpIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_stp_attachments_node_summary( + policy_info['l1RsStpIfPolCons'] + ) + + if not self.match_policy_interface_stp(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/stp/main.py b/lib/aci/policy/interface/stp/main.py new file mode 100644 index 00000000..9ab838ff --- /dev/null +++ b/lib/aci/policy/interface/stp/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.stp.attachment.main import PolicyInterfaceStpAttachment +from lib.aci.policy.interface.stp.api import PolicyInterfaceStpApi +from lib.aci.policy.interface.stp.context import PolicyInterfaceStpContext +from lib.aci.policy.interface.stp.info import PolicyInterfaceStpInfo + + +class PolicyInterfaceStp(PolicyInterfaceStpAttachment, PolicyInterfaceStpApi, PolicyInterfaceStpContext, PolicyInterfaceStpInfo): + def __init__(self): + PolicyInterfaceStpAttachment.__init__(self) + PolicyInterfaceStpApi.__init__(self) + PolicyInterfaceStpContext.__init__(self) + PolicyInterfaceStpInfo.__init__(self) diff --git a/lib/aci/policy/interface/stp/output.py b/lib/aci/policy/interface/stp/output.py new file mode 100644 index 00000000..e46c83d8 --- /dev/null +++ b/lib/aci/policy/interface/stp/output.py @@ -0,0 +1,177 @@ +class PolicyInterfaceStpOutput(): + def __init__(self): + pass + + def print_policy_interface_stp(self, info): + self.print_policy_interface_stp_properties( + info + ) + + self.print_policy_interface_stp_interfaces( + info['l1RsStpIfPolCons'] + ) + + self.print_policy_interface_stp_references( + info['relnFrom'] + ) + + def print_policy_interface_stp_properties(self, info): + order = [ + 'name', + 'tf', + 'bpduFilter', + 'bpduGuard', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'BPDU Filter', + 'BPDU Guard', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.dictionary( + info, + title='CDP Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_stp_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_stp_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_stp_summary(self, info): + order = [ + 'name', + 'tfTick', + 'bpduFilter', + 'bpduGuard', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'BPDU Filter', + 'BPDU Guard', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_stp_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_stp_interfaces(self, info): + order = [ + 'name', + 'l1RsStpIfPolCons.pod_node_name', + 'l1RsStpIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsStpIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/synce/__init__.py b/lib/aci/policy/interface/synce/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/synce/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..328d5d5a Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..f7e7ce55 Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..f4a4a6fe Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..de77e397 Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5455b07d Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/synce/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..090cfba8 Binary files /dev/null and b/lib/aci/policy/interface/synce/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/api.py b/lib/aci/policy/interface/synce/api.py new file mode 100644 index 00000000..47201c7b --- /dev/null +++ b/lib/aci/policy/interface/synce/api.py @@ -0,0 +1,51 @@ +class PolicyInterfaceSynceApi(): + def __init__(self): + self.policy_interface_synce_mo = None + + def get_policy_interface_synce_mo(self): + if self.policy_interface_synce_mo is not None: + return self.policy_interface_synce_mo + + cache = self.get_object_cache( + 'synceEthIfPol' + ) + if cache is not None: + self.policy_interface_synce_mo = cache + self.log.apic_mo( + 'synceEthIfPol', + self.policy_interface_synce_mo + ) + return self.policy_interface_synce_mo + + query = 'rsp-subtree=children&rsp-subtree-class=relnFrom' + managed_objects = self.get_class( + 'synceEthIfPol', + query=query + ) + if managed_objects is None: + return None + + self.policy_interface_synce_mo = [] + + for managed_object in managed_objects['imdata']: + attributes = managed_object['synceEthIfPol']['attributes'] + attributes['relnFrom'] = self.get_policy_interface_reln( + managed_object, + 'synceEthIfPol' + ) + + self.policy_interface_synce_mo.append( + attributes + ) + + self.log.apic_mo( + 'synceEthIfPol', + self.policy_interface_synce_mo + ) + + self.set_object_cache( + 'synceEthIfPol', + self.policy_interface_synce_mo + ) + + return self.policy_interface_synce_mo diff --git a/lib/aci/policy/interface/synce/attachment/__init__.py b/lib/aci/policy/interface/synce/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/synce/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/synce/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/synce/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/synce/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..a8c8553c Binary files /dev/null and b/lib/aci/policy/interface/synce/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/synce/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..246f647f Binary files /dev/null and b/lib/aci/policy/interface/synce/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/synce/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..09a72b3d Binary files /dev/null and b/lib/aci/policy/interface/synce/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/synce/attachment/api.py b/lib/aci/policy/interface/synce/attachment/api.py new file mode 100644 index 00000000..317bb280 --- /dev/null +++ b/lib/aci/policy/interface/synce/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceSynceAttachmentApi(): + def __init__(self): + self.policy_interface_synce_attachment_mo = None + + def get_policy_interface_synce_attachment_mo(self): + if self.policy_interface_synce_attachment_mo is not None: + return self.policy_interface_synce_attachment_mo + + cache = self.get_object_cache( + 'l1RsSynceEthIfPolCons' + ) + if cache is not None: + self.policy_interface_synce_attachment_mo = cache + self.log.apic_mo( + 'l1RsSynceEthIfPolCons', + self.policy_interface_synce_attachment_mo + ) + return self.policy_interface_synce_attachment_mo + + managed_objects = self.get_class( + 'l1RsSynceEthIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_synce_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_synce_attachment_mo.append( + managed_object['l1RsSynceEthIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsSynceEthIfPolCons', + self.policy_interface_synce_attachment_mo + ) + + self.set_object_cache( + 'l1RsSynceEthIfPolCons', + self.policy_interface_synce_attachment_mo + ) + + return self.policy_interface_synce_attachment_mo diff --git a/lib/aci/policy/interface/synce/attachment/info.py b/lib/aci/policy/interface/synce/attachment/info.py new file mode 100644 index 00000000..fb00e1d6 --- /dev/null +++ b/lib/aci/policy/interface/synce/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceSynceAttachmentInfo(): + def __init__(self): + self.policy_interface_synce_attachment = None + + def get_policy_interface_synce_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rssynceEthIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "synceEthIfPol", + # "tDn": "uni/infra/synceIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_synce_attachments_info(self): + if self.policy_interface_synce_attachment is not None: + return self.policy_interface_synce_attachment + + managed_objects = self.get_policy_interface_synce_attachment_mo() + if managed_objects is not None: + self.policy_interface_synce_attachment = [] + for managed_object in managed_objects: + self.policy_interface_synce_attachment.append( + self.get_policy_interface_synce_attachment_info( + managed_object + ) + ) + + return self.policy_interface_synce_attachment + + def match_policy_interface_synce_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_synce_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_synce_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_synce_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_synce_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/synce/attachment/main.py b/lib/aci/policy/interface/synce/attachment/main.py new file mode 100644 index 00000000..b631e416 --- /dev/null +++ b/lib/aci/policy/interface/synce/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.synce.attachment.api import PolicyInterfaceSynceAttachmentApi +from lib.aci.policy.interface.synce.attachment.info import PolicyInterfaceSynceAttachmentInfo + + +class PolicyInterfaceSynceAttachment(PolicyInterfaceSynceAttachmentApi, PolicyInterfaceSynceAttachmentInfo): + def __init__(self): + PolicyInterfaceSynceAttachmentApi.__init__(self) + PolicyInterfaceSynceAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/synce/context.py b/lib/aci/policy/interface/synce/context.py new file mode 100644 index 00000000..1895c91d --- /dev/null +++ b/lib/aci/policy/interface/synce/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceSynceContext(): + def __init__(self): + pass + + def set_policy_interface_synce_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "synceEthIfPol", + # "policyDn": "uni/infra/synceIfP-k8s_synce_enable", + # "policyName": "k8s_synce_enable" + # + # Context + # "synce": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsSynceEthIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-synce-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_synce_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_synce_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/synce/info.py b/lib/aci/policy/interface/synce/info.py new file mode 100644 index 00000000..5de3b0f3 --- /dev/null +++ b/lib/aci/policy/interface/synce/info.py @@ -0,0 +1,256 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceSynceInfo(): + def __init__(self): + self.policy_interface_synce = None + + def get_policy_interface_synce_reln_info(self, managed_object): + info = {} + info['class'] = 'synceEthIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_synce_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "childAction": "", + # "descr": "", + # "dn": "uni/infra/synceEthIfP-default", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2021-09-01T11:35:59.198+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "qloptype": "none", + # "qlrcvexactval": "fsync-ql-common-none", + # "qlrcvhval": "fsync-ql-common-none", + # "qlrcvlval": "fsync-ql-common-none", + # "qltxexactval": "fsync-ql-common-none", + # "qltxhval": "fsync-ql-common-none", + # "qltxlval": "fsync-ql-common-none", + # "selinput": "no", + # "srcpriority": "100", + # "ssm": "yes", + # "status": "", + # "uid": "0", + # "userdom": "all", + # "wtr": "5" + keys = [ + 'adminSt', + 'annotation', + 'dn', + 'name', + 'qloptype', + 'qlrcvexactval', + 'qlrcvhval', + 'qlrcvlval', + 'qltxexactval', + 'qltxhval', + 'qltxlval', + 'selinput', + 'srcpriority', + 'ssm', + 'wtr', + 'relnFrom' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + info['qlrcv'] = [] + info['qlrcv'].append('%s (min)' % (info['qlrcvlval'])) + info['qlrcv'].append('%s (eq)' % (info['qlrcvexactval'])) + info['qlrcv'].append('%s (max)' % (info['qlrcvhval'])) + + info['qltx'] = [] + info['qltx'].append('%s (min)' % (info['qltxlval'])) + info['qltx'].append('%s (eq)' % (info['qltxexactval'])) + info['qltx'].append('%s (max)' % (info['qltxhval'])) + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + info['relnFrom'] = [] + for reln_mo in managed_object['relnFrom']: + info['relnFrom'].append( + self.get_policy_interface_synce_reln_info( + reln_mo + ) + ) + + info['relnFrom'] = sorted( + info['relnFrom'], + key=lambda i: ( + i['policyType'], + i['policyName'] + ) + ) + + info['references'] = len( + info['relnFrom'] + ) + + return info + + def get_policies_interface_synce_info(self): + if self.policy_interface_synce is not None: + return self.policy_interface_synce + + managed_objects = self.get_policy_interface_synce_mo() + if managed_objects is not None: + self.policy_interface_synce = [] + for managed_object in managed_objects: + self.policy_interface_synce.append( + self.get_policy_interface_synce_info( + managed_object + ) + ) + + self.log.apic_mo( + 'synceEthIfPol.info', + self.policy_interface_synce + ) + + return self.policy_interface_synce + + def match_policy_interface_synce(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsSynceEthIfPolCons' in policy_info: + if len(policy_info['l1RsSynceEthIfPolCons']) == 0: + return False + + if key == 'ref_policy_name': + if len(policy_info['relnFrom']) == 0: + return False + + if key == 'used': + if value == 'true': + if len(policy_info['relnFrom']) == 0: + return False + + if 'l1RsSynceEthIfPolCons' in policy_info: + if len(policy_info['l1RsSynceEthIfPolCons']) == 0: + return False + + if value == 'false': + if len(policy_info['relnFrom']) > 0: + return False + + if 'l1RsSynceEthIfPolCons' in policy_info: + if len(policy_info['l1RsSynceEthIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_synce_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_synce(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_synce_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_synce(policy_info, policy_filter): + continue + + reln_from = [] + for policy_reln_info in policy_info['relnFrom']: + if not self.match_policy_interface_synce_reln(policy_reln_info, policy_filter): + continue + + reln_from.append( + policy_reln_info + ) + + policy_info['relnFrom'] = copy.deepcopy(reln_from) + policy_info['references'] = len( + policy_info['relnFrom'] + ) + + if not self.match_policy_interface_synce(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsSynceEthIfPolCons'] = self.get_policy_interface_synce_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsSynceEthIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsSynceEthIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_synce_attachments_node_summary( + policy_info['l1RsSynceEthIfPolCons'] + ) + + if not self.match_policy_interface_synce(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/synce/main.py b/lib/aci/policy/interface/synce/main.py new file mode 100644 index 00000000..f4e429fc --- /dev/null +++ b/lib/aci/policy/interface/synce/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.synce.attachment.main import PolicyInterfaceSynceAttachment +from lib.aci.policy.interface.synce.api import PolicyInterfaceSynceApi +from lib.aci.policy.interface.synce.context import PolicyInterfaceSynceContext +from lib.aci.policy.interface.synce.info import PolicyInterfaceSynceInfo + + +class PolicyInterfaceSynce(PolicyInterfaceSynceAttachment, PolicyInterfaceSynceApi, PolicyInterfaceSynceContext, PolicyInterfaceSynceInfo): + def __init__(self): + PolicyInterfaceSynceAttachment.__init__(self) + PolicyInterfaceSynceApi.__init__(self) + PolicyInterfaceSynceContext.__init__(self) + PolicyInterfaceSynceInfo.__init__(self) diff --git a/lib/aci/policy/interface/synce/output.py b/lib/aci/policy/interface/synce/output.py new file mode 100644 index 00000000..d3d2e9e4 --- /dev/null +++ b/lib/aci/policy/interface/synce/output.py @@ -0,0 +1,197 @@ +class PolicyInterfaceSynceOutput(): + def __init__(self): + pass + + def print_policy_interface_synce(self, info): + self.print_policy_interface_synce_properties( + info + ) + + self.print_policy_interface_synce_interfaces( + info['l1RsSynceEthIfPolCons'] + ) + + self.print_policy_interface_synce_references( + info['relnFrom'] + ) + + def print_policy_interface_synce_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt', + 'selinput', + 'srcpriority', + 'ssm', + 'wtr', + 'qlrcvlval', + 'qlrcvexactval', + 'qlrcvhval', + 'qltxlval', + 'qltxexactval', + 'qltxhval' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Input Selection', + 'Source Priority', + 'Sync Status Msg', + 'Wait-To-Restore', + 'Rx Qual Min', + 'Rx Qual Eq', + 'Rx Qual Max', + 'Tx Qual Min', + 'Tx Qual Eq', + 'Tx Qual Max' + ] + + self.my_output.dictionary( + info, + title='SyncE Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_synce_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policy_interface_synce_references(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'policyName', + 'policyType', + 'tCl' + ] + + headers = [ + 'Policy Name', + 'Policy Type', + 'Policy Class' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_synce_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'selinput', + 'srcpriority', + 'ssm', + 'wtr', + 'interfaces', + 'references' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Input Selection', + 'Source Priority', + 'Sync Status Msg', + 'Wait-To-Restore', + 'Interfaces', + 'Ref Policies' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_synce_usage(self, info): + order = [ + 'name', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces', + 'relnFrom.policyType', + 'relnFrom.policyName' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface Count', + 'Ref Policy Type', + 'Ref Policy Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces', 'relnFrom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_synce_interfaces(self, info): + order = [ + 'name', + 'l1RsSynceEthIfPolCons.pod_node_name', + 'l1RsSynceEthIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsSynceEthIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/interface/transceiver/__init__.py b/lib/aci/policy/interface/transceiver/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/transceiver/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b8c60e8c Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..60e3954d Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/__pycache__/attachment.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/attachment.cpython-310.pyc new file mode 100644 index 00000000..d16bb8ce Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/attachment.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/__pycache__/context.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..aa426515 Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..49a33ed1 Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..574a8315 Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/__pycache__/output.cpython-310.pyc b/lib/aci/policy/interface/transceiver/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..90418ed7 Binary files /dev/null and b/lib/aci/policy/interface/transceiver/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/api.py b/lib/aci/policy/interface/transceiver/api.py new file mode 100644 index 00000000..8b307950 --- /dev/null +++ b/lib/aci/policy/interface/transceiver/api.py @@ -0,0 +1,58 @@ +class PolicyInterfaceTransceiverApi(): + def __init__(self): + self.policy_interface_transceiver_mo = None + + def get_policy_interface_transceiver_mo(self): + if self.policy_interface_transceiver_mo is not None: + return self.policy_interface_transceiver_mo + + cache = self.get_object_cache( + 'xcvrOpticsIfPol' + ) + if cache is not None: + self.policy_interface_transceiver_mo = cache + self.log.apic_mo( + 'xcvrOpticsIfPol', + self.policy_interface_transceiver_mo + ) + return self.policy_interface_transceiver_mo + + managed_objects = self.get_class( + 'xcvrOpticsIfPol', + node_class=True + ) + if managed_objects is None: + return None + + self.policy_interface_transceiver_mo = [] + + for managed_object in managed_objects['imdata']: + if 'xcvrZRIfPol' in managed_object: + attributes = managed_object['xcvrZRIfPol']['attributes'] + attributes['type'] = 'xcvrZRIfPol' + self.policy_interface_transceiver_mo.append( + attributes + ) + + if 'xcvrZRPIfPol' in managed_object: + attributes = managed_object['xcvrZRPIfPol']['attributes'] + attributes['type'] = 'xcvrZRPIfPol' + self.policy_interface_transceiver_mo.append( + attributes + ) + + self.policy_interface_transceiver_mo.append( + attributes + ) + + self.log.apic_mo( + 'xcvrOpticsIfPol', + self.policy_interface_transceiver_mo + ) + + self.set_object_cache( + 'xcvrOpticsIfPol', + self.policy_interface_transceiver_mo + ) + + return self.policy_interface_transceiver_mo diff --git a/lib/aci/policy/interface/transceiver/attachment/__init__.py b/lib/aci/policy/interface/transceiver/attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/interface/transceiver/attachment/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/interface/transceiver/attachment/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ff760a7d Binary files /dev/null and b/lib/aci/policy/interface/transceiver/attachment/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/attachment/__pycache__/api.cpython-310.pyc b/lib/aci/policy/interface/transceiver/attachment/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2c41966b Binary files /dev/null and b/lib/aci/policy/interface/transceiver/attachment/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/attachment/__pycache__/info.cpython-310.pyc b/lib/aci/policy/interface/transceiver/attachment/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..387253de Binary files /dev/null and b/lib/aci/policy/interface/transceiver/attachment/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/attachment/__pycache__/main.cpython-310.pyc b/lib/aci/policy/interface/transceiver/attachment/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..02183ba3 Binary files /dev/null and b/lib/aci/policy/interface/transceiver/attachment/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/interface/transceiver/attachment/api.py b/lib/aci/policy/interface/transceiver/attachment/api.py new file mode 100644 index 00000000..5e860a12 --- /dev/null +++ b/lib/aci/policy/interface/transceiver/attachment/api.py @@ -0,0 +1,43 @@ +class PolicyInterfaceTransceiverAttachmentApi(): + def __init__(self): + self.policy_interface_transceiver_attachment_mo = None + + def get_policy_interface_transceiver_attachment_mo(self): + if self.policy_interface_transceiver_attachment_mo is not None: + return self.policy_interface_transceiver_attachment_mo + + cache = self.get_object_cache( + 'l1RsSynceEthIfPolCons' + ) + if cache is not None: + self.policy_interface_transceiver_attachment_mo = cache + self.log.apic_mo( + 'l1RsSynceEthIfPolCons', + self.policy_interface_transceiver_attachment_mo + ) + return self.policy_interface_transceiver_attachment_mo + + managed_objects = self.get_class( + 'l1RsSynceEthIfPolCons' + ) + if managed_objects is None: + return None + + self.policy_interface_transceiver_attachment_mo = [] + + for managed_object in managed_objects['imdata']: + self.policy_interface_transceiver_attachment_mo.append( + managed_object['l1RsSynceEthIfPolCons']['attributes'] + ) + + self.log.apic_mo( + 'l1RsSynceEthIfPolCons', + self.policy_interface_transceiver_attachment_mo + ) + + self.set_object_cache( + 'l1RsSynceEthIfPolCons', + self.policy_interface_transceiver_attachment_mo + ) + + return self.policy_interface_transceiver_attachment_mo diff --git a/lib/aci/policy/interface/transceiver/attachment/info.py b/lib/aci/policy/interface/transceiver/attachment/info.py new file mode 100644 index 00000000..ef5eb23d --- /dev/null +++ b/lib/aci/policy/interface/transceiver/attachment/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class PolicyInterfaceTransceiverAttachmentInfo(): + def __init__(self): + self.policy_interface_transceiver_attachment = None + + def get_policy_interface_transceiver_attachment_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-2101/sys/phys-[eth1/33]/rstransceiverIfPolCons", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2023-03-02T20:36:22.878+02:00", + # "parentSKey": "eth1/33", + # "rType": "mo", + # "selectorType": "none", + # "sourceRelStateQual": "none", + # "state": "formed", + # "stateQual": "none", + # "status": "", + # "tCl": "transceiverIfPol", + # "tDn": "uni/infra/transceiverIfP-default", + # "tType": "mo" + info = {} + info['podId'] = managed_object['dn'].split('/')[1].split('-')[1] + info['nodeId'] = managed_object['dn'].split('/')[2].split('-')[1] + info['nodeName'] = self.get_node_name( + info['nodeId'], + pod_id=info['podId'] + ) + info['apic'] = self.apic_name + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + info['nodeName'] + ) + + info['interfaceId'] = managed_object['parentSKey'] + info['policyType'] = managed_object['tCl'] + info['policyDn'] = managed_object['tDn'] + info['policyName'] = managed_object['tDn'].split('/')[2][7:] + + return info + + def get_policy_interface_transceiver_attachments_info(self): + if self.policy_interface_transceiver_attachment is not None: + return self.policy_interface_transceiver_attachment + + managed_objects = self.get_policy_interface_transceiver_attachment_mo() + if managed_objects is not None: + self.policy_interface_transceiver_attachment = [] + for managed_object in managed_objects: + self.policy_interface_transceiver_attachment.append( + self.get_policy_interface_transceiver_attachment_info( + managed_object + ) + ) + + return self.policy_interface_transceiver_attachment + + def match_policy_interface_transceiver_attachment(self, attachment_info, attachment_filter): + if attachment_filter is None or len(attachment_filter) == 0: + return True + + for ap_rule in attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'policy_dn': + if not filter_helper.match_string(value, attachment_info['policyDn']): + return False + + if key == 'policy_name': + if not filter_helper.match_string(value, attachment_info['policyName']): + return False + + if key == 'pod': + if not filter_helper.match_string(value, attachment_info['podId']): + return False + + if key == 'node': + if not filter_helper.match_string(value, attachment_info['nodeName']): + return False + + return True + + def get_policy_interface_transceiver_attachments(self, attachment_filter=None): + all_attachments = self.get_policy_interface_transceiver_attachments_info() + if all_attachments is None: + return None + + attachments = [] + + for attachment_info in all_attachments: + if not self.match_policy_interface_transceiver_attachment(attachment_info, attachment_filter): + continue + + attachments.append( + attachment_info + ) + + attachments = sorted( + attachments, + key=lambda i: ( + i['podId'], + int(i['nodeId']), + i['interfaceId'] + ) + ) + + return attachments + + def get_policy_interface_transceiver_attachments_node_summary(self, attachments): + nodes = {} + for attachment in attachments: + if attachment['pod_node_name'] not in nodes: + nodes[attachment['pod_node_name']] = 0 + + for attachment in attachments: + nodes[attachment['pod_node_name']] = nodes[attachment['pod_node_name']] + 1 + + summary = [] + for node in nodes: + item = {} + item['pod_node_name'] = node + item['interfaces'] = nodes[node] + summary.append(item) + + summary = sorted( + summary, + key=lambda i: i['pod_node_name'] + ) + return summary diff --git a/lib/aci/policy/interface/transceiver/attachment/main.py b/lib/aci/policy/interface/transceiver/attachment/main.py new file mode 100644 index 00000000..0435ac0d --- /dev/null +++ b/lib/aci/policy/interface/transceiver/attachment/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.interface.transceiver.attachment.api import PolicyInterfaceTransceiverAttachmentApi +from lib.aci.policy.interface.transceiver.attachment.info import PolicyInterfaceTransceiverAttachmentInfo + + +class PolicyInterfaceTransceiverAttachment(PolicyInterfaceTransceiverAttachmentApi, PolicyInterfaceTransceiverAttachmentInfo): + def __init__(self): + PolicyInterfaceTransceiverAttachmentApi.__init__(self) + PolicyInterfaceTransceiverAttachmentInfo.__init__(self) diff --git a/lib/aci/policy/interface/transceiver/context.py b/lib/aci/policy/interface/transceiver/context.py new file mode 100644 index 00000000..f58a4f41 --- /dev/null +++ b/lib/aci/policy/interface/transceiver/context.py @@ -0,0 +1,93 @@ +class PolicyInterfaceTransceiverContext(): + def __init__(self): + pass + + def set_policy_interface_transceiver_context(self, policies): + # Interface + # "podId": "1", + # "nodeId": "2207", + # "nodeName": "cl2207-eu-spdc", + # "apic": "apic21", + # "pod_node_name": "pod-1/cl2207-eu-spdc", + # "interfaceId": "eth1/1/1", + # "policyType": "transceiverIfPol", + # "policyDn": "uni/infra/transceiverIfP-k8s_transceiver_enable", + # "policyName": "k8s_transceiver_enable" + # + # Context + # "transceiver": { + # "apic": [ + # "apic11" + # ], + # "node": { + # "apic11": [ + # "cl202-eu-spdc", + # "cl201-eu-spdc" + # ] + # }, + # "interface": { + # "apic11": [ + # "pod-1:node-202:eth1/61", + # "pod-1:node-201:eth1/61" + # ] + # } + # } + + if policies is None or len(policies) == 0: + return None + + intf_context = {} + intf_context['apic'] = [] + intf_context['node'] = {} + intf_context['interface'] = {} + interface_count = 0 + + for policy in policies: + for interface_info in policy['l1RsSynceEthIfPolCons']: + if interface_info['apic'] not in intf_context['apic']: + intf_context['apic'].append( + interface_info['apic'] + ) + intf_context['node'][interface_info['apic']] = [] + intf_context['interface'][interface_info['apic']] = [] + + if interface_info['nodeName'] not in intf_context['node'][interface_info['apic']]: + intf_context['node'][interface_info['apic']].append( + interface_info['nodeName'] + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + interface_info['podId'], + interface_info['nodeId'], + interface_info['interfaceId'] + ) + if interface_name not in intf_context['interface'][interface_info['apic']]: + intf_context['interface'][interface_info['apic']].append( + interface_name + ) + interface_count = interface_count + 1 + + if interface_count == 0: + return None + + success = self.context_handler.set( + 'pol-transceiver-phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_transceiver_context', + 'Context set failed' + ) + + success = self.context_handler.set( + 'phy', + intf_context + ) + if not success: + self.log.error( + 'set_policy_interface_transceiver_context', + 'Context set failed' + ) + + return 'phy' diff --git a/lib/aci/policy/interface/transceiver/info.py b/lib/aci/policy/interface/transceiver/info.py new file mode 100644 index 00000000..140b14c2 --- /dev/null +++ b/lib/aci/policy/interface/transceiver/info.py @@ -0,0 +1,206 @@ +import copy + +from lib import filter_helper + + +class PolicyInterfaceTransceiverInfo(): + def __init__(self): + self.policy_interface_transceiver = None + + def get_policy_interface_transceiver_reln_info(self, managed_object): + info = {} + info['class'] = 'xcvrOpticsIfPol' + info['rn'] = managed_object['rn'] + info['tCl'] = managed_object['tCl'] + info['tDn'] = managed_object['tDn'] + info['policyType'] = self.get_policy_type_from_tcl( + managed_object['tCl'] + ) + info['policyName'] = self.get_policy_name_from_tdn( + managed_object['tDn'] + ) + return info + + def get_policy_interface_transceiver_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "cdMax": "2400", + # "cdMin": "-2400", + # "childAction": "", + # "dacRate": "1x1", + # "descr": "", + # "dn": "uni/infra/zr-default", + # "dwdmCarrier": "100MHzFrequency", + # "extMngdBy": "", + # "fecMode": "cFEC", + # "frequency100MHz": "1931000", + # "frequency50GHz": "19310", + # "ituChannel50GHz": "61", + # "lcOwn": "local", + # "modTs": "2022-09-14T19:08:11.182+01:00", + # "modulation": "16QAM", + # "muxponder": "1x400", + # "name": "default", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "transmitPower": "-190", + # "uid": "0", + # "userdom": "all", + # "wavelength50GHz": "1552524" + keys = [ + 'adminSt', + 'annotation', + 'cdMax', + 'cdMin', + 'dacRate', + 'dn', + 'dwdmCarrier', + 'fecMode', + 'frequency100MHz', + 'frequency50GHz', + 'ituChannel50GHz', + 'modulation', + 'muxponder', + 'name', + 'type', + 'transmitPower', + 'wavelength50GHz' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['annotation'] == 'orchestrator:terraform': + info['tf'] = True + info['tfTick'] = '\u2713' + else: + info['tf'] = False + info['tfTick'] = '' + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['type'] == 'xcvrZRIfPol': + info['typeT'] = 'ZR' + + if info['type'] == 'xcvrZRPIfPol': + info['typeT'] = 'ZRP' + + return info + + def get_policies_interface_transceiver_info(self): + if self.policy_interface_transceiver is not None: + return self.policy_interface_transceiver + + managed_objects = self.get_policy_interface_transceiver_mo() + if managed_objects is not None: + self.policy_interface_transceiver = [] + for managed_object in managed_objects: + self.policy_interface_transceiver.append( + self.get_policy_interface_transceiver_info( + managed_object + ) + ) + + self.log.apic_mo( + 'transceiverIfPol.info', + self.policy_interface_transceiver + ) + + return self.policy_interface_transceiver + + def match_policy_interface_transceiver(self, policy_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, policy_info['name']): + return False + + if key == 'node': + if 'l1RsSynceEthIfPolCons' in policy_info: + if len(policy_info['l1RsSynceEthIfPolCons']) == 0: + return False + + if key == 'used': + if value == 'true': + if 'l1RsSynceEthIfPolCons' in policy_info: + if len(policy_info['l1RsSynceEthIfPolCons']) == 0: + return False + + if value == 'false': + if 'l1RsSynceEthIfPolCons' in policy_info: + if len(policy_info['l1RsSynceEthIfPolCons']) > 0: + return False + + return True + + def match_policy_interface_transceiver_reln(self, policy_reln_info, policy_filter): + if policy_filter is None or len(policy_filter) == 0: + return True + + for ap_rule in policy_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'ref_policy_name': + if not filter_helper.match_string(value, policy_reln_info['policyName']): + return False + + return True + + def get_policy_interface_transceiver(self, policy_filter=None, reln_info=True, attachment_info=False): + all_policies = self.get_policies_interface_transceiver_info() + if all_policies is None: + return None + + policy = [] + + for policy_info in all_policies: + if not self.match_policy_interface_transceiver(policy_info, policy_filter): + continue + + if attachment_info: + attachment_filter = ['policy_dn:%s' % (policy_info['dn'])] + if policy_filter is not None: + attachment_filter = attachment_filter + policy_filter + + policy_info['l1RsSynceEthIfPolCons'] = self.get_policy_interface_transceiver_attachments( + attachment_filter=attachment_filter + ) + + policy_info['interfaces'] = 0 + if policy_info['l1RsSynceEthIfPolCons'] is not None: + policy_info['interfaces'] = len( + policy_info['l1RsSynceEthIfPolCons'] + ) + + policy_info['nodeInterfaces'] = self.get_policy_interface_transceiver_attachments_node_summary( + policy_info['l1RsSynceEthIfPolCons'] + ) + + if not self.match_policy_interface_transceiver(policy_info, policy_filter): + continue + + policy.append( + policy_info + ) + + policy = sorted( + policy, + key=lambda i: i['name'].lower() + ) + + return policy diff --git a/lib/aci/policy/interface/transceiver/main.py b/lib/aci/policy/interface/transceiver/main.py new file mode 100644 index 00000000..a3ad1b24 --- /dev/null +++ b/lib/aci/policy/interface/transceiver/main.py @@ -0,0 +1,12 @@ +from lib.aci.policy.interface.transceiver.attachment.main import PolicyInterfaceTransceiverAttachment +from lib.aci.policy.interface.transceiver.api import PolicyInterfaceTransceiverApi +from lib.aci.policy.interface.transceiver.context import PolicyInterfaceTransceiverContext +from lib.aci.policy.interface.transceiver.info import PolicyInterfaceTransceiverInfo + + +class PolicyInterfaceTransceiver(PolicyInterfaceTransceiverAttachment, PolicyInterfaceTransceiverApi, PolicyInterfaceTransceiverContext, PolicyInterfaceTransceiverInfo): + def __init__(self): + PolicyInterfaceTransceiverAttachment.__init__(self) + PolicyInterfaceTransceiverApi.__init__(self) + PolicyInterfaceTransceiverContext.__init__(self) + PolicyInterfaceTransceiverInfo.__init__(self) diff --git a/lib/aci/policy/interface/transceiver/output.py b/lib/aci/policy/interface/transceiver/output.py new file mode 100644 index 00000000..deb96106 --- /dev/null +++ b/lib/aci/policy/interface/transceiver/output.py @@ -0,0 +1,166 @@ +class PolicyInterfaceTransceiverOutput(): + def __init__(self): + pass + + def print_policy_interface_transceiver(self, info): + self.print_policy_interface_transceiver_properties( + info + ) + + self.print_policy_interface_transceiver_interfaces( + info['l1RsSynceEthIfPolCons'] + ) + + def print_policy_interface_transceiver_properties(self, info): + order = [ + 'name', + 'tf', + 'adminSt', + 'typeT', + 'cdMin', + 'cdMax', + 'dacRate', + 'dwdmCarrier', + 'fecMode', + 'frequency100MHz', + 'frequency50GHz', + 'ituChannel50GHz', + 'modulation', + 'muxponder', + 'transmitPower', + 'wavelength50GHz' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Type', + 'Chromatic Dispersion Minimum', + 'Chromatic Dispersion Maximum', + 'DAC Rate', + 'DWDM Carrier Grid Selector', + 'FEC Mode', + '100MHz Frequency', + '50GHz Frequency', + '50GHz ITU Channel', + 'Modulation', + 'Muxponder Mode', + 'Transmit Power', + '50GHz Wavelength' + ] + + self.my_output.dictionary( + info, + title='Transceiver Policy Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_interface_transceiver_interfaces(self, info): + if info is None or len(info) == 0: + return + + order = [ + 'pod_node_name', + 'interfaceId' + ] + + headers = [ + 'Node', + 'Interface' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_transceiver_summary(self, info): + order = [ + 'name', + 'tfTick', + 'adminSt', + 'typeT', + 'interfaces' + ] + + headers = [ + 'Policy Name', + 'TF', + 'Admin State', + 'Type', + 'Interfaces' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_transceiver_usage(self, info): + order = [ + 'name', + 'typeT', + 'nodeInterfaces.pod_node_name', + 'nodeInterfaces.interfaces' + ] + + headers = [ + 'Policy Name', + 'Type', + 'Node', + 'Interface Count' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['nodeInterfaces'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_policies_interface_transceiver_interfaces(self, info): + order = [ + 'name', + 'typeT', + 'l1RsSynceEthIfPolCons.pod_node_name', + 'l1RsSynceEthIfPolCons.interfaceId' + ] + + headers = [ + 'Policy Name', + 'Type', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['l1RsSynceEthIfPolCons'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/aci/policy/main.py b/lib/aci/policy/main.py new file mode 100644 index 00000000..c21ed64a --- /dev/null +++ b/lib/aci/policy/main.py @@ -0,0 +1,56 @@ +from lib.aci.policy.general.main import PolicyGeneral +from lib.aci.policy.interface.main import PolicyInterface +from lib.aci.policy.monitoring.main import PolicyMonitoring +from lib.aci.policy.snoop.main import PolicySnoop +from lib.aci.policy.switch.main import PolicySwitch +from lib.aci.policy.troubleshooting.main import PolicyTroubleshooting + + +class Policy( + PolicyGeneral, + PolicyInterface, + PolicyMonitoring, + PolicySnoop, + PolicySwitch, + PolicyTroubleshooting + ): + def __init__(self): + PolicyGeneral.__init__(self) + PolicyInterface.__init__(self) + PolicyMonitoring.__init__(self) + PolicySnoop.__init__(self) + PolicySwitch.__init__(self) + PolicyTroubleshooting.__init__(self) + + def get_policy_type_from_tcl(self, policy_type): + mapping = {} + mapping['infraInfra'] = 'Access Infra' + mapping['infraAccNodePGrp'] = 'Access Switch' + mapping['infraSpineAccNodePGrp'] = 'Spine Switch' + mapping['infraSpAccPortGrp'] = 'Spine Access Port' + mapping['infraAccPortGrp'] = 'Leaf Access Port' + mapping['infraAccBndlGrp'] = 'PC/VPC Interface' + mapping['infraBrkoutPortGrp'] = 'Breakout' + mapping['vmmDomP'] = 'VMM Domain' + mapping['vmmVSwitchPolicyCont'] = 'VMM Virtual Switch' + + if policy_type in mapping: + return mapping[policy_type] + + return policy_type + + def get_policy_name_from_tdn(self, policy_name): + if policy_name.startswith('uni/infra/funcprof/'): + funcname = policy_name.split('uni/infra/funcprof/')[1] + return '-'.join(funcname.split('-')[1:]) + + if policy_name.startswith('uni/vmmp-VMware/dom-'): + name = policy_name.split('uni/vmmp-VMware/dom-')[1] + if name.endswith('/vswitchpolcont'): + name = name.split('/vswitchpolcont')[0] + return name + + if policy_name == 'uni/infra': + return 'infra' + + return policy_name diff --git a/lib/aci/policy/monitoring/__init__.py b/lib/aci/policy/monitoring/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/monitoring/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/monitoring/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5059a925 Binary files /dev/null and b/lib/aci/policy/monitoring/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/monitoring/__pycache__/main.cpython-310.pyc b/lib/aci/policy/monitoring/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..73751d70 Binary files /dev/null and b/lib/aci/policy/monitoring/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/monitoring/main.py b/lib/aci/policy/monitoring/main.py new file mode 100644 index 00000000..1eebeae7 --- /dev/null +++ b/lib/aci/policy/monitoring/main.py @@ -0,0 +1,42 @@ +class PolicyMonitoring(): + def __init__(self): + pass + + def get_policy_monitoring_info(self, managed_object): + # "annotation": "", + # "childAction": "", + # "extMngdBy": "", + # "forceResolve": "yes", + # "lcOwn": "local", + # "modTs": "2021-05-19T18:26:53.317+01:00", + # "monPolDn": "uni/fabric/monfab-default", + # "rType": "mo", + # "rn": "rsmonIfInfraPol", + # "state": "formed", + # "stateQual": "default-target", + # "status": "", + # "tCl": "monInfraPol", + # "tContextDn": "", + # "tDn": "uni/infra/moninfra-default", + # "tRn": "moninfra-default", + # "tType": "name", + # "tnMonInfraPolName": "", + # "uid": "0", + # "userdom": "all" + keys = [ + 'state', + 'tDn', + 'tRn', + 'tnMonInfraPolName' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['name'] = info['tRn'].split('moninfra-')[1] + + return info diff --git a/lib/aci/policy/output.py b/lib/aci/policy/output.py new file mode 100644 index 00000000..25d4bc80 --- /dev/null +++ b/lib/aci/policy/output.py @@ -0,0 +1,10 @@ +from lib.aci.policy.general.output import PolicyGeneralOutput +from lib.aci.policy.interface.output import PolicyInterfaceOutput +from lib.aci.policy.snoop.output import PolicySnoopOutput + + +class PolicyOutput(PolicyGeneralOutput, PolicyInterfaceOutput, PolicySnoopOutput): + def __init__(self): + PolicyGeneralOutput.__init__(self) + PolicyInterfaceOutput.__init__(self) + PolicySnoopOutput.__init__(self) diff --git a/lib/aci/policy/snoop/__init__.py b/lib/aci/policy/snoop/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/snoop/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/snoop/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7df4bca2 Binary files /dev/null and b/lib/aci/policy/snoop/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/snoop/__pycache__/igmp.cpython-310.pyc b/lib/aci/policy/snoop/__pycache__/igmp.cpython-310.pyc new file mode 100644 index 00000000..5eb51a79 Binary files /dev/null and b/lib/aci/policy/snoop/__pycache__/igmp.cpython-310.pyc differ diff --git a/lib/aci/policy/snoop/__pycache__/main.cpython-310.pyc b/lib/aci/policy/snoop/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0b1935bf Binary files /dev/null and b/lib/aci/policy/snoop/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/snoop/__pycache__/mld.cpython-310.pyc b/lib/aci/policy/snoop/__pycache__/mld.cpython-310.pyc new file mode 100644 index 00000000..44982b94 Binary files /dev/null and b/lib/aci/policy/snoop/__pycache__/mld.cpython-310.pyc differ diff --git a/lib/aci/policy/snoop/__pycache__/output.cpython-310.pyc b/lib/aci/policy/snoop/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..a29be9a3 Binary files /dev/null and b/lib/aci/policy/snoop/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/policy/snoop/igmp.py b/lib/aci/policy/snoop/igmp.py new file mode 100644 index 00000000..80e1acba --- /dev/null +++ b/lib/aci/policy/snoop/igmp.py @@ -0,0 +1,115 @@ +class PolicySnoopIgmp(): + def __init__(self): + self.policy_snoop_igmp_mo = {} + + def get_policy_snoop_igmp_mo(self, tenant, name): + key = '%s.%s' % ( + tenant, + name + ) + if key in self.policy_snoop_igmp_mo: + return self.policy_snoop_igmp_mo[key] + + cache = self.get_object_cache( + 'igmpSnoopPol', + object_selector=key + ) + if cache is not None: + self.policy_snoop_igmp_mo[key] = cache + self.log.apic_mo( + 'igmpSnoopPol.%s' % (key), + self.policy_snoop_igmp_mo[key] + ) + return self.policy_snoop_igmp_mo[key] + + distinguished_name = 'uni/tn-%s/snPol-%s' % ( + tenant, + name + ) + + managed_objects = self.get_managed_object( + distinguished_name + ) + if managed_objects is None: + return None + + if managed_objects['totalCount'] != '1': + return None + + self.policy_snoop_igmp_mo[key] = managed_objects['imdata'][0]['igmpSnoopPol']['attributes'] + + self.log.apic_mo( + 'igmpSnoopPol', + self.policy_snoop_igmp_mo[key] + ) + + self.set_object_cache( + 'igmpSnoopPol', + self.policy_snoop_igmp_mo[key], + object_selector=key + ) + + return self.policy_snoop_igmp_mo[key] + + def get_policy_snoop_igmp_info(self, managed_object): + # "adminSt": "enabled", + # "annotation": "", + # "childAction": "", + # "ctrl": "", + # "descr": "", + # "dn": "uni/tn-k8s/snPol-Test", + # "extMngdBy": "", + # "lastMbrIntvl": "1", + # "lcOwn": "local", + # "modTs": "2023-01-20T07:23:12.364+01:00", + # "name": "Test", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "queryIntvl": "125", + # "rspIntvl": "10", + # "startQueryCnt": "2", + # "startQueryIntvl": "31", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:", + # "ver": "v3" + + keys = [ + 'adminSt', + 'dn', + 'lastMbrIntvl', + 'name', + 'queryIntvl', + 'rspIntvl', + 'startQueryCnt', + 'startQueryIntvl' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "uni/tn-k8s/snPol-Test" + info['tenant'] = managed_object['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_policy_snoop_igmp(self, tenant, name): + managed_object = self.get_policy_snoop_igmp_mo(tenant, name) + if managed_object is None: + return None + + return self.get_policy_snoop_igmp_info(managed_object) diff --git a/lib/aci/policy/snoop/main.py b/lib/aci/policy/snoop/main.py new file mode 100644 index 00000000..0fc4807b --- /dev/null +++ b/lib/aci/policy/snoop/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.snoop.igmp import PolicySnoopIgmp +from lib.aci.policy.snoop.mld import PolicySnoopMld + + +class PolicySnoop(PolicySnoopIgmp, PolicySnoopMld): + def __init__(self): + PolicySnoopIgmp.__init__(self) + PolicySnoopMld.__init__(self) diff --git a/lib/aci/policy/snoop/mld.py b/lib/aci/policy/snoop/mld.py new file mode 100644 index 00000000..de878af3 --- /dev/null +++ b/lib/aci/policy/snoop/mld.py @@ -0,0 +1,114 @@ +class PolicySnoopMld(): + def __init__(self): + self.policy_snoop_mld_mo = {} + + def get_policy_snoop_mld_mo(self, tenant, name): + key = '%s.%s' % ( + tenant, + name + ) + if key in self.policy_snoop_mld_mo: + return self.policy_snoop_mld_mo[key] + + cache = self.get_object_cache( + 'mldSnoopPol', + object_selector=key + ) + if cache is not None: + self.policy_snoop_mld_mo[key] = cache + self.log.apic_mo( + 'mldSnoopPol.%s' % (key), + self.policy_snoop_mld_mo[key] + ) + return self.policy_snoop_mld_mo[key] + + distinguished_name = 'uni/tn-%s/mldsnoopPol-%s' % ( + tenant, + name + ) + + managed_objects = self.get_managed_object( + distinguished_name + ) + if managed_objects is None: + return None + + if managed_objects['totalCount'] != '1': + return None + + self.policy_snoop_mld_mo[key] = managed_objects['imdata'][0]['mldSnoopPol']['attributes'] + + self.log.apic_mo( + 'mldSnoopPol', + self.policy_snoop_mld_mo[key] + ) + + self.set_object_cache( + 'mldSnoopPol', + self.policy_snoop_mld_mo[key], + object_selector=key + ) + + return self.policy_snoop_mld_mo[key] + + def get_policy_snoop_mld_info(self, managed_object): + # "adminSt": "disabled", + # "annotation": "", + # "childAction": "", + # "ctrl": "", + # "descr": "", + # "dn": "uni/tn-k8s/mldsnoopPol-Test", + # "extMngdBy": "", + # "lastMbrIntvl": "1", + # "lcOwn": "local", + # "modTs": "2023-01-20T07:23:26.975+01:00", + # "name": "Test", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "queryIntvl": "125", + # "rspIntvl": "10", + # "startQueryCnt": "2", + # "startQueryIntvl": "31", + # "status": "", + # "uid": "15374", + # "userdom": ":all:common:", + # "ver": "v2" + keys = [ + 'adminSt', + 'dn', + 'lastMbrIntvl', + 'name', + 'queryIntvl', + 'rspIntvl', + 'startQueryCnt', + 'startQueryIntvl', + 'ver' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # "dn": "uni/tn-k8s/mldsnoopPol-Test" + info['tenant'] = managed_object['dn'].split('/')[1][3:] + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_policy_snoop_mld(self, tenant, name): + managed_object = self.get_policy_snoop_mld_mo(tenant, name) + if managed_object is None: + return None + return self.get_policy_snoop_mld_info(managed_object) diff --git a/lib/aci/policy/snoop/output.py b/lib/aci/policy/snoop/output.py new file mode 100644 index 00000000..2d0ac83c --- /dev/null +++ b/lib/aci/policy/snoop/output.py @@ -0,0 +1,71 @@ +class PolicySnoopOutput(): + def __init__(self): + pass + + def print_policy_snoop_igmp(self, info): + order = [ + 'tenant', + 'name', + 'adminSt', + 'lastMbrIntvl', + 'queryIntvl', + 'rspIntvl', + 'startQueryCnt', + 'startQueryIntvl' + ] + + headers = [ + 'Tenant', + 'Name', + 'Admin state', + 'Last Member Query Interval', + 'Query Interval', + 'Query Response interval', + 'Start Query Count', + 'Start Query interval' + ] + + self.my_output.dictionary( + info, + title='IGMP Snoop Policy', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_policy_snoop_mld(self, info): + order = [ + 'tenant', + 'name', + 'adminSt', + 'ver', + 'lastMbrIntvl', + 'queryIntvl', + 'rspIntvl', + 'startQueryCnt', + 'startQueryIntvl' + ] + + headers = [ + 'Tenant', + 'Name', + 'Admin state', + 'Version', + 'Last Member Query Interval', + 'Query Interval', + 'Query Response interval', + 'Start Query Count', + 'Start Query interval' + ] + + self.my_output.dictionary( + info, + title='MLD Snoop Policy', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/policy/switch/__init__.py b/lib/aci/policy/switch/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/switch/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/switch/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5cf8e5e8 Binary files /dev/null and b/lib/aci/policy/switch/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/switch/__pycache__/main.cpython-310.pyc b/lib/aci/policy/switch/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..04674752 Binary files /dev/null and b/lib/aci/policy/switch/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/switch/main.py b/lib/aci/policy/switch/main.py new file mode 100644 index 00000000..ccffc63f --- /dev/null +++ b/lib/aci/policy/switch/main.py @@ -0,0 +1,3 @@ +class PolicySwitch(): + def __init__(self): + pass diff --git a/lib/aci/policy/troubleshooting/__init__.py b/lib/aci/policy/troubleshooting/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/troubleshooting/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/troubleshooting/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b9b8d470 Binary files /dev/null and b/lib/aci/policy/troubleshooting/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/troubleshooting/__pycache__/main.cpython-310.pyc b/lib/aci/policy/troubleshooting/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..70f34a12 Binary files /dev/null and b/lib/aci/policy/troubleshooting/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/troubleshooting/main.py b/lib/aci/policy/troubleshooting/main.py new file mode 100644 index 00000000..9eb9cf89 --- /dev/null +++ b/lib/aci/policy/troubleshooting/main.py @@ -0,0 +1,6 @@ +from lib.aci.policy.troubleshooting.span.main import PolicyTroubleshootingSpan + + +class PolicyTroubleshooting(PolicyTroubleshootingSpan): + def __init__(self): + PolicyTroubleshootingSpan.__init__(self) diff --git a/lib/aci/policy/troubleshooting/span/__init__.py b/lib/aci/policy/troubleshooting/span/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/policy/troubleshooting/span/__pycache__/__init__.cpython-310.pyc b/lib/aci/policy/troubleshooting/span/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ac37a515 Binary files /dev/null and b/lib/aci/policy/troubleshooting/span/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/policy/troubleshooting/span/__pycache__/destination.cpython-310.pyc b/lib/aci/policy/troubleshooting/span/__pycache__/destination.cpython-310.pyc new file mode 100644 index 00000000..379c0767 Binary files /dev/null and b/lib/aci/policy/troubleshooting/span/__pycache__/destination.cpython-310.pyc differ diff --git a/lib/aci/policy/troubleshooting/span/__pycache__/main.cpython-310.pyc b/lib/aci/policy/troubleshooting/span/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c049780e Binary files /dev/null and b/lib/aci/policy/troubleshooting/span/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/policy/troubleshooting/span/__pycache__/source.cpython-310.pyc b/lib/aci/policy/troubleshooting/span/__pycache__/source.cpython-310.pyc new file mode 100644 index 00000000..94cbdece Binary files /dev/null and b/lib/aci/policy/troubleshooting/span/__pycache__/source.cpython-310.pyc differ diff --git a/lib/aci/policy/troubleshooting/span/destination.py b/lib/aci/policy/troubleshooting/span/destination.py new file mode 100644 index 00000000..cee20868 --- /dev/null +++ b/lib/aci/policy/troubleshooting/span/destination.py @@ -0,0 +1,19 @@ +class PolicyTroubleshootingSpanDestination(): + def __init__(self): + pass + + def get_policy_troubleshooting_span_destination_info(self, managed_object): + keys = [ + 'state', + 'tDn', + 'tRn' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/policy/troubleshooting/span/main.py b/lib/aci/policy/troubleshooting/span/main.py new file mode 100644 index 00000000..e3f1ad9a --- /dev/null +++ b/lib/aci/policy/troubleshooting/span/main.py @@ -0,0 +1,8 @@ +from lib.aci.policy.troubleshooting.span.source import PolicyTroubleshootingSpanSource +from lib.aci.policy.troubleshooting.span.destination import PolicyTroubleshootingSpanDestination + + +class PolicyTroubleshootingSpan(PolicyTroubleshootingSpanSource, PolicyTroubleshootingSpanDestination): + def __init__(self): + PolicyTroubleshootingSpanSource.__init__(self) + PolicyTroubleshootingSpanDestination.__init__(self) diff --git a/lib/aci/policy/troubleshooting/span/source.py b/lib/aci/policy/troubleshooting/span/source.py new file mode 100644 index 00000000..08919fa0 --- /dev/null +++ b/lib/aci/policy/troubleshooting/span/source.py @@ -0,0 +1,19 @@ +class PolicyTroubleshootingSpanSource(): + def __init__(self): + pass + + def get_policy_troubleshooting_span_source_info(self, managed_object): + keys = [ + 'state', + 'tDn', + 'tRn' + ] + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/pool/__init__.py b/lib/aci/pool/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pool/__pycache__/__init__.cpython-310.pyc b/lib/aci/pool/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e8015277 Binary files /dev/null and b/lib/aci/pool/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pool/__pycache__/main.cpython-310.pyc b/lib/aci/pool/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6f57e7fc Binary files /dev/null and b/lib/aci/pool/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pool/__pycache__/output.cpython-310.pyc b/lib/aci/pool/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..d28573f1 Binary files /dev/null and b/lib/aci/pool/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pool/main.py b/lib/aci/pool/main.py new file mode 100644 index 00000000..7eaad6b5 --- /dev/null +++ b/lib/aci/pool/main.py @@ -0,0 +1,8 @@ +from lib.aci.pool.vlan.main import PoolVlan + + +class Pool( + PoolVlan + ): + def __init__(self): + PoolVlan.__init__(self) diff --git a/lib/aci/pool/output.py b/lib/aci/pool/output.py new file mode 100644 index 00000000..b573bde6 --- /dev/null +++ b/lib/aci/pool/output.py @@ -0,0 +1,6 @@ +from lib.aci.pool.vlan.output import PoolVlanOutput + + +class PoolOutput(PoolVlanOutput): + def __init__(self): + PoolVlanOutput.__init__(self) diff --git a/lib/aci/pool/vlan/__init__.py b/lib/aci/pool/vlan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pool/vlan/__pycache__/__init__.cpython-310.pyc b/lib/aci/pool/vlan/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0213b4bd Binary files /dev/null and b/lib/aci/pool/vlan/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/pool/vlan/__pycache__/api.cpython-310.pyc b/lib/aci/pool/vlan/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..ccff2808 Binary files /dev/null and b/lib/aci/pool/vlan/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/pool/vlan/__pycache__/info.cpython-310.pyc b/lib/aci/pool/vlan/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..9c2e7bdc Binary files /dev/null and b/lib/aci/pool/vlan/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/pool/vlan/__pycache__/main.cpython-310.pyc b/lib/aci/pool/vlan/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..83923da7 Binary files /dev/null and b/lib/aci/pool/vlan/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/pool/vlan/__pycache__/output.cpython-310.pyc b/lib/aci/pool/vlan/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..9fd3c90a Binary files /dev/null and b/lib/aci/pool/vlan/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/pool/vlan/api.py b/lib/aci/pool/vlan/api.py new file mode 100644 index 00000000..b2005450 --- /dev/null +++ b/lib/aci/pool/vlan/api.py @@ -0,0 +1,77 @@ +class PoolVlanApi(): + def __init__(self): + self.pool_vlan_mo = None + + def get_pool_vlan_block_attributes(self, managed_object): + attributes = [] + for child in managed_object['fvnsVlanInstP']['children']: + for key in child: + if key == 'fvnsEncapBlk': + attributes.append( + child['fvnsEncapBlk']['attributes'] + ) + return attributes + + def get_pool_vlan_domain_attributes(self, managed_object): + attributes = [] + for child in managed_object['fvnsVlanInstP']['children']: + for key in child: + if key == 'fvnsRtVlanNs': + attributes.append( + child['fvnsRtVlanNs']['attributes'] + ) + return attributes + + def get_pool_vlan_mo(self): + if self.pool_vlan_mo is not None: + return self.pool_vlan_mo + + cache = self.get_object_cache( + 'fvnsVlanInstP' + ) + if cache is not None: + self.pool_vlan_mo = cache + self.log.apic_mo( + 'fvnsVlanInstP', + self.pool_vlan_mo + ) + return self.pool_vlan_mo + + query = 'rsp-subtree=children&rsp-subtree-include=fault-count&rsp-subtree-class=fvnsEncapBlk,fvnsRtVlanNs' + managed_objects = self.get_class( + 'fvnsVlanInstP', + query=query + ) + + if managed_objects is None: + return None + + self.pool_vlan_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvnsVlanInstP']['attributes'] + attributes['fvnsEncapBlk'] = self.get_pool_vlan_block_attributes( + managed_object + ) + attributes['fvnsRtVlanNs'] = self.get_pool_vlan_domain_attributes( + managed_object + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'fvnsVlanInstP', + managed_object, + 'faultCounts' + ) + self.pool_vlan_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvnsVlanInstP', + self.pool_vlan_mo + ) + + self.set_object_cache( + 'fvnsVlanInstP', + self.pool_vlan_mo + ) + + return self.pool_vlan_mo diff --git a/lib/aci/pool/vlan/audit/__init__.py b/lib/aci/pool/vlan/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pool/vlan/audit/api.py b/lib/aci/pool/vlan/audit/api.py new file mode 100644 index 00000000..19ac9961 --- /dev/null +++ b/lib/aci/pool/vlan/audit/api.py @@ -0,0 +1,48 @@ +class PoolVlanAuditApi(): + def __init__(self): + self.pool_vlan_audit_mo = None + + def get_pool_vlan_audit_mo(self): + cache = self.get_object_cache( + 'fvnsVlanInstP.audit' + ) + if cache is not None: + self.pool_vlan_audit_mo = cache + self.log.apic_mo( + 'fvnsVlanInstP.audit', + self.pool_vlan_audit_mo + ) + return self.pool_vlan_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'fvnsVlanInstP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_pool_vlan_audit_mo', + 'API failed' + ) + return None + + self.pool_vlan_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.pool_vlan_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvnsVlanInstP.audit', + self.pool_vlan_audit_mo + ) + + self.set_object_cache( + 'fvnsVlanInstP.audit', + self.pool_vlan_audit_mo + ) + + return self.pool_vlan_audit_mo diff --git a/lib/aci/pool/vlan/audit/info.py b/lib/aci/pool/vlan/audit/info.py new file mode 100644 index 00000000..224af81d --- /dev/null +++ b/lib/aci/pool/vlan/audit/info.py @@ -0,0 +1,98 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PoolVlanAuditInfo(): + def __init__(self): + self.pool_vlan_audit = None + + def get_pool_vlan_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['poolName'] = None + + if 'uni/infra/vlanns-[' in info['affected']: + info['poolName'] = info['affected'].split('uni/infra/vlanns-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_pool_vlan_audit(self): + if self.pool_vlan_audit is not None: + return self.pool_vlan_audit + + managed_objects = self.get_pool_vlan_audit_mo() + if managed_objects is None: + return None + + self.pool_vlan_audit = [] + for managed_object in managed_objects: + audit_info = self.get_pool_vlan_audit_info( + managed_object + ) + self.pool_vlan_audit.append( + audit_info + ) + + self.log.apic_mo( + 'fvnsVlanInstP.auditRecord.info', + self.pool_vlan_audit + ) + + return self.pool_vlan_audit + + def get_pool_vlan_id_audit(self, pool_name, audit_filter=None): + audits = [] + + all_audits = self.get_pool_vlan_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['poolName'] is not None: + if audit_info['poolName'] == pool_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/pool/vlan/audit/main.py b/lib/aci/pool/vlan/audit/main.py new file mode 100644 index 00000000..c09e241f --- /dev/null +++ b/lib/aci/pool/vlan/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.pool.vlan.audit.api import PoolVlanAuditApi +from lib.aci.pool.vlan.audit.info import PoolVlanAuditInfo + + +class PoolVlanAudit(PoolVlanAuditApi, PoolVlanAuditInfo): + def __init__(self): + PoolVlanAuditApi.__init__(self) + PoolVlanAuditInfo.__init__(self) diff --git a/lib/aci/pool/vlan/event/__init__.py b/lib/aci/pool/vlan/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pool/vlan/event/api.py b/lib/aci/pool/vlan/event/api.py new file mode 100644 index 00000000..3c841ab1 --- /dev/null +++ b/lib/aci/pool/vlan/event/api.py @@ -0,0 +1,51 @@ +class PoolVlanEventApi(): + def __init__(self): + self.pool_vlan_event_mo = None + + def get_pool_vlan_event_mo(self): + if self.pool_vlan_event_mo is not None: + return self.pool_vlan_event_mo + + cache = self.get_object_cache( + 'fvnsVlanInstP.eventLog' + ) + if cache is not None: + self.pool_vlan_event_mo = cache + self.log.apic_mo( + 'fvnsVlanInstP.eventLog', + self.pool_vlan_event_mo + ) + return self.pool_vlan_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'fvnsVlanInstP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_pool_vlan_event_mo', + 'API failed' + ) + return None + + self.pool_vlan_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.pool_vlan_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvnsVlanInstP.eventLog', + self.pool_vlan_event_mo + ) + + self.set_object_cache( + 'fvnsVlanInstP.eventLog', + self.pool_vlan_event_mo + ) + + return self.pool_vlan_event_mo diff --git a/lib/aci/pool/vlan/event/info.py b/lib/aci/pool/vlan/event/info.py new file mode 100644 index 00000000..e0053762 --- /dev/null +++ b/lib/aci/pool/vlan/event/info.py @@ -0,0 +1,108 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PoolVlanEventInfo(): + def __init__(self): + self.pool_vlan_event = None + + def get_pool_vlan_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['poolName'] = None + + if 'affected' in info: + if 'uni/infra/vlanns-[' in info['affected']: + info['poolName'] = info['affected'].split('uni/infra/vlanns-[')[1].split(']')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/infra/vlanns-[' in info['dn']: + info['poolName'] = info['dn'].split('uni/infra/vlanns-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_pool_vlan_event(self, deduplicate=True): + if self.pool_vlan_event is not None: + return self.pool_vlan_event + + managed_objects = self.get_pool_vlan_event_mo() + if managed_objects is None: + return None + + self.pool_vlan_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_pool_vlan_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.pool_vlan_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'fvnsVlanInstP.eventLog.info', + self.pool_vlan_event + ) + + return self.pool_vlan_event + + def get_pool_vlan_id_event(self, pool_name, event_filter=None): + events = [] + + all_events = self.get_pool_vlan_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['poolName'] is not None: + if event_info['poolName'] == pool_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/pool/vlan/event/main.py b/lib/aci/pool/vlan/event/main.py new file mode 100644 index 00000000..f4b6eb14 --- /dev/null +++ b/lib/aci/pool/vlan/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.pool.vlan.event.api import PoolVlanEventApi +from lib.aci.pool.vlan.event.info import PoolVlanEventInfo + + +class PoolVlanEvent(PoolVlanEventApi, PoolVlanEventInfo): + def __init__(self): + PoolVlanEventApi.__init__(self) + PoolVlanEventInfo.__init__(self) diff --git a/lib/aci/pool/vlan/fault/__init__.py b/lib/aci/pool/vlan/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/pool/vlan/fault/api.py b/lib/aci/pool/vlan/fault/api.py new file mode 100644 index 00000000..c606a4b1 --- /dev/null +++ b/lib/aci/pool/vlan/fault/api.py @@ -0,0 +1,118 @@ +class PoolVlanFaultApi(): + def __init__(self): + self.pool_vlan_fault_mo = None + self.pool_vlan_fault_record_mo = None + + def get_pool_vlan_fault_mo(self): + cache = self.get_object_cache( + 'fvnsVlanInstP.fault' + ) + if cache is not None: + self.pool_vlan_fault_mo = cache + self.log.apic_mo( + 'fvnsVlanInstP.fault', + self.pool_vlan_fault_mo + ) + return self.pool_vlan_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'fvnsVlanInstP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_pool_vlan_fault_mo', + 'API failed' + ) + return None + + self.pool_vlan_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.pool_vlan_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.pool_vlan_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvnsVlanInstP.fault', + self.pool_vlan_fault_mo + ) + + self.set_object_cache( + 'fvnsVlanInstP.fault', + self.pool_vlan_fault_mo + ) + + return self.pool_vlan_fault_mo + + def get_pool_vlan_fault_record_mo(self): + cache = self.get_object_cache( + 'fvnsVlanInstP.faultRecord' + ) + if cache is not None: + self.pool_vlan_fault_record_mo = cache + self.log.apic_mo( + 'fvnsVlanInstP.faultRecord', + self.pool_vlan_fault_record_mo + ) + return self.pool_vlan_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'fvnsVlanInstP', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_pool_vlan_fault_record_mo', + 'API failed' + ) + return None + + self.pool_vlan_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.pool_vlan_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.pool_vlan_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvnsVlanInstP.faultRecord', + self.pool_vlan_fault_record_mo + ) + + self.set_object_cache( + 'fvnsVlanInstP.faultRecord', + self.pool_vlan_fault_record_mo + ) + + return self.pool_vlan_fault_record_mo diff --git a/lib/aci/pool/vlan/fault/info.py b/lib/aci/pool/vlan/fault/info.py new file mode 100644 index 00000000..3033e603 --- /dev/null +++ b/lib/aci/pool/vlan/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class PoolVlanFaultInfo(): + def __init__(self): + self.pool_vlan_fault = None + self.pool_vlan_fault_record = None + + def get_pool_vlan_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['poolName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/infra/vlanns-[' in info['affected']: + info['poolName'] = info['affected'].split('uni/infra/vlanns-[')[1].split(']')[0] + + if info['poolName'] is None: + if 'uni/infra/vlanns-[' in info['dn']: + info['poolName'] = info['dn'].split('uni/infra/vlanns-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_pool_vlan_fault(self): + if self.pool_vlan_fault is not None: + return self.pool_vlan_fault + + managed_objects = self.get_pool_vlan_fault_mo() + if managed_objects is None: + return None + + self.pool_vlan_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_pool_vlan_fault_info( + managed_object + ) + self.pool_vlan_fault.append( + fault_info + ) + + self.log.apic_mo( + 'fvnsVlanInstP.fault.info', + self.pool_vlan_fault + ) + + return self.pool_vlan_fault + + def get_pool_vlan_fault_record(self, deduplicate=True): + if self.pool_vlan_fault_record is not None: + return self.pool_vlan_fault_record + + managed_objects = self.get_pool_vlan_fault_record_mo() + if managed_objects is None: + return None + + self.pool_vlan_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_pool_vlan_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.pool_vlan_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'fvnsVlanInstP.faultRecord.info', + self.pool_vlan_fault_record + ) + + return self.pool_vlan_fault_record + + def get_pool_vlan_id_fault(self, pool_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_pool_vlan_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_pool_vlan_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['poolName'] is not None: + if fault_info['poolName'] == pool_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/pool/vlan/fault/main.py b/lib/aci/pool/vlan/fault/main.py new file mode 100644 index 00000000..8dd59a88 --- /dev/null +++ b/lib/aci/pool/vlan/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.pool.vlan.fault.api import PoolVlanFaultApi +from lib.aci.pool.vlan.fault.info import PoolVlanFaultInfo + + +class PoolVlanFault(PoolVlanFaultApi, PoolVlanFaultInfo): + def __init__(self): + PoolVlanFaultApi.__init__(self) + PoolVlanFaultInfo.__init__(self) diff --git a/lib/aci/pool/vlan/info.py b/lib/aci/pool/vlan/info.py new file mode 100644 index 00000000..95bd72d0 --- /dev/null +++ b/lib/aci/pool/vlan/info.py @@ -0,0 +1,284 @@ +from lib import filter_helper + + +class PoolVlanInfo(): + def __init__(self): + pass + + def get_pool_vlan_domain_info(self, managed_object): + keys = [ + 'dn', + 'tCl', + 'tDn' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['domainName'] = info['tDn'] + + if info['tCl'] == 'l2extDomP': + # "tDn": "uni/l2dom-Infra_L2dom" + info['domainName'] = info['tDn'].split('uni/l2dom-')[1] + + if info['tCl'] == 'l3extDomP': + # "tDn": "uni/l3dom-UCSB1_L3Dom" + info['domainName'] = info['tDn'].split('uni/l3dom-')[1] + + if info['tCl'] == 'physDomP': + # "tDn": "uni/phys-UCSB1_PhysDom" + info['domainName'] = info['tDn'].split('uni/phys-')[1] + + if info['tCl'] == 'vmmDomP': + # "tDn": "uni/vmmp-VMware/dom-EU-SPDC-R7DC" + info['domainName'] = info['tDn'].split('uni/vmmp-VMware/dom-')[1] + + return info + + def get_pool_vlan_block_info(self, managed_object, parent_alloc_mode): + keys = [ + 'allocMode', + 'descr', + 'dn', + 'from', + 'name', + 'rn', + 'role', + 'to' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['allocMode'] == 'inherit': + info['allocMode'] = parent_alloc_mode + + info['fromVlan'] = info['from'][5:] + info['toVlan'] = info['to'][5:] + info['blockInfo'] = '[%s-%s] (%s)' % ( + info['fromVlan'], + info['toVlan'], + info['allocMode'] + ) + + return info + + def get_pool_vlan_info(self, managed_object): + keys = [ + 'allocMode', + 'descr', + 'dn', + 'name' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['fvnsEncapBlk'] = [] + info['vlanCount'] = 0 + + domain_vmm_epg_filter = ['pool:%s' % (info['name'])] + for block_managed_object in managed_object['fvnsEncapBlk']: + block_info = self.get_pool_vlan_block_info( + block_managed_object, + info['allocMode'] + ) + + domain_vmm_epg_filter.append( + 'range:%s,%s' % ( + block_info['fromVlan'], + block_info['toVlan'] + ) + ) + + info['vlanCount'] = info['vlanCount'] + int(block_info['toVlan']) - int(block_info['fromVlan']) + 1 + + info['fvnsEncapBlk'].append( + block_info + ) + + info['fvnsEncapBlk'] = sorted( + info['fvnsEncapBlk'], + key=lambda i: int(i['fromVlan']) + ) + + info['fvnsRtVlanNs'] = [] + for domain_managed_object in managed_object['fvnsRtVlanNs']: + info['fvnsRtVlanNs'].append( + self.get_pool_vlan_domain_info( + domain_managed_object + ) + ) + info['fvnsRtVlanNs'] = sorted( + info['fvnsRtVlanNs'], + key=lambda i: i['domainName'].lower() + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def match_pool_vlan(self, pool_vlan_info, pool_vlan_filter): + if pool_vlan_filter is None or len(pool_vlan_filter) == 0: + return True + + for aepg_rule in pool_vlan_filter: + (key, value) = aepg_rule.split(':') + if key == 'name': + if not filter_helper.match_string(value, pool_vlan_info['name']): + return False + + if key == 'dn': + if not filter_helper.match_string(value, pool_vlan_info['dn']): + return False + + if key == 'vlan': + try: + vlan_id = int(value) + except BaseException: + return False + + found = False + for vlan_block_info in pool_vlan_info['fvnsEncapBlk']: + if int(vlan_block_info['fromVlan']) <= vlan_id <= int(vlan_block_info['toVlan']): + found = True + + if not found: + return False + + if key == 'domain': + found = False + for domain_info in pool_vlan_info['fvnsRtVlanNs']: + if filter_helper.match_string(value, domain_info['domainName']): + found = True + + if not found: + return False + + if key == 'fault': + if value == 'any': + if not pool_vlan_info['isAnyFault']: + return False + + return True + + def get_pool_vlans( + self, + pool_vlan_filter=None, + vlan_usage_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_pools = self.get_pool_vlan_mo() + if all_pools is None: + return None + + pool_vlans = [] + + for managed_object in all_pools: + pool_vlan_info = self.get_pool_vlan_info( + managed_object + ) + + if not self.match_pool_vlan(pool_vlan_info, pool_vlan_filter): + continue + + if vlan_usage_info: + domain_vmm_epg_filter = ['pool:%s' % (pool_vlan_info['name'])] + pool_vlan_info['epg'] = self.get_domain_vmm_epgs( + domain_vmm_epg_filter=domain_vmm_epg_filter + ) + + pool_vlan_info['epgCount'] = len( + pool_vlan_info['epg'] + ) + + pool_vlan_info['epgUsage'] = '%s/%s' % ( + pool_vlan_info['epgCount'], + pool_vlan_info['vlanCount'] + ) + + if fault_info: + pool_vlan_info['faultInst'] = self.get_pool_vlan_id_fault( + pool_vlan_info['name'], + 'faultInst' + ) + + if hfault_info: + pool_vlan_info['faultRecord'] = self.get_pool_vlan_id_fault( + pool_vlan_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + pool_vlan_info['eventLog'] = self.get_pool_vlan_id_event( + pool_vlan_info['name'], + event_filter=event_filter + ) + + if audit_info: + pool_vlan_info['auditLog'] = self.get_pool_vlan_id_audit( + pool_vlan_info['name'], + audit_filter=audit_filter + ) + + pool_vlans.append(pool_vlan_info) + + pool_vlans = sorted( + pool_vlans, + key=lambda i: i['name'].lower() + ) + + self.log.apic_mo( + 'fvnsVlanInstP.info', + pool_vlans + ) + + return pool_vlans + + def get_pool_vlan(self, pool_vlan_name, vlan_usage_info=False, domain_name=None): + pool_vlan_filter = ['name:%s' % (pool_vlan_name)] + if domain_name is not None: + pool_vlan_filter.append( + 'domain:%s' % (domain_name) + ) + + vlans = self.get_pool_vlans( + pool_vlan_filter=pool_vlan_filter, + vlan_usage_info=vlan_usage_info + ) + + if vlans is None or len(vlans) == 0: + return None + + if len(vlans) > 1: + return None + + return vlans[0] diff --git a/lib/aci/pool/vlan/main.py b/lib/aci/pool/vlan/main.py new file mode 100644 index 00000000..97348bd3 --- /dev/null +++ b/lib/aci/pool/vlan/main.py @@ -0,0 +1,20 @@ +from lib.aci.pool.vlan.api import PoolVlanApi +from lib.aci.pool.vlan.info import PoolVlanInfo +from lib.aci.pool.vlan.audit.main import PoolVlanAudit +from lib.aci.pool.vlan.event.main import PoolVlanEvent +from lib.aci.pool.vlan.fault.main import PoolVlanFault + + +class PoolVlan( + PoolVlanApi, + PoolVlanInfo, + PoolVlanAudit, + PoolVlanEvent, + PoolVlanFault + ): + def __init__(self): + PoolVlanApi.__init__(self) + PoolVlanInfo.__init__(self) + PoolVlanAudit.__init__(self) + PoolVlanEvent.__init__(self) + PoolVlanFault.__init__(self) diff --git a/lib/aci/pool/vlan/output.py b/lib/aci/pool/vlan/output.py new file mode 100644 index 00000000..b7a66497 --- /dev/null +++ b/lib/aci/pool/vlan/output.py @@ -0,0 +1,318 @@ +class PoolVlanOutput(): + def __init__(self): + pass + + def print_pool_vlans(self, info, title=False): + if title: + self.my_output.default( + 'Pool VLAN [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'faults', + 'name', + 'allocMode', + 'fvnsEncapBlk.blockInfo', + 'fvnsEncapBlk.role', + 'fvnsRtVlanNs.domainName', + 'epgUsage' + ] + + headers = [ + 'Faults', + 'VLAN Pool Name', + 'Allocation Mode', + 'Encapsulation Block', + 'Role', + 'Domain', + 'EPG Usage' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fvnsEncapBlk', 'fvnsRtVlanNs'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_pool_vlans_epg(self, info, title=False): + epg = [] + for item in info: + for epg_info in item['epg']: + epg_info['poolName'] = item['name'] + epg.append( + epg_info + ) + + epg = sorted( + epg, + key=lambda i: ( + i['poolName'], + i['tenantAppEpg'] + ) + ) + + if title: + self.my_output.default( + 'Pool VLAN - Associated EPG [#%s]' % (len(epg)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'poolName', + 'tenantAppEpg', + 'encapCtx', + 'allocMode', + 'vlanId', + 'instrImedcy', + 'resImedcy', + 'switchingMode' + ] + + headers = [ + 'Pool Name', + 'EPG', + 'VLAN Pool', + 'Alloc Mode', + 'VLAN', + 'Deployment', + 'Resolution', + 'Switching' + ] + + self.my_output.my_table( + epg, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_pool_vlans_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Pool VLAN - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Pool VLAN - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'poolName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_pool_vlans_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Pool VLAN - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'poolName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_pool_vlans_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Pool VLAN - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Pool VLAN - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'poolName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_pool_vlans_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Pool VLAN - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Pool VLAN - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'poolName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Name', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/__init__.py b/lib/aci/proto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d940449c Binary files /dev/null and b/lib/aci/proto/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/__pycache__/main.cpython-310.pyc b/lib/aci/proto/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f96dac4a Binary files /dev/null and b/lib/aci/proto/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/__pycache__/output.cpython-310.pyc b/lib/aci/proto/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..8fe740c6 Binary files /dev/null and b/lib/aci/proto/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/__init__.py b/lib/aci/proto/arp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/arp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/arp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..edb91740 Binary files /dev/null and b/lib/aci/proto/arp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/__pycache__/adjacency.cpython-310.pyc b/lib/aci/proto/arp/__pycache__/adjacency.cpython-310.pyc new file mode 100644 index 00000000..65e2f385 Binary files /dev/null and b/lib/aci/proto/arp/__pycache__/adjacency.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/arp/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..c86e9ab6 Binary files /dev/null and b/lib/aci/proto/arp/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/arp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e5aa38d5 Binary files /dev/null and b/lib/aci/proto/arp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/__pycache__/output.cpython-310.pyc b/lib/aci/proto/arp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..37fa0a4a Binary files /dev/null and b/lib/aci/proto/arp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/__pycache__/route.cpython-310.pyc b/lib/aci/proto/arp/__pycache__/route.cpython-310.pyc new file mode 100644 index 00000000..202d24a4 Binary files /dev/null and b/lib/aci/proto/arp/__pycache__/route.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/adjacency/__init__.py b/lib/aci/proto/arp/adjacency/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/arp/adjacency/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/arp/adjacency/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c1707033 Binary files /dev/null and b/lib/aci/proto/arp/adjacency/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/adjacency/__pycache__/api.cpython-310.pyc b/lib/aci/proto/arp/adjacency/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c2f15391 Binary files /dev/null and b/lib/aci/proto/arp/adjacency/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/adjacency/__pycache__/info.cpython-310.pyc b/lib/aci/proto/arp/adjacency/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..763a8731 Binary files /dev/null and b/lib/aci/proto/arp/adjacency/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/adjacency/__pycache__/main.cpython-310.pyc b/lib/aci/proto/arp/adjacency/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0369f1ea Binary files /dev/null and b/lib/aci/proto/arp/adjacency/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/adjacency/api.py b/lib/aci/proto/arp/adjacency/api.py new file mode 100644 index 00000000..b8430fe2 --- /dev/null +++ b/lib/aci/proto/arp/adjacency/api.py @@ -0,0 +1,53 @@ +class ProtocolArpAdjacencyApi(): + def __init__(self): + self.arp_adjacencies_mo = {} + + def get_protocol_arp_adjacencies_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.arp_adjacencies_mo: + return self.arp_adjacencies_mo[key] + + cache = self.get_object_cache( + 'arpAdjEp', + object_selector=key + ) + if cache is not None: + self.arp_adjacencies_mo[key] = cache + self.log.apic_mo( + 'arpAdjEp.%s' % (key), + self.arp_adjacencies_mo[key] + ) + return self.arp_adjacencies_mo[key] + + class_name = 'topology/pod-%s/node-%s/arpDom' % (pod_id, node_id) + query = 'query-target=subtree&target-subtree-class=arpAdjEp' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_arp_adjacencies_mo', + 'API failed' + ) + return None + + self.arp_adjacencies_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.arp_adjacencies_mo[key].append( + managed_object['arpAdjEp']['attributes'] + ) + + self.log.apic_mo( + 'arpAdjEp.%s' % (key), + self.arp_adjacencies_mo[key] + ) + + self.set_object_cache( + 'arpAdjEp', + self.arp_adjacencies_mo[key], + object_selector=key + ) + + return self.arp_adjacencies_mo[key] diff --git a/lib/aci/proto/arp/adjacency/info.py b/lib/aci/proto/arp/adjacency/info.py new file mode 100644 index 00000000..88a2d3f6 --- /dev/null +++ b/lib/aci/proto/arp/adjacency/info.py @@ -0,0 +1,101 @@ +from lib import filter_helper +from lib import ip_helper + + +class ProtocolArpAdjacencyInfo(): + def __init__(self): + self.arp_adjacencies = {} + + def get_protocol_arp_adjacency_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['domain_name'] = info['dn'].split('/')[6][4:] + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['physIfId'] == 'unspecified': + info['physIfId'] = '' + + info['__Output']['name'] = 'Yellow' + if info['operSt'] == 'normal': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_protocol_arp_adjacencies_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.arp_adjacencies: + return self.arp_adjacencies[key] + + arp_adjacencies_mo = self.get_protocol_arp_adjacencies_mo(pod_id, node_id) + if arp_adjacencies_mo is not None: + self.arp_adjacencies[key] = [] + for arp_adjacency_mo in arp_adjacencies_mo: + self.arp_adjacencies[key].append( + self.get_protocol_arp_adjacency_info( + arp_adjacency_mo + ) + ) + + self.log.apic_mo( + 'arpAdjEp.info.%s' % (key), + self.arp_adjacencies[key] + ) + + return self.arp_adjacencies[key] + + def match_protocol_arp_adjacency(self, arp_adjacency_info, arp_adjacency_filter): + if arp_adjacency_filter is None or len(arp_adjacency_filter) == 0: + return True + + for ap_rule in arp_adjacency_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + if key == 'name': + if not filter_helper.match_string(value, arp_adjacency_info['domain_name']): + return False + + if key == 'mac': + if not filter_helper.match_mac(value, arp_adjacency_info['mac']): + return False + + if key == 'ip': + if not filter_helper.match_string(value, arp_adjacency_info['ip']): + return False + + if key == 'subnet': + if not ip_helper.is_ipv4_in_cidr(arp_adjacency_info['ip'], value): + return False + + return True + + def get_protocol_arp_adjacencies(self, pod_id, node_id, arp_adjacency_filter=None): + all_arp_adjacencies = self.get_protocol_arp_adjacencies_info(pod_id, node_id) + if all_arp_adjacencies is None: + return None + + arp_adjacencies = [] + + for arp_adjacency_info in all_arp_adjacencies: + if not self.match_protocol_arp_adjacency(arp_adjacency_info, arp_adjacency_filter): + continue + + arp_adjacencies.append( + arp_adjacency_info + ) + + arp_adjacencies = sorted( + arp_adjacencies, + key=lambda i: i['mac'].lower() + ) + + return arp_adjacencies diff --git a/lib/aci/proto/arp/adjacency/main.py b/lib/aci/proto/arp/adjacency/main.py new file mode 100644 index 00000000..39e77e5a --- /dev/null +++ b/lib/aci/proto/arp/adjacency/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.arp.adjacency.api import ProtocolArpAdjacencyApi +from lib.aci.proto.arp.adjacency.info import ProtocolArpAdjacencyInfo + + +class ProtocolArpAdjacency(ProtocolArpAdjacencyApi, ProtocolArpAdjacencyInfo): + def __init__(self): + ProtocolArpAdjacencyApi.__init__(self) + ProtocolArpAdjacencyInfo.__init__(self) diff --git a/lib/aci/proto/arp/domain/__init__.py b/lib/aci/proto/arp/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/arp/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/arp/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7df3932d Binary files /dev/null and b/lib/aci/proto/arp/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/arp/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e410bba1 Binary files /dev/null and b/lib/aci/proto/arp/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/arp/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..04e8274f Binary files /dev/null and b/lib/aci/proto/arp/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/arp/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..03820bb8 Binary files /dev/null and b/lib/aci/proto/arp/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/arp/domain/api.py b/lib/aci/proto/arp/domain/api.py new file mode 100644 index 00000000..a9341460 --- /dev/null +++ b/lib/aci/proto/arp/domain/api.py @@ -0,0 +1,64 @@ +class ProtocolArpDomainApi(): + def __init__(self): + self.arp_domain_mo = {} + + def get_protocol_arp_domains_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.arp_domain_mo: + return self.arp_domain_mo[key] + + cache = self.get_object_cache( + 'arpDom', + object_selector=key + ) + if cache is not None: + self.arp_domain_mo[key] = cache + self.log.apic_mo( + 'arpDom.%s' % (key), + self.arp_domain_mo[key] + ) + return self.arp_domain_mo[key] + + class_name = 'topology/pod-%s/node-%s/arpDom' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_arp_domains_mo', + 'API failed' + ) + return None + + self.arp_domain_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['arpDom']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'arpDom', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'arpDom', + managed_object, + 'faultCounts' + ) + self.arp_domain_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'arpDom.%s' % (key), + self.arp_domain_mo[key] + ) + + self.set_object_cache( + 'arpDom', + self.arp_domain_mo[key], + object_selector=key + ) + + return self.arp_domain_mo[key] diff --git a/lib/aci/proto/arp/domain/info.py b/lib/aci/proto/arp/domain/info.py new file mode 100644 index 00000000..51a1c418 --- /dev/null +++ b/lib/aci/proto/arp/domain/info.py @@ -0,0 +1,143 @@ +from lib import filter_helper + + +class ProtocolArpDomainInfo(): + def __init__(self): + self.arp_domains = {} + + def get_protocol_arp_domains_interface_summary(self, domains): + interface = {} + + for domain in domains: + pod_node_name = domain['pod_node_name'] + if 'adjacency' in domain and domain['adjacency'] is not None: + for adjacency in domain['adjacency']: + if adjacency['ifId'] not in interface: + interface[adjacency['ifId']] = 0 + + interface[adjacency['ifId']] = interface[adjacency['ifId']] + 1 + + interface_list = [] + for intf in interface: + entry = {} + entry['pod_node_name'] = pod_node_name + entry['interface'] = intf + entry['count'] = interface[intf] + interface_list.append(entry) + + interface_list = sorted( + interface_list, + key=lambda i: ( + i['pod_node_name'], + i['interface'].lower() + ) + ) + return interface_list + + def get_protocol_arp_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['name'] = 'Yellow' + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_arp_domains_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.arp_domains: + return self.arp_domains[key] + + arp_domains_mo = self.get_protocol_arp_domains_mo(pod_id, node_id) + if arp_domains_mo is not None: + self.arp_domains[key] = [] + for arp_domain_mo in arp_domains_mo: + self.arp_domains[key].append( + self.get_protocol_arp_domain_info( + arp_domain_mo + ) + ) + + return self.arp_domains[key] + + def match_protocol_arp_domain(self, arp_domain_info, arp_domain_filter): + if arp_domain_filter is None or len(arp_domain_filter) == 0: + return True + + for ap_rule in arp_domain_filter: + (key, value) = ap_rule.split(':') + if key == 'name': + if not filter_helper.match_string(value, arp_domain_info['name']): + return False + + return True + + def get_protocol_arp_adjacency_filter(self, arp_domain_info, arp_domain_filter): + if arp_domain_filter is None: + return None + + arp_adjacency_filter = ['name:%s' % (arp_domain_info['name'])] + for rule in arp_domain_filter: + if rule.split(':')[0] == 'name': + continue + + arp_adjacency_filter.append( + rule + ) + + return arp_adjacency_filter + + def get_protocol_arp_domains(self, pod_id, node_id, arp_domain_filter=None, adjacency_info=False): + all_arp_domains = self.get_protocol_arp_domains_info(pod_id, node_id) + if all_arp_domains is None: + return None + + arp_domains = [] + + for arp_domain_info in all_arp_domains: + if not self.match_protocol_arp_domain(arp_domain_info, arp_domain_filter): + continue + + if adjacency_info: + arp_domain_info['adjacency'] = self.get_protocol_arp_adjacencies( + pod_id, + node_id, + arp_adjacency_filter=self.get_protocol_arp_adjacency_filter( + arp_domain_info, + arp_domain_filter + ) + ) + + arp_domain_info['adjacency_count'] = 0 + if arp_domain_info['adjacency'] is not None: + arp_domain_info['adjacency_count'] = len(arp_domain_info['adjacency']) + + arp_domains.append( + arp_domain_info + ) + + arp_domains = sorted( + arp_domains, + key=lambda i: i['name'].lower() + ) + + return arp_domains diff --git a/lib/aci/proto/arp/domain/main.py b/lib/aci/proto/arp/domain/main.py new file mode 100644 index 00000000..7c0a7473 --- /dev/null +++ b/lib/aci/proto/arp/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.arp.domain.api import ProtocolArpDomainApi +from lib.aci.proto.arp.domain.info import ProtocolArpDomainInfo + + +class ProtocolArpDomain(ProtocolArpDomainApi, ProtocolArpDomainInfo): + def __init__(self): + ProtocolArpDomainApi.__init__(self) + ProtocolArpDomainInfo.__init__(self) diff --git a/lib/aci/proto/arp/event/__init__.py b/lib/aci/proto/arp/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/arp/event/api.py b/lib/aci/proto/arp/event/api.py new file mode 100644 index 00000000..5491afab --- /dev/null +++ b/lib/aci/proto/arp/event/api.py @@ -0,0 +1,55 @@ +class ProtocolArpEventApi(): + def __init__(self): + self.proto_arp_event_mo = {} + + def get_protocol_arp_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_arp_event_mo: + return self.proto_arp_event_mo[key] + + cache = self.get_object_cache( + 'arpDom.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_arp_event_mo[key] = cache + self.log.apic_mo( + 'arpDom.eventLog.%s' % (key), + self.proto_arp_event_mo[key] + ) + return self.proto_arp_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/arp' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_arp_event_mo', + 'API failed' + ) + return None + + self.proto_arp_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_arp_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'arpDom.eventLog.%s' % (key), + self.proto_arp_event_mo[key] + ) + + self.set_object_cache( + 'arpDom.eventLog', + self.proto_arp_event_mo[key], + object_selector=key + ) + + return self.proto_arp_event_mo[key] diff --git a/lib/aci/proto/arp/event/info.py b/lib/aci/proto/arp/event/info.py new file mode 100644 index 00000000..bda3e342 --- /dev/null +++ b/lib/aci/proto/arp/event/info.py @@ -0,0 +1,83 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolArpEventInfo(): + def __init__(self): + self.proto_arp_event = {} + + def get_protocol_arp_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/arp/inst + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_arp_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_arp_event: + return self.proto_arp_event[key] + + managed_objects = self.get_protocol_arp_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_arp_event[key] = [] + for managed_object in managed_objects: + self.proto_arp_event[key].append( + self.get_protocol_arp_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'arpDom.eventLog.info.%s' % (key), + self.proto_arp_event[key] + ) + + return self.proto_arp_event[key] diff --git a/lib/aci/proto/arp/event/main.py b/lib/aci/proto/arp/event/main.py new file mode 100644 index 00000000..efc2de91 --- /dev/null +++ b/lib/aci/proto/arp/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.arp.event.api import ProtocolArpEventApi +from lib.aci.proto.arp.event.info import ProtocolArpEventInfo + + +class ProtocolArpEvent(ProtocolArpEventApi, ProtocolArpEventInfo): + def __init__(self): + ProtocolArpEventApi.__init__(self) + ProtocolArpEventInfo.__init__(self) diff --git a/lib/aci/proto/arp/fault/__init__.py b/lib/aci/proto/arp/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/arp/fault/api.py b/lib/aci/proto/arp/fault/api.py new file mode 100644 index 00000000..68333be4 --- /dev/null +++ b/lib/aci/proto/arp/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolArpFaultApi(): + def __init__(self): + self.proto_arp_fault_mo = {} + self.proto_arp_fault_record_mo = {} + + def get_protocol_arp_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_arp_fault_mo: + return self.proto_arp_fault_mo[key] + + cache = self.get_object_cache( + 'arpDom.fault', + object_selector=key + ) + if cache is not None: + self.proto_arp_fault_mo[key] = cache + self.log.apic_mo( + 'arpDom.fault.%s' % (key), + self.proto_arp_fault_mo[key] + ) + return self.proto_arp_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/arp' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_arp_fault_mo', + 'API failed' + ) + return None + + self.proto_arp_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_arp_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'arpDom.fault.%s' % (key), + self.proto_arp_fault_mo[key] + ) + + self.set_object_cache( + 'arpDom.fault', + self.proto_arp_fault_mo[key], + object_selector=key + ) + + return self.proto_arp_fault_mo[key] + + def get_protocol_arp_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_arp_fault_record_mo: + return self.proto_arp_fault_record_mo[key] + + cache = self.get_object_cache( + 'arpDom.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_arp_fault_record_mo[key] = cache + self.log.apic_mo( + 'arpDom.faultRecord.%s' % (key), + self.proto_arp_fault_record_mo[key] + ) + return self.proto_arp_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/arp' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_arp_fault_record_mo', + 'API failed' + ) + return None + + self.proto_arp_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_arp_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'arpDom.faultRecord.%s' % (key), + self.proto_arp_fault_record_mo[key] + ) + + self.set_object_cache( + 'arpDom.faultRecord', + self.proto_arp_fault_record_mo[key], + object_selector=key + ) + + return self.proto_arp_fault_record_mo[key] diff --git a/lib/aci/proto/arp/fault/info.py b/lib/aci/proto/arp/fault/info.py new file mode 100644 index 00000000..cd8809ac --- /dev/null +++ b/lib/aci/proto/arp/fault/info.py @@ -0,0 +1,69 @@ +class ProtocolArpFaultInfo(): + def __init__(self): + self.proto_arp_fault = {} + self.proto_arp_fault_record = {} + + def get_protocol_arp_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_arp_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_arp_fault: + return self.proto_arp_fault[key] + + managed_objects = self.get_protocol_arp_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_arp_fault[key] = [] + for managed_object in managed_objects: + self.proto_arp_fault[key].append( + self.get_protocol_arp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'arpDom.fault.info.%s' % (key), + self.proto_arp_fault[key] + ) + + return self.proto_arp_fault[key] + + def get_protocol_arp_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_arp_fault_record: + return self.proto_arp_fault_record[key] + + managed_objects = self.get_protocol_arp_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_arp_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_arp_fault_record[key].append( + self.get_protocol_arp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'arpDom.faultRecord.info.%s' % (key), + self.proto_arp_fault_record[key] + ) + + return self.proto_arp_fault_record[key] diff --git a/lib/aci/proto/arp/fault/main.py b/lib/aci/proto/arp/fault/main.py new file mode 100644 index 00000000..d57cde04 --- /dev/null +++ b/lib/aci/proto/arp/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.arp.fault.api import ProtocolArpFaultApi +from lib.aci.proto.arp.fault.info import ProtocolArpFaultInfo + + +class ProtocolArpFault(ProtocolArpFaultApi, ProtocolArpFaultInfo): + def __init__(self): + ProtocolArpFaultApi.__init__(self) + ProtocolArpFaultInfo.__init__(self) diff --git a/lib/aci/proto/arp/instance/__init__.py b/lib/aci/proto/arp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/arp/instance/api.py b/lib/aci/proto/arp/instance/api.py new file mode 100644 index 00000000..5827e368 --- /dev/null +++ b/lib/aci/proto/arp/instance/api.py @@ -0,0 +1,71 @@ +class ProtocolArpInstanceApi(): + def __init__(self): + self.arp_instance_mo = {} + + def get_protocol_arp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.arp_instance_mo: + return self.arp_instance_mo[key] + + cache = self.get_object_cache( + 'arpInst', + object_selector=key + ) + if cache is not None: + self.arp_instance_mo[key] = cache + self.log.apic_mo( + 'arpInst.%s' % (key), + self.arp_instance_mo[key] + ) + return self.arp_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/arp' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_arp_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_arp_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.arp_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['arpInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'arpInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'arpInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.arp_instance_mo[key] = attributes + + self.log.apic_mo( + 'arpInst.%s' % (key), + self.arp_instance_mo[key] + ) + + self.set_object_cache( + 'arpInst', + self.arp_instance_mo[key], + object_selector=key + ) + + return self.arp_instance_mo[key] diff --git a/lib/aci/proto/arp/instance/info.py b/lib/aci/proto/arp/instance/info.py new file mode 100644 index 00000000..0e1fe515 --- /dev/null +++ b/lib/aci/proto/arp/instance/info.py @@ -0,0 +1,44 @@ +class ProtocolArpInstanceInfo(): + def __init__(self): + pass + + def get_protocol_arp_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_arp_instance(self, pod_id, node_id): + managed_object = self.get_protocol_arp_instance_mo(pod_id, node_id) + if managed_object is None: + return None + + return self.get_protocol_arp_instance_info(managed_object) diff --git a/lib/aci/proto/arp/instance/main.py b/lib/aci/proto/arp/instance/main.py new file mode 100644 index 00000000..dfaa1c01 --- /dev/null +++ b/lib/aci/proto/arp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.arp.instance.api import ProtocolArpInstanceApi +from lib.aci.proto.arp.instance.info import ProtocolArpInstanceInfo + + +class ProtocolArpInstance(ProtocolArpInstanceApi, ProtocolArpInstanceInfo): + def __init__(self): + ProtocolArpInstanceApi.__init__(self) + ProtocolArpInstanceInfo.__init__(self) diff --git a/lib/aci/proto/arp/main.py b/lib/aci/proto/arp/main.py new file mode 100644 index 00000000..e7583deb --- /dev/null +++ b/lib/aci/proto/arp/main.py @@ -0,0 +1,97 @@ +from lib.aci.proto.arp.instance.main import ProtocolArpInstance +from lib.aci.proto.arp.domain.main import ProtocolArpDomain +from lib.aci.proto.arp.adjacency.main import ProtocolArpAdjacency +from lib.aci.proto.arp.event.main import ProtocolArpEvent +from lib.aci.proto.arp.fault.main import ProtocolArpFault + + +class ProtocolArp( + ProtocolArpInstance, + ProtocolArpDomain, + ProtocolArpAdjacency, + ProtocolArpEvent, + ProtocolArpFault + ): + def __init__(self): + ProtocolArpInstance.__init__(self) + ProtocolArpDomain.__init__(self) + ProtocolArpAdjacency.__init__(self) + ProtocolArpEvent.__init__(self) + ProtocolArpFault.__init__(self) + + def get_protocol_arp( + self, + pod_id, + node_id, + arp_domain_filter=None, + instance_info=False, + domain_info=False, + adjacency_info=False, + interface_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_arp_instance( + pod_id, + node_id + ) + + if domain_info: + info['domain'] = self.get_protocol_arp_domains( + pod_id, + node_id, + arp_domain_filter=arp_domain_filter, + adjacency_info=adjacency_info + ) + + if adjacency_info: + info['adjacency'] = [] + for domain in info['domain']: + info['adjacency'] = info['adjacency'] + domain['adjacency'] + + if interface_info: + info['interface'] = self.get_protocol_arp_domains_interface_summary( + info['domain'] + ) + + if fault_info: + info['faultInst'] = self.get_protocol_arp_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_arp_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_arp_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/arp/output.py b/lib/aci/proto/arp/output.py new file mode 100644 index 00000000..53cb93ff --- /dev/null +++ b/lib/aci/proto/arp/output.py @@ -0,0 +1,315 @@ +class ProtocolArpOutput(): + def __init__(self): + pass + + def print_proto_arp_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ARP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'adminSt', + 'health', + 'faults' + ] + + headers = [ + 'Node', + 'Admin State', + 'Health', + 'Faults' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_arp_domains(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ARP - Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'name', + 'health', + 'faults', + 'adjacency_count' + ] + + headers = [ + 'Node', + 'VRF', + 'Health', + 'Faults', + 'Adjacency' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_arp_interface_summary(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ARP - Interface Adjacency Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interface', + 'count' + ] + + headers = [ + 'Node', + 'Interface', + 'Adjacency' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_arp_adjacencies(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ARP - Adjacency [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain_name', + 'mac', + 'ip', + 'operSt', + 'ifId', + 'physIfId', + 'upTS' + ] + + headers = [ + 'Node', + 'VRF', + 'MAC', + 'IP', + 'State', + 'Interface', + 'Phy Interface', + 'Timestamp' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_arp_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ARP - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_arp_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol ARP - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol ARP - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_arp_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol ARP - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol ARP - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/bfd/TODO.md b/lib/aci/proto/bfd/TODO.md new file mode 100644 index 00000000..d10b3559 --- /dev/null +++ b/lib/aci/proto/bfd/TODO.md @@ -0,0 +1,11 @@ +# BFD + +how to show/use sessions apps +bgp view? +bfd session timers follow policy... how to get the policy name? +when showing instances, indicate the node role and maybe version as there are bfd deps +c-bit awareness +resolve ip to names (?) +interface context +ease of going from vlan intf to phy interface(s) +where bfd is configured \ No newline at end of file diff --git a/lib/aci/proto/bfd/__init__.py b/lib/aci/proto/bfd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..792cf9ad Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..e177898a Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/interface.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..3245855e Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..fce8cf59 Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/output.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..1869d73f Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/session.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/session.cpython-310.pyc new file mode 100644 index 00000000..a61ac007 Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/session.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/session_peer.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/session_peer.cpython-310.pyc new file mode 100644 index 00000000..7f06d989 Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/session_peer.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/__pycache__/session_stats.cpython-310.pyc b/lib/aci/proto/bfd/__pycache__/session_stats.cpython-310.pyc new file mode 100644 index 00000000..2122dac4 Binary files /dev/null and b/lib/aci/proto/bfd/__pycache__/session_stats.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/event/__init__.py b/lib/aci/proto/bfd/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/event/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/event/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..85471a97 Binary files /dev/null and b/lib/aci/proto/bfd/event/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/event/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/event/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..fbcbe9c4 Binary files /dev/null and b/lib/aci/proto/bfd/event/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/event/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/event/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..d8716cb5 Binary files /dev/null and b/lib/aci/proto/bfd/event/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/event/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/event/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a9d20d9f Binary files /dev/null and b/lib/aci/proto/bfd/event/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/event/api.py b/lib/aci/proto/bfd/event/api.py new file mode 100644 index 00000000..2cc047ef --- /dev/null +++ b/lib/aci/proto/bfd/event/api.py @@ -0,0 +1,55 @@ +class ProtocolBfdEventApi(): + def __init__(self): + self.bfd_event_mo = {} + + def get_protocol_bfd_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_event_mo: + return self.bfd_event_mo[key] + + cache = self.get_object_cache( + 'bfdInst.eventLog', + object_selector=key + ) + if cache is not None: + self.bfd_event_mo[key] = cache + self.log.apic_mo( + 'bfdInst.eventLog.%s' % (key), + self.bfd_event_mo[key] + ) + return self.bfd_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_event_mo', + 'API failed' + ) + return None + + self.bfd_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.bfd_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bfdInst.eventLog.%s' % (key), + self.bfd_event_mo[key] + ) + + self.set_object_cache( + 'bfdInst.eventLog', + self.bfd_event_mo[key], + object_selector=key + ) + + return self.bfd_event_mo[key] diff --git a/lib/aci/proto/bfd/event/info.py b/lib/aci/proto/bfd/event/info.py new file mode 100644 index 00000000..11ccca48 --- /dev/null +++ b/lib/aci/proto/bfd/event/info.py @@ -0,0 +1,108 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolBfdEventInfo(): + def __init__(self): + self.bfd_event = {} + + def get_protocol_bfd_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/bfd/inst/session-1090519092" + info['session_id'] = None + if len(info['affected'].split('/')) == 7: + if info['affected'].split('/')[6].startswith('session-'): + info['session_id'] = info['affected'].split('/')[6].split('-')[1] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_bfd_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_event: + return self.bfd_event[key] + + managed_objects = self.get_protocol_bfd_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.bfd_event[key] = [] + for managed_object in managed_objects: + self.bfd_event[key].append( + self.get_protocol_bfd_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'bfdInst.eventRecord.info.%s' % (key), + self.bfd_event[key] + ) + + return self.bfd_event[key] + + def get_protocol_bfd_session_event(self, pod_id, node_id, session_id, event_filter=None): + events = [] + + all_events = self.get_protocol_bfd_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['session_id'] is not None: + if event_info['session_id'] == session_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/proto/bfd/event/main.py b/lib/aci/proto/bfd/event/main.py new file mode 100644 index 00000000..6058552a --- /dev/null +++ b/lib/aci/proto/bfd/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bfd.event.api import ProtocolBfdEventApi +from lib.aci.proto.bfd.event.info import ProtocolBfdEventInfo + + +class ProtocolBfdEvent(ProtocolBfdEventApi, ProtocolBfdEventInfo): + def __init__(self): + ProtocolBfdEventApi.__init__(self) + ProtocolBfdEventInfo.__init__(self) diff --git a/lib/aci/proto/bfd/fault/__init__.py b/lib/aci/proto/bfd/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/fault/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/fault/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..85471a97 Binary files /dev/null and b/lib/aci/proto/bfd/fault/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/fault/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/fault/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e6712b08 Binary files /dev/null and b/lib/aci/proto/bfd/fault/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/fault/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/fault/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b2ec418b Binary files /dev/null and b/lib/aci/proto/bfd/fault/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/fault/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/fault/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..86ed52a4 Binary files /dev/null and b/lib/aci/proto/bfd/fault/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/fault/api.py b/lib/aci/proto/bfd/fault/api.py new file mode 100644 index 00000000..928a6285 --- /dev/null +++ b/lib/aci/proto/bfd/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolBfdFaultApi(): + def __init__(self): + self.bfd_fault_mo = {} + self.bfd_fault_record_mo = {} + + def get_protocol_bfd_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_fault_mo: + return self.bfd_fault_mo[key] + + cache = self.get_object_cache( + 'bfdInst.fault', + object_selector=key + ) + if cache is not None: + self.bfd_fault_mo[key] = cache + self.log.apic_mo( + 'bfdInst.fault.%s' % (key), + self.bfd_fault_mo[key] + ) + return self.bfd_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_fault_mo', + 'API failed' + ) + return None + + self.bfd_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.bfd_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bfdInst.fault.%s' % (key), + self.bfd_fault_mo[key] + ) + + self.set_object_cache( + 'bfdInst.fault', + self.bfd_fault_mo[key], + object_selector=key + ) + + return self.bfd_fault_mo[key] + + def get_protocol_bfd_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_fault_record_mo: + return self.bfd_fault_record_mo[key] + + cache = self.get_object_cache( + 'bfdInst.faultRecord', + object_selector=key + ) + if cache is not None: + self.bfd_fault_record_mo[key] = cache + self.log.apic_mo( + 'bfdInst.faultRecord.%s' % (key), + self.bfd_fault_record_mo[key] + ) + return self.bfd_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_fault_record_mo', + 'API failed' + ) + return None + + self.bfd_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.bfd_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bfdInst.faultRecord.%s' % (key), + self.bfd_fault_record_mo[key] + ) + + self.set_object_cache( + 'bfdInst.faultRecord', + self.bfd_fault_record_mo[key], + object_selector=key + ) + + return self.bfd_fault_record_mo[key] diff --git a/lib/aci/proto/bfd/fault/info.py b/lib/aci/proto/bfd/fault/info.py new file mode 100644 index 00000000..5f6f6ddf --- /dev/null +++ b/lib/aci/proto/bfd/fault/info.py @@ -0,0 +1,111 @@ +class ProtocolBfdFaultInfo(): + def __init__(self): + self.bfd_fault = {} + self.bfd_fault_record = {} + + def get_protocol_bfd_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/bfd/inst/session-1090519092" + info['session_id'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if len(info['affected'].split('/')) == 7: + if info['affected'].split('/')[6].startswith('session-'): + info['session_id'] = info['affected'].split('/')[6].split('-')[1] + + if info['session_id'] is None: + if info['dn'].split('/')[6].startswith('session-'): + info['session_id'] = info['dn'].split('/')[6].split('-')[1] + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_bfd_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_fault: + return self.bfd_fault[key] + + managed_objects = self.get_protocol_bfd_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.bfd_fault[key] = [] + for managed_object in managed_objects: + self.bfd_fault[key].append( + self.get_protocol_bfd_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'bfdInst.fault.info.%s' % (key), + self.bfd_fault[key] + ) + + return self.bfd_fault[key] + + def get_protocol_bfd_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_fault_record: + return self.bfd_fault_record[key] + + managed_objects = self.get_protocol_bfd_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.bfd_fault_record[key] = [] + for managed_object in managed_objects: + self.bfd_fault_record[key].append( + self.get_protocol_bfd_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'bfdInst.faultRecord.info.%s' % (key), + self.bfd_fault_record[key] + ) + + return self.bfd_fault_record[key] + + def get_protocol_bfd_session_fault(self, pod_id, node_id, session_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_protocol_bfd_fault(pod_id, node_id) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_protocol_bfd_fault_record(pod_id, node_id) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['session_id'] is not None: + if fault_info['session_id'] == session_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/proto/bfd/fault/main.py b/lib/aci/proto/bfd/fault/main.py new file mode 100644 index 00000000..b740a004 --- /dev/null +++ b/lib/aci/proto/bfd/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bfd.fault.api import ProtocolBfdFaultApi +from lib.aci.proto.bfd.fault.info import ProtocolBfdFaultInfo + + +class ProtocolBfdFault(ProtocolBfdFaultApi, ProtocolBfdFaultInfo): + def __init__(self): + ProtocolBfdFaultApi.__init__(self) + ProtocolBfdFaultInfo.__init__(self) diff --git a/lib/aci/proto/bfd/instance/__init__.py b/lib/aci/proto/bfd/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..85471a97 Binary files /dev/null and b/lib/aci/proto/bfd/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3dc13631 Binary files /dev/null and b/lib/aci/proto/bfd/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1f7b95b8 Binary files /dev/null and b/lib/aci/proto/bfd/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..338b5094 Binary files /dev/null and b/lib/aci/proto/bfd/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/instance/api.py b/lib/aci/proto/bfd/instance/api.py new file mode 100644 index 00000000..ac94b0d6 --- /dev/null +++ b/lib/aci/proto/bfd/instance/api.py @@ -0,0 +1,70 @@ +class ProtocolBfdInstanceApi(): + def __init__(self): + self.bfd_instance_mo = {} + + def get_protocol_bfd_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_instance_mo: + return self.bfd_instance_mo[key] + + cache = self.get_object_cache( + 'bfdInst', + object_selector=key + ) + if cache is not None: + self.bfd_instance_mo[key] = cache + self.log.apic_mo( + 'bfdInst.%s' % (key), + self.bfd_instance_mo[key] + ) + return self.bfd_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_bfd_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.bfd_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['bfdInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'bfdInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'bfdInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.bfd_instance_mo[key] = attributes + + self.log.apic_mo( + 'bfdInst.%s' % (key), + self.bfd_instance_mo[key] + ) + + self.set_object_cache( + 'bfdInst', + self.bfd_instance_mo[key], + object_selector=key + ) + + return self.bfd_instance_mo[key] diff --git a/lib/aci/proto/bfd/instance/info.py b/lib/aci/proto/bfd/instance/info.py new file mode 100644 index 00000000..09744cbd --- /dev/null +++ b/lib/aci/proto/bfd/instance/info.py @@ -0,0 +1,54 @@ +class ProtocolBfdInstanceInfo(): + def __init__(self): + self.bfd_instance = {} + + def get_protocol_bfd_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key in ['healthInst']: + continue + + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_bfd_instance(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_instance: + return self.bfd_instance[key] + + managed_object = self.get_protocol_bfd_instance_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + self.bfd_instance[key] = self.get_protocol_bfd_instance_info( + managed_object + ) + + self.log.apic_mo( + 'bfd.instance.info.%s' % (key), + self.bfd_instance[key] + ) + + return self.bfd_instance[key] diff --git a/lib/aci/proto/bfd/instance/main.py b/lib/aci/proto/bfd/instance/main.py new file mode 100644 index 00000000..c4e42147 --- /dev/null +++ b/lib/aci/proto/bfd/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bfd.instance.api import ProtocolBfdInstanceApi +from lib.aci.proto.bfd.instance.info import ProtocolBfdInstanceInfo + + +class ProtocolBfdInstance(ProtocolBfdInstanceApi, ProtocolBfdInstanceInfo): + def __init__(self): + ProtocolBfdInstanceApi.__init__(self) + ProtocolBfdInstanceInfo.__init__(self) diff --git a/lib/aci/proto/bfd/interface/__init__.py b/lib/aci/proto/bfd/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9a49fcb3 Binary files /dev/null and b/lib/aci/proto/bfd/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/interface/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/interface/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..cb5a8eef Binary files /dev/null and b/lib/aci/proto/bfd/interface/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/interface/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/interface/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..2572b0d6 Binary files /dev/null and b/lib/aci/proto/bfd/interface/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/interface/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1ddc0495 Binary files /dev/null and b/lib/aci/proto/bfd/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/interface/api.py b/lib/aci/proto/bfd/interface/api.py new file mode 100644 index 00000000..ea78dd65 --- /dev/null +++ b/lib/aci/proto/bfd/interface/api.py @@ -0,0 +1,86 @@ +class ProtocolBfdInterfaceApi(): + def __init__(self): + self.bfd_interfaces_mo = {} + + def set_protocol_bfd_interface_mo(self, managed_object): + # "dn": "topology/pod-1/node-2208/sys/bfd/inst/if-[vlan27]" + + interface_dn = managed_object['bfdIf']['attributes']['dn'] + pod_id = interface_dn.split('/')[1][4:] + node_id = interface_dn.split('/')[2][5:] + key = '%s.%s' % (pod_id, node_id) + + if key not in self.bfd_interfaces_mo: + self.bfd_interfaces_mo[key] = [] + + self.bfd_interfaces_mo[key].append( + managed_object['bfdIf']['attributes'] + ) + + def set_protocol_bfd_interface_log(self, key): + if key not in self.bfd_interfaces_mo: + return False + + self.log.apic_mo( + 'bfdIf.%s' % (key), + self.bfd_interfaces_mo[key] + ) + + self.set_object_cache( + 'bfdIf', + self.bfd_interfaces_mo[key], + object_selector=key + ) + + return True + + def get_protocol_bfd_interfaces_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_interfaces_mo: + return self.bfd_interfaces_mo[key] + + cache = self.get_object_cache( + 'bfdIf', + object_selector=key + ) + if cache is not None: + self.bfd_interfaces_mo[key] = cache + self.log.apic_mo( + 'bfdIf.%s' % (key), + self.bfd_interfaces_mo[key] + ) + return self.bfd_interfaces_mo[key] + + # url: https:///api/node/mo/topology/pod-1/node-201/sys/bfd/inst.json?query-target=children&target-subtree-class=bfdIf&subscription=yes + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst' % (pod_id, node_id) + query = 'query-target=children&target-subtree-class=bfdIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_interfaces_mo', + 'API failed' + ) + return None + + self.bfd_interfaces_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.bfd_interfaces_mo[key].append( + managed_object['bfdIf']['attributes'] + ) + + self.log.apic_mo( + 'bfdIf.%s' % (key), + self.bfd_interfaces_mo[key] + ) + + self.set_object_cache( + 'bfdIf', + self.bfd_interfaces_mo[key], + object_selector=key + ) + + return self.bfd_interfaces_mo[key] diff --git a/lib/aci/proto/bfd/interface/info.py b/lib/aci/proto/bfd/interface/info.py new file mode 100644 index 00000000..aea783b7 --- /dev/null +++ b/lib/aci/proto/bfd/interface/info.py @@ -0,0 +1,123 @@ +import copy + + +class ProtocolBfdInterfaceInfo(): + def __init__(self): + self.bfd_interfaces = {} + + def add_protocol_bfd_interface_session_info(self, interfaces, sessions, remove_no_sessions=False): + for interface in interfaces: + interface['sessionUp'] = 0 + interface['sessionCount'] = 0 + + for session in sessions: + if session['ifId'] == interface['id']: + if session['up']: + interface['sessionUp'] = interface['sessionUp'] + 1 + interface['sessionCount'] = interface['sessionCount'] + 1 + + interface['sessionSummary'] = '%s/%s' % ( + interface['sessionUp'], + interface['sessionCount'] + ) + + if interface['sessionUp'] == interface['sessionCount']: + interface['__Output']['sessionSummary'] = 'Green' + else: + interface['__Output']['sessionSummary'] = 'Red' + + if remove_no_sessions: + new_interfaces = [] + for interface in interfaces: + if interface['sessionCount'] > 0: + new_interfaces.append( + interface + ) + + interfaces = copy.deepcopy(new_interfaces) + + return interfaces + + def get_protocol_bfd_interface_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['id'] = 'Yellow' + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_protocol_bfd_interfaces_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_interfaces: + return self.bfd_interfaces[key] + + bfd_interfaces_mo = self.get_protocol_bfd_interfaces_mo(pod_id, node_id) + if bfd_interfaces_mo is not None: + self.bfd_interfaces[key] = [] + for bfd_interface_mo in bfd_interfaces_mo: + self.bfd_interfaces[key].append( + self.get_protocol_bfd_interface_info( + bfd_interface_mo + ) + ) + + self.log.apic_mo( + 'bfd.interface.info.%s' % (key), + self.bfd_interfaces[key] + ) + + return self.bfd_interfaces[key] + + def match_protocol_bfd_interface(self, bfd_interface_info, bfd_interface_filter): + if bfd_interface_filter is None or len(bfd_interface_filter) == 0: + return True + + for ap_rule in bfd_interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + # if key == 'name': + # if not filter_helper.match_string(value, bfd_interface_info['domain_name']): + # return False + + # if key == 'mac': + # if not filter_helper.match_mac(value, bfd_interface_info['mac']): + # return False + + # if key == 'ip': + # if not filter_helper.match_string(value, bfd_interface_info['ip']): + # return False + + # if key == 'subnet': + # if not ip_helper.is_ipv4_in_cidr(bfd_interface_info['ip'], value): + # return False + + return True + + def get_protocol_bfd_interfaces(self, pod_id, node_id, bfd_interface_filter=None): + all_bfd_interfaces = self.get_protocol_bfd_interfaces_info(pod_id, node_id) + if all_bfd_interfaces is None: + return None + + bfd_interfaces = [] + + for bfd_interface_info in all_bfd_interfaces: + if not self.match_protocol_bfd_interface(bfd_interface_info, bfd_interface_filter): + continue + + bfd_interfaces.append( + bfd_interface_info + ) + + bfd_interfaces = sorted( + bfd_interfaces, + key=lambda i: i['id'] + ) + + return bfd_interfaces diff --git a/lib/aci/proto/bfd/interface/main.py b/lib/aci/proto/bfd/interface/main.py new file mode 100644 index 00000000..1698e48e --- /dev/null +++ b/lib/aci/proto/bfd/interface/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bfd.interface.api import ProtocolBfdInterfaceApi +from lib.aci.proto.bfd.interface.info import ProtocolBfdInterfaceInfo + + +class ProtocolBfdInterface(ProtocolBfdInterfaceApi, ProtocolBfdInterfaceInfo): + def __init__(self): + ProtocolBfdInterfaceApi.__init__(self) + ProtocolBfdInterfaceInfo.__init__(self) diff --git a/lib/aci/proto/bfd/main.py b/lib/aci/proto/bfd/main.py new file mode 100644 index 00000000..174ae30c --- /dev/null +++ b/lib/aci/proto/bfd/main.py @@ -0,0 +1,116 @@ +from lib.aci.proto.bfd.event.main import ProtocolBfdEvent +from lib.aci.proto.bfd.fault.main import ProtocolBfdFault +from lib.aci.proto.bfd.instance.main import ProtocolBfdInstance +from lib.aci.proto.bfd.interface.main import ProtocolBfdInterface +from lib.aci.proto.bfd.session.main import ProtocolBfdSession + + +class ProtocolBfd(ProtocolBfdEvent, ProtocolBfdFault, ProtocolBfdInstance, ProtocolBfdInterface, ProtocolBfdSession): + def __init__(self): + ProtocolBfdEvent.__init__(self) + ProtocolBfdFault.__init__(self) + ProtocolBfdInstance.__init__(self) + ProtocolBfdInterface.__init__(self) + ProtocolBfdSession.__init__(self) + + def get_protocol_bfd( + self, + pod_id, + node_id, + bfd_filter=None, + instance_info=False, + session_info=False, + interface_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + info['node'] = self.get_node( + pod_id=pod_id, + node_id=node_id + ) + + if instance_info: + info['instance'] = self.get_protocol_bfd_instance( + pod_id=pod_id, + node_id=node_id + ) + + if session_info: + info['sessions'] = self.get_protocol_bfd_sessions( + pod_id, + node_id, + bfd_session_filter=bfd_filter + ) + + if instance_info: + sessions_up = self.get_protocol_bfd_sessions_up_count(info['sessions']) + sessions_count = len(info['sessions']) + info['instance']['sessionSummary'] = '%s/%s' % ( + sessions_up, + sessions_count + ) + + if sessions_up == sessions_count: + info['instance']['__Output']['sessionSummary'] = 'Green' + else: + info['instance']['__Output']['sessionSummary'] = 'Red' + + if interface_info: + info['interfaces'] = self.get_protocol_bfd_interfaces( + pod_id, + node_id + ) + + if session_info: + info['interfaces'] = self.add_protocol_bfd_interface_session_info( + info['interfaces'], + info['sessions'], + remove_no_sessions=True + ) + + if fault_info: + info['faultInst'] = self.get_protocol_bfd_fault( + pod_id, + node_id + ) + for session in info['sessions']: + session['faultInst'] = self.get_protocol_bfd_session_fault( + pod_id, + node_id, + session['session_id'], + 'faultInst' + ) + + if hfault_info: + info['faultRecord'] = self.get_protocol_bfd_fault_record( + pod_id, + node_id + ) + for session in info['sessions']: + session['faultRecord'] = self.get_protocol_bfd_session_fault( + pod_id, + node_id, + session['session_id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + info['eventLog'] = self.get_protocol_bfd_event( + pod_id, + node_id + ) + for session in info['sessions']: + session['eventLog'] = self.get_protocol_bfd_session_event( + pod_id, + node_id, + session['session_id'], + event_filter=event_filter + ) + + return info diff --git a/lib/aci/proto/bfd/output.py b/lib/aci/proto/bfd/output.py new file mode 100644 index 00000000..a191bc3d --- /dev/null +++ b/lib/aci/proto/bfd/output.py @@ -0,0 +1,510 @@ +class ProtocolBfdOutput(): + def __init__(self): + pass + + def print_proto_bfd_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BFD - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'instance.pod_node_name', + 'node.roleUi', + 'node.model', + 'instance.adminSt', + 'instance.health', + 'instance.faults', + 'instance.echoIf', + 'instance.sessionSummary', + 'interfaces.id', + 'interfaces.adminSt', + 'interfaces.sessionSummary' + ] + + headers = [ + 'Node', + 'Role', + 'HW', + 'Admin', + 'Health', + 'Faults', + 'Echo Intf', + 'Sessions', + 'Intf', + 'State', + 'Sessions' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interfaces'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bfd_sessions(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BFD - Session [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'health', + 'faults', + 'vrfName', + 'ifId', + 'sessionType', + 'srcAddr', + 'localMac', + 'operSt', + 'discr', + 'destAddr', + 'remoteMac', + 'remoteOperSt', + 'remoteDiscr', + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'VRF', + 'Interface', + 'Type', + 'Local Address', + 'Local MAC', + 'State', + 'Session Id', + 'Remote Address', + 'Remote MAC', + 'State', + 'Session Id' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bfd_sessions_stats(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BFD - Session Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'vrfName', + 'srcAddr', + 'destAddr', + 'stats.upCnt', + 'stats.downCnt', + 'stats.rxCnt', + 'rxIntvl', + 'stats.rxMin', + 'stats.rxAvg', + 'stats.rxMax', + 'stats.txCnt', + 'txIntvl', + 'stats.txMin', + 'stats.txAvg', + 'stats.txMax' + ] + + headers = [ + 'Node', + 'VRF', + 'Local Address', + 'Remote Address', + 'Up', + 'Down', + 'Rx Cnt', + 'Rx Interval [msec]', + 'Min', + 'Avg', + 'Max', + 'Tx Cnt', + 'Tx Interval [msec]', + 'Min', + 'Avg', + 'Max' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bfd_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol BFD - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol BFD - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'session_id', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Session Id', + 'Severity', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bfd_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BFD - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'session_id', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Session Id', + 'Severity', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bfd_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol BFD - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol BFD - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'session_id', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Session Id', + 'Severity', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bfd_session(self, info, when=None): + order = [ + 'pod_node_name', + 'health', + 'faults', + 'srcAddr', + 'operSt', + 'discr', + 'localMac', + 'destAddr', + 'remoteOperSt', + 'remoteDiscr', + 'remoteMac', + 'vrfName', + 'ifId', + 'sessionType', + 'iod', + 'lastDownTime', + 'lastTransTime', + 'lastDiag', + 'authSeqno', + 'asyncPort', + 'diag', + 'detectMult', + 'localDetectMult', + 'rxIntvl', + 'txIntvl', + 'slowIntvl', + 'localRxIntvl', + 'localTxIntvl', + 'echoPort', + 'echoTxIntvl' + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'Local Address', + 'Local State', + 'Local Session Id', + 'Local MAC', + 'Remote Address', + 'Remote State', + 'Remote Session Id', + 'Remote MAC', + 'VRF', + 'Interface', + 'Session Type', + 'IOD', + 'Last Down Time', + 'Last Trans Time', + 'Last Diag Code', + 'Authentication Sequence Number', + 'Async mode source port', + 'Protocol diag code', + 'Detect Multiplier', + 'Local Detect Multiplier', + 'Active Receive Interval (msec)', + 'Active Transmit Interval (msec)', + 'Active Slow Interval (msec)', + 'Local Receive Interval (msec)', + 'Local Transmit Interval (msec)', + 'Echo mode source port', + 'Active Echo Transmit Interval (msec)' + ] + + self.my_output.dictionary( + info, + title='Protocol BFD - Session', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + self.print_proto_bfd_session_peer(info['peer']) + self.print_proto_bfd_session_stats(info['stats']) + self.print_proto_bfd_event_logs( + info['eventLog'], + when=when, + title=True + ) + self.print_proto_bfd_fault_inst( + info['faultInst'], + title=True + ) + self.print_proto_bfd_fault_record( + info['faultRecord'], + when=when, + title=True + ) + + def print_proto_bfd_session_peer(self, info): + order = [ + 'operSt', + 'diag', + 'flags', + 'minRx', + 'minRx', + 'minTx', + 'minEcho', + 'myDisc', + 'yourDisc', + 'CBit' + ] + + headers = [ + 'Oper State', + 'Diag Code', + 'BFD Flags', + 'Detect Multiplier', + 'Min Receive Interval (msec)', + 'Min Transmit Interval (msec)', + 'Min Echo Interval (msec)', + 'My discriminator', + 'Your discriminator', + 'C-Bit' + ] + + self.my_output.dictionary( + info, + title='Protocol BFD - Peer', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_proto_bfd_session_stats(self, info): + order = [ + 'upCnt', + 'downCnt', + 'lastRxPkt', + 'lastTxPkt', + 'rxCnt', + 'rxAvg', + 'rxMax', + 'rxMin', + 'txCnt', + 'txAvg', + 'txMax', + 'txMin' + ] + + headers = [ + 'Up State Counts', + 'Down State Counts', + 'Last packet received', + 'Last packet transmitted', + 'Packets Received', + 'Average Received Packets Interval', + 'Maximum Received Packets Interval', + 'Minimum Received Packets Interval', + 'Packets Transmitted', + 'Average Transmitted Packets Interval', + 'Maximum Transmitted Packets Interval', + 'Minimum Transmitted Packets Interval' + ] + + self.my_output.dictionary( + info, + title='Protocol BFD - Session Stats', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/aci/proto/bfd/session/__init__.py b/lib/aci/proto/bfd/session/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/session/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/session/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..db9d28d3 Binary files /dev/null and b/lib/aci/proto/bfd/session/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/session/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..72e2072f Binary files /dev/null and b/lib/aci/proto/bfd/session/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/session/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..77696431 Binary files /dev/null and b/lib/aci/proto/bfd/session/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/session/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3de75bf6 Binary files /dev/null and b/lib/aci/proto/bfd/session/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/api.py b/lib/aci/proto/bfd/session/api.py new file mode 100644 index 00000000..f8205c4c --- /dev/null +++ b/lib/aci/proto/bfd/session/api.py @@ -0,0 +1,84 @@ +class ProtocolBfdSessionApi(): + def __init__(self): + self.bfd_sessions_mo = {} + + def get_protocol_bfd_sessions_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_sessions_mo: + return self.bfd_sessions_mo[key] + + cache = self.get_object_cache( + 'bfdSess', + object_selector=key + ) + if cache is not None: + self.bfd_sessions_mo[key] = cache + self.log.apic_mo( + 'bfdSess.%s' % (key), + self.bfd_sessions_mo[key] + ) + return self.bfd_sessions_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst' % (pod_id, node_id) + query = 'query-target=subtree&target-subtree-class=bfdSess,bfdSessStats,bfdPeerV,bfdIf&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_sessions_mo', + 'API failed' + ) + return None + + self.bfd_sessions_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'bfdSess' in managed_object: + attributes = managed_object['bfdSess']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'bfdSess', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'bfdSess', + managed_object, + 'faultCounts' + ) + self.bfd_sessions_mo[key].append( + attributes + ) + + if 'bfdSessStats' in managed_object: + self.set_protocol_bfd_session_stats_mo( + managed_object + ) + + if 'bfdPeerV' in managed_object: + self.set_protocol_bfd_session_peer_mo( + managed_object + ) + + if 'bfdIf' in managed_object: + self.set_protocol_bfd_interface_mo( + managed_object + ) + + self.set_protocol_bfd_interface_log( + key + ) + + self.log.apic_mo( + 'bfdSess.%s' % (key), + self.bfd_sessions_mo[key] + ) + + self.set_object_cache( + 'bfdSess', + self.bfd_sessions_mo[key], + object_selector=key + ) + + return self.bfd_sessions_mo[key] diff --git a/lib/aci/proto/bfd/session/info.py b/lib/aci/proto/bfd/session/info.py new file mode 100644 index 00000000..a8f59fcc --- /dev/null +++ b/lib/aci/proto/bfd/session/info.py @@ -0,0 +1,157 @@ +from lib import filter_helper +from lib import ip_helper + + +class ProtocolBfdSessionInfo(): + def __init__(self): + self.bfd_sessions = {} + + def get_protocol_bfd_sessions_up_count(self, sessions): + sessions_up = 0 + for session in sessions: + if session['up']: + sessions_up = sessions_up + 1 + return sessions_up + + def get_protocol_bfd_session_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key in ['healthInst']: + continue + + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "dn": "topology/pod-1/node-2208/sys/bfd/inst/session-1090519058" + info['session_id'] = None + if len(info['dn'].split('/')) == 7: + if info['dn'].split('/')[6].startswith('session-'): + info['session_id'] = info['dn'].split('/')[6].split('-')[1] + + info['__Output']['discr'] = 'Yellow' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + if info['remoteOperSt'] == 'up': + info['__Output']['remoteOperSt'] = 'Green' + else: + info['__Output']['remoteOperSt'] = 'Red' + + info['up'] = False + if info['operSt'] == 'up' and info['remoteOperSt'] == 'up': + info['up'] = True + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_bfd_sessions_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bfd_sessions: + return self.bfd_sessions[key] + + bfd_sessions_mo = self.get_protocol_bfd_sessions_mo(pod_id, node_id) + if bfd_sessions_mo is not None: + self.bfd_sessions[key] = [] + for bfd_session_mo in bfd_sessions_mo: + self.bfd_sessions[key].append( + self.get_protocol_bfd_session_info( + bfd_session_mo + ) + ) + + self.log.apic_mo( + 'bfd.sessions.info.%s' % (key), + self.bfd_sessions[key] + ) + + return self.bfd_sessions[key] + + def match_protocol_bfd_session(self, bfd_session_info, bfd_session_filter): + if bfd_session_filter is None or len(bfd_session_filter) == 0: + return True + + for ap_rule in bfd_session_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + if key == 'session_id': + if not filter_helper.match_string(value, bfd_session_info['discr']) and not filter_helper.match_string(value, bfd_session_info['remoteDiscr']): + return False + + if key == 'interface_id': + if not filter_helper.match_string(value, bfd_session_info['ifId']): + return False + + if key == 'session_state': + if value != 'any': + if not filter_helper.match_string(value, bfd_session_info['operSt']) and not filter_helper.match_string(value, bfd_session_info['remoteOperSt']): + return False + + if key == 'vrf': + if not filter_helper.match_string(value, bfd_session_info['vrfName']): + return False + + if key == 'ip': + if not filter_helper.match_string(value, bfd_session_info['destAddr']) and not filter_helper.match_string(value, bfd_session_info['srcAddr']): + return False + + if key == 'subnet': + if not ip_helper.is_ipv4_in_cidr(bfd_session_info['destAddr'], value) and not ip_helper.is_ipv4_in_cidr(bfd_session_info['srcAddr'], value): + return False + + return True + + def get_protocol_bfd_sessions(self, pod_id, node_id, bfd_session_filter=None): + all_bfd_sessions = self.get_protocol_bfd_sessions_info(pod_id, node_id) + if all_bfd_sessions is None: + return None + + bfd_sessions = [] + + for bfd_session_info in all_bfd_sessions: + if not self.match_protocol_bfd_session(bfd_session_info, bfd_session_filter): + continue + + bfd_session_info['stats'] = self.get_protocol_bfd_session_stats( + pod_id, + node_id, + bfd_session_info['discr'] + ) + + bfd_session_info['peer'] = None + if bfd_session_info['up']: + bfd_session_info['peer'] = self.get_protocol_bfd_session_peer( + pod_id, + node_id, + bfd_session_info['discr'] + ) + + bfd_sessions.append( + bfd_session_info + ) + + bfd_sessions = sorted( + bfd_sessions, + key=lambda i: ( + i['srcAddr'].lower(), + i['destAddr'].lower() + ) + ) + + return bfd_sessions diff --git a/lib/aci/proto/bfd/session/main.py b/lib/aci/proto/bfd/session/main.py new file mode 100644 index 00000000..032369b5 --- /dev/null +++ b/lib/aci/proto/bfd/session/main.py @@ -0,0 +1,12 @@ +from lib.aci.proto.bfd.session.api import ProtocolBfdSessionApi +from lib.aci.proto.bfd.session.info import ProtocolBfdSessionInfo +from lib.aci.proto.bfd.session.stats.main import ProtocolBfdSessionStats +from lib.aci.proto.bfd.session.peer.main import ProtocolBfdSessionPeer + + +class ProtocolBfdSession(ProtocolBfdSessionApi, ProtocolBfdSessionInfo, ProtocolBfdSessionStats, ProtocolBfdSessionPeer): + def __init__(self): + ProtocolBfdSessionApi.__init__(self) + ProtocolBfdSessionInfo.__init__(self) + ProtocolBfdSessionStats.__init__(self) + ProtocolBfdSessionPeer.__init__(self) diff --git a/lib/aci/proto/bfd/session/peer/__init__.py b/lib/aci/proto/bfd/session/peer/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/session/peer/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/session/peer/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2ce4f841 Binary files /dev/null and b/lib/aci/proto/bfd/session/peer/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/peer/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/session/peer/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..dad75e80 Binary files /dev/null and b/lib/aci/proto/bfd/session/peer/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/peer/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/session/peer/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..4dcc951f Binary files /dev/null and b/lib/aci/proto/bfd/session/peer/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/peer/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/session/peer/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9755603a Binary files /dev/null and b/lib/aci/proto/bfd/session/peer/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/peer/api.py b/lib/aci/proto/bfd/session/peer/api.py new file mode 100644 index 00000000..9cd6fa6b --- /dev/null +++ b/lib/aci/proto/bfd/session/peer/api.py @@ -0,0 +1,79 @@ +class ProtocolBfdSessionPeerApi(): + def __init__(self): + self.bfd_session_peer_mo = {} + + def set_protocol_bfd_session_peer_mo(self, managed_object): + # "dn": "topology/pod-1/node-2208/sys/bfd/inst/session-1090519051/peerv" + + stats_dn = managed_object['bfdPeerV']['attributes']['dn'] + pod_id = stats_dn.split('/')[1][4:] + node_id = stats_dn.split('/')[2][5:] + session_id = stats_dn.split('/')[6][8:] + key = '%s.%s.%s' % (pod_id, node_id, session_id) + + self.bfd_session_peer_mo[key] = managed_object['bfdPeerV']['attributes'] + + self.log.apic_mo( + 'bfdPeerV.%s' % (key), + self.bfd_session_peer_mo[key] + ) + + self.set_object_cache( + 'bfdPeerV', + self.bfd_session_peer_mo[key], + object_selector=key + ) + + def get_protocol_bfd_session_peer_mo(self, pod_id, node_id, session_id): + key = '%s.%s.%s' % (pod_id, node_id, session_id) + if key in self.bfd_session_peer_mo: + return self.bfd_session_peer_mo[key] + + cache = self.get_object_cache( + 'bfdPeerV', + object_selector=key + ) + if cache is not None: + self.bfd_session_peer_mo[key] = cache + self.log.apic_mo( + 'bfdPeerV.%s' % (key), + self.bfd_session_peer_mo[key] + ) + return self.bfd_session_peer_mo[key] + + # url: https:///api/node/mo/topology/pod-1/node-201/sys/bfd/inst/session-1090519172.json?query-target=children&target-subtree-class=bfdPeerV&subscription=yes + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst/session-%s' % (pod_id, node_id, session_id) + query = 'query-target=children&target-subtree-class=bfdPeerV' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_session_peer_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_protocol_bfd_session_peer_mo', + 'Unexpected objects count' + ) + return None + + self.bfd_session_peer_mo[key] = managed_objects['imdata'][0]['bfdPeerV']['attributes'] + + self.log.apic_mo( + 'bfdPeerV.%s' % (key), + self.bfd_session_peer_mo[key] + ) + + self.set_object_cache( + 'bfdPeerV', + self.bfd_session_peer_mo[key], + object_selector=key + ) + + return self.bfd_session_peer_mo[key] diff --git a/lib/aci/proto/bfd/session/peer/info.py b/lib/aci/proto/bfd/session/peer/info.py new file mode 100644 index 00000000..5ff1c2f4 --- /dev/null +++ b/lib/aci/proto/bfd/session/peer/info.py @@ -0,0 +1,23 @@ +class ProtocolBfdSessionPeerInfo(): + def __init__(self): + pass + + def get_protocol_bfd_session_peer_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_protocol_bfd_session_peer(self, pod_id, node_id, session_id): + managed_object = self.get_protocol_bfd_session_peer_mo(pod_id, node_id, session_id) + if managed_object is None: + return None + + return self.get_protocol_bfd_session_peer_info(managed_object) diff --git a/lib/aci/proto/bfd/session/peer/main.py b/lib/aci/proto/bfd/session/peer/main.py new file mode 100644 index 00000000..3f16c5ea --- /dev/null +++ b/lib/aci/proto/bfd/session/peer/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bfd.session.peer.api import ProtocolBfdSessionPeerApi +from lib.aci.proto.bfd.session.peer.info import ProtocolBfdSessionPeerInfo + + +class ProtocolBfdSessionPeer(ProtocolBfdSessionPeerApi, ProtocolBfdSessionPeerInfo): + def __init__(self): + ProtocolBfdSessionPeerApi.__init__(self) + ProtocolBfdSessionPeerInfo.__init__(self) diff --git a/lib/aci/proto/bfd/session/stats/__init__.py b/lib/aci/proto/bfd/session/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bfd/session/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bfd/session/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..42c06244 Binary files /dev/null and b/lib/aci/proto/bfd/session/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/stats/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bfd/session/stats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..9b870589 Binary files /dev/null and b/lib/aci/proto/bfd/session/stats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/stats/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bfd/session/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..4c299ccb Binary files /dev/null and b/lib/aci/proto/bfd/session/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/stats/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bfd/session/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..eaab1c2c Binary files /dev/null and b/lib/aci/proto/bfd/session/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bfd/session/stats/api.py b/lib/aci/proto/bfd/session/stats/api.py new file mode 100644 index 00000000..105555df --- /dev/null +++ b/lib/aci/proto/bfd/session/stats/api.py @@ -0,0 +1,79 @@ +class ProtocolBfdSessionStatsApi(): + def __init__(self): + self.bfd_session_stats_mo = {} + + def set_protocol_bfd_session_stats_mo(self, managed_object): + # "dn": "topology/pod-1/node-2208/sys/bfd/inst/session-1090519041/stats" + + stats_dn = managed_object['bfdSessStats']['attributes']['dn'] + pod_id = stats_dn.split('/')[1][4:] + node_id = stats_dn.split('/')[2][5:] + session_id = stats_dn.split('/')[6][8:] + key = '%s.%s.%s' % (pod_id, node_id, session_id) + + self.bfd_session_stats_mo[key] = managed_object['bfdSessStats']['attributes'] + + self.log.apic_mo( + 'bfdSessStats.%s' % (key), + self.bfd_session_stats_mo[key] + ) + + self.set_object_cache( + 'bfdSessStats', + self.bfd_session_stats_mo[key], + object_selector=key + ) + + def get_protocol_bfd_session_stats_mo(self, pod_id, node_id, session_id): + key = '%s.%s.%s' % (pod_id, node_id, session_id) + if key in self.bfd_session_stats_mo: + return self.bfd_session_stats_mo[key] + + cache = self.get_object_cache( + 'bfdSessStats', + object_selector=key + ) + if cache is not None: + self.bfd_session_stats_mo[key] = cache + self.log.apic_mo( + 'bfdSessStats.%s' % (key), + self.bfd_session_stats_mo[key] + ) + return self.bfd_session_stats_mo[key] + + # url: https:///api/node/mo/topology/pod-1/node-201/sys/bfd/inst/session-1090519172.json?query-target=children&target-subtree-class=bfdPeerV&subscription=yes + distinguished_name = 'topology/pod-%s/node-%s/sys/bfd/inst/session-%s' % (pod_id, node_id, session_id) + query = 'query-target=children&target-subtree-class=bfdSessStats' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bfd_session_stats', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_protocol_bfd_session_stats', + 'Unexpected objects count' + ) + return None + + self.bfd_session_stats_mo[key] = managed_objects['imdata'][0]['bfdSessStats']['attributes'] + + self.log.apic_mo( + 'bfdSessStats.%s' % (key), + self.bfd_session_stats_mo[key] + ) + + self.set_object_cache( + 'bfdSessStats', + self.bfd_session_stats_mo[key], + object_selector=key + ) + + return self.bfd_session_stats_mo[key] diff --git a/lib/aci/proto/bfd/session/stats/info.py b/lib/aci/proto/bfd/session/stats/info.py new file mode 100644 index 00000000..b07745a0 --- /dev/null +++ b/lib/aci/proto/bfd/session/stats/info.py @@ -0,0 +1,18 @@ +class ProtocolBfdSessionStatsInfo(): + def __init__(self): + pass + + def get_protocol_bfd_session_stats_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_protocol_bfd_session_stats(self, pod_id, node_id, session_id): + managed_object = self.get_protocol_bfd_session_stats_mo(pod_id, node_id, session_id) + if managed_object is None: + return None + + return self.get_protocol_bfd_session_stats_info(managed_object) diff --git a/lib/aci/proto/bfd/session/stats/main.py b/lib/aci/proto/bfd/session/stats/main.py new file mode 100644 index 00000000..3d683a66 --- /dev/null +++ b/lib/aci/proto/bfd/session/stats/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bfd.session.stats.api import ProtocolBfdSessionStatsApi +from lib.aci.proto.bfd.session.stats.info import ProtocolBfdSessionStatsInfo + + +class ProtocolBfdSessionStats(ProtocolBfdSessionStatsApi, ProtocolBfdSessionStatsInfo): + def __init__(self): + ProtocolBfdSessionStatsApi.__init__(self) + ProtocolBfdSessionStatsInfo.__init__(self) diff --git a/lib/aci/proto/bgp/__init__.py b/lib/aci/proto/bgp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9d77cde0 Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..93d6122b Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..97fb25d2 Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c5256241 Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/neighbor.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/neighbor.cpython-310.pyc new file mode 100644 index 00000000..305db985 Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/neighbor.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/neighbor_stats.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/neighbor_stats.cpython-310.pyc new file mode 100644 index 00000000..29bbc31f Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/neighbor_stats.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/output.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..f6d42c08 Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/__pycache__/route.cpython-310.pyc b/lib/aci/proto/bgp/__pycache__/route.cpython-310.pyc new file mode 100644 index 00000000..71444e36 Binary files /dev/null and b/lib/aci/proto/bgp/__pycache__/route.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/domain/__init__.py b/lib/aci/proto/bgp/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bgp/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3f1d4f9d Binary files /dev/null and b/lib/aci/proto/bgp/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bgp/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..1f5e0814 Binary files /dev/null and b/lib/aci/proto/bgp/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bgp/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..7e38fc9a Binary files /dev/null and b/lib/aci/proto/bgp/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bgp/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d867fa77 Binary files /dev/null and b/lib/aci/proto/bgp/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/domain/api.py b/lib/aci/proto/bgp/domain/api.py new file mode 100644 index 00000000..67603323 --- /dev/null +++ b/lib/aci/proto/bgp/domain/api.py @@ -0,0 +1,64 @@ +class ProtocolBgpDomainApi(): + def __init__(self): + self.bgp_domains_mo = {} + + def get_protocol_bgp_domains_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bgp_domains_mo: + return self.bgp_domains_mo[key] + + cache = self.get_object_cache( + 'bgpDom', + object_selector=key + ) + if cache is not None: + self.bgp_domains_mo[key] = cache + self.log.apic_mo( + 'bgpDom.%s' % (key), + self.bgp_domains_mo[key] + ) + return self.bgp_domains_mo[key] + + class_name = 'topology/pod-%s/node-%s/bgpDom' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_domains_mo', + 'API failed' + ) + return None + + self.bgp_domains_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['bgpDom']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'bgpDom', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'bgpDom', + managed_object, + 'faultCounts' + ) + self.bgp_domains_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bgpDom.%s' % (key), + self.bgp_domains_mo[key] + ) + + self.set_object_cache( + 'bgpDom', + self.bgp_domains_mo[key], + object_selector=key + ) + + return self.bgp_domains_mo[key] diff --git a/lib/aci/proto/bgp/domain/info.py b/lib/aci/proto/bgp/domain/info.py new file mode 100644 index 00000000..712b6b16 --- /dev/null +++ b/lib/aci/proto/bgp/domain/info.py @@ -0,0 +1,112 @@ +from lib import filter_helper + + +class ProtocolBgpDomainInfo(): + def __init__(self): + self.bgp_domains = {} + + def get_protocol_bgp_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['__Output']['name'] = 'Yellow' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + if info['numPeers'] == '0': + info['isPeer'] = False + else: + info['isPeer'] = True + info['__Output']['numPeers'] = 'Blue' + + info['peerSummary'] = '%s/%s' % ( + info['numEstPeers'], + info['numPeers'] + ) + + if info['numEstPeers'] != '0': + if info['numPeers'] == info['numEstPeers']: + info['__Output']['peerSummary'] = 'Green' + info['__Output']['numEstPeers'] = 'Green' + else: + info['__Output']['peerSummary'] = 'Red' + info['__Output']['numEstPeers'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_bgp_domains_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bgp_domains: + return self.bgp_domains[key] + + bgp_domains_mo = self.get_protocol_bgp_domains_mo(pod_id, node_id) + if bgp_domains_mo is not None: + self.bgp_domains[key] = [] + for bgp_domain_mo in bgp_domains_mo: + self.bgp_domains[key].append( + self.get_protocol_bgp_domain_info( + bgp_domain_mo + ) + ) + + return self.bgp_domains[key] + + def match_protocol_bgp_domain(self, bgp_domain_info, bgp_domain_filter): + if bgp_domain_filter is None or len(bgp_domain_filter) == 0: + return True + + for ap_rule in bgp_domain_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'vrf': + if not filter_helper.match_string(value, bgp_domain_info['name']): + return False + + return True + + def get_protocol_bgp_domains(self, pod_id, node_id, bgp_domain_filter=None): + all_bgp_domains = self.get_protocol_bgp_domains_info(pod_id, node_id) + if all_bgp_domains is None: + return None + + bgp_domains = [] + + for bgp_domain_info in all_bgp_domains: + if not self.match_protocol_bgp_domain(bgp_domain_info, bgp_domain_filter): + continue + + bgp_domains.append( + bgp_domain_info + ) + + bgp_domains = sorted( + bgp_domains, + key=lambda i: i['name'].lower() + ) + + return bgp_domains diff --git a/lib/aci/proto/bgp/domain/main.py b/lib/aci/proto/bgp/domain/main.py new file mode 100644 index 00000000..4951015b --- /dev/null +++ b/lib/aci/proto/bgp/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bgp.domain.api import ProtocolBgpDomainApi +from lib.aci.proto.bgp.domain.info import ProtocolBgpDomainInfo + + +class ProtocolBgpDomain(ProtocolBgpDomainApi, ProtocolBgpDomainInfo): + def __init__(self): + ProtocolBgpDomainApi.__init__(self) + ProtocolBgpDomainInfo.__init__(self) diff --git a/lib/aci/proto/bgp/event/__init__.py b/lib/aci/proto/bgp/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/event/api.py b/lib/aci/proto/bgp/event/api.py new file mode 100644 index 00000000..81f30a20 --- /dev/null +++ b/lib/aci/proto/bgp/event/api.py @@ -0,0 +1,55 @@ +class ProtocolBgpEventApi(): + def __init__(self): + self.proto_bgp_event_mo = {} + + def get_protocol_bgp_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_bgp_event_mo: + return self.proto_bgp_event_mo[key] + + cache = self.get_object_cache( + 'bgpDom.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_bgp_event_mo[key] = cache + self.log.apic_mo( + 'bgpDom.eventLog.%s' % (key), + self.proto_bgp_event_mo[key] + ) + return self.proto_bgp_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bgp' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_event_mo', + 'API failed' + ) + return None + + self.proto_bgp_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_bgp_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bgpDom.eventLog.%s' % (key), + self.proto_bgp_event_mo[key] + ) + + self.set_object_cache( + 'bgpDom.eventLog', + self.proto_bgp_event_mo[key], + object_selector=key + ) + + return self.proto_bgp_event_mo[key] diff --git a/lib/aci/proto/bgp/event/info.py b/lib/aci/proto/bgp/event/info.py new file mode 100644 index 00000000..a6ca5397 --- /dev/null +++ b/lib/aci/proto/bgp/event/info.py @@ -0,0 +1,100 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolBgpEventInfo(): + def __init__(self): + self.proto_bgp_event = {} + + def get_protocol_bgp_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/bgp/inst + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['domainName'] = None + info['nei'] = None + + if 'sys/bgp/inst/dom-' in info['affected']: + info['domainName'] = info['affected'].split('sys/bgp/inst/dom-')[1].split('/')[0] + + if '/peer-[' in info['affected']: + info['nei'] = info['affected'].split('/peer-[')[1].split(']')[0] + + info['domainNameT'] = info['domainName'] + if info['domainNameT'] is None: + info['domainNameT'] = '--' + + info['neiT'] = info['nei'] + if info['neiT'] is None: + info['neiT'] = '--' + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_bgp_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_bgp_event: + return self.proto_bgp_event[key] + + managed_objects = self.get_protocol_bgp_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_bgp_event[key] = [] + for managed_object in managed_objects: + self.proto_bgp_event[key].append( + self.get_protocol_bgp_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'bgpDom.eventLog.info.%s' % (key), + self.proto_bgp_event[key] + ) + + return self.proto_bgp_event[key] diff --git a/lib/aci/proto/bgp/event/main.py b/lib/aci/proto/bgp/event/main.py new file mode 100644 index 00000000..11e61563 --- /dev/null +++ b/lib/aci/proto/bgp/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bgp.event.api import ProtocolBgpEventApi +from lib.aci.proto.bgp.event.info import ProtocolBgpEventInfo + + +class ProtocolBgpEvent(ProtocolBgpEventApi, ProtocolBgpEventInfo): + def __init__(self): + ProtocolBgpEventApi.__init__(self) + ProtocolBgpEventInfo.__init__(self) diff --git a/lib/aci/proto/bgp/fault/__init__.py b/lib/aci/proto/bgp/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/fault/api.py b/lib/aci/proto/bgp/fault/api.py new file mode 100644 index 00000000..63380889 --- /dev/null +++ b/lib/aci/proto/bgp/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolBgpFaultApi(): + def __init__(self): + self.proto_bgp_fault_mo = {} + self.proto_bgp_fault_record_mo = {} + + def get_protocol_bgp_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_bgp_fault_mo: + return self.proto_bgp_fault_mo[key] + + cache = self.get_object_cache( + 'bgpDom.fault', + object_selector=key + ) + if cache is not None: + self.proto_bgp_fault_mo[key] = cache + self.log.apic_mo( + 'bgpDom.fault.%s' % (key), + self.proto_bgp_fault_mo[key] + ) + return self.proto_bgp_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bgp' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_fault_mo', + 'API failed' + ) + return None + + self.proto_bgp_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_bgp_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bgpDom.fault.%s' % (key), + self.proto_bgp_fault_mo[key] + ) + + self.set_object_cache( + 'bgpDom.fault', + self.proto_bgp_fault_mo[key], + object_selector=key + ) + + return self.proto_bgp_fault_mo[key] + + def get_protocol_bgp_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_bgp_fault_record_mo: + return self.proto_bgp_fault_record_mo[key] + + cache = self.get_object_cache( + 'bgpDom.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_bgp_fault_record_mo[key] = cache + self.log.apic_mo( + 'bgpDom.faultRecord.%s' % (key), + self.proto_bgp_fault_record_mo[key] + ) + return self.proto_bgp_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bgp' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_fault_record_mo', + 'API failed' + ) + return None + + self.proto_bgp_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_bgp_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'bgpDom.faultRecord.%s' % (key), + self.proto_bgp_fault_record_mo[key] + ) + + self.set_object_cache( + 'bgpDom.faultRecord', + self.proto_bgp_fault_record_mo[key], + object_selector=key + ) + + return self.proto_bgp_fault_record_mo[key] diff --git a/lib/aci/proto/bgp/fault/info.py b/lib/aci/proto/bgp/fault/info.py new file mode 100644 index 00000000..4e1e5712 --- /dev/null +++ b/lib/aci/proto/bgp/fault/info.py @@ -0,0 +1,96 @@ +class ProtocolBgpFaultInfo(): + def __init__(self): + self.proto_bgp_fault = {} + self.proto_bgp_fault_record = {} + + def get_protocol_bgp_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "dn": "topology/pod-1/node-2208/sys/bgp/inst/dom-vEPC_demo:ACC_VRF/peer-[/32]/ent-[]/fault-F0299" + + info['domainName'] = None + info['nei'] = None + + if 'affected' in info: + if 'sys/bgp/inst/dom-' in info['affected']: + info['domainName'] = info['affected'].split('sys/bgp/inst/dom-')[1].split('/')[0] + + if '/peer-[' in info['affected']: + info['nei'] = info['affected'].split('/peer-[')[1].split(']')[0] + + if info['domainName'] is None: + if 'sys/bgp/inst/dom-' in info['dn']: + info['domainName'] = info['dn'].split('sys/bgp/inst/dom-')[1].split('/')[0] + + if '/peer-[' in info['dn']: + info['nei'] = info['dn'].split('/peer-[')[1].split(']')[0] + + info['domainNameT'] = info['domainName'] + if info['domainNameT'] is None: + info['domainNameT'] = '--' + + info['neiT'] = info['nei'] + if info['neiT'] is None: + info['neiT'] = '--' + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_bgp_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_bgp_fault: + return self.proto_bgp_fault[key] + + managed_objects = self.get_protocol_bgp_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_bgp_fault[key] = [] + for managed_object in managed_objects: + self.proto_bgp_fault[key].append( + self.get_protocol_bgp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'bgpDom.fault.info.%s' % (key), + self.proto_bgp_fault[key] + ) + + return self.proto_bgp_fault[key] + + def get_protocol_bgp_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_bgp_fault_record: + return self.proto_bgp_fault_record[key] + + managed_objects = self.get_protocol_bgp_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_bgp_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_bgp_fault_record[key].append( + self.get_protocol_bgp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'bgpDom.faultRecord.info.%s' % (key), + self.proto_bgp_fault_record[key] + ) + + return self.proto_bgp_fault_record[key] diff --git a/lib/aci/proto/bgp/fault/main.py b/lib/aci/proto/bgp/fault/main.py new file mode 100644 index 00000000..d80b2122 --- /dev/null +++ b/lib/aci/proto/bgp/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bgp.fault.api import ProtocolBgpFaultApi +from lib.aci.proto.bgp.fault.info import ProtocolBgpFaultInfo + + +class ProtocolBgpFault(ProtocolBgpFaultApi, ProtocolBgpFaultInfo): + def __init__(self): + ProtocolBgpFaultApi.__init__(self) + ProtocolBgpFaultInfo.__init__(self) diff --git a/lib/aci/proto/bgp/instance/__init__.py b/lib/aci/proto/bgp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bgp/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..bd494984 Binary files /dev/null and b/lib/aci/proto/bgp/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bgp/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..1d833389 Binary files /dev/null and b/lib/aci/proto/bgp/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bgp/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ffb66e45 Binary files /dev/null and b/lib/aci/proto/bgp/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bgp/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..36aa8861 Binary files /dev/null and b/lib/aci/proto/bgp/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/instance/api.py b/lib/aci/proto/bgp/instance/api.py new file mode 100644 index 00000000..7c32ca6f --- /dev/null +++ b/lib/aci/proto/bgp/instance/api.py @@ -0,0 +1,70 @@ +class ProtocolBgpInstanceApi(): + def __init__(self): + self.bgp_instance_mo = {} + + def get_protocol_bgp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bgp_instance_mo: + return self.bgp_instance_mo[key] + + cache = self.get_object_cache( + 'bgpInst', + object_selector=key + ) + if cache is not None: + self.bgp_instance_mo[key] = cache + self.log.apic_mo( + 'bgpInst.%s' % (key), + self.bgp_instance_mo[key] + ) + return self.bgp_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/bgp' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_bgp_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.bgp_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['bgpInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'bgpInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'bgpInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.bgp_instance_mo[key] = attributes + + self.log.apic_mo( + 'bgpInst.%s' % (key), + self.bgp_instance_mo[key] + ) + + self.set_object_cache( + 'bgpInst', + self.bgp_instance_mo[key], + object_selector=key + ) + + return self.bgp_instance_mo[key] diff --git a/lib/aci/proto/bgp/instance/info.py b/lib/aci/proto/bgp/instance/info.py new file mode 100644 index 00000000..a4ea6526 --- /dev/null +++ b/lib/aci/proto/bgp/instance/info.py @@ -0,0 +1,78 @@ +class ProtocolBgpInstanceInfo(): + def __init__(self): + pass + + def get_protocol_bgp_instance_summary(self, instance_info): + summary = {} + summary['__Output'] = {} + + summary['domainsCount'] = len(instance_info['domain']) + summary['domainsUp'] = 0 + for domain_info in instance_info['domain']: + if domain_info['operSt'] == 'up': + summary['domainsUp'] = summary['domainsUp'] + 1 + + summary['domains'] = '%s/%s' % ( + summary['domainsUp'], + summary['domainsCount'] + ) + if summary['domainsUp'] == summary['domainsCount']: + summary['__Output']['domains'] = 'Green' + else: + summary['__Output']['domains'] = 'Red' + + summary['neighborsCount'] = len(instance_info['neighbor']) + summary['neighborsUp'] = 0 + for neighbor_info in instance_info['neighbor']: + if neighbor_info['state']['operSt'] == 'established': + summary['neighborsUp'] = summary['neighborsUp'] + 1 + + summary['neighbors'] = '%s/%s' % ( + summary['neighborsUp'], + summary['neighborsCount'] + ) + if summary['neighborsUp'] == summary['neighborsCount']: + summary['__Output']['neighbors'] = 'Green' + else: + summary['__Output']['neighbors'] = 'Red' + + return summary + + def get_protocol_bgp_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_bgp_instance(self, pod_id, node_id): + managed_object = self.get_protocol_bgp_instance_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_bgp_instance_info(managed_object) diff --git a/lib/aci/proto/bgp/instance/main.py b/lib/aci/proto/bgp/instance/main.py new file mode 100644 index 00000000..8ac6539a --- /dev/null +++ b/lib/aci/proto/bgp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bgp.instance.api import ProtocolBgpInstanceApi +from lib.aci.proto.bgp.instance.info import ProtocolBgpInstanceInfo + + +class ProtocolBgpInstance(ProtocolBgpInstanceApi, ProtocolBgpInstanceInfo): + def __init__(self): + ProtocolBgpInstanceApi.__init__(self) + ProtocolBgpInstanceInfo.__init__(self) diff --git a/lib/aci/proto/bgp/main.py b/lib/aci/proto/bgp/main.py new file mode 100644 index 00000000..cf82d0a4 --- /dev/null +++ b/lib/aci/proto/bgp/main.py @@ -0,0 +1,104 @@ +from lib.aci.proto.bgp.domain.main import ProtocolBgpDomain +from lib.aci.proto.bgp.instance.main import ProtocolBgpInstance +from lib.aci.proto.bgp.neighbor.main import ProtocolBgpNeighbor +from lib.aci.proto.bgp.event.main import ProtocolBgpEvent +from lib.aci.proto.bgp.fault.main import ProtocolBgpFault + + +class ProtocolBgp( + ProtocolBgpDomain, + ProtocolBgpInstance, + ProtocolBgpNeighbor, + ProtocolBgpEvent, + ProtocolBgpFault + ): + def __init__(self): + ProtocolBgpDomain.__init__(self) + ProtocolBgpInstance.__init__(self) + ProtocolBgpNeighbor.__init__(self) + ProtocolBgpEvent.__init__(self) + ProtocolBgpFault.__init__(self) + + def get_protocol_bgp( + self, + pod_id, + node_id, + bgp_filter=None, + instance_info=False, + domain_info=False, + neighbor_info=False, + stats_info=False, + prefix_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_bgp_instance( + pod_id, + node_id + ) + + if domain_info: + info['domain'] = self.get_protocol_bgp_domains( + pod_id, + node_id, + bgp_domain_filter=bgp_filter + ) + + if neighbor_info: + info['neighbor'] = self.get_protocol_bgp_neighbors( + pod_id, + node_id, + bgp_neighbor_filter=bgp_filter, + stats_info=stats_info, + prefix_info=prefix_info + ) + + if instance_info and domain_info and neighbor_info: + info['instance']['summary'] = self.get_protocol_bgp_instance_summary( + info + ) + info['instance'] = self.my_output.merge_output( + info['instance'] + ) + + if fault_info: + info['faultInst'] = self.get_protocol_bgp_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_bgp_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_bgp_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/bgp/neighbor/__init__.py b/lib/aci/proto/bgp/neighbor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/neighbor/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..388da909 Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2e2bf3c5 Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..2d0bd7ba Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..da9f7184 Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/api.py b/lib/aci/proto/bgp/neighbor/api.py new file mode 100644 index 00000000..50e826f1 --- /dev/null +++ b/lib/aci/proto/bgp/neighbor/api.py @@ -0,0 +1,140 @@ +import copy + + +class ProtocolBgpNeighborApi(): + def __init__(self): + self.bgp_neighbors_mo = {} + + def get_protocol_bgp_neighbors_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bgp_neighbors_mo: + return self.bgp_neighbors_mo[key] + + cache = self.get_object_cache( + 'bgpPeer', + object_selector=key + ) + if cache is not None: + self.bgp_neighbors_mo[key] = cache + self.log.apic_mo( + 'bgpPeer.%s' % (key), + self.bgp_neighbors_mo[key] + ) + return self.bgp_neighbors_mo[key] + + class_name = 'topology/pod-%s/node-%s/bgpDom' % (pod_id, node_id) + query = 'query-target=subtree&target-subtree-class=bgpPeer&target-subtree-class=bgpPeerEntry&target-subtree-class=bgpPeerAfEntry' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_neighbors_mo', + 'API failed' + ) + return None + + bgp_peers = [] + for managed_object in managed_objects['imdata']: + if 'bgpPeer' in managed_object: + bgp_peer_attributes = managed_object['bgpPeer']['attributes'] + bgp_peer_attributes['state'] = [] + bgp_peers.append( + bgp_peer_attributes + ) + + for managed_object in managed_objects['imdata']: + if 'bgpPeerEntry' in managed_object: + entry_bgp_domain = managed_object['bgpPeerEntry']['attributes']['dn'].split('/')[6] + entry_bgp_peer_dn = managed_object['bgpPeerEntry']['attributes']['dn'].split('/')[7] + for bgp_peer in bgp_peers: + if entry_bgp_domain in bgp_peer['dn'] and entry_bgp_peer_dn in bgp_peer['dn']: + bgp_peer['state'].append( + managed_object['bgpPeerEntry']['attributes'] + ) + + for managed_object in managed_objects['imdata']: + if 'bgpPeerAfEntry' in managed_object: + # "topology/pod-1/node-201/sys/bgp/inst/dom-overlay-1/peer-[/32]/ent-[]/af-vpnv4-ucast" + af_bgp_peer_dn = managed_object['bgpPeerAfEntry']['attributes']['dn'].split('/')[7] + af_bgp_entry_dn = managed_object['bgpPeerAfEntry']['attributes']['dn'].split('/')[8] + af_name = managed_object['bgpPeerAfEntry']['attributes']['dn'].split('/')[-1] + for bgp_peer in bgp_peers: + if af_bgp_peer_dn in bgp_peer['dn']: + for state in bgp_peer['state']: + if af_bgp_entry_dn in state['dn']: + state[af_name] = managed_object['bgpPeerAfEntry']['attributes'] + + class_name = 'bgpLocalAsnP' + managed_objects = self.get_class( + class_name + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_neighbors_mo', + 'API bgpLocalAsnP failed' + ) + + if managed_objects is not None: + self.log.apic_mo( + 'bgpLocalAsnP', + managed_objects + ) + + for managed_object in managed_objects['imdata']: + if 'bgpLocalAsnP' in managed_object: + # [0]: uni/controller/mdpPolCont/localDomP-{name}/provider-{name}/infraPeerP-[{addr}]/localasn + # [1]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/vlifp-[{nodeDn}]-[{encap}]/infraPeerP-[{addr}]/localasn + # [2]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/rspathL3OutAtt-[{tDn}]/infraPeerP-[{addr}]/localasn + # [3]: uni/tn-{name}/out-{name}/lnodep-{name}/infraPeerP-[{addr}]/localasn + # [4]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/vlifp-[{nodeDn}]-[{encap}]/peerP-[{addr}]/localasn + # [5]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/rspathL3OutAtt-[{tDn}]/peerP-[{addr}]/localasn + # [6]: uni/tn-{name}/out-{name}/lnodep-{name}/peerP-[{addr}]/localasn + + dn_mo = managed_object['bgpLocalAsnP']['attributes']['dn'] + if dn_mo.split('/')[5].split('-')[0] == 'vlifp': + # [1]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/vlifp-[{nodeDn}]-[{encap}]/infraPeerP-[{addr}]/localasn + # [4]: uni/tn-{name}/out-{name}/lnodep-{name}/lifp-{name}/vlifp-[{nodeDn}]-[{encap}]/peerP-[{addr}]/localasn + # uni/tn-k8s/out-vk8s_1/lnodep-node-205-206/lifp-floating_svi/vlifp-[topology/pod-1/node-205]-[vlan-500]/peerP-[/28]/localasn + l3out_name = dn_mo.split('/')[2][4:] + lnodep_name = dn_mo.split('/')[3][7:] + lifp_name = dn_mo.split('/')[4][5:] + peer_address = None + if len(dn_mo.split('/infraPeerP-[')) > 1: + peer_address = dn_mo.split('/infraPeerP-[')[1].split(']')[0] + if len(dn_mo.split('/peerP-[')) > 1: + peer_address = dn_mo.split('/peerP-[')[1].split(']')[0] + + if peer_address is not None: + for bgp_peer in bgp_peers: + if bgp_peer['addr'] == peer_address: + bgp_peer['l3out'] = l3out_name + bgp_peer['lnodep'] = lnodep_name + bgp_peer['lifp'] = lifp_name + bgp_peer['localAsn'] = managed_object['bgpLocalAsnP']['attributes']['localAsn'] + bgp_peer['asnPropagate'] = managed_object['bgpLocalAsnP']['attributes']['asnPropagate'] + + flat_bgp_peers = [] + for bgp_peer in bgp_peers: + for state in bgp_peer['state']: + new_entry = copy.deepcopy(bgp_peer) + new_entry['state'] = copy.deepcopy(state) + flat_bgp_peers.append(new_entry) + + self.bgp_neighbors_mo[key] = copy.deepcopy(flat_bgp_peers) + + self.log.apic_mo( + 'bgpPeer.%s' % (key), + self.bgp_neighbors_mo[key] + ) + + self.set_object_cache( + 'bgpPeer', + self.bgp_neighbors_mo[key], + object_selector=key + ) + + return self.bgp_neighbors_mo[key] diff --git a/lib/aci/proto/bgp/neighbor/info.py b/lib/aci/proto/bgp/neighbor/info.py new file mode 100644 index 00000000..f297b7b6 --- /dev/null +++ b/lib/aci/proto/bgp/neighbor/info.py @@ -0,0 +1,220 @@ +from lib import filter_helper +from lib import ip_helper + + +class ProtocolBgpNeighborInfo(): + def __init__(self): + self.bgp_neighbors = {} + + def get_protocol_bgp_neighbor_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "dn": "topology/pod-1/node-201/sys/bgp/inst/dom-common:smi5Gc-cvim4-N6_VRF/peer-[/28]" + info['bgpDomainName'] = info['dn'].split('/')[6][4:] + + info['__Output']['name'] = 'Yellow' + info['__Output']['bgpDomainName'] = 'Yellow' + info['__Output']['state.addr'] = 'Yellow' + info['__Output']['asn'] = 'Blue' + + if info['ctrl'] == 'bfd': + info['bfdTick'] = '\u2713' + else: + info['bfdTick'] = '\u2717' + + if info['state']['connAttempts'] == 'na': + info['state']['connAttempts'] = 0 + + info['state']['connSummary'] = '%s/%s/%s' % ( + info['state']['connAttempts'], + info['state']['connDrop'], + info['state']['connEst'] + ) + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['state']['operSt'] == 'established': + info['__Output']['state.operSt'] = 'Green' + else: + info['__Output']['state.operSt'] = 'Red' + + if info['curPfxPeers'] != '0': + info['__Output']['curPfxPeers'] = 'Blue' + + if info['state']['connDrop'] != '0': + info['__Output']['state.connDrop'] = 'Red' + + if 'af-ipv4-ucast' in info['state']: + if info['state']['af-ipv4-ucast']['acceptedPaths'] != '0': + info['__Output']['state.af-ipv4-ucast.acceptedPaths'] = 'Blue' + + info['paths'] = [] + + if 'af-ipv4-ucast' in info['state']: + if info['state']['af-ipv4-ucast']['acceptedPaths'] != '0': + info['paths'].append( + 'IPv4-ucast:%s' % ( + info['state']['af-ipv4-ucast']['acceptedPaths'] + ) + ) + + if 'af-ipv6-ucast' in info['state']: + if info['state']['af-ipv6-ucast']['acceptedPaths'] != '0': + info['paths'].append( + 'IPv6-ucast:%s' % ( + info['state']['af-ipv6-ucast']['acceptedPaths'] + ) + ) + + if 'af-vpnv4-ucast' in info['state']: + if info['state']['af-vpnv4-ucast']['acceptedPaths'] != '0': + info['paths'].append( + 'VPNv4-ucast:%s' % ( + info['state']['af-vpnv4-ucast']['acceptedPaths'] + ) + ) + + if 'af-vpnv6-ucast' in info['state']: + if info['state']['af-vpnv6-ucast']['acceptedPaths'] != '0': + info['paths'].append( + 'VPNv6-ucast:%s' % ( + info['state']['af-vpnv6-ucast']['acceptedPaths'] + ) + ) + + return info + + def get_protocol_bgp_neighbors_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.bgp_neighbors: + return self.bgp_neighbors[key] + + bgp_neighbors_mo = self.get_protocol_bgp_neighbors_mo(pod_id, node_id) + if bgp_neighbors_mo is not None: + self.bgp_neighbors[key] = [] + for bgp_neighbor_mo in bgp_neighbors_mo: + self.bgp_neighbors[key].append( + self.get_protocol_bgp_neighbor_info( + bgp_neighbor_mo + ) + ) + + self.log.apic_mo( + 'bgp.neighbors.info.%s' % (key), + self.bgp_neighbors[key] + ) + + return self.bgp_neighbors[key] + + def match_protocol_bgp_neighbor(self, bgp_neighbor_info, bgp_neighbor_filter): + if bgp_neighbor_filter is None or len(bgp_neighbor_filter) == 0: + return True + + for ap_rule in bgp_neighbor_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + if key == 'asn': + if not filter_helper.match_string(value, bgp_neighbor_info['asn']): + return False + + if key == 'vrf': + if not filter_helper.match_string(value, bgp_neighbor_info['bgpDomainName']): + return False + + if key == 'rtr-ip': + if not filter_helper.match_string(value, bgp_neighbor_info['state']['rtrId']): + return False + + if key == 'rtr-subnet': + if not ip_helper.is_ipv4_in_cidr(bgp_neighbor_info['state']['rtrId'], value): + return False + + if key == 'nbr-ip': + if not filter_helper.match_string(value, bgp_neighbor_info['state']['addr']): + return False + + if key == 'nbr-subnet': + if not ip_helper.is_ipv4_in_cidr(bgp_neighbor_info['state']['addr'], value): + return False + + if key == 'state': + if value != 'any': + if value == 'up': + if not filter_helper.match_string('established', bgp_neighbor_info['state']['operSt']): + return False + + if value == 'down': + if not filter_helper.match_string('idle', bgp_neighbor_info['state']['operSt']): + return False + + if key == 'type': + if value != 'any': + if not filter_helper.match_string(value, bgp_neighbor_info['state']['type']): + return False + + if key == 'interface': + if not filter_helper.match_string(value, bgp_neighbor_info['srcIf']): + return False + + return True + + def get_protocol_bgp_neighbors( + self, + pod_id, + node_id, + bgp_neighbor_filter=None, + stats_info=False, + prefix_info=False + ): + all_bgp_neighbors = self.get_protocol_bgp_neighbors_info(pod_id, node_id) + if all_bgp_neighbors is None: + return None + + bgp_neighbors = [] + + for bgp_neighbor_info in all_bgp_neighbors: + if not self.match_protocol_bgp_neighbor(bgp_neighbor_info, bgp_neighbor_filter): + continue + + if stats_info: + bgp_neighbor_info['stats'] = self.get_protocol_bgp_neighbor_stats( + pod_id, + node_id, + bgp_neighbor_info['bgpDomainName'], + bgp_neighbor_info['addr'], + bgp_neighbor_info['state']['addr'] + ) + + if prefix_info: + bgp_neighbor_info['route'] = self.get_protocol_ipv4_routes( + pod_id, + node_id, + bgp_neighbor_info['bgpDomainName'], + route_filter=['bgp', 'nh:%s' % (bgp_neighbor_info['state']['addr'])] + ) + + bgp_neighbors.append( + bgp_neighbor_info + ) + + bgp_neighbors = sorted( + bgp_neighbors, + key=lambda i: ( + i['bgpDomainName'].lower(), + i['addr'] + ) + ) + + return bgp_neighbors diff --git a/lib/aci/proto/bgp/neighbor/main.py b/lib/aci/proto/bgp/neighbor/main.py new file mode 100644 index 00000000..cb2e0329 --- /dev/null +++ b/lib/aci/proto/bgp/neighbor/main.py @@ -0,0 +1,10 @@ +from lib.aci.proto.bgp.neighbor.stats.main import ProtocolBgpNeighborStats +from lib.aci.proto.bgp.neighbor.api import ProtocolBgpNeighborApi +from lib.aci.proto.bgp.neighbor.info import ProtocolBgpNeighborInfo + + +class ProtocolBgpNeighbor(ProtocolBgpNeighborApi, ProtocolBgpNeighborInfo, ProtocolBgpNeighborStats): + def __init__(self): + ProtocolBgpNeighborApi.__init__(self) + ProtocolBgpNeighborInfo.__init__(self) + ProtocolBgpNeighborStats.__init__(self) diff --git a/lib/aci/proto/bgp/neighbor/stats/__init__.py b/lib/aci/proto/bgp/neighbor/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/bgp/neighbor/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..84ebfebe Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/stats/__pycache__/api.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/stats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..0c41665a Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/stats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/stats/__pycache__/info.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..3c3f48fc Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/stats/__pycache__/main.cpython-310.pyc b/lib/aci/proto/bgp/neighbor/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8ec6b75a Binary files /dev/null and b/lib/aci/proto/bgp/neighbor/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/bgp/neighbor/stats/api.py b/lib/aci/proto/bgp/neighbor/stats/api.py new file mode 100644 index 00000000..69d5a723 --- /dev/null +++ b/lib/aci/proto/bgp/neighbor/stats/api.py @@ -0,0 +1,70 @@ +class ProtocolBgpNeighborStatsApi(): + def __init__(self): + self.bgp_nbr_stats_mo = {} + + def get_protocol_bgp_neighbor_stats_mo(self, pod_id, node_id, bgp_domain_name, bgp_peer_addr, bgp_state_addr): + key = '%s.%s.%s.%s.%s' % ( + pod_id, + node_id, + bgp_domain_name, + bgp_peer_addr, + bgp_state_addr + ) + if key in self.bgp_nbr_stats_mo: + return self.bgp_nbr_stats_mo[key] + + cache = self.get_object_cache( + 'bgpPeerEntryStats', + object_selector=key + ) + if cache is not None: + self.bgp_nbr_stats_mo[key] = cache + self.log.apic_mo( + 'bgpPeerEntryStats.%s' % (key), + self.bgp_nbr_stats_mo[key] + ) + return self.bgp_nbr_stats_mo[key] + + # https:///api/node/mo/topology/pod-1/node-201/sys/bgp/inst/dom-common:smi5Gc-cvim4-N3-N4_VRF/peer-[/32]/ent-[]/peerstats.json + distinguished_name = 'topology/pod-%s/node-%s/sys/bgp/inst/dom-%s/peer-[%s]/ent-[%s]/peerstats' % ( + pod_id, + node_id, + bgp_domain_name, + bgp_peer_addr, + bgp_state_addr + ) + managed_objects = self.get_managed_object( + distinguished_name + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_bgp_neighbor_stats_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_bgp_neighbor_stats_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.bgp_nbr_stats_mo[key] = {} + else: + self.bgp_nbr_stats_mo[key] = managed_objects['imdata'][0]['bgpPeerEntryStats']['attributes'] + + self.log.apic_mo( + 'bgpPeerEntryStats.%s' % (key), + self.bgp_nbr_stats_mo[key] + ) + + self.set_object_cache( + 'bgpPeerEntryStats', + self.bgp_nbr_stats_mo[key], + object_selector=key + ) + + return self.bgp_nbr_stats_mo[key] diff --git a/lib/aci/proto/bgp/neighbor/stats/info.py b/lib/aci/proto/bgp/neighbor/stats/info.py new file mode 100644 index 00000000..9323b5e5 --- /dev/null +++ b/lib/aci/proto/bgp/neighbor/stats/info.py @@ -0,0 +1,51 @@ +class ProtocolBgpNeighborStatsInfo(): + def __init__(self): + pass + + def get_protocol_bgp_neighbor_stats_info(self, managed_object): + info = {} + info['__Output'] = {} + + # "byteInRecvQ":"0", + # "byteInSendQ":"0", + # "byteRcvd":"16116741", + # "byteSent":"13610230", + # "capRcvd":"0", + # "capSent":"0", + # "childAction":"", + # "connectRetryTs":"1970-01-01T01:00:00.000+01:00", + # "dn":"topology/pod-1/node-201/sys/bgp/inst/dom-common:smi5Gc-cvim4-N3-N4_VRF/peer-[/32]/ent-[]/peerstats", + # "kaRcvd":"848117", + # "kaSent":"710369", + # "kaTs":"2023-01-16T15:23:37.122+01:00", + # "modTs":"never", + # "monPolDn":"", + # "msgRcvd":"848179", + # "msgSent":"712365", + # "notifRcvd":"0", + # "notifSent":"17", + # "openRcvd":"18", + # "openSent":"19", + # "routeRefreshRcvd":"0", + # "routeRefreshSent":"26", + # "status":"", + # "updateRcvd":"44", + # "updateSent":"1934" + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_protocol_bgp_neighbor_stats(self, pod_id, node_id, bgp_domain_name, bgp_peer_addr, bgp_state_addr): + managed_object = self.get_protocol_bgp_neighbor_stats_mo( + pod_id, + node_id, + bgp_domain_name, + bgp_peer_addr, + bgp_state_addr + ) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_bgp_neighbor_stats_info(managed_object) diff --git a/lib/aci/proto/bgp/neighbor/stats/main.py b/lib/aci/proto/bgp/neighbor/stats/main.py new file mode 100644 index 00000000..d1a7a401 --- /dev/null +++ b/lib/aci/proto/bgp/neighbor/stats/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.bgp.neighbor.stats.api import ProtocolBgpNeighborStatsApi +from lib.aci.proto.bgp.neighbor.stats.info import ProtocolBgpNeighborStatsInfo + + +class ProtocolBgpNeighborStats(ProtocolBgpNeighborStatsApi, ProtocolBgpNeighborStatsInfo): + def __init__(self): + ProtocolBgpNeighborStatsApi.__init__(self) + ProtocolBgpNeighborStatsInfo.__init__(self) diff --git a/lib/aci/proto/bgp/output.py b/lib/aci/proto/bgp/output.py new file mode 100644 index 00000000..1aca1fff --- /dev/null +++ b/lib/aci/proto/bgp/output.py @@ -0,0 +1,507 @@ +class ProtocolBgpOutput(): + def __init__(self): + pass + + def print_proto_bgp_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BGP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'health', + 'faults', + 'adminSt', + 'asn', + 'summary.domains', + 'summary.neighbors', + 'numAsPath', + 'numRtAttrib', + 'memAlert', + 'snmpTrapSt', + 'syslogLvl' + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'Admin', + 'ASN', + 'Domain (VRF)', + 'Neighbor', + 'AS Path', + 'Attribute', + 'Mem Status', + 'SNMP Trap', + 'Syslog Level' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bgp_domains(self, info, show_no_peers=False, title=False): + domains = [] + for item in info: + if show_no_peers: + domains.append(item) + continue + + if item['isPeer']: + domains.append(item) + continue + + if title: + self.my_output.default( + 'Protocol BGP - Domain (VRF) [#%s]' % (len(domains)), + underline=True, + before_newline=True + ) + + if len(domains) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'name', + 'health', + 'faults', + 'operSt', + 'mode', + 'operRtrId', + 'rd', + 'peerSummary' + ] + + headers = [ + 'Node', + 'Domain (VRF)', + 'Health', + 'Faults', + 'BGP State', + 'Mode', + 'Router ID', + 'RD', + 'Neighbors' + ] + + self.my_output.my_table( + domains, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bgp_peers(self, info): + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + order = [ + 'bgpDomainName', + 'state.addr', + 'state.rtrId', + 'state.localPort', + 'state.remotePort', + 'adminSt', + 'state.operSt', + 'state.lastFlapTs', + 'bfdTick', + 'asn', + 'localAsn', + 'asnPropagate', + 'state.type', + 'ttl', + 'srcIf', + 'state.localIp', + 'state.holdIntvl', + 'state.kaIntvl', + 'state.passwdSet', + 'state.connAttempts', + 'state.connDrop', + 'state.connEst', + 'state.advCap', + 'state.rcvCap', + 'l3out', + 'lnodep', + 'lifp' + ] + + headers = [ + 'Domain (VRF)', + 'Neighbor Address', + 'Remote Router Id', + 'Local Port', + 'Remote Port', + 'Admin State', + 'Session State', + 'Last Flap', + 'BFD', + 'Remote ASN', + 'Local ASN', + 'ASN Propagate', + 'Type', + 'TTL', + 'Source Intf', + 'Local IP', + 'Hold Interval', + 'Keepalive Interval', + 'MD5 Authentication', + 'Connection Attempts', + 'Connection Dropped', + 'Connection Established', + 'Capabilities Advertised', + 'Capabilities Received', + 'L3Out', + 'Logical Node Profile', + 'Logical Interface Profile' + ] + + self.my_output.dictionary( + item, + title='Protocol BGP - Node %s - Peer %s' % (item['pod_node_name'], item['state']['addr']), + keys=order, + title_keys=headers, + justify=True + ) + + stats = [] + stats.append( + dict( + type='Opens', + sent=item['stats']['openSent'], + rcvd=item['stats']['openRcvd'] + ) + ) + + stats.append( + dict( + type='Notifications', + sent=item['stats']['notifSent'], + rcvd=item['stats']['notifRcvd'] + ) + ) + + stats.append( + dict( + type='Updates', + sent=item['stats']['updateSent'], + rcvd=item['stats']['updateRcvd'] + ) + ) + + stats.append( + dict( + type='Keepalives', + sent=item['stats']['kaSent'], + rcvd=item['stats']['kaRcvd'] + ) + ) + + stats.append( + dict( + type='Route Refresh', + sent=item['stats']['routeRefreshSent'], + rcvd=item['stats']['routeRefreshRcvd'] + ) + ) + + stats.append( + dict( + type='Capability', + sent=item['stats']['capSent'], + rcvd=item['stats']['capRcvd'] + ) + ) + + stats.append( + dict( + type='Total', + sent=item['stats']['msgSent'], + rcvd=item['stats']['msgRcvd'] + ) + ) + + stats.append( + dict( + type='Total Bytes', + sent=item['stats']['byteSent'], + rcvd=item['stats']['byteRcvd'] + ) + ) + + stats.append( + dict( + type='Bytes in Queue', + sent=item['stats']['byteInSendQ'], + rcvd=item['stats']['byteInRecvQ'] + ) + ) + + self.my_output.my_table( + stats, + order=['type', 'sent', 'rcvd'], + headers=['Message Type', 'Sent', 'Received'], + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + for address_family in ['af-ipv4-ucast', 'af-ipv4-lu', 'af-l2vpn-evpn']: + if 'state' in item and address_family in item['state']: + self.my_output.dictionary( + item['state'][address_family], + title='AF %s' % (address_family), + keys=['acceptedPaths', 'pfxFlushed', 'pfxSaved', 'pfxSent', 'tblSt', 'tblVer'], + title_keys=['acceptedPaths', 'pfxFlushed', 'pfxSaved', 'pfxSent', 'tblSt', 'tblVer'], + justify=True + ) + + def print_proto_bgp_neighbors(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BGP - Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'bgpDomainName', + 'state.addr', + 'state.rtrId', + 'adminSt', + 'state.operSt', + 'bfdTick', + 'asn', + 'state.type', + 'ttl', + 'srcIf', + 'state.localIp', + 'state.connSummary', + 'paths' + ] + + headers = [ + 'Node', + 'Domain (VRF)', + 'Nbr Address', + 'Router Id', + 'Admin', + 'Session', + 'BFD', + 'ASN', + 'Type', + 'TTL', + 'Src Intf', + 'Local IP', + 'Conns (A/D/E)', + 'Paths' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['paths'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bgp_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol BGP - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'domainNameT', + 'neiT', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Domain (VRF)', + 'Nbr', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bgp_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol BGP - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol BGP - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'domainNameT', + 'neiT', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Domain (VRF)', + 'Nbr', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_bgp_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol BGP - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol BGP - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'domainNameT', + 'neiT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Domain (VRF)', + 'Nbr', + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/bot_output.py b/lib/aci/proto/bot_output.py new file mode 100644 index 00000000..fb4c666b --- /dev/null +++ b/lib/aci/proto/bot_output.py @@ -0,0 +1,11 @@ +from lib.aci.proto.lacp.bot_output import ProtocolLacpBotOutput +from lib.aci.proto.lldp.bot_output import ProtocolLldpBotOutput + + +class ProtocolBotOutput( + ProtocolLacpBotOutput, + ProtocolLldpBotOutput + ): + def __init__(self): + ProtocolLacpBotOutput.__init__(self) + ProtocolLldpBotOutput.__init__(self) diff --git a/lib/aci/proto/cdp/__init__.py b/lib/aci/proto/cdp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/cdp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4c65e5b8 Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..2eaef0c6 Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/__pycache__/interface.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..07fd7265 Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/__pycache__/interface_stats.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/interface_stats.cpython-310.pyc new file mode 100644 index 00000000..628f9277 Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/interface_stats.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f3f2810b Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/__pycache__/neighbor.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/neighbor.cpython-310.pyc new file mode 100644 index 00000000..29b38e31 Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/neighbor.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/__pycache__/output.cpython-310.pyc b/lib/aci/proto/cdp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..2c87dad1 Binary files /dev/null and b/lib/aci/proto/cdp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/event/__init__.py b/lib/aci/proto/cdp/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/cdp/event/api.py b/lib/aci/proto/cdp/event/api.py new file mode 100644 index 00000000..ed251b2a --- /dev/null +++ b/lib/aci/proto/cdp/event/api.py @@ -0,0 +1,55 @@ +class ProtocolCdpEventApi(): + def __init__(self): + self.proto_cdp_event_mo = {} + + def get_protocol_cdp_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_cdp_event_mo: + return self.proto_cdp_event_mo[key] + + cache = self.get_object_cache( + 'cdp.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_cdp_event_mo[key] = cache + self.log.apic_mo( + 'cdp.eventLog.%s' % (key), + self.proto_cdp_event_mo[key] + ) + return self.proto_cdp_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/cdp/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_cdp_event_mo', + 'API failed' + ) + return None + + self.proto_cdp_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_cdp_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cdp.eventLog.%s' % (key), + self.proto_cdp_event_mo[key] + ) + + self.set_object_cache( + 'cdp.eventLog', + self.proto_cdp_event_mo[key], + object_selector=key + ) + + return self.proto_cdp_event_mo[key] diff --git a/lib/aci/proto/cdp/event/info.py b/lib/aci/proto/cdp/event/info.py new file mode 100644 index 00000000..861fc9ea --- /dev/null +++ b/lib/aci/proto/cdp/event/info.py @@ -0,0 +1,92 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolCdpEventInfo(): + def __init__(self): + self.proto_cdp_event = {} + + def get_protocol_cdp_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/cdp/inst + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + # topology/pod-1/node-2205/sys/cdp/inst/if-[eth1/27]/adj-1 + info['interfaceId'] = None + if '/sys/cdp/inst/if-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/sys/cdp/inst/if-[')[1].split(']')[0] + + info['interfaceT'] = info['interfaceId'] + if info['interfaceT'] is None: + info['interfaceT'] = '--' + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_cdp_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_cdp_event: + return self.proto_cdp_event[key] + + managed_objects = self.get_protocol_cdp_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_cdp_event[key] = [] + for managed_object in managed_objects: + self.proto_cdp_event[key].append( + self.get_protocol_cdp_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'cdp.eventLog.info.%s' % (key), + self.proto_cdp_event[key] + ) + + return self.proto_cdp_event[key] diff --git a/lib/aci/proto/cdp/event/main.py b/lib/aci/proto/cdp/event/main.py new file mode 100644 index 00000000..14bf560f --- /dev/null +++ b/lib/aci/proto/cdp/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.cdp.event.api import ProtocolCdpEventApi +from lib.aci.proto.cdp.event.info import ProtocolCdpEventInfo + + +class ProtocolCdpEvent(ProtocolCdpEventApi, ProtocolCdpEventInfo): + def __init__(self): + ProtocolCdpEventApi.__init__(self) + ProtocolCdpEventInfo.__init__(self) diff --git a/lib/aci/proto/cdp/instance/__init__.py b/lib/aci/proto/cdp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/cdp/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/cdp/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2daf6a5d Binary files /dev/null and b/lib/aci/proto/cdp/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/cdp/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2233be52 Binary files /dev/null and b/lib/aci/proto/cdp/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/cdp/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1c347798 Binary files /dev/null and b/lib/aci/proto/cdp/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/cdp/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..48432755 Binary files /dev/null and b/lib/aci/proto/cdp/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/instance/api.py b/lib/aci/proto/cdp/instance/api.py new file mode 100644 index 00000000..fb837a0e --- /dev/null +++ b/lib/aci/proto/cdp/instance/api.py @@ -0,0 +1,57 @@ +class ProtocolCdpInstanceApi(): + def __init__(self): + self.cdp_instance_mo = {} + + def get_protocol_cdp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.cdp_instance_mo: + return self.cdp_instance_mo[key] + + cache = self.get_object_cache( + 'cdpInst', + object_selector=key + ) + if cache is not None: + self.cdp_instance_mo[key] = cache + self.log.apic_mo( + 'cdpInst.%s' % (key), + self.cdp_instance_mo[key] + ) + return self.cdp_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/cdp/inst' % (pod_id, node_id) + managed_objects = self.get_managed_object( + distinguished_name + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_cdp_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_cdp_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.cdp_instance_mo[key] = {} + else: + self.cdp_instance_mo[key] = managed_objects['imdata'][0]['cdpInst']['attributes'] + + self.log.apic_mo( + 'cdpInst.%s' % (key), + self.cdp_instance_mo[key] + ) + + self.set_object_cache( + 'cdpInst', + self.cdp_instance_mo[key], + object_selector=key + ) + + return self.cdp_instance_mo[key] diff --git a/lib/aci/proto/cdp/instance/info.py b/lib/aci/proto/cdp/instance/info.py new file mode 100644 index 00000000..22060365 --- /dev/null +++ b/lib/aci/proto/cdp/instance/info.py @@ -0,0 +1,32 @@ +class ProtocolCdpInstanceInfo(): + def __init__(self): + pass + + def get_protocol_cdp_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + return info + + def get_protocol_cdp_instance(self, pod_id, node_id): + managed_object = self.get_protocol_cdp_instance_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_cdp_instance_info(managed_object) diff --git a/lib/aci/proto/cdp/instance/main.py b/lib/aci/proto/cdp/instance/main.py new file mode 100644 index 00000000..2da3b835 --- /dev/null +++ b/lib/aci/proto/cdp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.cdp.instance.api import ProtocolCdpInstanceApi +from lib.aci.proto.cdp.instance.info import ProtocolCdpInstanceInfo + + +class ProtocolCdpInstance(ProtocolCdpInstanceApi, ProtocolCdpInstanceInfo): + def __init__(self): + ProtocolCdpInstanceApi.__init__(self) + ProtocolCdpInstanceInfo.__init__(self) diff --git a/lib/aci/proto/cdp/interface/__init__.py b/lib/aci/proto/cdp/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/cdp/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/cdp/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ebad57e7 Binary files /dev/null and b/lib/aci/proto/cdp/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/__pycache__/api.cpython-310.pyc b/lib/aci/proto/cdp/interface/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..0c99606f Binary files /dev/null and b/lib/aci/proto/cdp/interface/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/__pycache__/info.cpython-310.pyc b/lib/aci/proto/cdp/interface/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..820bc67f Binary files /dev/null and b/lib/aci/proto/cdp/interface/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/__pycache__/main.cpython-310.pyc b/lib/aci/proto/cdp/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3c451441 Binary files /dev/null and b/lib/aci/proto/cdp/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/api.py b/lib/aci/proto/cdp/interface/api.py new file mode 100644 index 00000000..7e06df7e --- /dev/null +++ b/lib/aci/proto/cdp/interface/api.py @@ -0,0 +1,61 @@ +class ProtocolCdpInterfaceApi(): + def __init__(self): + self.cdp_interfaces_mo = {} + + def get_protocol_cdp_interfaces_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.cdp_interfaces_mo: + return self.cdp_interfaces_mo[key] + + cache = self.get_object_cache( + 'cdpIf', + object_selector=key + ) + if cache is not None: + self.cdp_interfaces_mo[key] = cache + self.log.apic_mo( + 'cdpIf.%s' % (key), + self.cdp_interfaces_mo[key] + ) + return self.cdp_interfaces_mo[key] + + # url: https:///api/node/class/topology/pod-1/node-201/cdpIf.json?rsp-subtree=children&rsp-subtree-class=cdpIf,cdpIfStats&rsp-subtree-include=required + class_name = 'topology/pod-%s/node-%s/cdpIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-class=cdpIf,cdpIfStats&rsp-subtree-include=required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_cdp_interfaces_mo', + 'API failed' + ) + return None + + self.cdp_interfaces_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['cdpIf']['attributes'] + attributes['stats'] = self.get_mo_child_attributes( + 'cdpIf', + managed_object, + 'cdpIfStats' + ) + + self.cdp_interfaces_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'cdpIf.%s' % (key), + self.cdp_interfaces_mo[key] + ) + + self.set_object_cache( + 'cdpIf', + self.cdp_interfaces_mo[key], + object_selector=key + ) + + return self.cdp_interfaces_mo[key] diff --git a/lib/aci/proto/cdp/interface/info.py b/lib/aci/proto/cdp/interface/info.py new file mode 100644 index 00000000..915bbf7d --- /dev/null +++ b/lib/aci/proto/cdp/interface/info.py @@ -0,0 +1,135 @@ +import copy + +from lib import filter_helper +from lib.aci.proto.cdp.interface.stats.main import ProtocolCdpInterfaceStats + + +class ProtocolCdpInterfaceInfo(ProtocolCdpInterfaceStats): + def __init__(self): + ProtocolCdpInterfaceStats.__init__(self) + self.cdp_interfaces = {} + + def get_cdp_active_interface_count(self, interfaces): + count = 0 + for interface in interfaces: + if 'neighborCount' in interface and interface['neighborCount'] > 0: + count = count + 1 + return count + + def add_protocol_cdp_interface_neighbor_info(self, interfaces, neighbors, remove_no_neighbors=False): + for interface in interfaces: + interface['neighborCount'] = 0 + interface_neighbors = [] + + for neighbor in neighbors: + if neighbor['interfaceId'] == interface['id']: + interface['neighborCount'] = interface['neighborCount'] + 1 + interface_neighbors.append( + neighbor['sysName'] + ) + + interface['neighborList'] = ', '.join(interface_neighbors) + + if remove_no_neighbors: + new_interfaces = [] + for interface in interfaces: + if interface['neighborCount'] > 0: + new_interfaces.append( + interface + ) + + interfaces = copy.deepcopy(new_interfaces) + + return interfaces + + def get_protocol_cdp_interface_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key == 'stats': + info['stats'] = self.get_protocol_cdp_interface_stats_info(managed_object[key]) + info['stats'] = self.my_output.merge_output( + info['stats'] + ) + else: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['__Output']['id'] = 'Yellow' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + info['operStQual'] = '' + else: + info['__Output']['operSt'] = 'Red' + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_protocol_cdp_interfaces_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.cdp_interfaces: + return self.cdp_interfaces[key] + + cdp_interfaces_mo = self.get_protocol_cdp_interfaces_mo(pod_id, node_id) + if cdp_interfaces_mo is not None: + self.cdp_interfaces[key] = [] + for cdp_interface_mo in cdp_interfaces_mo: + self.cdp_interfaces[key].append( + self.get_protocol_cdp_interface_info( + cdp_interface_mo + ) + ) + + self.log.apic_mo( + 'cdpIf.info.%s' % (key), + self.cdp_interfaces[key] + ) + + return self.cdp_interfaces[key] + + def match_protocol_cdp_interface(self, cdp_interface_info, cdp_interface_filter): + if cdp_interface_filter is None or len(cdp_interface_filter) == 0: + return True + + for ap_rule in cdp_interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'interface': + if not filter_helper.match_string(value, cdp_interface_info['id']): + return False + + return True + + def get_protocol_cdp_interfaces(self, pod_id, node_id, cdp_interface_filter=None): + all_cdp_interfaces = self.get_protocol_cdp_interfaces_info(pod_id, node_id) + if all_cdp_interfaces is None: + return None + + cdp_interfaces = [] + + for cdp_interface_info in all_cdp_interfaces: + if not self.match_protocol_cdp_interface(cdp_interface_info, cdp_interface_filter): + continue + + cdp_interfaces.append( + cdp_interface_info + ) + + cdp_interfaces = sorted( + cdp_interfaces, + key=lambda i: i['id'] + ) + + return cdp_interfaces diff --git a/lib/aci/proto/cdp/interface/main.py b/lib/aci/proto/cdp/interface/main.py new file mode 100644 index 00000000..b3616fd3 --- /dev/null +++ b/lib/aci/proto/cdp/interface/main.py @@ -0,0 +1,10 @@ +from lib.aci.proto.cdp.interface.stats.main import ProtocolCdpInterfaceStats +from lib.aci.proto.cdp.interface.api import ProtocolCdpInterfaceApi +from lib.aci.proto.cdp.interface.info import ProtocolCdpInterfaceInfo + + +class ProtocolCdpInterface(ProtocolCdpInterfaceApi, ProtocolCdpInterfaceInfo, ProtocolCdpInterfaceStats): + def __init__(self): + ProtocolCdpInterfaceApi.__init__(self) + ProtocolCdpInterfaceInfo.__init__(self) + ProtocolCdpInterfaceStats.__init__(self) diff --git a/lib/aci/proto/cdp/interface/stats/__init__.py b/lib/aci/proto/cdp/interface/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/cdp/interface/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/cdp/interface/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..dd60b3be Binary files /dev/null and b/lib/aci/proto/cdp/interface/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/stats/__pycache__/info.cpython-310.pyc b/lib/aci/proto/cdp/interface/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..199befab Binary files /dev/null and b/lib/aci/proto/cdp/interface/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/stats/__pycache__/main.cpython-310.pyc b/lib/aci/proto/cdp/interface/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..cdaed5da Binary files /dev/null and b/lib/aci/proto/cdp/interface/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/interface/stats/info.py b/lib/aci/proto/cdp/interface/stats/info.py new file mode 100644 index 00000000..58ecf720 --- /dev/null +++ b/lib/aci/proto/cdp/interface/stats/info.py @@ -0,0 +1,21 @@ +class ProtocolCdpInterfaceStatsInfo(): + def __init__(self): + pass + + def get_protocol_cdp_interface_stats_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + keys = [ + 'cksumErrRcvd', + 'failedSent', + 'malformRcvd', + 'unSupVerRcvd' + ] + for key in keys: + if info[key] != '0': + info['__Output'][key] = 'Red' + + return info diff --git a/lib/aci/proto/cdp/interface/stats/main.py b/lib/aci/proto/cdp/interface/stats/main.py new file mode 100644 index 00000000..7af3532e --- /dev/null +++ b/lib/aci/proto/cdp/interface/stats/main.py @@ -0,0 +1,6 @@ +from lib.aci.proto.cdp.interface.stats.info import ProtocolCdpInterfaceStatsInfo + + +class ProtocolCdpInterfaceStats(ProtocolCdpInterfaceStatsInfo): + def __init__(self): + ProtocolCdpInterfaceStatsInfo.__init__(self) diff --git a/lib/aci/proto/cdp/main.py b/lib/aci/proto/cdp/main.py new file mode 100644 index 00000000..547c0b4d --- /dev/null +++ b/lib/aci/proto/cdp/main.py @@ -0,0 +1,89 @@ +from lib.aci.proto.cdp.instance.main import ProtocolCdpInstance +from lib.aci.proto.cdp.interface.main import ProtocolCdpInterface +from lib.aci.proto.cdp.neighbor.main import ProtocolCdpNeighbor +from lib.aci.proto.cdp.event.main import ProtocolCdpEvent + + +class ProtocolCdp( + ProtocolCdpInstance, + ProtocolCdpNeighbor, + ProtocolCdpInterface, + ProtocolCdpEvent + ): + def __init__(self): + ProtocolCdpInstance.__init__(self) + ProtocolCdpInterface.__init__(self) + ProtocolCdpNeighbor.__init__(self) + ProtocolCdpEvent.__init__(self) + + def get_protocol_cdp( + self, + pod_id, + node_id, + cdp_filter=None, + instance_info=False, + nei_info=False, + interface_info=False, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_cdp_instance( + pod_id=pod_id, + node_id=node_id + ) + + if nei_info: + info['neighbors'] = self.get_protocol_cdp_neighbors( + pod_id, + node_id, + cdp_neighbor_filter=cdp_filter + ) + + if instance_info: + info['instance']['neighborCount'] = len(info['neighbors']) + + if interface_info: + info['interfaces'] = self.get_protocol_cdp_interfaces( + pod_id, + node_id, + cdp_interface_filter=cdp_filter + ) + + if nei_info: + info['interfaces'] = self.add_protocol_cdp_interface_neighbor_info( + info['interfaces'], + info['neighbors'], + remove_no_neighbors=True + ) + + if instance_info: + info['instance']['activeInterfaceCount'] = self.get_cdp_active_interface_count( + info['interfaces'] + ) + + if event_info: + all_events = self.get_protocol_cdp_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + self.log.apic_mo( + 'cdp.info.%s.%s' % ( + pod_id, + node_id + ), + info + ) + + return info diff --git a/lib/aci/proto/cdp/neighbor/__init__.py b/lib/aci/proto/cdp/neighbor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/cdp/neighbor/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/cdp/neighbor/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..eeda49a5 Binary files /dev/null and b/lib/aci/proto/cdp/neighbor/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/neighbor/__pycache__/api.cpython-310.pyc b/lib/aci/proto/cdp/neighbor/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e6b614ae Binary files /dev/null and b/lib/aci/proto/cdp/neighbor/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/neighbor/__pycache__/info.cpython-310.pyc b/lib/aci/proto/cdp/neighbor/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f48cd371 Binary files /dev/null and b/lib/aci/proto/cdp/neighbor/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/neighbor/__pycache__/main.cpython-310.pyc b/lib/aci/proto/cdp/neighbor/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..701076f5 Binary files /dev/null and b/lib/aci/proto/cdp/neighbor/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/cdp/neighbor/api.py b/lib/aci/proto/cdp/neighbor/api.py new file mode 100644 index 00000000..855c635e --- /dev/null +++ b/lib/aci/proto/cdp/neighbor/api.py @@ -0,0 +1,53 @@ +class ProtocolCdpNeighborApi(): + def __init__(self): + self.cdp_neighbors_mo = {} + + def get_protocol_cdp_neighbors_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.cdp_neighbors_mo: + return self.cdp_neighbors_mo[key] + + cache = self.get_object_cache( + 'cdpAdjEp', + object_selector=key + ) + if cache is not None: + self.cdp_neighbors_mo[key] = cache + self.log.apic_mo( + 'cdpAdjEp.%s' % (key), + self.cdp_neighbors_mo[key] + ) + return self.cdp_neighbors_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/cdp/inst' % (pod_id, node_id) + query = 'query-target=subtree&target-subtree-class=cdpAdjEp' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_cdp_neighbors_mo', + 'API failed' + ) + return None + + self.cdp_neighbors_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.cdp_neighbors_mo[key].append( + managed_object['cdpAdjEp']['attributes'] + ) + + self.log.apic_mo( + 'cdpAdjEp.%s' % (key), + self.cdp_neighbors_mo[key] + ) + + self.set_object_cache( + 'cdpAdjEp', + self.cdp_neighbors_mo[key], + object_selector=key + ) + + return self.cdp_neighbors_mo[key] diff --git a/lib/aci/proto/cdp/neighbor/info.py b/lib/aci/proto/cdp/neighbor/info.py new file mode 100644 index 00000000..13108599 --- /dev/null +++ b/lib/aci/proto/cdp/neighbor/info.py @@ -0,0 +1,98 @@ +from lib import filter_helper + + +class ProtocolCdpNeighborInfo(): + def __init__(self): + self.cdp_neighbors = {} + + def get_protocol_cdp_neighbor_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # topology/pod-1/node-201/sys/cdp/inst/if-[mgmt0]/adj-1 + info['interfaceId'] = info['dn'].split('if-')[1].split(']')[0][1:] + info['__Output']['interfaceId'] = 'Yellow' + + if info['nativeVlan'] == 'unspecified': + info['nativeVlan'] = '' + + return info + + def get_protocol_cdp_neighbors_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.cdp_neighbors: + return self.cdp_neighbors[key] + + cdp_neighbors_mo = self.get_protocol_cdp_neighbors_mo(pod_id, node_id) + if cdp_neighbors_mo is not None: + self.cdp_neighbors[key] = [] + for cdp_neighbor_mo in cdp_neighbors_mo: + self.cdp_neighbors[key].append( + self.get_protocol_cdp_neighbor_info( + cdp_neighbor_mo + ) + ) + + self.log.apic_mo( + 'cdpAdjEp.info.%s' % (key), + self.cdp_neighbors[key] + ) + + return self.cdp_neighbors[key] + + def match_protocol_cdp_neighbor(self, cdp_neighbor_info, cdp_neighbor_filter): + if cdp_neighbor_filter is None or len(cdp_neighbor_filter) == 0: + return True + + for ap_rule in cdp_neighbor_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'system': + if not filter_helper.match_string(value, cdp_neighbor_info['sysName']): + return False + + if key == 'platform': + if not filter_helper.match_string(value, cdp_neighbor_info['platId']): + return False + + if key == 'cap': + if not filter_helper.match_string(value, cdp_neighbor_info['cap']): + return False + + if key == 'interface': + if not filter_helper.match_string(value, cdp_neighbor_info['interfaceId']): + return False + + return True + + def get_protocol_cdp_neighbors(self, pod_id, node_id, cdp_neighbor_filter=None): + all_cdp_neighbors = self.get_protocol_cdp_neighbors_info(pod_id, node_id) + if all_cdp_neighbors is None: + return None + + cdp_neighbors = [] + + for cdp_neighbor_info in all_cdp_neighbors: + if not self.match_protocol_cdp_neighbor(cdp_neighbor_info, cdp_neighbor_filter): + continue + + cdp_neighbors.append( + cdp_neighbor_info + ) + + cdp_neighbors = sorted( + cdp_neighbors, + key=lambda i: i['sysName'] + ) + + return cdp_neighbors diff --git a/lib/aci/proto/cdp/neighbor/main.py b/lib/aci/proto/cdp/neighbor/main.py new file mode 100644 index 00000000..834da73e --- /dev/null +++ b/lib/aci/proto/cdp/neighbor/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.cdp.neighbor.api import ProtocolCdpNeighborApi +from lib.aci.proto.cdp.neighbor.info import ProtocolCdpNeighborInfo + + +class ProtocolCdpNeighbor(ProtocolCdpNeighborApi, ProtocolCdpNeighborInfo): + def __init__(self): + ProtocolCdpNeighborApi.__init__(self) + ProtocolCdpNeighborInfo.__init__(self) diff --git a/lib/aci/proto/cdp/output.py b/lib/aci/proto/cdp/output.py new file mode 100644 index 00000000..13fd46ac --- /dev/null +++ b/lib/aci/proto/cdp/output.py @@ -0,0 +1,209 @@ +class ProtocolCdpOutput(): + def __init__(self): + pass + + def print_proto_cdp_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol CDP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'instance.sysName', + 'instance.adminSt', + 'instance.ver', + 'instance.txFreq', + 'instance.holdIntvl', + 'instance.neighborCount', + 'instance.activeInterfaceCount' + ] + + headers = [ + 'System Name', + 'Admin State', + 'CDP Version', + 'Transmit Frequency', + 'Hold Interval', + 'CDP Neighbors', + 'Active Interfaces' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_cdp_neighbors(self, info, title=False): + if title: + self.my_output.default( + 'Protocol CDP - Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceId', + 'sysName', + 'platId', + 'portId', + 'duplex', + 'mtu', + 'nativeVlan', + 'cap' + ] + + headers = [ + 'Node', + 'Local Interface', + 'Neighbor System Name', + 'Platform', + 'Port', + 'Duplex', + 'MTU', + 'Native VLAN', + 'Capabilities' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_cdp_interfaces(self, info, title=False): + if title: + self.my_output.default( + 'Protocol CDP - Interface Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'id', + 'adminSt', + 'operSt', + 'neighborCount', + 'neighborList', + 'stats.v2Sent', + 'stats.validV2Rcvd', + 'stats.v1Sent', + 'stats.validV1Rcvd', + 'stats.failedSent', + 'stats.cksumErrRcvd', + 'stats.malformRcvd', + 'stats.unSupVerRcvd' + ] + + headers = [ + 'Node', + 'Interface ID', + 'Admin State', + 'Oper State', + 'Count', + 'Neighbors', + 'v2 Sent', + 'v2 Received', + 'v1 Sent', + 'v2 Received', + 'Failed Sent', + 'Checksum Error', + 'Malformed', + 'Unsupported Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_cdp_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol CDP - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol CDP - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceT', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/hsrp/__init__.py b/lib/aci/proto/hsrp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/hsrp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1c28bb47 Binary files /dev/null and b/lib/aci/proto/hsrp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/hsrp/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..2272183f Binary files /dev/null and b/lib/aci/proto/hsrp/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/hsrp/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..69ecfb1b Binary files /dev/null and b/lib/aci/proto/hsrp/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/__pycache__/interface.cpython-310.pyc b/lib/aci/proto/hsrp/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..53d828a9 Binary files /dev/null and b/lib/aci/proto/hsrp/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/hsrp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4d17b946 Binary files /dev/null and b/lib/aci/proto/hsrp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/__pycache__/output.cpython-310.pyc b/lib/aci/proto/hsrp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..57cf650b Binary files /dev/null and b/lib/aci/proto/hsrp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/domain/__init__.py b/lib/aci/proto/hsrp/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/hsrp/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..55e65cfc Binary files /dev/null and b/lib/aci/proto/hsrp/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/hsrp/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..8fbf61f5 Binary files /dev/null and b/lib/aci/proto/hsrp/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/hsrp/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b7d03d89 Binary files /dev/null and b/lib/aci/proto/hsrp/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/hsrp/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c6ebaba8 Binary files /dev/null and b/lib/aci/proto/hsrp/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/domain/api.py b/lib/aci/proto/hsrp/domain/api.py new file mode 100644 index 00000000..35d928c3 --- /dev/null +++ b/lib/aci/proto/hsrp/domain/api.py @@ -0,0 +1,64 @@ +class ProtocolHsrpDomainApi(): + def __init__(self): + self.hsrp_domains_mo = {} + + def get_protocol_hsrp_domains_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.hsrp_domains_mo: + return self.hsrp_domains_mo[key] + + cache = self.get_object_cache( + 'hsrpDom', + object_selector=key + ) + if cache is not None: + self.hsrp_domains_mo[key] = cache + self.log.apic_mo( + 'hsrpDom.%s' % (key), + self.hsrp_domains_mo[key] + ) + return self.hsrp_domains_mo[key] + + class_name = 'topology/pod-%s/node-%s/hsrpDom' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_hsrp_domains_mo', + 'API failed' + ) + return None + + self.hsrp_domains_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['hsrpDom']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'hsrpDom', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'hsrpDom', + managed_object, + 'faultCounts' + ) + self.hsrp_domains_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'hsrpDom.%s' % (key), + self.hsrp_domains_mo[key] + ) + + self.set_object_cache( + 'hsrpDom', + self.hsrp_domains_mo[key], + object_selector=key + ) + + return self.hsrp_domains_mo[key] diff --git a/lib/aci/proto/hsrp/domain/info.py b/lib/aci/proto/hsrp/domain/info.py new file mode 100644 index 00000000..bbc65db2 --- /dev/null +++ b/lib/aci/proto/hsrp/domain/info.py @@ -0,0 +1,98 @@ +from lib import filter_helper + + +class ProtocolHsrpDomainInfo(): + def __init__(self): + self.hsrp_domains = {} + + def add_protocol_hsrp_domain_interface_info(self, domains, interfaces): + for domain in domains: + domain['interfacesCount'] = 0 + + for interface in interfaces: + if interface['domainName'] == domain['name']: + domain['interfacesCount'] = domain['interfacesCount'] + 1 + + return domains + + def get_protocol_hsrp_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['name'] = 'Yellow' + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_hsrp_domains_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.hsrp_domains: + return self.hsrp_domains[key] + + hsrp_domains_mo = self.get_protocol_hsrp_domains_mo(pod_id, node_id) + if hsrp_domains_mo is not None: + self.hsrp_domains[key] = [] + for hsrp_domain_mo in hsrp_domains_mo: + self.hsrp_domains[key].append( + self.get_protocol_hsrp_domain_info( + hsrp_domain_mo + ) + ) + + return self.hsrp_domains[key] + + def match_protocol_hsrp_domain(self, hsrp_domain_info, hsrp_domain_filter): + if hsrp_domain_filter is None or len(hsrp_domain_filter) == 0: + return True + + for ap_rule in hsrp_domain_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'vrf': + if not filter_helper.match_string(value, hsrp_domain_info['name']): + return False + + return True + + def get_protocol_hsrp_domains(self, pod_id, node_id, hsrp_domain_filter=None): + all_hsrp_domains = self.get_protocol_hsrp_domains_info(pod_id, node_id) + if all_hsrp_domains is None: + return None + + hsrp_domains = [] + + for hsrp_domain_info in all_hsrp_domains: + if not self.match_protocol_hsrp_domain(hsrp_domain_info, hsrp_domain_filter): + continue + + hsrp_domains.append( + hsrp_domain_info + ) + + hsrp_domains = sorted( + hsrp_domains, + key=lambda i: i['name'].lower() + ) + + return hsrp_domains diff --git a/lib/aci/proto/hsrp/domain/main.py b/lib/aci/proto/hsrp/domain/main.py new file mode 100644 index 00000000..ef9fa49c --- /dev/null +++ b/lib/aci/proto/hsrp/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.hsrp.domain.api import ProtocolHsrpDomainApi +from lib.aci.proto.hsrp.domain.info import ProtocolHsrpDomainInfo + + +class ProtocolHsrpDomain(ProtocolHsrpDomainApi, ProtocolHsrpDomainInfo): + def __init__(self): + ProtocolHsrpDomainApi.__init__(self) + ProtocolHsrpDomainInfo.__init__(self) diff --git a/lib/aci/proto/hsrp/event/__init__.py b/lib/aci/proto/hsrp/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/event/api.py b/lib/aci/proto/hsrp/event/api.py new file mode 100644 index 00000000..caa636fa --- /dev/null +++ b/lib/aci/proto/hsrp/event/api.py @@ -0,0 +1,55 @@ +class ProtocolHsrpEventApi(): + def __init__(self): + self.proto_hsrp_event_mo = {} + + def get_protocol_hsrp_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_hsrp_event_mo: + return self.proto_hsrp_event_mo[key] + + cache = self.get_object_cache( + 'hsrp.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_hsrp_event_mo[key] = cache + self.log.apic_mo( + 'hsrp.eventLog.%s' % (key), + self.proto_hsrp_event_mo[key] + ) + return self.proto_hsrp_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/hsrp' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_hsrp_event_mo', + 'API failed' + ) + return None + + self.proto_hsrp_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_hsrp_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'hsrp.eventLog.%s' % (key), + self.proto_hsrp_event_mo[key] + ) + + self.set_object_cache( + 'hsrp.eventLog', + self.proto_hsrp_event_mo[key], + object_selector=key + ) + + return self.proto_hsrp_event_mo[key] diff --git a/lib/aci/proto/hsrp/event/info.py b/lib/aci/proto/hsrp/event/info.py new file mode 100644 index 00000000..684f642c --- /dev/null +++ b/lib/aci/proto/hsrp/event/info.py @@ -0,0 +1,83 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolHsrpEventInfo(): + def __init__(self): + self.proto_hsrp_event = {} + + def get_protocol_hsrp_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/hsrp/inst + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_hsrp_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_hsrp_event: + return self.proto_hsrp_event[key] + + managed_objects = self.get_protocol_hsrp_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_hsrp_event[key] = [] + for managed_object in managed_objects: + self.proto_hsrp_event[key].append( + self.get_protocol_hsrp_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'hsrp.eventLog.info.%s' % (key), + self.proto_hsrp_event[key] + ) + + return self.proto_hsrp_event[key] diff --git a/lib/aci/proto/hsrp/event/main.py b/lib/aci/proto/hsrp/event/main.py new file mode 100644 index 00000000..2edacfb7 --- /dev/null +++ b/lib/aci/proto/hsrp/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.hsrp.event.api import ProtocolHsrpEventApi +from lib.aci.proto.hsrp.event.info import ProtocolHsrpEventInfo + + +class ProtocolHsrpEvent(ProtocolHsrpEventApi, ProtocolHsrpEventInfo): + def __init__(self): + ProtocolHsrpEventApi.__init__(self) + ProtocolHsrpEventInfo.__init__(self) diff --git a/lib/aci/proto/hsrp/fault/__init__.py b/lib/aci/proto/hsrp/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/fault/api.py b/lib/aci/proto/hsrp/fault/api.py new file mode 100644 index 00000000..d2932528 --- /dev/null +++ b/lib/aci/proto/hsrp/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolHsrpFaultApi(): + def __init__(self): + self.proto_hsrp_fault_mo = {} + self.proto_hsrp_fault_record_mo = {} + + def get_protocol_hsrp_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_hsrp_fault_mo: + return self.proto_hsrp_fault_mo[key] + + cache = self.get_object_cache( + 'hsrp.fault', + object_selector=key + ) + if cache is not None: + self.proto_hsrp_fault_mo[key] = cache + self.log.apic_mo( + 'hsrp.fault.%s' % (key), + self.proto_hsrp_fault_mo[key] + ) + return self.proto_hsrp_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/hsrp' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_hsrp_fault_mo', + 'API failed' + ) + return None + + self.proto_hsrp_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_hsrp_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'hsrp.fault.%s' % (key), + self.proto_hsrp_fault_mo[key] + ) + + self.set_object_cache( + 'hsrp.fault', + self.proto_hsrp_fault_mo[key], + object_selector=key + ) + + return self.proto_hsrp_fault_mo[key] + + def get_protocol_hsrp_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_hsrp_fault_record_mo: + return self.proto_hsrp_fault_record_mo[key] + + cache = self.get_object_cache( + 'hsrp.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_hsrp_fault_record_mo[key] = cache + self.log.apic_mo( + 'hsrp.faultRecord.%s' % (key), + self.proto_hsrp_fault_record_mo[key] + ) + return self.proto_hsrp_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/hsrp' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_hsrp_fault_record_mo', + 'API failed' + ) + return None + + self.proto_hsrp_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_hsrp_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'hsrp.faultRecord.%s' % (key), + self.proto_hsrp_fault_record_mo[key] + ) + + self.set_object_cache( + 'hsrp.faultRecord', + self.proto_hsrp_fault_record_mo[key], + object_selector=key + ) + + return self.proto_hsrp_fault_record_mo[key] diff --git a/lib/aci/proto/hsrp/fault/info.py b/lib/aci/proto/hsrp/fault/info.py new file mode 100644 index 00000000..aee77b9d --- /dev/null +++ b/lib/aci/proto/hsrp/fault/info.py @@ -0,0 +1,69 @@ +class ProtocolHsrpFaultInfo(): + def __init__(self): + self.proto_hsrp_fault = {} + self.proto_hsrp_fault_record = {} + + def get_protocol_hsrp_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_hsrp_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_hsrp_fault: + return self.proto_hsrp_fault[key] + + managed_objects = self.get_protocol_hsrp_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_hsrp_fault[key] = [] + for managed_object in managed_objects: + self.proto_hsrp_fault[key].append( + self.get_protocol_hsrp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'hsrp.fault.info.%s' % (key), + self.proto_hsrp_fault[key] + ) + + return self.proto_hsrp_fault[key] + + def get_protocol_hsrp_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_hsrp_fault_record: + return self.proto_hsrp_fault_record[key] + + managed_objects = self.get_protocol_hsrp_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_hsrp_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_hsrp_fault_record[key].append( + self.get_protocol_hsrp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'hsrp.faultRecord.info.%s' % (key), + self.proto_hsrp_fault_record[key] + ) + + return self.proto_hsrp_fault_record[key] diff --git a/lib/aci/proto/hsrp/fault/main.py b/lib/aci/proto/hsrp/fault/main.py new file mode 100644 index 00000000..92a65224 --- /dev/null +++ b/lib/aci/proto/hsrp/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.hsrp.fault.api import ProtocolHsrpFaultApi +from lib.aci.proto.hsrp.fault.info import ProtocolHsrpFaultInfo + + +class ProtocolHsrpFault(ProtocolHsrpFaultApi, ProtocolHsrpFaultInfo): + def __init__(self): + ProtocolHsrpFaultApi.__init__(self) + ProtocolHsrpFaultInfo.__init__(self) diff --git a/lib/aci/proto/hsrp/instance/__init__.py b/lib/aci/proto/hsrp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/hsrp/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9d11ce37 Binary files /dev/null and b/lib/aci/proto/hsrp/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/hsrp/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..1efe94ae Binary files /dev/null and b/lib/aci/proto/hsrp/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/hsrp/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..e5c11d15 Binary files /dev/null and b/lib/aci/proto/hsrp/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/hsrp/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..64095b0e Binary files /dev/null and b/lib/aci/proto/hsrp/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/instance/api.py b/lib/aci/proto/hsrp/instance/api.py new file mode 100644 index 00000000..84027e07 --- /dev/null +++ b/lib/aci/proto/hsrp/instance/api.py @@ -0,0 +1,71 @@ +class ProtocolHsrpInstanceApi(): + def __init__(self): + self.hsrp_instance_mo = {} + + def get_protocol_hsrp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.hsrp_instance_mo: + return self.hsrp_instance_mo[key] + + cache = self.get_object_cache( + 'hsrpInst', + object_selector=key + ) + if cache is not None: + self.hsrp_instance_mo[key] = cache + self.log.apic_mo( + 'hsrpInst.%s' % (key), + self.hsrp_instance_mo[key] + ) + return self.hsrp_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/hsrp' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_hsrp_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_hsrp_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.hsrp_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['hsrpInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'hsrpInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'hsrpInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.hsrp_instance_mo[key] = attributes + + self.log.apic_mo( + 'hsrpInst.%s' % (key), + self.hsrp_instance_mo[key] + ) + + self.set_object_cache( + 'hsrpInst', + self.hsrp_instance_mo[key], + object_selector=key + ) + + return self.hsrp_instance_mo[key] diff --git a/lib/aci/proto/hsrp/instance/info.py b/lib/aci/proto/hsrp/instance/info.py new file mode 100644 index 00000000..e618f40d --- /dev/null +++ b/lib/aci/proto/hsrp/instance/info.py @@ -0,0 +1,44 @@ +class ProtocolHsrpInstanceInfo(): + def __init__(self): + pass + + def get_protocol_hsrp_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_hsrp_instance(self, pod_id, node_id): + managed_object = self.get_protocol_hsrp_instance_mo(pod_id, node_id) + if managed_object is None: + return None + + return self.get_protocol_hsrp_instance_info(managed_object) diff --git a/lib/aci/proto/hsrp/instance/main.py b/lib/aci/proto/hsrp/instance/main.py new file mode 100644 index 00000000..f867712a --- /dev/null +++ b/lib/aci/proto/hsrp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.hsrp.instance.api import ProtocolHsrpInstanceApi +from lib.aci.proto.hsrp.instance.info import ProtocolHsrpInstanceInfo + + +class ProtocolHsrpInstance(ProtocolHsrpInstanceApi, ProtocolHsrpInstanceInfo): + def __init__(self): + ProtocolHsrpInstanceApi.__init__(self) + ProtocolHsrpInstanceInfo.__init__(self) diff --git a/lib/aci/proto/hsrp/interface/__init__.py b/lib/aci/proto/hsrp/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/hsrp/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ebb8028b Binary files /dev/null and b/lib/aci/proto/hsrp/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/__pycache__/api.cpython-310.pyc b/lib/aci/proto/hsrp/interface/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d1df156c Binary files /dev/null and b/lib/aci/proto/hsrp/interface/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/__pycache__/info.cpython-310.pyc b/lib/aci/proto/hsrp/interface/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..300a41b9 Binary files /dev/null and b/lib/aci/proto/hsrp/interface/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/__pycache__/main.cpython-310.pyc b/lib/aci/proto/hsrp/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..25ebb11a Binary files /dev/null and b/lib/aci/proto/hsrp/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/api.py b/lib/aci/proto/hsrp/interface/api.py new file mode 100644 index 00000000..3baab2f0 --- /dev/null +++ b/lib/aci/proto/hsrp/interface/api.py @@ -0,0 +1,61 @@ +class ProtocolHsrpInterfaceApi(): + def __init__(self): + self.hsrp_interfaces_mo = {} + + def get_protocol_hsrp_interfaces_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.hsrp_interfaces_mo: + return self.hsrp_interfaces_mo[key] + + cache = self.get_object_cache( + 'hsrpIf', + object_selector=key + ) + if cache is not None: + self.hsrp_interfaces_mo[key] = cache + self.log.apic_mo( + 'hsrpIf.%s' % (key), + self.hsrp_interfaces_mo[key] + ) + return self.hsrp_interfaces_mo[key] + + class_name = 'topology/pod-%s/node-%s/hsrpIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-class=hsrpIf,hsrpIfStats&rsp-subtree-include=required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_hsrp_interfaces_mo', + 'API failed' + ) + return None + + self.hsrp_interfaces_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'hsrpIf' in managed_object: + attributes = managed_object['hsrpIf']['attributes'] + attributes['stats'] = self.get_mo_child_attributes( + 'hsrpIf', + managed_object, + 'hsrpIfStats' + ) + + self.hsrp_interfaces_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'hsrpIf.%s' % (key), + self.hsrp_interfaces_mo[key] + ) + + self.set_object_cache( + 'hsrpIf', + self.hsrp_interfaces_mo[key], + object_selector=key + ) + + return self.hsrp_interfaces_mo[key] diff --git a/lib/aci/proto/hsrp/interface/info.py b/lib/aci/proto/hsrp/interface/info.py new file mode 100644 index 00000000..402f6540 --- /dev/null +++ b/lib/aci/proto/hsrp/interface/info.py @@ -0,0 +1,93 @@ +from lib import filter_helper + + +class ProtocolHsrpInterfaceInfo(): + def __init__(self): + self.hsrp_interfaces = {} + + def get_protocol_hsrp_interface_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key == 'stats': + info[key] = self.get_protocol_hsrp_interface_stats_info(managed_object[key]) + info['stats'] = self.my_output.merge_output( + info['stats'] + ) + else: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['domainName'] = info['dn'].split('/')[6][4:] + + info['__Output']['id'] = 'Yellow' + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_protocol_hsrp_interfaces_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.hsrp_interfaces: + return self.hsrp_interfaces[key] + + hsrp_interfaces_mo = self.get_protocol_hsrp_interfaces_mo(pod_id, node_id) + if hsrp_interfaces_mo is not None: + self.hsrp_interfaces[key] = [] + for hsrp_interface_mo in hsrp_interfaces_mo: + self.hsrp_interfaces[key].append( + self.get_protocol_hsrp_interface_info( + hsrp_interface_mo + ) + ) + + self.log.apic_mo( + 'hsrpIf.info.%s' % (key), + self.hsrp_interfaces[key] + ) + + return self.hsrp_interfaces[key] + + def match_protocol_hsrp_interface(self, hsrp_interface_info, hsrp_interface_filter): + if hsrp_interface_filter is None or len(hsrp_interface_filter) == 0: + return True + + for ap_rule in hsrp_interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'interface': + if not filter_helper.match_string(value, hsrp_interface_info['id']): + return False + + return True + + def get_protocol_hsrp_interfaces(self, pod_id, node_id, hsrp_interface_filter=None): + all_hsrp_interfaces = self.get_protocol_hsrp_interfaces_info(pod_id, node_id) + if all_hsrp_interfaces is None: + return None + + hsrp_interfaces = [] + + for hsrp_interface_info in all_hsrp_interfaces: + if not self.match_protocol_hsrp_interface(hsrp_interface_info, hsrp_interface_filter): + continue + + hsrp_interfaces.append( + hsrp_interface_info + ) + + hsrp_interfaces = sorted( + hsrp_interfaces, + key=lambda i: i['id'] + ) + + return hsrp_interfaces diff --git a/lib/aci/proto/hsrp/interface/main.py b/lib/aci/proto/hsrp/interface/main.py new file mode 100644 index 00000000..efd5f4b7 --- /dev/null +++ b/lib/aci/proto/hsrp/interface/main.py @@ -0,0 +1,10 @@ +from lib.aci.proto.hsrp.interface.stats.main import ProtocolHsrpInterfaceStats +from lib.aci.proto.hsrp.interface.api import ProtocolHsrpInterfaceApi +from lib.aci.proto.hsrp.interface.info import ProtocolHsrpInterfaceInfo + + +class ProtocolHsrpInterface(ProtocolHsrpInterfaceApi, ProtocolHsrpInterfaceInfo, ProtocolHsrpInterfaceStats): + def __init__(self): + ProtocolHsrpInterfaceApi.__init__(self) + ProtocolHsrpInterfaceInfo.__init__(self) + ProtocolHsrpInterfaceStats.__init__(self) diff --git a/lib/aci/proto/hsrp/interface/stats/__init__.py b/lib/aci/proto/hsrp/interface/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/hsrp/interface/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/hsrp/interface/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..dd60b3be Binary files /dev/null and b/lib/aci/proto/hsrp/interface/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/stats/__pycache__/info.cpython-310.pyc b/lib/aci/proto/hsrp/interface/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..7ef94ce6 Binary files /dev/null and b/lib/aci/proto/hsrp/interface/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/stats/__pycache__/main.cpython-310.pyc b/lib/aci/proto/hsrp/interface/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..46cb659e Binary files /dev/null and b/lib/aci/proto/hsrp/interface/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/hsrp/interface/stats/info.py b/lib/aci/proto/hsrp/interface/stats/info.py new file mode 100644 index 00000000..0ecd356c --- /dev/null +++ b/lib/aci/proto/hsrp/interface/stats/info.py @@ -0,0 +1,11 @@ +class ProtocolHsrpInterfaceStatsInfo(): + def __init__(self): + pass + + def get_protocol_hsrp_interface_stats_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/proto/hsrp/interface/stats/main.py b/lib/aci/proto/hsrp/interface/stats/main.py new file mode 100644 index 00000000..a529198c --- /dev/null +++ b/lib/aci/proto/hsrp/interface/stats/main.py @@ -0,0 +1,6 @@ +from lib.aci.proto.hsrp.interface.stats.info import ProtocolHsrpInterfaceStatsInfo + + +class ProtocolHsrpInterfaceStats(ProtocolHsrpInterfaceStatsInfo): + def __init__(self): + ProtocolHsrpInterfaceStatsInfo.__init__(self) diff --git a/lib/aci/proto/hsrp/main.py b/lib/aci/proto/hsrp/main.py new file mode 100644 index 00000000..b4a183d9 --- /dev/null +++ b/lib/aci/proto/hsrp/main.py @@ -0,0 +1,98 @@ +from lib.aci.proto.hsrp.instance.main import ProtocolHsrpInstance +from lib.aci.proto.hsrp.domain.main import ProtocolHsrpDomain +from lib.aci.proto.hsrp.interface.main import ProtocolHsrpInterface +from lib.aci.proto.hsrp.event.main import ProtocolHsrpEvent +from lib.aci.proto.hsrp.fault.main import ProtocolHsrpFault + + +class ProtocolHsrp( + ProtocolHsrpInstance, + ProtocolHsrpDomain, + ProtocolHsrpInterface, + ProtocolHsrpEvent, + ProtocolHsrpFault + ): + def __init__(self): + ProtocolHsrpInstance.__init__(self) + ProtocolHsrpDomain.__init__(self) + ProtocolHsrpInterface.__init__(self) + ProtocolHsrpEvent.__init__(self) + ProtocolHsrpFault.__init__(self) + + def get_protocol_hsrp( + self, + pod_id, + node_id, + hsrp_filter=None, + instance_info=False, + domain_info=False, + interface_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_hsrp_instance( + pod_id=pod_id, + node_id=node_id + ) + + if domain_info: + info['domains'] = self.get_protocol_hsrp_domains( + pod_id=pod_id, + node_id=node_id, + hsrp_domain_filter=hsrp_filter + ) + + if interface_info: + info['interfaces'] = self.get_protocol_hsrp_interfaces( + pod_id=pod_id, + node_id=node_id, + hsrp_interface_filter=hsrp_filter + ) + + if domain_info: + info['domains'] = self.add_protocol_hsrp_domain_interface_info( + info['domains'], + info['interfaces'] + ) + + if fault_info: + info['faultInst'] = self.get_protocol_hsrp_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_hsrp_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_hsrp_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/hsrp/output.py b/lib/aci/proto/hsrp/output.py new file mode 100644 index 00000000..c1acbd82 --- /dev/null +++ b/lib/aci/proto/hsrp/output.py @@ -0,0 +1,261 @@ +import json + + +class ProtocolHsrpOutput(): + def __init__(self): + pass + + def print_proto_hsrp_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol HSRP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'instance.pod_node_name', + 'instance.adminSt', + 'instance.health', + 'instance.faults' + ] + + headers = [ + 'Node', + 'Admin State', + 'Health', + 'Faults' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_hsrp_domains(self, info, title=False): + if title: + self.my_output.default( + 'Protocol HSRP - Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + if len(info) == 0: + return + + order = [ + 'pod_node_name', + 'name', + 'health', + 'faults', + 'interfacesCount' + ] + + headers = [ + 'Node', + 'VRF', + 'Health', + 'Faults', + 'Interfaces' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_hsrp_interfaces(self, info, title=False): + if title: + self.my_output.default( + 'Protocol HSRP - Interface [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) + + def print_proto_hsrp_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol HSRP - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_hsrp_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol HSRP - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol HSRP - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_hsrp_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol HSRP - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol HSRP - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/ipv4/__init__.py b/lib/aci/proto/ipv4/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv4/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/ipv4/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..edb91740 Binary files /dev/null and b/lib/aci/proto/ipv4/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/ipv4/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..4ef9aa44 Binary files /dev/null and b/lib/aci/proto/ipv4/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/__pycache__/main.cpython-310.pyc b/lib/aci/proto/ipv4/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..42d3673d Binary files /dev/null and b/lib/aci/proto/ipv4/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/__pycache__/output.cpython-310.pyc b/lib/aci/proto/ipv4/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..b032cdb7 Binary files /dev/null and b/lib/aci/proto/ipv4/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/__pycache__/route.cpython-310.pyc b/lib/aci/proto/ipv4/__pycache__/route.cpython-310.pyc new file mode 100644 index 00000000..1585e1d0 Binary files /dev/null and b/lib/aci/proto/ipv4/__pycache__/route.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/domain/__init__.py b/lib/aci/proto/ipv4/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv4/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/ipv4/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..36975862 Binary files /dev/null and b/lib/aci/proto/ipv4/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/ipv4/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2a05b6af Binary files /dev/null and b/lib/aci/proto/ipv4/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/ipv4/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..28c7bd93 Binary files /dev/null and b/lib/aci/proto/ipv4/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/ipv4/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..43a28e71 Binary files /dev/null and b/lib/aci/proto/ipv4/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/domain/api.py b/lib/aci/proto/ipv4/domain/api.py new file mode 100644 index 00000000..d4e7a5e1 --- /dev/null +++ b/lib/aci/proto/ipv4/domain/api.py @@ -0,0 +1,63 @@ +class ProtocolIpv4DomainApi(): + def __init__(self): + self.ipv4_domains_mo = {} + + def get_protocol_ipv4_domains_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.ipv4_domains_mo: + return self.ipv4_domains_mo[key] + + cache = self.get_object_cache( + 'uribv4Dom', + object_selector=key + ) + if cache is not None: + self.ipv4_domains_mo[key] = cache + self.log.apic_mo( + 'uribv4Dom.%s' % (key), + self.ipv4_domains_mo[key] + ) + return self.ipv4_domains_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/uribv4' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count&target-subtree-class=uribv4Dom' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + if managed_objects is None: + self.log.error( + 'get_protocol_ipv4_domains_mo', + 'API failed' + ) + return None + + self.ipv4_domains_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['uribv4Dom']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'uribv4Dom', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'uribv4Dom', + managed_object, + 'faultCounts' + ) + self.ipv4_domains_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'uribv4Dom.%s' % (key), + self.ipv4_domains_mo[key] + ) + + self.set_object_cache( + 'uribv4Dom', + self.ipv4_domains_mo[key], + object_selector=key + ) + + return self.ipv4_domains_mo[key] diff --git a/lib/aci/proto/ipv4/domain/info.py b/lib/aci/proto/ipv4/domain/info.py new file mode 100644 index 00000000..490fcabb --- /dev/null +++ b/lib/aci/proto/ipv4/domain/info.py @@ -0,0 +1,93 @@ +from lib import filter_helper + + +class ProtocolIpv4DomainInfo(): + def __init__(self): + self.ipv4_domains = {} + + def get_protocol_ipv4_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['__Output']['name'] = 'Yellow' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_ipv4_domains_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.ipv4_domains: + return self.ipv4_domains[key] + + ipv4_domains_mo = self.get_protocol_ipv4_domains_mo(pod_id, node_id) + if ipv4_domains_mo is not None: + self.ipv4_domains[key] = [] + for ipv4_domain_mo in ipv4_domains_mo: + self.ipv4_domains[key].append( + self.get_protocol_ipv4_domain_info( + ipv4_domain_mo + ) + ) + + return self.ipv4_domains[key] + + def match_protocol_ipv4_domain(self, ipv4_domain_info, ipv4_domain_filter): + if ipv4_domain_filter is None or len(ipv4_domain_filter) == 0: + return True + + for ap_rule in ipv4_domain_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'vrf': + if not filter_helper.match_tenant_name(value, ipv4_domain_info['name'], delimiter=':'): + return False + + return True + + def get_protocol_ipv4_domains(self, pod_id, node_id, ipv4_domain_filter=None): + all_ipv4_domains = self.get_protocol_ipv4_domains_info(pod_id, node_id) + if all_ipv4_domains is None: + return None + + ipv4_domains = [] + + for ipv4_domain_info in all_ipv4_domains: + if not self.match_protocol_ipv4_domain(ipv4_domain_info, ipv4_domain_filter): + continue + + ipv4_domains.append( + ipv4_domain_info + ) + + ipv4_domains = sorted( + ipv4_domains, + key=lambda i: i['name'].lower() + ) + + return ipv4_domains diff --git a/lib/aci/proto/ipv4/domain/main.py b/lib/aci/proto/ipv4/domain/main.py new file mode 100644 index 00000000..65df5791 --- /dev/null +++ b/lib/aci/proto/ipv4/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv4.domain.api import ProtocolIpv4DomainApi +from lib.aci.proto.ipv4.domain.info import ProtocolIpv4DomainInfo + + +class ProtocolIpv4Domain(ProtocolIpv4DomainApi, ProtocolIpv4DomainInfo): + def __init__(self): + ProtocolIpv4DomainApi.__init__(self) + ProtocolIpv4DomainInfo.__init__(self) diff --git a/lib/aci/proto/ipv4/event/__init__.py b/lib/aci/proto/ipv4/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv4/event/api.py b/lib/aci/proto/ipv4/event/api.py new file mode 100644 index 00000000..f7182db3 --- /dev/null +++ b/lib/aci/proto/ipv4/event/api.py @@ -0,0 +1,55 @@ +class ProtocolIpv4EventApi(): + def __init__(self): + self.proto_ipv4_event_mo = {} + + def get_protocol_ipv4_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv4_event_mo: + return self.proto_ipv4_event_mo[key] + + cache = self.get_object_cache( + 'ipv4Dom.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_ipv4_event_mo[key] = cache + self.log.apic_mo( + 'ipv4Dom.eventLog.%s' % (key), + self.proto_ipv4_event_mo[key] + ) + return self.proto_ipv4_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv4' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv4_event_mo', + 'API failed' + ) + return None + + self.proto_ipv4_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_ipv4_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ipv4Dom.eventLog.%s' % (key), + self.proto_ipv4_event_mo[key] + ) + + self.set_object_cache( + 'ipv4Dom.eventLog', + self.proto_ipv4_event_mo[key], + object_selector=key + ) + + return self.proto_ipv4_event_mo[key] diff --git a/lib/aci/proto/ipv4/event/info.py b/lib/aci/proto/ipv4/event/info.py new file mode 100644 index 00000000..df6aaf8e --- /dev/null +++ b/lib/aci/proto/ipv4/event/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolIpv4EventInfo(): + def __init__(self): + self.proto_ipv4_event = {} + + def get_protocol_ipv4_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2208/sys/ipv4/inst/dom-common:Infra_privIP_VRF/if-[vlan50]/addr-[/24] + info['domainName'] = None + if 'sys/ipv4/inst/dom-' in info['affected']: + info['domainName'] = info['affected'].split('sys/ipv4/inst/dom-')[1].split('/')[0] + info['domainNameT'] = info['domainName'] + if info['domainNameT'] is None: + info['domainNameT'] = '--' + + info['interfaceId'] = None + if '/if-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/if-[')[1].split(']')[0] + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['address'] = None + if '/addr-[' in info['affected']: + info['address'] = info['affected'].split('/addr-[')[1].split(']')[0] + info['addressT'] = info['address'] + if info['addressT'] is None: + info['addressT'] = '--' + + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_ipv4_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv4_event: + return self.proto_ipv4_event[key] + + managed_objects = self.get_protocol_ipv4_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_ipv4_event[key] = [] + for managed_object in managed_objects: + self.proto_ipv4_event[key].append( + self.get_protocol_ipv4_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ipv4Dom.eventLog.info.%s' % (key), + self.proto_ipv4_event[key] + ) + + return self.proto_ipv4_event[key] diff --git a/lib/aci/proto/ipv4/event/main.py b/lib/aci/proto/ipv4/event/main.py new file mode 100644 index 00000000..f4150323 --- /dev/null +++ b/lib/aci/proto/ipv4/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv4.event.api import ProtocolIpv4EventApi +from lib.aci.proto.ipv4.event.info import ProtocolIpv4EventInfo + + +class ProtocolIpv4Event(ProtocolIpv4EventApi, ProtocolIpv4EventInfo): + def __init__(self): + ProtocolIpv4EventApi.__init__(self) + ProtocolIpv4EventInfo.__init__(self) diff --git a/lib/aci/proto/ipv4/fault/__init__.py b/lib/aci/proto/ipv4/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv4/fault/api.py b/lib/aci/proto/ipv4/fault/api.py new file mode 100644 index 00000000..58fd41f5 --- /dev/null +++ b/lib/aci/proto/ipv4/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolIpv4FaultApi(): + def __init__(self): + self.proto_ipv4_fault_mo = {} + self.proto_ipv4_fault_record_mo = {} + + def get_protocol_ipv4_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv4_fault_mo: + return self.proto_ipv4_fault_mo[key] + + cache = self.get_object_cache( + 'ipv4Dom.fault', + object_selector=key + ) + if cache is not None: + self.proto_ipv4_fault_mo[key] = cache + self.log.apic_mo( + 'ipv4Dom.fault.%s' % (key), + self.proto_ipv4_fault_mo[key] + ) + return self.proto_ipv4_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv4' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv4_fault_mo', + 'API failed' + ) + return None + + self.proto_ipv4_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_ipv4_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ipv4Dom.fault.%s' % (key), + self.proto_ipv4_fault_mo[key] + ) + + self.set_object_cache( + 'ipv4Dom.fault', + self.proto_ipv4_fault_mo[key], + object_selector=key + ) + + return self.proto_ipv4_fault_mo[key] + + def get_protocol_ipv4_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv4_fault_record_mo: + return self.proto_ipv4_fault_record_mo[key] + + cache = self.get_object_cache( + 'ipv4Dom.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_ipv4_fault_record_mo[key] = cache + self.log.apic_mo( + 'ipv4Dom.faultRecord.%s' % (key), + self.proto_ipv4_fault_record_mo[key] + ) + return self.proto_ipv4_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv4' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv4_fault_record_mo', + 'API failed' + ) + return None + + self.proto_ipv4_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_ipv4_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ipv4Dom.faultRecord.%s' % (key), + self.proto_ipv4_fault_record_mo[key] + ) + + self.set_object_cache( + 'ipv4Dom.faultRecord', + self.proto_ipv4_fault_record_mo[key], + object_selector=key + ) + + return self.proto_ipv4_fault_record_mo[key] diff --git a/lib/aci/proto/ipv4/fault/info.py b/lib/aci/proto/ipv4/fault/info.py new file mode 100644 index 00000000..a750cd50 --- /dev/null +++ b/lib/aci/proto/ipv4/fault/info.py @@ -0,0 +1,94 @@ +class ProtocolIpv4FaultInfo(): + def __init__(self): + self.proto_ipv4_fault = {} + self.proto_ipv4_fault_record = {} + + def get_protocol_ipv4_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # topology/pod-1/node-2208/sys/ipv4/inst/dom-common:Infra_privIP_VRF/if-[vlan50]/addr-[/24] + info['domainName'] = None + if 'affected' in info: + if 'sys/ipv4/inst/dom-' in info['affected']: + info['domainName'] = info['affected'].split('sys/ipv4/inst/dom-')[1].split('/')[0] + info['domainNameT'] = info['domainName'] + if info['domainNameT'] is None: + info['domainNameT'] = '--' + + info['interfaceId'] = None + if 'affected' in info: + if '/if-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/if-[')[1].split(']')[0] + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['address'] = None + if 'affected' in info: + if '/addr-[' in info['affected']: + info['address'] = info['affected'].split('/addr-[')[1].split(']')[0] + info['addressT'] = info['address'] + if info['addressT'] is None: + info['addressT'] = '--' + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_ipv4_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv4_fault: + return self.proto_ipv4_fault[key] + + managed_objects = self.get_protocol_ipv4_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_ipv4_fault[key] = [] + for managed_object in managed_objects: + self.proto_ipv4_fault[key].append( + self.get_protocol_ipv4_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ipv4Dom.fault.info.%s' % (key), + self.proto_ipv4_fault[key] + ) + + return self.proto_ipv4_fault[key] + + def get_protocol_ipv4_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv4_fault_record: + return self.proto_ipv4_fault_record[key] + + managed_objects = self.get_protocol_ipv4_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_ipv4_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_ipv4_fault_record[key].append( + self.get_protocol_ipv4_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ipv4Dom.faultRecord.info.%s' % (key), + self.proto_ipv4_fault_record[key] + ) + + return self.proto_ipv4_fault_record[key] diff --git a/lib/aci/proto/ipv4/fault/main.py b/lib/aci/proto/ipv4/fault/main.py new file mode 100644 index 00000000..214c6507 --- /dev/null +++ b/lib/aci/proto/ipv4/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv4.fault.api import ProtocolIpv4FaultApi +from lib.aci.proto.ipv4.fault.info import ProtocolIpv4FaultInfo + + +class ProtocolIpv4Fault(ProtocolIpv4FaultApi, ProtocolIpv4FaultInfo): + def __init__(self): + ProtocolIpv4FaultApi.__init__(self) + ProtocolIpv4FaultInfo.__init__(self) diff --git a/lib/aci/proto/ipv4/instance/__init__.py b/lib/aci/proto/ipv4/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv4/instance/api.py b/lib/aci/proto/ipv4/instance/api.py new file mode 100644 index 00000000..544cb630 --- /dev/null +++ b/lib/aci/proto/ipv4/instance/api.py @@ -0,0 +1,71 @@ +class ProtocolIpv4InstanceApi(): + def __init__(self): + self.ipv4_instance_mo = {} + + def get_protocol_ipv4_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.ipv4_instance_mo: + return self.ipv4_instance_mo[key] + + cache = self.get_object_cache( + 'ipv4Inst', + object_selector=key + ) + if cache is not None: + self.ipv4_instance_mo[key] = cache + self.log.apic_mo( + 'ipv4Inst.%s' % (key), + self.ipv4_instance_mo[key] + ) + return self.ipv4_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv4' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv4_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_ipv4_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.ipv4_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['ipv4Inst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'ipv4Inst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'ipv4Inst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.ipv4_instance_mo[key] = attributes + + self.log.apic_mo( + 'ipv4Inst.%s' % (key), + self.ipv4_instance_mo[key] + ) + + self.set_object_cache( + 'ipv4Inst', + self.ipv4_instance_mo[key], + object_selector=key + ) + + return self.ipv4_instance_mo[key] diff --git a/lib/aci/proto/ipv4/instance/info.py b/lib/aci/proto/ipv4/instance/info.py new file mode 100644 index 00000000..62c140c1 --- /dev/null +++ b/lib/aci/proto/ipv4/instance/info.py @@ -0,0 +1,44 @@ +class ProtocolIpv4InstanceInfo(): + def __init__(self): + pass + + def get_protocol_ipv4_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_ipv4_instance(self, pod_id, node_id): + managed_object = self.get_protocol_ipv4_instance_mo(pod_id, node_id) + if managed_object is None: + return None + + return self.get_protocol_ipv4_instance_info(managed_object) diff --git a/lib/aci/proto/ipv4/instance/main.py b/lib/aci/proto/ipv4/instance/main.py new file mode 100644 index 00000000..1d420d0e --- /dev/null +++ b/lib/aci/proto/ipv4/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv4.instance.api import ProtocolIpv4InstanceApi +from lib.aci.proto.ipv4.instance.info import ProtocolIpv4InstanceInfo + + +class ProtocolIpv4Instance(ProtocolIpv4InstanceApi, ProtocolIpv4InstanceInfo): + def __init__(self): + ProtocolIpv4InstanceApi.__init__(self) + ProtocolIpv4InstanceInfo.__init__(self) diff --git a/lib/aci/proto/ipv4/main.py b/lib/aci/proto/ipv4/main.py new file mode 100644 index 00000000..c6cd3173 --- /dev/null +++ b/lib/aci/proto/ipv4/main.py @@ -0,0 +1,126 @@ +from lib.aci.proto.ipv4.instance.main import ProtocolIpv4Instance +from lib.aci.proto.ipv4.domain.main import ProtocolIpv4Domain +from lib.aci.proto.ipv4.route.main import ProtocolIpv4Route +from lib.aci.proto.ipv4.event.main import ProtocolIpv4Event +from lib.aci.proto.ipv4.fault.main import ProtocolIpv4Fault + + +class ProtocolIpv4( + ProtocolIpv4Instance, + ProtocolIpv4Domain, + ProtocolIpv4Route, + ProtocolIpv4Event, + ProtocolIpv4Fault + ): + def __init__(self): + ProtocolIpv4Instance.__init__(self) + ProtocolIpv4Domain.__init__(self) + ProtocolIpv4Route.__init__(self) + ProtocolIpv4Event.__init__(self) + ProtocolIpv4Fault.__init__(self) + + def get_protocol_ipv4( + self, + pod_id, + node_id, + ipv4_filter=None, + instance_info=False, + domain_info=False, + route_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_ipv4_instance( + pod_id, + node_id + ) + + if domain_info: + info['domain'] = self.get_protocol_ipv4_domains( + pod_id, + node_id, + ipv4_domain_filter=ipv4_filter + ) + if instance_info: + info['instance']['domains'] = len(info['domain']) + + if route_info: + info['route'] = [] + for domain in info['domain']: + domain_route = self.get_protocol_ipv4_routes( + pod_id, + node_id, + domain['name'], + route_filter=ipv4_filter + ) + + info['route'] = info['route'] + domain_route + domain['summary'] = self.get_protocol_ipv4_routes_summary( + domain_route + ) + + if instance_info: + info['instance']['routes'] = len(info['route']) + info['instance']['summary'] = self.get_protocol_ipv4_routes_summary( + info['route'] + ) + + # if domain_info: + # info['domain'] = self.get_protocol_arp_domains( + # pod_id, + # node_id, + # arp_domain_filter=arp_domain_filter, + # adjacency_info=adjacency_info + # ) + + # if adjacency_info: + # info['adjacency'] = [] + # for domain in info['domain']: + # info['adjacency'] = info['adjacency'] + domain['adjacency'] + + # if interface_info: + # info['interface'] = self.get_protocol_arp_domains_interface_summary( + # info['domain'] + # ) + + if fault_info: + info['faultInst'] = self.get_protocol_ipv4_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_ipv4_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_ipv4_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/ipv4/output.py b/lib/aci/proto/ipv4/output.py new file mode 100644 index 00000000..65987f91 --- /dev/null +++ b/lib/aci/proto/ipv4/output.py @@ -0,0 +1,372 @@ +class ProtocolIpv4Output(): + def __init__(self): + pass + + def print_proto_ipv4_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv4 - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'adminSt', + 'health', + 'faults', + 'domains', + 'summary.count', + 'summary.default', + 'summary.direct', + 'summary.local', + 'summary.bgp', + 'summary.ibgp', + 'summary.ebgp' + ] + + headers = [ + 'Node', + 'Admin State', + 'Health', + 'Faults', + 'Domain', + 'Route', + 'Default', + 'Direct', + 'Local', + 'BGP', + 'iBGP', + 'eBGP' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv4_domains(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv4 - Domain (VRF) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'name', + 'health', + 'faults', + 'operSt', + 'summary.count', + 'summary.default', + 'summary.direct', + 'summary.local', + 'summary.bgp', + 'summary.ibgp', + 'summary.ebgp' + ] + + headers = [ + 'Node', + 'VRF', + 'Health', + 'Faults', + 'OperSt', + 'Route', + 'Default', + 'Direct', + 'Local', + 'BGP', + 'iBGP', + 'eBGP' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv4_routes(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv4 - Route [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'vrf', + 'prefix', + 'health', + 'faults', + 'next_hop.addr', + 'next_hop.routeType', + 'next_hop.owner', + 'next_hop.if', + 'next_hop.vrf', + 'next_hop.mplsLabel', + 'next_hop.active', + 'next_hop.pref', + ] + + headers = [ + 'Node', + 'VRF', + 'Prefix', + 'Health', + 'Faults', + 'Next Hop', + 'Type', + 'Source', + 'Interface', + 'NH VRF', + 'MPLS Label', + 'Active', + 'Preference' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['next_hop'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_proto_ipv4_routes_summary(self, info): + order = [ + 'count', + 'default', + 'direct', + 'local', + 'bgp', + 'ibgp', + 'ebgp' + ] + + headers = [ + 'Routes', + 'Default', + 'Direct', + 'Local', + 'BGP', + 'iBGP', + 'eBGP' + ] + + self.my_output.dictionary( + info, + title='IPv4 Routes Summary', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_proto_ipv4_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv4 - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'domainNameT', + 'interfaceIdT', + 'addressT', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Domain', + 'Interface', + 'Address', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv4_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol IPv4 - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol IPv4 - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'domainNameT', + 'interfaceIdT', + 'addressT', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Domain', + 'Interface', + 'Address', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv4_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol IPv4 - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol IPv4 - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'domainNameT', + 'interfaceIdT', + 'addressT', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Domain', + 'Interface', + 'Address', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/ipv4/route/__init__.py b/lib/aci/proto/ipv4/route/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv4/route/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/ipv4/route/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..bc882aff Binary files /dev/null and b/lib/aci/proto/ipv4/route/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/route/__pycache__/api.cpython-310.pyc b/lib/aci/proto/ipv4/route/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3bbb4251 Binary files /dev/null and b/lib/aci/proto/ipv4/route/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/route/__pycache__/info.cpython-310.pyc b/lib/aci/proto/ipv4/route/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..6d471336 Binary files /dev/null and b/lib/aci/proto/ipv4/route/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/route/__pycache__/main.cpython-310.pyc b/lib/aci/proto/ipv4/route/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..de1bb497 Binary files /dev/null and b/lib/aci/proto/ipv4/route/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv4/route/api.py b/lib/aci/proto/ipv4/route/api.py new file mode 100644 index 00000000..c10e1893 --- /dev/null +++ b/lib/aci/proto/ipv4/route/api.py @@ -0,0 +1,87 @@ +class ProtocolIpv4RouteApi(): + def __init__(self): + self.ipv4_routes_mo = {} + + def get_protocol_ipv4_routes_mo(self, pod_id, node_id, ipv4_domain_name): + key = '%s.%s.%s' % (pod_id, node_id, '.'.join(ipv4_domain_name.split(':'))) + if key in self.ipv4_routes_mo: + return self.ipv4_routes_mo[key] + + cache = self.get_object_cache( + 'uribv4Route', + object_selector=key + ) + if cache is not None: + self.ipv4_routes_mo[key] = cache + self.log.apic_mo( + 'uribv4Route.%s' % (key), + self.ipv4_routes_mo[key] + ) + return self.ipv4_routes_mo[key] + + # url: https:///api/node/mo/topology/pod-1/node-201/sys/uribv4/dom-common:smi5Gc-cvim1-N6_VRF.json?query-target=subtree&target-subtree-class=uribv4Route&page=0&page-size=15 + distinguished_name = 'topology/pod-%s/node-%s/sys/uribv4/dom-%s' % ( + pod_id, + node_id, + ipv4_domain_name + ) + query = 'query-target=subtree&rsp-subtree-include=health,fault-count&target-subtree-class=uribv4Route&target-subtree-class=uribv4Nexthop' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + self.log.apic_mo( + 'uribv4Route.raw.%s' % (key), + managed_objects + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv4_routes_mo', + 'API failed' + ) + return None + + self.ipv4_routes_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'uribv4Route' in managed_object: + attributes = managed_object['uribv4Route']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'uribv4Route', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'uribv4Route', + managed_object, + 'faultCounts' + ) + self.ipv4_routes_mo[key].append( + attributes + ) + + for managed_object in managed_objects['imdata']: + if 'uribv4Nexthop' in managed_object: + next_hop_rt = managed_object['uribv4Nexthop']['attributes']['dn'].split('/')[7] + for entry in self.ipv4_routes_mo[key]: + if next_hop_rt in entry['dn']: + if 'next_hop' not in entry: + entry['next_hop'] = [] + + entry['next_hop'].append( + managed_object['uribv4Nexthop']['attributes'] + ) + + self.log.apic_mo( + 'uribv4Route.%s' % (key), + self.ipv4_routes_mo[key] + ) + + self.set_object_cache( + 'uribv4Route', + self.ipv4_routes_mo[key], + object_selector=key + ) + + return self.ipv4_routes_mo[key] diff --git a/lib/aci/proto/ipv4/route/info.py b/lib/aci/proto/ipv4/route/info.py new file mode 100644 index 00000000..a4dccba9 --- /dev/null +++ b/lib/aci/proto/ipv4/route/info.py @@ -0,0 +1,183 @@ +from lib import ip_helper + + +class ProtocolIpv4RouteInfo(): + def __init__(self): + self.ipv4_routes = {} + + def get_protocol_ipv4_route_next_hop_types(self, route): + next_hop_types = [] + + if 'next_hop' in route: + for next_hop in route['next_hop']: + if next_hop['routeType'] not in next_hop_types: + next_hop_types.append( + next_hop['routeType'] + ) + + if 'ebgp' in next_hop_types or 'ibgp' in next_hop_types: + next_hop_types.append('bgp') + + return next_hop_types + + def get_protocol_ipv4_routes_summary(self, routes): + summary = {} + summary['count'] = 0 + summary['default'] = False + summary['ebgp'] = 0 + summary['ibgp'] = 0 + summary['bgp'] = 0 + summary['local'] = 0 + summary['direct'] = 0 + + for route in routes: + summary['count'] = summary['count'] + 1 + if route['prefix'] == '0.0.0.0/0': + summary['default'] = True + + next_hop_types = self.get_protocol_ipv4_route_next_hop_types(route) + for next_hop_type in next_hop_types: + if next_hop_type in summary: + summary[next_hop_type] = summary[next_hop_type] + 1 + + return summary + + def check_protocol_ipv4_route_filter_match(self, ipv4_route_info, route_filter): + if route_filter is None or len(route_filter) == 0: + return True + + for rule in route_filter: + if rule in ['ibgp', 'ebgp', 'static', 'local', 'direct']: + match = False + if 'next_hop' in ipv4_route_info: + for next_hop in ipv4_route_info['next_hop']: + if next_hop['routeType'] == rule: + match = True + + if not match: + return False + + if rule == 'bgp': + match = False + for match_rule in ['ibgp', 'ebgp']: + if 'next_hop' in ipv4_route_info: + for next_hop in ipv4_route_info['next_hop']: + if next_hop['routeType'] == match_rule: + match = True + + if not match: + return False + + if rule.startswith('nh:'): + match = False + if 'next_hop' in ipv4_route_info: + for next_hop in ipv4_route_info['next_hop']: + if next_hop['addr'].split('/')[0] == rule.split(':')[1]: + match = True + + if not match: + return False + + if rule.startswith('ip:'): + ip_address_search = rule.split(':')[1] + if ipv4_route_info['prefix'] != '0.0.0.0/0': + if not ip_helper.is_ipv4_in_cidr(ip_address_search, ipv4_route_info['prefix']): + return False + + if rule.startswith('subnet:'): + ip_subnet_search = rule.split(':')[1] + if ip_subnet_search != ipv4_route_info['prefix']: + return False + + if rule.startswith('subnet-longer:'): + ip_subnet_search = rule.split(':')[1] + if not ip_helper.is_subnet_in_subnet(ipv4_route_info['prefix'], ip_subnet_search): + return False + + return True + + def get_protocol_ipv4_route_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['vrf'] = info['dn'].split('/')[5][4:] + if 'next_hop' in managed_object: + for nh_info in managed_object['next_hop']: + if nh_info['if'] == 'unspecified': + nh_info['if'] = '' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_ipv4_routes_info(self, pod_id, node_id, ipv4_domain_name): + key = '%s.%s.%s' % (pod_id, node_id, '.'.join(ipv4_domain_name.split(':'))) + if key in self.ipv4_routes: + return self.ipv4_routes[key] + + ipv4_routes_mo = self.get_protocol_ipv4_routes_mo(pod_id, node_id, ipv4_domain_name) + if ipv4_routes_mo is not None: + self.ipv4_routes[key] = [] + for hsrp_interface_mo in ipv4_routes_mo: + self.ipv4_routes[key].append( + self.get_protocol_ipv4_route_info( + hsrp_interface_mo + ) + ) + + self.log.apic_mo( + 'uribv4Route.info.%s' % (key), + self.ipv4_routes[key] + ) + + return self.ipv4_routes[key] + + def get_protocol_ipv4_routes(self, pod_id, node_id, ipv4_domain_name, route_filter=None): + all_routes = self.get_protocol_ipv4_routes_info( + pod_id, + node_id, + ipv4_domain_name + ) + + info = [] + default_routes = [] + + for ipv4_route_info in all_routes: + if ipv4_route_info['prefix'] == '0.0.0.0/0': + default_routes.append( + ipv4_route_info + ) + + if route_filter is not None: + if not self.check_protocol_ipv4_route_filter_match(ipv4_route_info, route_filter): + continue + + info.append( + ipv4_route_info + ) + + info = sorted( + info, + key=lambda i: i['prefix'] + ) + + return info diff --git a/lib/aci/proto/ipv4/route/main.py b/lib/aci/proto/ipv4/route/main.py new file mode 100644 index 00000000..05a113a5 --- /dev/null +++ b/lib/aci/proto/ipv4/route/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv4.route.api import ProtocolIpv4RouteApi +from lib.aci.proto.ipv4.route.info import ProtocolIpv4RouteInfo + + +class ProtocolIpv4Route(ProtocolIpv4RouteApi, ProtocolIpv4RouteInfo): + def __init__(self): + ProtocolIpv4RouteApi.__init__(self) + ProtocolIpv4RouteInfo.__init__(self) diff --git a/lib/aci/proto/ipv6/__init__.py b/lib/aci/proto/ipv6/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv6/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/ipv6/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..edb91740 Binary files /dev/null and b/lib/aci/proto/ipv6/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/ipv6/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..4ef9aa44 Binary files /dev/null and b/lib/aci/proto/ipv6/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/__pycache__/main.cpython-310.pyc b/lib/aci/proto/ipv6/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f236d137 Binary files /dev/null and b/lib/aci/proto/ipv6/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/__pycache__/output.cpython-310.pyc b/lib/aci/proto/ipv6/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..9865e657 Binary files /dev/null and b/lib/aci/proto/ipv6/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/__pycache__/route.cpython-310.pyc b/lib/aci/proto/ipv6/__pycache__/route.cpython-310.pyc new file mode 100644 index 00000000..1585e1d0 Binary files /dev/null and b/lib/aci/proto/ipv6/__pycache__/route.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/domain/__init__.py b/lib/aci/proto/ipv6/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv6/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/ipv6/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..36975862 Binary files /dev/null and b/lib/aci/proto/ipv6/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/ipv6/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c73bfa3e Binary files /dev/null and b/lib/aci/proto/ipv6/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/ipv6/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b051d10f Binary files /dev/null and b/lib/aci/proto/ipv6/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/ipv6/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..22de9d9a Binary files /dev/null and b/lib/aci/proto/ipv6/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/domain/api.py b/lib/aci/proto/ipv6/domain/api.py new file mode 100644 index 00000000..a9f8987f --- /dev/null +++ b/lib/aci/proto/ipv6/domain/api.py @@ -0,0 +1,58 @@ +class ProtocolIpv6DomainApi(): + def __init__(self): + self.ipv6_domains_mo = {} + + def get_protocol_ipv6_domains_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.ipv6_domains_mo: + return self.ipv6_domains_mo[key] + + cache = self.get_object_cache( + 'uribv6Dom', + object_selector=key + ) + if cache is not None: + self.ipv6_domains_mo[key] = cache + self.log.apic_mo( + 'uribv6Dom.%s' % (key), + self.ipv6_domains_mo[key] + ) + return self.ipv6_domains_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/uribv6' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=fault-count&target-subtree-class=uribv6Dom' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + if managed_objects is None: + self.log.error( + 'get_protocol_ipv6_domains_mo', + 'API failed' + ) + return None + + self.ipv6_domains_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['uribv6Dom']['attributes'] + attributes['faultCounts'] = self.get_mo_child_attributes( + 'uribv6Dom', + managed_object, + 'faultCounts' + ) + self.ipv6_domains_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'uribv6Dom.%s' % (key), + self.ipv6_domains_mo[key] + ) + + self.set_object_cache( + 'uribv6Dom', + self.ipv6_domains_mo[key], + object_selector=key + ) + + return self.ipv6_domains_mo[key] diff --git a/lib/aci/proto/ipv6/domain/info.py b/lib/aci/proto/ipv6/domain/info.py new file mode 100644 index 00000000..52c49328 --- /dev/null +++ b/lib/aci/proto/ipv6/domain/info.py @@ -0,0 +1,89 @@ +from lib import filter_helper + + +class ProtocolIpv6DomainInfo(): + def __init__(self): + self.ipv6_domains = {} + + def get_protocol_ipv6_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['__Output']['name'] = 'Yellow' + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_ipv6_domains_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.ipv6_domains: + return self.ipv6_domains[key] + + ipv6_domains_mo = self.get_protocol_ipv6_domains_mo(pod_id, node_id) + if ipv6_domains_mo is not None: + self.ipv6_domains[key] = [] + for ipv6_domain_mo in ipv6_domains_mo: + self.ipv6_domains[key].append( + self.get_protocol_ipv6_domain_info( + ipv6_domain_mo + ) + ) + + return self.ipv6_domains[key] + + def match_protocol_ipv6_domain(self, ipv6_domain_info, ipv6_domain_filter): + if ipv6_domain_filter is None or len(ipv6_domain_filter) == 0: + return True + + for ap_rule in ipv6_domain_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'vrf': + if not filter_helper.match_tenant_name(value, ipv6_domain_info['name'], delimiter=':'): + return False + + return True + + def get_protocol_ipv6_domains(self, pod_id, node_id, ipv6_domain_filter=None): + all_ipv6_domains = self.get_protocol_ipv6_domains_info(pod_id, node_id) + if all_ipv6_domains is None: + return None + + ipv6_domains = [] + + for ipv6_domain_info in all_ipv6_domains: + if not self.match_protocol_ipv6_domain(ipv6_domain_info, ipv6_domain_filter): + continue + + ipv6_domains.append( + ipv6_domain_info + ) + + ipv6_domains = sorted( + ipv6_domains, + key=lambda i: i['name'].lower() + ) + + return ipv6_domains diff --git a/lib/aci/proto/ipv6/domain/main.py b/lib/aci/proto/ipv6/domain/main.py new file mode 100644 index 00000000..352728b6 --- /dev/null +++ b/lib/aci/proto/ipv6/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv6.domain.api import ProtocolIpv6DomainApi +from lib.aci.proto.ipv6.domain.info import ProtocolIpv6DomainInfo + + +class ProtocolIpv6Domain(ProtocolIpv6DomainApi, ProtocolIpv6DomainInfo): + def __init__(self): + ProtocolIpv6DomainApi.__init__(self) + ProtocolIpv6DomainInfo.__init__(self) diff --git a/lib/aci/proto/ipv6/event/__init__.py b/lib/aci/proto/ipv6/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv6/event/api.py b/lib/aci/proto/ipv6/event/api.py new file mode 100644 index 00000000..bb18c88b --- /dev/null +++ b/lib/aci/proto/ipv6/event/api.py @@ -0,0 +1,55 @@ +class ProtocolIpv6EventApi(): + def __init__(self): + self.proto_ipv6_event_mo = {} + + def get_protocol_ipv6_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv6_event_mo: + return self.proto_ipv6_event_mo[key] + + cache = self.get_object_cache( + 'ipv6Dom.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_ipv6_event_mo[key] = cache + self.log.apic_mo( + 'ipv6Dom.eventLog.%s' % (key), + self.proto_ipv6_event_mo[key] + ) + return self.proto_ipv6_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv6' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv6_event_mo', + 'API failed' + ) + return None + + self.proto_ipv6_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_ipv6_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ipv6Dom.eventLog.%s' % (key), + self.proto_ipv6_event_mo[key] + ) + + self.set_object_cache( + 'ipv6Dom.eventLog', + self.proto_ipv6_event_mo[key], + object_selector=key + ) + + return self.proto_ipv6_event_mo[key] diff --git a/lib/aci/proto/ipv6/event/info.py b/lib/aci/proto/ipv6/event/info.py new file mode 100644 index 00000000..ba09b91d --- /dev/null +++ b/lib/aci/proto/ipv6/event/info.py @@ -0,0 +1,104 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolIpv6EventInfo(): + def __init__(self): + self.proto_ipv6_event = {} + + def get_protocol_ipv6_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2208/sys/ipv6/inst/dom-common:Infra_privIP_VRF/if-[vlan50]/addr-[/24] + info['domainName'] = None + if 'sys/ipv6/inst/dom-' in info['affected']: + info['domainName'] = info['affected'].split('sys/ipv6/inst/dom-')[1].split('/')[0] + info['domainNameT'] = info['domainName'] + if info['domainNameT'] is None: + info['domainNameT'] = '--' + + info['interfaceId'] = None + if '/if-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/if-[')[1].split(']')[0] + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['address'] = None + if '/addr-[' in info['affected']: + info['address'] = info['affected'].split('/addr-[')[1].split(']')[0] + info['addressT'] = info['address'] + if info['addressT'] is None: + info['addressT'] = '--' + + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_ipv6_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv6_event: + return self.proto_ipv6_event[key] + + managed_objects = self.get_protocol_ipv6_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_ipv6_event[key] = [] + for managed_object in managed_objects: + self.proto_ipv6_event[key].append( + self.get_protocol_ipv6_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ipv6Dom.eventLog.info.%s' % (key), + self.proto_ipv6_event[key] + ) + + return self.proto_ipv6_event[key] diff --git a/lib/aci/proto/ipv6/event/main.py b/lib/aci/proto/ipv6/event/main.py new file mode 100644 index 00000000..aab520a3 --- /dev/null +++ b/lib/aci/proto/ipv6/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv6.event.api import ProtocolIpv6EventApi +from lib.aci.proto.ipv6.event.info import ProtocolIpv6EventInfo + + +class ProtocolIpv6Event(ProtocolIpv6EventApi, ProtocolIpv6EventInfo): + def __init__(self): + ProtocolIpv6EventApi.__init__(self) + ProtocolIpv6EventInfo.__init__(self) diff --git a/lib/aci/proto/ipv6/fault/__init__.py b/lib/aci/proto/ipv6/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv6/fault/api.py b/lib/aci/proto/ipv6/fault/api.py new file mode 100644 index 00000000..7f5ccaf0 --- /dev/null +++ b/lib/aci/proto/ipv6/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolIpv6FaultApi(): + def __init__(self): + self.proto_ipv6_fault_mo = {} + self.proto_ipv6_fault_record_mo = {} + + def get_protocol_ipv6_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv6_fault_mo: + return self.proto_ipv6_fault_mo[key] + + cache = self.get_object_cache( + 'ipv6Dom.fault', + object_selector=key + ) + if cache is not None: + self.proto_ipv6_fault_mo[key] = cache + self.log.apic_mo( + 'ipv6Dom.fault.%s' % (key), + self.proto_ipv6_fault_mo[key] + ) + return self.proto_ipv6_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv6' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv6_fault_mo', + 'API failed' + ) + return None + + self.proto_ipv6_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_ipv6_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ipv6Dom.fault.%s' % (key), + self.proto_ipv6_fault_mo[key] + ) + + self.set_object_cache( + 'ipv6Dom.fault', + self.proto_ipv6_fault_mo[key], + object_selector=key + ) + + return self.proto_ipv6_fault_mo[key] + + def get_protocol_ipv6_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv6_fault_record_mo: + return self.proto_ipv6_fault_record_mo[key] + + cache = self.get_object_cache( + 'ipv6Dom.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_ipv6_fault_record_mo[key] = cache + self.log.apic_mo( + 'ipv6Dom.faultRecord.%s' % (key), + self.proto_ipv6_fault_record_mo[key] + ) + return self.proto_ipv6_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv6' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv6_fault_record_mo', + 'API failed' + ) + return None + + self.proto_ipv6_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_ipv6_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ipv6Dom.faultRecord.%s' % (key), + self.proto_ipv6_fault_record_mo[key] + ) + + self.set_object_cache( + 'ipv6Dom.faultRecord', + self.proto_ipv6_fault_record_mo[key], + object_selector=key + ) + + return self.proto_ipv6_fault_record_mo[key] diff --git a/lib/aci/proto/ipv6/fault/info.py b/lib/aci/proto/ipv6/fault/info.py new file mode 100644 index 00000000..ebc658f3 --- /dev/null +++ b/lib/aci/proto/ipv6/fault/info.py @@ -0,0 +1,94 @@ +class ProtocolIpv6FaultInfo(): + def __init__(self): + self.proto_ipv6_fault = {} + self.proto_ipv6_fault_record = {} + + def get_protocol_ipv6_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # topology/pod-1/node-2208/sys/ipv6/inst/dom-common:Infra_privIP_VRF/if-[vlan50]/addr-[/24] + info['domainName'] = None + if 'affected' in info: + if 'sys/ipv6/inst/dom-' in info['affected']: + info['domainName'] = info['affected'].split('sys/ipv6/inst/dom-')[1].split('/')[0] + info['domainNameT'] = info['domainName'] + if info['domainNameT'] is None: + info['domainNameT'] = '--' + + info['interfaceId'] = None + if 'affected' in info: + if '/if-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/if-[')[1].split(']')[0] + info['interfaceIdT'] = info['interfaceId'] + if info['interfaceIdT'] is None: + info['interfaceIdT'] = '--' + + info['address'] = None + if 'affected' in info: + if '/addr-[' in info['affected']: + info['address'] = info['affected'].split('/addr-[')[1].split(']')[0] + info['addressT'] = info['address'] + if info['addressT'] is None: + info['addressT'] = '--' + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_ipv6_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv6_fault: + return self.proto_ipv6_fault[key] + + managed_objects = self.get_protocol_ipv6_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_ipv6_fault[key] = [] + for managed_object in managed_objects: + self.proto_ipv6_fault[key].append( + self.get_protocol_ipv6_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ipv6Dom.fault.info.%s' % (key), + self.proto_ipv6_fault[key] + ) + + return self.proto_ipv6_fault[key] + + def get_protocol_ipv6_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_ipv6_fault_record: + return self.proto_ipv6_fault_record[key] + + managed_objects = self.get_protocol_ipv6_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_ipv6_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_ipv6_fault_record[key].append( + self.get_protocol_ipv6_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ipv6Dom.faultRecord.info.%s' % (key), + self.proto_ipv6_fault_record[key] + ) + + return self.proto_ipv6_fault_record[key] diff --git a/lib/aci/proto/ipv6/fault/main.py b/lib/aci/proto/ipv6/fault/main.py new file mode 100644 index 00000000..c57e47f4 --- /dev/null +++ b/lib/aci/proto/ipv6/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv6.fault.api import ProtocolIpv6FaultApi +from lib.aci.proto.ipv6.fault.info import ProtocolIpv6FaultInfo + + +class ProtocolIpv6Fault(ProtocolIpv6FaultApi, ProtocolIpv6FaultInfo): + def __init__(self): + ProtocolIpv6FaultApi.__init__(self) + ProtocolIpv6FaultInfo.__init__(self) diff --git a/lib/aci/proto/ipv6/instance/__init__.py b/lib/aci/proto/ipv6/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv6/instance/api.py b/lib/aci/proto/ipv6/instance/api.py new file mode 100644 index 00000000..6063e459 --- /dev/null +++ b/lib/aci/proto/ipv6/instance/api.py @@ -0,0 +1,71 @@ +class ProtocolIpv6InstanceApi(): + def __init__(self): + self.ipv6_instance_mo = {} + + def get_protocol_ipv6_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.ipv6_instance_mo: + return self.ipv6_instance_mo[key] + + cache = self.get_object_cache( + 'ipv6Inst', + object_selector=key + ) + if cache is not None: + self.ipv6_instance_mo[key] = cache + self.log.apic_mo( + 'ipv6Inst.%s' % (key), + self.ipv6_instance_mo[key] + ) + return self.ipv6_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/ipv6' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv6_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_ipv6_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.ipv6_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['ipv6Inst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'ipv6Inst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'ipv6Inst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.ipv6_instance_mo[key] = attributes + + self.log.apic_mo( + 'ipv6Inst.%s' % (key), + self.ipv6_instance_mo[key] + ) + + self.set_object_cache( + 'ipv6Inst', + self.ipv6_instance_mo[key], + object_selector=key + ) + + return self.ipv6_instance_mo[key] diff --git a/lib/aci/proto/ipv6/instance/info.py b/lib/aci/proto/ipv6/instance/info.py new file mode 100644 index 00000000..3edac733 --- /dev/null +++ b/lib/aci/proto/ipv6/instance/info.py @@ -0,0 +1,44 @@ +class ProtocolIpv6InstanceInfo(): + def __init__(self): + pass + + def get_protocol_ipv6_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_ipv6_instance(self, pod_id, node_id): + managed_object = self.get_protocol_ipv6_instance_mo(pod_id, node_id) + if managed_object is None: + return None + + return self.get_protocol_ipv6_instance_info(managed_object) diff --git a/lib/aci/proto/ipv6/instance/main.py b/lib/aci/proto/ipv6/instance/main.py new file mode 100644 index 00000000..ffce7640 --- /dev/null +++ b/lib/aci/proto/ipv6/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv6.instance.api import ProtocolIpv6InstanceApi +from lib.aci.proto.ipv6.instance.info import ProtocolIpv6InstanceInfo + + +class ProtocolIpv6Instance(ProtocolIpv6InstanceApi, ProtocolIpv6InstanceInfo): + def __init__(self): + ProtocolIpv6InstanceApi.__init__(self) + ProtocolIpv6InstanceInfo.__init__(self) diff --git a/lib/aci/proto/ipv6/main.py b/lib/aci/proto/ipv6/main.py new file mode 100644 index 00000000..342b70f1 --- /dev/null +++ b/lib/aci/proto/ipv6/main.py @@ -0,0 +1,126 @@ +from lib.aci.proto.ipv6.instance.main import ProtocolIpv6Instance +from lib.aci.proto.ipv6.domain.main import ProtocolIpv6Domain +from lib.aci.proto.ipv6.route.main import ProtocolIpv6Route +from lib.aci.proto.ipv6.event.main import ProtocolIpv6Event +from lib.aci.proto.ipv6.fault.main import ProtocolIpv6Fault + + +class ProtocolIpv6( + ProtocolIpv6Instance, + ProtocolIpv6Domain, + ProtocolIpv6Route, + ProtocolIpv6Event, + ProtocolIpv6Fault + ): + def __init__(self): + ProtocolIpv6Instance.__init__(self) + ProtocolIpv6Domain.__init__(self) + ProtocolIpv6Route.__init__(self) + ProtocolIpv6Event.__init__(self) + ProtocolIpv6Fault.__init__(self) + + def get_protocol_ipv6( + self, + pod_id, + node_id, + ipv6_filter=None, + instance_info=False, + domain_info=False, + route_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_ipv6_instance( + pod_id, + node_id + ) + + if domain_info: + info['domain'] = self.get_protocol_ipv6_domains( + pod_id, + node_id, + ipv6_domain_filter=ipv6_filter + ) + if instance_info: + info['instance']['domains'] = len(info['domain']) + + if route_info: + info['route'] = [] + for domain in info['domain']: + domain_route = self.get_protocol_ipv6_routes( + pod_id, + node_id, + domain['name'], + route_filter=ipv6_filter + ) + + info['route'] = info['route'] + domain_route + domain['summary'] = self.get_protocol_ipv6_routes_summary( + domain_route + ) + + if instance_info: + info['instance']['routes'] = len(info['route']) + info['instance']['summary'] = self.get_protocol_ipv6_routes_summary( + info['route'] + ) + + # if domain_info: + # info['domain'] = self.get_protocol_arp_domains( + # pod_id, + # node_id, + # arp_domain_filter=arp_domain_filter, + # adjacency_info=adjacency_info + # ) + + # if adjacency_info: + # info['adjacency'] = [] + # for domain in info['domain']: + # info['adjacency'] = info['adjacency'] + domain['adjacency'] + + # if interface_info: + # info['interface'] = self.get_protocol_arp_domains_interface_summary( + # info['domain'] + # ) + + if fault_info: + info['faultInst'] = self.get_protocol_ipv6_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_ipv6_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_ipv6_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/ipv6/output.py b/lib/aci/proto/ipv6/output.py new file mode 100644 index 00000000..349b2227 --- /dev/null +++ b/lib/aci/proto/ipv6/output.py @@ -0,0 +1,370 @@ +class ProtocolIpv6Output(): + def __init__(self): + pass + + def print_proto_ipv6_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv6 - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'adminSt', + 'health', + 'faults', + 'domains', + 'summary.count', + 'summary.default', + 'summary.direct', + 'summary.local', + 'summary.bgp', + 'summary.ibgp', + 'summary.ebgp' + ] + + headers = [ + 'Node', + 'Admin State', + 'Health', + 'Faults', + 'Domain', + 'Route', + 'Default', + 'Direct', + 'Local', + 'BGP', + 'iBGP', + 'eBGP' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv6_domains(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv6 - Domain (VRF) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'name', + 'faults', + 'operSt', + 'summary.count', + 'summary.default', + 'summary.direct', + 'summary.local', + 'summary.bgp', + 'summary.ibgp', + 'summary.ebgp' + ] + + headers = [ + 'Node', + 'VRF', + 'Faults', + 'OperSt', + 'Route', + 'Default', + 'Direct', + 'Local', + 'BGP', + 'iBGP', + 'eBGP' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv6_routes(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv6 - Route [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'vrf', + 'prefix', + 'health', + 'faults', + 'next_hop.addr', + 'next_hop.routeType', + 'next_hop.owner', + 'next_hop.if', + 'next_hop.vrf', + 'next_hop.mplsLabel', + 'next_hop.active', + 'next_hop.pref', + ] + + headers = [ + 'Node', + 'VRF', + 'Prefix', + 'Health', + 'Faults', + 'Next Hop', + 'Type', + 'Source', + 'Interface', + 'NH VRF', + 'MPLS Label', + 'Active', + 'Preference' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['next_hop'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_proto_ipv6_routes_summary(self, info): + order = [ + 'count', + 'default', + 'direct', + 'local', + 'bgp', + 'ibgp', + 'ebgp' + ] + + headers = [ + 'Routes', + 'Default', + 'Direct', + 'Local', + 'BGP', + 'iBGP', + 'eBGP' + ] + + self.my_output.dictionary( + info, + title='IPv6 Routes Summary', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_proto_ipv6_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol IPv6 - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'domainNameT', + 'interfaceIdT', + 'addressT', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Domain', + 'Interface', + 'Address', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv6_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol IPv6 - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol IPv6 - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'domainNameT', + 'interfaceIdT', + 'addressT', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Domain', + 'Interface', + 'Address', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_ipv6_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol IPv6 - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol IPv6 - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'domainNameT', + 'interfaceIdT', + 'addressT', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Domain', + 'Interface', + 'Address', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/ipv6/route/__init__.py b/lib/aci/proto/ipv6/route/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/ipv6/route/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/ipv6/route/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..bc882aff Binary files /dev/null and b/lib/aci/proto/ipv6/route/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/route/__pycache__/api.cpython-310.pyc b/lib/aci/proto/ipv6/route/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..82b25c30 Binary files /dev/null and b/lib/aci/proto/ipv6/route/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/route/__pycache__/info.cpython-310.pyc b/lib/aci/proto/ipv6/route/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b3f31fa9 Binary files /dev/null and b/lib/aci/proto/ipv6/route/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/route/__pycache__/main.cpython-310.pyc b/lib/aci/proto/ipv6/route/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1a66377c Binary files /dev/null and b/lib/aci/proto/ipv6/route/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/ipv6/route/api.py b/lib/aci/proto/ipv6/route/api.py new file mode 100644 index 00000000..9e6a2851 --- /dev/null +++ b/lib/aci/proto/ipv6/route/api.py @@ -0,0 +1,87 @@ +class ProtocolIpv6RouteApi(): + def __init__(self): + self.ipv6_routes_mo = {} + + def get_protocol_ipv6_routes_mo(self, pod_id, node_id, ipv6_domain_name): + key = '%s.%s.%s' % (pod_id, node_id, '.'.join(ipv6_domain_name.split(':'))) + if key in self.ipv6_routes_mo: + return self.ipv6_routes_mo[key] + + cache = self.get_object_cache( + 'uribv6Route', + object_selector=key + ) + if cache is not None: + self.ipv6_routes_mo[key] = cache + self.log.apic_mo( + 'uribv6Route.%s' % (key), + self.ipv6_routes_mo[key] + ) + return self.ipv6_routes_mo[key] + + # url: https:///api/node/mo/topology/pod-1/node-201/sys/uribv6/dom-common:smi5Gc-cvim1-N6_VRF.json?query-target=subtree&target-subtree-class=uribv6Route&page=0&page-size=15 + distinguished_name = 'topology/pod-%s/node-%s/sys/uribv6/dom-%s' % ( + pod_id, + node_id, + ipv6_domain_name + ) + query = 'query-target=subtree&rsp-subtree-include=health,fault-count&target-subtree-class=uribv6Route&target-subtree-class=uribv6Nexthop' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + self.log.apic_mo( + 'uribv6Route.raw.%s' % (key), + managed_objects + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_ipv6_routes_mo', + 'API failed' + ) + return None + + self.ipv6_routes_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'uribv6Route' in managed_object: + attributes = managed_object['uribv6Route']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'uribv6Route', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'uribv6Route', + managed_object, + 'faultCounts' + ) + self.ipv6_routes_mo[key].append( + attributes + ) + + for managed_object in managed_objects['imdata']: + if 'uribv6Nexthop' in managed_object: + next_hop_rt = managed_object['uribv6Nexthop']['attributes']['dn'].split('/')[7] + for entry in self.ipv6_routes_mo[key]: + if next_hop_rt in entry['dn']: + if 'next_hop' not in entry: + entry['next_hop'] = [] + + entry['next_hop'].append( + managed_object['uribv6Nexthop']['attributes'] + ) + + self.log.apic_mo( + 'uribv6Route.%s' % (key), + self.ipv6_routes_mo[key] + ) + + self.set_object_cache( + 'uribv6Route', + self.ipv6_routes_mo[key], + object_selector=key + ) + + return self.ipv6_routes_mo[key] diff --git a/lib/aci/proto/ipv6/route/info.py b/lib/aci/proto/ipv6/route/info.py new file mode 100644 index 00000000..4822a319 --- /dev/null +++ b/lib/aci/proto/ipv6/route/info.py @@ -0,0 +1,183 @@ +from lib import ip_helper + + +class ProtocolIpv6RouteInfo(): + def __init__(self): + self.ipv6_routes = {} + + def get_protocol_ipv6_route_next_hop_types(self, route): + next_hop_types = [] + + if 'next_hop' in route: + for next_hop in route['next_hop']: + if next_hop['routeType'] not in next_hop_types: + next_hop_types.append( + next_hop['routeType'] + ) + + if 'ebgp' in next_hop_types or 'ibgp' in next_hop_types: + next_hop_types.append('bgp') + + return next_hop_types + + def get_protocol_ipv6_routes_summary(self, routes): + summary = {} + summary['count'] = 0 + summary['default'] = False + summary['ebgp'] = 0 + summary['ibgp'] = 0 + summary['bgp'] = 0 + summary['local'] = 0 + summary['direct'] = 0 + + for route in routes: + summary['count'] = summary['count'] + 1 + if route['prefix'] == '0.0.0.0/0': + summary['default'] = True + + next_hop_types = self.get_protocol_ipv6_route_next_hop_types(route) + for next_hop_type in next_hop_types: + if next_hop_type in summary: + summary[next_hop_type] = summary[next_hop_type] + 1 + + return summary + + def check_protocol_ipv6_route_filter_match(self, ipv6_route_info, route_filter): + if route_filter is None or len(route_filter) == 0: + return True + + for rule in route_filter: + if rule in ['ibgp', 'ebgp', 'static', 'local', 'direct']: + match = False + if 'next_hop' in ipv6_route_info: + for next_hop in ipv6_route_info['next_hop']: + if next_hop['routeType'] == rule: + match = True + + if not match: + return False + + if rule == 'bgp': + match = False + for match_rule in ['ibgp', 'ebgp']: + if 'next_hop' in ipv6_route_info: + for next_hop in ipv6_route_info['next_hop']: + if next_hop['routeType'] == match_rule: + match = True + + if not match: + return False + + if rule.startswith('nh:'): + match = False + if 'next_hop' in ipv6_route_info: + for next_hop in ipv6_route_info['next_hop']: + if next_hop['addr'].split('/')[0] == rule.split(':')[1]: + match = True + + if not match: + return False + + if rule.startswith('ip:'): + ip_address_search = rule.split(':')[1] + if ipv6_route_info['prefix'] != '0.0.0.0/0': + if not ip_helper.is_ipv6_in_cidr(ip_address_search, ipv6_route_info['prefix']): + return False + + if rule.startswith('subnet:'): + ip_subnet_search = rule.split(':')[1] + if ip_subnet_search != ipv6_route_info['prefix']: + return False + + if rule.startswith('subnet-longer:'): + ip_subnet_search = rule.split(':')[1] + if not ip_helper.is_subnet_in_subnet(ipv6_route_info['prefix'], ip_subnet_search): + return False + + return True + + def get_protocol_ipv6_route_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['vrf'] = info['dn'].split('/')[5][4:] + if 'next_hop' in managed_object: + for nh_info in managed_object['next_hop']: + if nh_info['if'] == 'unspecified': + nh_info['if'] = '' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_ipv6_routes_info(self, pod_id, node_id, ipv6_domain_name): + key = '%s.%s.%s' % (pod_id, node_id, '.'.join(ipv6_domain_name.split(':'))) + if key in self.ipv6_routes: + return self.ipv6_routes[key] + + ipv6_routes_mo = self.get_protocol_ipv6_routes_mo(pod_id, node_id, ipv6_domain_name) + if ipv6_routes_mo is not None: + self.ipv6_routes[key] = [] + for hsrp_interface_mo in ipv6_routes_mo: + self.ipv6_routes[key].append( + self.get_protocol_ipv6_route_info( + hsrp_interface_mo + ) + ) + + self.log.apic_mo( + 'uribv6Route.info.%s' % (key), + self.ipv6_routes[key] + ) + + return self.ipv6_routes[key] + + def get_protocol_ipv6_routes(self, pod_id, node_id, ipv6_domain_name, route_filter=None): + all_routes = self.get_protocol_ipv6_routes_info( + pod_id, + node_id, + ipv6_domain_name + ) + + info = [] + default_routes = [] + + for ipv6_route_info in all_routes: + if ipv6_route_info['prefix'] == '0.0.0.0/0': + default_routes.append( + ipv6_route_info + ) + + if route_filter is not None: + if not self.check_protocol_ipv6_route_filter_match(ipv6_route_info, route_filter): + continue + + info.append( + ipv6_route_info + ) + + info = sorted( + info, + key=lambda i: i['prefix'] + ) + + return info diff --git a/lib/aci/proto/ipv6/route/main.py b/lib/aci/proto/ipv6/route/main.py new file mode 100644 index 00000000..fd51e3b2 --- /dev/null +++ b/lib/aci/proto/ipv6/route/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.ipv6.route.api import ProtocolIpv6RouteApi +from lib.aci.proto.ipv6.route.info import ProtocolIpv6RouteInfo + + +class ProtocolIpv6Route(ProtocolIpv6RouteApi, ProtocolIpv6RouteInfo): + def __init__(self): + ProtocolIpv6RouteApi.__init__(self) + ProtocolIpv6RouteInfo.__init__(self) diff --git a/lib/aci/proto/isis/__init__.py b/lib/aci/proto/isis/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f80a4795 Binary files /dev/null and b/lib/aci/proto/isis/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/isis/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..42140d46 Binary files /dev/null and b/lib/aci/proto/isis/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/isis/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..e0b35d69 Binary files /dev/null and b/lib/aci/proto/isis/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f771920b Binary files /dev/null and b/lib/aci/proto/isis/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/__pycache__/output.cpython-310.pyc b/lib/aci/proto/isis/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..bc90c03f Binary files /dev/null and b/lib/aci/proto/isis/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/domain/__init__.py b/lib/aci/proto/isis/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..23f2c5b1 Binary files /dev/null and b/lib/aci/proto/isis/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c534734b Binary files /dev/null and b/lib/aci/proto/isis/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..0658255b Binary files /dev/null and b/lib/aci/proto/isis/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..065e0c81 Binary files /dev/null and b/lib/aci/proto/isis/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/domain/api.py b/lib/aci/proto/isis/domain/api.py new file mode 100644 index 00000000..0d5995f2 --- /dev/null +++ b/lib/aci/proto/isis/domain/api.py @@ -0,0 +1,53 @@ +class ProtocolIsisDomainApi(): + def __init__(self): + self.isis_domains_mo = {} + + def get_protocol_isis_domains_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.isis_domains_mo: + return self.isis_domains_mo[key] + + cache = self.get_object_cache( + 'isisDom', + object_selector=key + ) + if cache is not None: + self.isis_domains_mo[key] = cache + self.log.apic_mo( + 'isisDom.%s' % (key), + self.isis_domains_mo[key] + ) + return self.isis_domains_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis' % (pod_id, node_id) + query = 'query-target=subtree&target-subtree-class=isisDom' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domains_mo', + 'API failed' + ) + return None + + self.isis_domains_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.isis_domains_mo[key].append( + managed_object['isisDom']['attributes'] + ) + + self.log.apic_mo( + 'isisDom.%s' % (key), + self.isis_domains_mo[key] + ) + + self.set_object_cache( + 'isisDom', + self.isis_domains_mo[key], + object_selector=key + ) + + return self.isis_domains_mo[key] diff --git a/lib/aci/proto/isis/domain/info.py b/lib/aci/proto/isis/domain/info.py new file mode 100644 index 00000000..5c8dd4c1 --- /dev/null +++ b/lib/aci/proto/isis/domain/info.py @@ -0,0 +1,132 @@ +from lib import filter_helper + + +class ProtocolIsisDomainInfo(): + def __init__(self): + self.isis_domains = {} + + def get_protocol_isis_domain_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "dn": "topology/pod-1/node-201/sys/isis/inst-default/dom-overlay-1" + info['instance'] = info['dn'].split('/')[5].split('-')[1] + + info['__Output']['name'] = 'Yellow' + + if info['operSt'] == 'ok': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_protocol_isis_domains_info(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.isis_domains: + return self.isis_domains[key] + + isis_domains_mo = self.get_protocol_isis_domains_mo(pod_id, node_id) + if isis_domains_mo is not None: + self.isis_domains[key] = [] + for isis_domain_mo in isis_domains_mo: + self.isis_domains[key].append( + self.get_protocol_isis_domain_info( + isis_domain_mo + ) + ) + + return self.isis_domains[key] + + def match_protocol_isis_domain(self, isis_domain_info, isis_domain_filter): + if isis_domain_filter is None or len(isis_domain_filter) == 0: + return True + + for ap_rule in isis_domain_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'name': + if not filter_helper.match_string(value, isis_domain_info['name']): + return False + + return True + + def get_protocol_isis_domains(self, pod_id, node_id, isis_domain_filter=None, tunnel_info=False, lsp_info=False, interface_info=False, neighbor_info=False, tree_info=False, route_info=False): + all_isis_domains = self.get_protocol_isis_domains_info(pod_id, node_id) + if all_isis_domains is None: + return None + + isis_domains = [] + + for isis_domain_info in all_isis_domains: + if not self.match_protocol_isis_domain(isis_domain_info, isis_domain_filter): + continue + + if tunnel_info: + isis_domain_info['tunnel'] = self.get_protocol_isis_domain_tunnels( + pod_id, + node_id, + isis_domain_info['instance'], + isis_domain_info['name'] + ) + + if lsp_info: + isis_domain_info['lsp'] = self.get_protocol_isis_domain_lsps( + pod_id, + node_id, + isis_domain_info['instance'], + isis_domain_info['name'] + ) + + if interface_info: + isis_domain_info['interface'] = self.get_protocol_isis_domain_interfaces( + pod_id, + node_id, + isis_domain_info['instance'], + isis_domain_info['name'] + ) + + if neighbor_info: + isis_domain_info['neighbor'] = self.get_protocol_isis_domain_neighbors( + pod_id, + node_id, + isis_domain_info['instance'], + isis_domain_info['name'] + ) + + if tree_info: + isis_domain_info['tree'] = self.get_protocol_isis_domain_trees( + pod_id, + node_id, + isis_domain_info['instance'], + isis_domain_info['name'] + ) + + if route_info: + isis_domain_info['route'] = self.get_protocol_isis_domain_routes( + pod_id, + node_id, + isis_domain_info['instance'], + isis_domain_info['name'] + ) + + isis_domains.append( + isis_domain_info + ) + + isis_domains = sorted( + isis_domains, + key=lambda i: i['name'].lower() + ) + + return isis_domains diff --git a/lib/aci/proto/isis/domain/main.py b/lib/aci/proto/isis/domain/main.py new file mode 100644 index 00000000..80821a1e --- /dev/null +++ b/lib/aci/proto/isis/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.domain.api import ProtocolIsisDomainApi +from lib.aci.proto.isis.domain.info import ProtocolIsisDomainInfo + + +class ProtocolIsisDomain(ProtocolIsisDomainApi, ProtocolIsisDomainInfo): + def __init__(self): + ProtocolIsisDomainApi.__init__(self) + ProtocolIsisDomainInfo.__init__(self) diff --git a/lib/aci/proto/isis/event/__init__.py b/lib/aci/proto/isis/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/event/api.py b/lib/aci/proto/isis/event/api.py new file mode 100644 index 00000000..195e9133 --- /dev/null +++ b/lib/aci/proto/isis/event/api.py @@ -0,0 +1,55 @@ +class ProtocolIsisEventApi(): + def __init__(self): + self.proto_isis_event_mo = {} + + def get_protocol_isis_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_isis_event_mo: + return self.proto_isis_event_mo[key] + + cache = self.get_object_cache( + 'isisDom.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_isis_event_mo[key] = cache + self.log.apic_mo( + 'isisDom.eventLog.%s' % (key), + self.proto_isis_event_mo[key] + ) + return self.proto_isis_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_event_mo', + 'API failed' + ) + return None + + self.proto_isis_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_isis_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'isisDom.eventLog.%s' % (key), + self.proto_isis_event_mo[key] + ) + + self.set_object_cache( + 'isisDom.eventLog', + self.proto_isis_event_mo[key], + object_selector=key + ) + + return self.proto_isis_event_mo[key] diff --git a/lib/aci/proto/isis/event/info.py b/lib/aci/proto/isis/event/info.py new file mode 100644 index 00000000..dc44405d --- /dev/null +++ b/lib/aci/proto/isis/event/info.py @@ -0,0 +1,83 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolIsisEventInfo(): + def __init__(self): + self.proto_isis_event = {} + + def get_protocol_isis_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/isis/inst + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_isis_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_isis_event: + return self.proto_isis_event[key] + + managed_objects = self.get_protocol_isis_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_isis_event[key] = [] + for managed_object in managed_objects: + self.proto_isis_event[key].append( + self.get_protocol_isis_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'isisDom.eventLog.info.%s' % (key), + self.proto_isis_event[key] + ) + + return self.proto_isis_event[key] diff --git a/lib/aci/proto/isis/event/main.py b/lib/aci/proto/isis/event/main.py new file mode 100644 index 00000000..c6c87c42 --- /dev/null +++ b/lib/aci/proto/isis/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.event.api import ProtocolIsisEventApi +from lib.aci.proto.isis.event.info import ProtocolIsisEventInfo + + +class ProtocolIsisEvent(ProtocolIsisEventApi, ProtocolIsisEventInfo): + def __init__(self): + ProtocolIsisEventApi.__init__(self) + ProtocolIsisEventInfo.__init__(self) diff --git a/lib/aci/proto/isis/fault/__init__.py b/lib/aci/proto/isis/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/fault/api.py b/lib/aci/proto/isis/fault/api.py new file mode 100644 index 00000000..a267f326 --- /dev/null +++ b/lib/aci/proto/isis/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolIsisFaultApi(): + def __init__(self): + self.proto_isis_fault_mo = {} + self.proto_isis_fault_record_mo = {} + + def get_protocol_isis_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_isis_fault_mo: + return self.proto_isis_fault_mo[key] + + cache = self.get_object_cache( + 'isisDom.fault', + object_selector=key + ) + if cache is not None: + self.proto_isis_fault_mo[key] = cache + self.log.apic_mo( + 'isisDom.fault.%s' % (key), + self.proto_isis_fault_mo[key] + ) + return self.proto_isis_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_fault_mo', + 'API failed' + ) + return None + + self.proto_isis_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_isis_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'isisDom.fault.%s' % (key), + self.proto_isis_fault_mo[key] + ) + + self.set_object_cache( + 'isisDom.fault', + self.proto_isis_fault_mo[key], + object_selector=key + ) + + return self.proto_isis_fault_mo[key] + + def get_protocol_isis_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_isis_fault_record_mo: + return self.proto_isis_fault_record_mo[key] + + cache = self.get_object_cache( + 'isisDom.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_isis_fault_record_mo[key] = cache + self.log.apic_mo( + 'isisDom.faultRecord.%s' % (key), + self.proto_isis_fault_record_mo[key] + ) + return self.proto_isis_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_fault_record_mo', + 'API failed' + ) + return None + + self.proto_isis_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_isis_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'isisDom.faultRecord.%s' % (key), + self.proto_isis_fault_record_mo[key] + ) + + self.set_object_cache( + 'isisDom.faultRecord', + self.proto_isis_fault_record_mo[key], + object_selector=key + ) + + return self.proto_isis_fault_record_mo[key] diff --git a/lib/aci/proto/isis/fault/info.py b/lib/aci/proto/isis/fault/info.py new file mode 100644 index 00000000..9e7eaee3 --- /dev/null +++ b/lib/aci/proto/isis/fault/info.py @@ -0,0 +1,69 @@ +class ProtocolIsisFaultInfo(): + def __init__(self): + self.proto_isis_fault = {} + self.proto_isis_fault_record = {} + + def get_protocol_isis_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_isis_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_isis_fault: + return self.proto_isis_fault[key] + + managed_objects = self.get_protocol_isis_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_isis_fault[key] = [] + for managed_object in managed_objects: + self.proto_isis_fault[key].append( + self.get_protocol_isis_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'isisDom.fault.info.%s' % (key), + self.proto_isis_fault[key] + ) + + return self.proto_isis_fault[key] + + def get_protocol_isis_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_isis_fault_record: + return self.proto_isis_fault_record[key] + + managed_objects = self.get_protocol_isis_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_isis_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_isis_fault_record[key].append( + self.get_protocol_isis_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'isisDom.faultRecord.info.%s' % (key), + self.proto_isis_fault_record[key] + ) + + return self.proto_isis_fault_record[key] diff --git a/lib/aci/proto/isis/fault/main.py b/lib/aci/proto/isis/fault/main.py new file mode 100644 index 00000000..874b3b51 --- /dev/null +++ b/lib/aci/proto/isis/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.fault.api import ProtocolIsisFaultApi +from lib.aci.proto.isis.fault.info import ProtocolIsisFaultInfo + + +class ProtocolIsisFault(ProtocolIsisFaultApi, ProtocolIsisFaultInfo): + def __init__(self): + ProtocolIsisFaultApi.__init__(self) + ProtocolIsisFaultInfo.__init__(self) diff --git a/lib/aci/proto/isis/instance/__init__.py b/lib/aci/proto/isis/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..fa112bc7 Binary files /dev/null and b/lib/aci/proto/isis/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..1b5103d7 Binary files /dev/null and b/lib/aci/proto/isis/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..b375a843 Binary files /dev/null and b/lib/aci/proto/isis/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a7a8f366 Binary files /dev/null and b/lib/aci/proto/isis/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/instance/api.py b/lib/aci/proto/isis/instance/api.py new file mode 100644 index 00000000..42a1c528 --- /dev/null +++ b/lib/aci/proto/isis/instance/api.py @@ -0,0 +1,70 @@ +class ProtocolIsisInstanceApi(): + def __init__(self): + self.isis_instance_mo = {} + + def get_protocol_isis_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.isis_instance_mo: + return self.isis_instance_mo[key] + + cache = self.get_object_cache( + 'isisInst', + object_selector=key + ) + if cache is not None: + self.isis_instance_mo[key] = cache + self.log.apic_mo( + 'isisInst.%s' % (key), + self.isis_instance_mo[key] + ) + return self.isis_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_isis_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.isis_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['isisInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'isisInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'isisInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.isis_instance_mo[key] = attributes + + self.log.apic_mo( + 'isisInst.%s' % (key), + self.isis_instance_mo[key] + ) + + self.set_object_cache( + 'isisInst', + self.isis_instance_mo[key], + object_selector=key + ) + + return self.isis_instance_mo[key] diff --git a/lib/aci/proto/isis/instance/info.py b/lib/aci/proto/isis/instance/info.py new file mode 100644 index 00000000..58caec6a --- /dev/null +++ b/lib/aci/proto/isis/instance/info.py @@ -0,0 +1,51 @@ +class ProtocolIsisInstanceInfo(): + def __init__(self): + pass + + def get_protocol_isis_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + if info['operSt'] == 'enabled': + info['enable'] = True + info['__Output']['operSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['operSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_isis_instance(self, pod_id, node_id): + managed_object = self.get_protocol_isis_instance_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_isis_instance_info(managed_object) diff --git a/lib/aci/proto/isis/instance/main.py b/lib/aci/proto/isis/instance/main.py new file mode 100644 index 00000000..2e937b9f --- /dev/null +++ b/lib/aci/proto/isis/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.instance.api import ProtocolIsisInstanceApi +from lib.aci.proto.isis.instance.info import ProtocolIsisInstanceInfo + + +class ProtocolIsisInstance(ProtocolIsisInstanceApi, ProtocolIsisInstanceInfo): + def __init__(self): + ProtocolIsisInstanceApi.__init__(self) + ProtocolIsisInstanceInfo.__init__(self) diff --git a/lib/aci/proto/isis/interface/__init__.py b/lib/aci/proto/isis/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7c8b673e Binary files /dev/null and b/lib/aci/proto/isis/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/interface/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/interface/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..a064248e Binary files /dev/null and b/lib/aci/proto/isis/interface/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/interface/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/interface/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..15791094 Binary files /dev/null and b/lib/aci/proto/isis/interface/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/interface/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b10c68ed Binary files /dev/null and b/lib/aci/proto/isis/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/interface/api.py b/lib/aci/proto/isis/interface/api.py new file mode 100644 index 00000000..0a144c27 --- /dev/null +++ b/lib/aci/proto/isis/interface/api.py @@ -0,0 +1,64 @@ +class ProtocolIsisInterfaceApi(): + def __init__(self): + self.isis_domain_interfaces_mo = {} + + def get_protocol_isis_domain_interfaces_mo(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_interfaces_mo: + return self.isis_domain_interfaces_mo[key] + + cache = self.get_object_cache( + 'isisIf', + object_selector=key + ) + if cache is not None: + self.isis_domain_interfaces_mo[key] = cache + self.log.apic_mo( + 'isisIf.%s' % (key), + self.isis_domain_interfaces_mo[key] + ) + return self.isis_domain_interfaces_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis/inst-%s/dom-%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + query = 'query-target=subtree&target-subtree-class=isisIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domain_interfaces_mo', + 'API failed' + ) + return None + + self.isis_domain_interfaces_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.isis_domain_interfaces_mo[key].append( + managed_object['isisIf']['attributes'] + ) + + self.log.apic_mo( + 'isisIf.%s' % (key), + self.isis_domain_interfaces_mo[key] + ) + + self.set_object_cache( + 'isisIf', + self.isis_domain_interfaces_mo[key], + object_selector=key + ) + + return self.isis_domain_interfaces_mo[key] diff --git a/lib/aci/proto/isis/interface/info.py b/lib/aci/proto/isis/interface/info.py new file mode 100644 index 00000000..895bef6e --- /dev/null +++ b/lib/aci/proto/isis/interface/info.py @@ -0,0 +1,69 @@ +class ProtocolIsisInterfaceInfo(): + def __init__(self): + self.isis_domain_interfaces = {} + + def get_protocol_isis_domain_interface_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + info['instance'] = info['dn'].split('/')[5].split('-')[1] + info['domain'] = info['dn'].split('/')[6].split('-')[1] + + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + if info['iibState'] == 'Ready': + info['__Output']['iibState'] = 'Green' + else: + info['__Output']['iibState'] = 'Red' + + return info + + def get_protocol_isis_domain_interfaces_info(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_interfaces: + return self.isis_domain_interfaces[key] + + isis_domain_interfaces_mo = self.get_protocol_isis_domain_interfaces_mo( + pod_id, + node_id, + instance_name, + domain_name + ) + if isis_domain_interfaces_mo is not None: + self.isis_domain_interfaces[key] = [] + for isis_domain_interface_mo in isis_domain_interfaces_mo: + self.isis_domain_interfaces[key].append( + self.get_protocol_isis_domain_interface_info( + isis_domain_interface_mo + ) + ) + + return self.isis_domain_interfaces[key] + + def get_protocol_isis_domain_interfaces(self, pod_id, node_id, instance_name, domain_name): + interfaces = self.get_protocol_isis_domain_interfaces_info(pod_id, node_id, instance_name, domain_name) + if interfaces is None: + return None + + interfaces = sorted( + interfaces, + key=lambda i: i['id'].lower() + ) + + return interfaces diff --git a/lib/aci/proto/isis/interface/main.py b/lib/aci/proto/isis/interface/main.py new file mode 100644 index 00000000..a2ce4c25 --- /dev/null +++ b/lib/aci/proto/isis/interface/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.interface.api import ProtocolIsisInterfaceApi +from lib.aci.proto.isis.interface.info import ProtocolIsisInterfaceInfo + + +class ProtocolIsisInterface(ProtocolIsisInterfaceApi, ProtocolIsisInterfaceInfo): + def __init__(self): + ProtocolIsisInterfaceApi.__init__(self) + ProtocolIsisInterfaceInfo.__init__(self) diff --git a/lib/aci/proto/isis/interface/stats/__init__.py b/lib/aci/proto/isis/interface/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/lsp/__init__.py b/lib/aci/proto/isis/lsp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/lsp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/lsp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..fc33f389 Binary files /dev/null and b/lib/aci/proto/isis/lsp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/lsp/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/lsp/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..4790790e Binary files /dev/null and b/lib/aci/proto/isis/lsp/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/lsp/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/lsp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..34f00b13 Binary files /dev/null and b/lib/aci/proto/isis/lsp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/lsp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/lsp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..da7c50d9 Binary files /dev/null and b/lib/aci/proto/isis/lsp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/lsp/api.py b/lib/aci/proto/isis/lsp/api.py new file mode 100644 index 00000000..19f7ae9d --- /dev/null +++ b/lib/aci/proto/isis/lsp/api.py @@ -0,0 +1,64 @@ +class ProtocolIsisLspApi(): + def __init__(self): + self.isis_domain_lsps_mo = {} + + def get_protocol_isis_domain_lsps_mo(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_lsps_mo: + return self.isis_domain_lsps_mo[key] + + cache = self.get_object_cache( + 'isisLspRec', + object_selector=key + ) + if cache is not None: + self.isis_domain_lsps_mo[key] = cache + self.log.apic_mo( + 'isisLspRec.%s' % (key), + self.isis_domain_lsps_mo[key] + ) + return self.isis_domain_lsps_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis/inst-%s/dom-%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + query = 'query-target=subtree&target-subtree-class=isisLspRec' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domain_lsps_mo', + 'API failed' + ) + return None + + self.isis_domain_lsps_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.isis_domain_lsps_mo[key].append( + managed_object['isisLspRec']['attributes'] + ) + + self.log.apic_mo( + 'isisLspRec.%s' % (key), + self.isis_domain_lsps_mo[key] + ) + + self.set_object_cache( + 'isisLspRec', + self.isis_domain_lsps_mo[key], + object_selector=key + ) + + return self.isis_domain_lsps_mo[key] diff --git a/lib/aci/proto/isis/lsp/info.py b/lib/aci/proto/isis/lsp/info.py new file mode 100644 index 00000000..3cbef2a8 --- /dev/null +++ b/lib/aci/proto/isis/lsp/info.py @@ -0,0 +1,59 @@ +class ProtocolIsisLspInfo(): + def __init__(self): + self.isis_domain_lsps = {} + + def get_protocol_isis_domain_lsp_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + info['instance'] = info['dn'].split('/')[5].split('-')[1] + info['domain'] = info['dn'].split('/')[6].split('-')[1] + + return info + + def get_protocol_isis_domain_lsps_info(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_lsps: + return self.isis_domain_lsps[key] + + isis_domain_lsps_mo = self.get_protocol_isis_domain_lsps_mo( + pod_id, + node_id, + instance_name, + domain_name + ) + if isis_domain_lsps_mo is not None: + self.isis_domain_lsps[key] = [] + for isis_domain_lsp_mo in isis_domain_lsps_mo: + self.isis_domain_lsps[key].append( + self.get_protocol_isis_domain_lsp_info( + isis_domain_lsp_mo + ) + ) + + return self.isis_domain_lsps[key] + + def get_protocol_isis_domain_lsps(self, pod_id, node_id, instance_name, domain_name): + lsps = self.get_protocol_isis_domain_lsps_info(pod_id, node_id, instance_name, domain_name) + if lsps is None: + return None + + lsps = sorted( + lsps, + key=lambda i: i['sysId'].lower() + ) + + return lsps diff --git a/lib/aci/proto/isis/lsp/main.py b/lib/aci/proto/isis/lsp/main.py new file mode 100644 index 00000000..8e362748 --- /dev/null +++ b/lib/aci/proto/isis/lsp/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.lsp.api import ProtocolIsisLspApi +from lib.aci.proto.isis.lsp.info import ProtocolIsisLspInfo + + +class ProtocolIsisLsp(ProtocolIsisLspApi, ProtocolIsisLspInfo): + def __init__(self): + ProtocolIsisLspApi.__init__(self) + ProtocolIsisLspInfo.__init__(self) diff --git a/lib/aci/proto/isis/main.py b/lib/aci/proto/isis/main.py new file mode 100644 index 00000000..e2e292e3 --- /dev/null +++ b/lib/aci/proto/isis/main.py @@ -0,0 +1,114 @@ +from lib.aci.proto.isis.domain.main import ProtocolIsisDomain +from lib.aci.proto.isis.instance.main import ProtocolIsisInstance +from lib.aci.proto.isis.interface.main import ProtocolIsisInterface +from lib.aci.proto.isis.lsp.main import ProtocolIsisLsp +from lib.aci.proto.isis.neighbor.main import ProtocolIsisNeighbor +from lib.aci.proto.isis.route.main import ProtocolIsisRoute +from lib.aci.proto.isis.tree.main import ProtocolIsisTree +from lib.aci.proto.isis.tunnel.main import ProtocolIsisTunnel +from lib.aci.proto.isis.event.main import ProtocolIsisEvent +from lib.aci.proto.isis.fault.main import ProtocolIsisFault + + +class ProtocolIsis( + ProtocolIsisDomain, + ProtocolIsisInterface, + ProtocolIsisInstance, + ProtocolIsisLsp, + ProtocolIsisNeighbor, + ProtocolIsisRoute, + ProtocolIsisTree, + ProtocolIsisTunnel, + ProtocolIsisEvent, + ProtocolIsisFault + ): + def __init__(self): + ProtocolIsisDomain.__init__(self) + ProtocolIsisInstance.__init__(self) + ProtocolIsisInterface.__init__(self) + ProtocolIsisLsp.__init__(self) + ProtocolIsisNeighbor.__init__(self) + ProtocolIsisRoute.__init__(self) + ProtocolIsisTree.__init__(self) + ProtocolIsisTunnel.__init__(self) + ProtocolIsisEvent.__init__(self) + ProtocolIsisFault.__init__(self) + + def get_protocol_isis( + self, + pod_id, + node_id, + isis_domain_filter=None, + instance_info=False, + domain_info=False, + tunnel_info=False, + lsp_info=False, + interface_info=False, + neighbor_info=False, + tree_info=False, + route_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_isis_instance( + pod_id=pod_id, + node_id=node_id + ) + + if domain_info: + info['domain'] = self.get_protocol_isis_domains( + pod_id, + node_id, + isis_domain_filter=isis_domain_filter, + tunnel_info=tunnel_info, + lsp_info=lsp_info, + interface_info=interface_info, + neighbor_info=neighbor_info, + tree_info=tree_info, + route_info=route_info + ) + + if instance_info: + info['instance']['domainCount'] = len(info['domain']) + + if fault_info: + info['faultInst'] = self.get_protocol_isis_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_isis_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_isis_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/isis/neighbor/__init__.py b/lib/aci/proto/isis/neighbor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/neighbor/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/neighbor/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2a9681db Binary files /dev/null and b/lib/aci/proto/isis/neighbor/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/neighbor/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/neighbor/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..e2d00236 Binary files /dev/null and b/lib/aci/proto/isis/neighbor/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/neighbor/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/neighbor/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f1a7a25a Binary files /dev/null and b/lib/aci/proto/isis/neighbor/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/neighbor/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/neighbor/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..62793d8d Binary files /dev/null and b/lib/aci/proto/isis/neighbor/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/neighbor/api.py b/lib/aci/proto/isis/neighbor/api.py new file mode 100644 index 00000000..96cfc140 --- /dev/null +++ b/lib/aci/proto/isis/neighbor/api.py @@ -0,0 +1,70 @@ +class ProtocolIsisNeighborApi(): + def __init__(self): + self.isis_domain_neighbors_mo = {} + + def get_protocol_isis_domain_neighbors_mo(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_neighbors_mo: + return self.isis_domain_neighbors_mo[key] + + cache = self.get_object_cache( + 'isisAdjEp', + object_selector=key + ) + if cache is not None: + self.isis_domain_neighbors_mo[key] = cache + self.log.apic_mo( + 'isisAdjEp.%s' % (key), + self.isis_domain_neighbors_mo[key] + ) + return self.isis_domain_neighbors_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis/inst-%s/dom-%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + query = 'query-target=subtree&target-subtree-class=isisAdjEp&rsp-subtree=children&rsp-subtree-class=isisPeerIpAddr' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domain_neighbors_mo', + 'API failed' + ) + return None + + self.isis_domain_neighbors_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['isisAdjEp']['attributes'] + attributes['isisPeerIpAddr'] = self.get_mo_child_attributes( + 'isisAdjEp', + managed_object, + 'isisPeerIpAddr' + ) + self.isis_domain_neighbors_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'isisAdjEp.%s' % (key), + self.isis_domain_neighbors_mo[key] + ) + + self.set_object_cache( + 'isisAdjEp', + self.isis_domain_neighbors_mo[key], + object_selector=key + ) + + return self.isis_domain_neighbors_mo[key] diff --git a/lib/aci/proto/isis/neighbor/info.py b/lib/aci/proto/isis/neighbor/info.py new file mode 100644 index 00000000..65081200 --- /dev/null +++ b/lib/aci/proto/isis/neighbor/info.py @@ -0,0 +1,72 @@ +class ProtocolIsisNeighborInfo(): + def __init__(self): + self.isis_domain_neighbors = {} + + def get_protocol_isis_domain_neighbor_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + info['instance'] = info['dn'].split('/')[5].split('-')[1] + info['domain'] = info['dn'].split('/')[6].split('-')[1] + info['interface'] = info['dn'].split('[')[1].split(']')[0] + + if info['operSt'] == 'up': + info['__Output']['operSt'] = 'Green' + else: + info['__Output']['operSt'] = 'Red' + + return info + + def get_protocol_isis_domain_neighbors_info(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_neighbors: + return self.isis_domain_neighbors[key] + + isis_domain_neighbors_mo = self.get_protocol_isis_domain_neighbors_mo( + pod_id, + node_id, + instance_name, + domain_name + ) + if isis_domain_neighbors_mo is not None: + self.isis_domain_neighbors[key] = [] + for isis_domain_neighbor_mo in isis_domain_neighbors_mo: + self.isis_domain_neighbors[key].append( + self.get_protocol_isis_domain_neighbor_info( + isis_domain_neighbor_mo + ) + ) + + return self.isis_domain_neighbors[key] + + def get_protocol_isis_domain_neighbors(self, pod_id, node_id, instance_name, domain_name): + neighbors = self.get_protocol_isis_domain_neighbors_info(pod_id, node_id, instance_name, domain_name) + if neighbors is None: + return None + + neighbors = sorted( + neighbors, + key=lambda i: i['name'].lower() + ) + + return neighbors diff --git a/lib/aci/proto/isis/neighbor/main.py b/lib/aci/proto/isis/neighbor/main.py new file mode 100644 index 00000000..a7f94a0a --- /dev/null +++ b/lib/aci/proto/isis/neighbor/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.neighbor.api import ProtocolIsisNeighborApi +from lib.aci.proto.isis.neighbor.info import ProtocolIsisNeighborInfo + + +class ProtocolIsisNeighbor(ProtocolIsisNeighborApi, ProtocolIsisNeighborInfo): + def __init__(self): + ProtocolIsisNeighborApi.__init__(self) + ProtocolIsisNeighborInfo.__init__(self) diff --git a/lib/aci/proto/isis/output.py b/lib/aci/proto/isis/output.py new file mode 100644 index 00000000..6ab638ec --- /dev/null +++ b/lib/aci/proto/isis/output.py @@ -0,0 +1,536 @@ +class ProtocolIsisOutput(): + def __init__(self): + pass + + def print_proto_isis_domains(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'name', + 'operSt', + 'sysId', + 'areaId', + 'nSel', + 'mode', + 'maxEcmp', + 'metricStyle', + 'mtu' + ] + + headers = [ + 'Domain', + 'Oper State', + 'System ID', + 'Area', + 'Protocol', + 'Mode', + 'Max ECMP', + 'Metric Style', + 'MTU' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + if len(info) == 0: + return + + order = [ + 'instance.pod_node_name', + 'instance.health', + 'instance.faults', + 'instance.adminSt', + 'domain.name', + 'domain.operSt', + 'domain.sysId', + 'domain.areaId', + 'domain.nSel', + 'domain.mode', + 'domain.maxEcmp', + 'domain.metricStyle', + 'domain.mtu' + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'Admin State', + 'Domain Name', + 'Oper State', + 'System ID', + 'Area', + 'Protocol', + 'Mode', + 'Max ECMP', + 'Metric Style', + 'MTU' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['domain'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True, + merge=True + ) + + def print_proto_isis_interfaces(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Interface [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain', + 'id', + 'adminSt', + 'cktT', + 'ctrl', + 'iibState' + ] + + headers = [ + 'Node', + 'Domain', + 'Id', + 'Admin State', + 'Circuit Type', + 'Control', + 'Protocol State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_lsps(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - LSP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain', + 'sysId', + 'lanId', + 'frag', + 'type', + 'timerExpiryTS', + 'seqNum' + ] + + headers = [ + 'Node', + 'Domain', + 'Sys Id', + 'Lan Id', + 'Frag', + 'Type', + 'Lifetime', + 'Seqnum' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_neighbors(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain', + 'interface', + 'sysId', + 'type', + 'cktType', + 'isisPeerIpAddr.addr', + 'operSt' + ] + + headers = [ + 'Node', + 'Domain', + 'Interface', + 'System Id', + 'Level', + 'Circuit Type', + 'Peer IP', + 'State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_routes(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Route [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain', + 'pfx', + 'metric', + 'pref', + 'isisNexthop.interface', + 'isisNexthop.address' + ] + + headers = [ + 'Node', + 'Domain', + 'Prefix', + 'Metric', + 'Preference', + 'NH Interface', + 'NH Address' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['isisNexthop'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_trees(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Tree [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain', + 'id', + 'root', + 'rootPort', + 'diameter', + 'origin', + 'diaAlert', + 'operSt' + ] + + headers = [ + 'Node', + 'Domain', + 'Id', + 'Root Address', + 'Root Port', + 'Diameter', + 'Origin', + 'Diameter Alert', + 'Oper State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_tunnels(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Tunnel [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domain', + 'id', + 'dest_node', + 'role', + 'type' + ] + + headers = [ + 'Node', + 'Domain', + 'Id', + 'Destination', + 'Role', + 'Type' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ISIS - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol ISIS - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol ISIS - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_isis_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol ISIS - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol ISIS - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/isis/route/__init__.py b/lib/aci/proto/isis/route/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/route/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/route/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..19e200ab Binary files /dev/null and b/lib/aci/proto/isis/route/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/route/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/route/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..c2061db4 Binary files /dev/null and b/lib/aci/proto/isis/route/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/route/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/route/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1a1f68f8 Binary files /dev/null and b/lib/aci/proto/isis/route/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/route/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/route/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..05d6ac01 Binary files /dev/null and b/lib/aci/proto/isis/route/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/route/api.py b/lib/aci/proto/isis/route/api.py new file mode 100644 index 00000000..2e0e3470 --- /dev/null +++ b/lib/aci/proto/isis/route/api.py @@ -0,0 +1,78 @@ +class ProtocolIsisRouteApi(): + def __init__(self): + self.isis_domain_routes_mo = {} + + def get_protocol_isis_domain_routes_mo(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_routes_mo: + return self.isis_domain_routes_mo[key] + + cache = self.get_object_cache( + 'isisRoute', + object_selector=key + ) + if cache is not None: + self.isis_domain_routes_mo[key] = cache + self.log.apic_mo( + 'isisRoute.%s' % (key), + self.isis_domain_routes_mo[key] + ) + return self.isis_domain_routes_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis/inst-%s/dom-%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + query = 'query-target=subtree&target-subtree-class=isisRoute&target-subtree-class=isisRsNhAtt' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domain_routes_mo', + 'API failed' + ) + return None + + self.isis_domain_routes_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'isisRoute' in managed_object: + attributes = managed_object['isisRoute']['attributes'] + attributes['isisNexthop'] = [] + self.isis_domain_routes_mo[key].append( + attributes + ) + + for managed_object in managed_objects['imdata']: + if 'isisRsNhAtt' in managed_object: + attributes = managed_object['isisRsNhAtt']['attributes'] + for route in self.isis_domain_routes_mo[key]: + pfx = route['dn'].split('rt-[')[1].split(']')[0] + if route['pfx'] == pfx: + if attributes['tDn'] not in route['isisNexthop']: + route['isisNexthop'].append( + attributes['tDn'] + ) + + self.log.apic_mo( + 'isisRoute.%s' % (key), + self.isis_domain_routes_mo[key] + ) + + self.set_object_cache( + 'isisRoute', + self.isis_domain_routes_mo[key], + object_selector=key + ) + + return self.isis_domain_routes_mo[key] diff --git a/lib/aci/proto/isis/route/info.py b/lib/aci/proto/isis/route/info.py new file mode 100644 index 00000000..4e7216e0 --- /dev/null +++ b/lib/aci/proto/isis/route/info.py @@ -0,0 +1,70 @@ +class ProtocolIsisRouteInfo(): + def __init__(self): + self.isis_domain_routes = {} + + def get_protocol_isis_domain_route_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key == 'isisNexthop': + info['isisNexthop'] = [] + for next_hop in managed_object['isisNexthop']: + # "topology/pod-1/node-201/sys/isis/inst-default/dom-overlay-1/db-nh/nh-[eth1/107.7]-[]", + nh_info = {} + nh_info['interface'] = next_hop.split('nh-[')[1].split(']')[0] + nh_info['address'] = next_hop.split(']-[')[1].split(']')[0] + info['isisNexthop'].append( + nh_info + ) + else: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + info['instance'] = info['dn'].split('/')[5].split('-')[1] + info['domain'] = info['dn'].split('/')[6].split('-')[1] + + return info + + def get_protocol_isis_domain_routes_info(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_routes: + return self.isis_domain_routes[key] + + isis_domain_routes_mo = self.get_protocol_isis_domain_routes_mo( + pod_id, + node_id, + instance_name, + domain_name + ) + if isis_domain_routes_mo is not None: + self.isis_domain_routes[key] = [] + for isis_domain_route_mo in isis_domain_routes_mo: + self.isis_domain_routes[key].append( + self.get_protocol_isis_domain_route_info( + isis_domain_route_mo + ) + ) + + return self.isis_domain_routes[key] + + def get_protocol_isis_domain_routes(self, pod_id, node_id, instance_name, domain_name): + routes = self.get_protocol_isis_domain_routes_info(pod_id, node_id, instance_name, domain_name) + if routes is None: + return None + + routes = sorted( + routes, + key=lambda i: i['pfx'].lower() + ) + + return routes diff --git a/lib/aci/proto/isis/route/main.py b/lib/aci/proto/isis/route/main.py new file mode 100644 index 00000000..9672c841 --- /dev/null +++ b/lib/aci/proto/isis/route/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.route.api import ProtocolIsisRouteApi +from lib.aci.proto.isis.route.info import ProtocolIsisRouteInfo + + +class ProtocolIsisRoute(ProtocolIsisRouteApi, ProtocolIsisRouteInfo): + def __init__(self): + ProtocolIsisRouteApi.__init__(self) + ProtocolIsisRouteInfo.__init__(self) diff --git a/lib/aci/proto/isis/tree/__init__.py b/lib/aci/proto/isis/tree/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/tree/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/tree/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a35b776a Binary files /dev/null and b/lib/aci/proto/isis/tree/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tree/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/tree/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..b3668a74 Binary files /dev/null and b/lib/aci/proto/isis/tree/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tree/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/tree/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..4f63a721 Binary files /dev/null and b/lib/aci/proto/isis/tree/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tree/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/tree/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f3aef95f Binary files /dev/null and b/lib/aci/proto/isis/tree/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tree/api.py b/lib/aci/proto/isis/tree/api.py new file mode 100644 index 00000000..c2e182ca --- /dev/null +++ b/lib/aci/proto/isis/tree/api.py @@ -0,0 +1,64 @@ +class ProtocolIsisTreeApi(): + def __init__(self): + self.isis_domain_trees_mo = {} + + def get_protocol_isis_domain_trees_mo(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_trees_mo: + return self.isis_domain_trees_mo[key] + + cache = self.get_object_cache( + 'isisFmcastTree', + object_selector=key + ) + if cache is not None: + self.isis_domain_trees_mo[key] = cache + self.log.apic_mo( + 'isisFmcastTree.%s' % (key), + self.isis_domain_trees_mo[key] + ) + return self.isis_domain_trees_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis/inst-%s/dom-%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + query = 'query-target=subtree&target-subtree-class=isisFmcastTree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domain_trees_mo', + 'API failed' + ) + return None + + self.isis_domain_trees_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.isis_domain_trees_mo[key].append( + managed_object['isisFmcastTree']['attributes'] + ) + + self.log.apic_mo( + 'isisFmcastTree.%s' % (key), + self.isis_domain_trees_mo[key] + ) + + self.set_object_cache( + 'isisFmcastTree', + self.isis_domain_trees_mo[key], + object_selector=key + ) + + return self.isis_domain_trees_mo[key] diff --git a/lib/aci/proto/isis/tree/info.py b/lib/aci/proto/isis/tree/info.py new file mode 100644 index 00000000..cd7c7a39 --- /dev/null +++ b/lib/aci/proto/isis/tree/info.py @@ -0,0 +1,67 @@ +class ProtocolIsisTreeInfo(): + def __init__(self): + self.isis_domain_trees = {} + + def get_protocol_isis_domain_tree_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['instance'] = info['dn'].split('/')[5].split('-')[1] + info['domain'] = info['dn'].split('/')[6].split('-')[1] + + if info['operSt'] == 'active': + info['enable'] = True + info['__Output']['operSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['operSt'] = 'Red' + + return info + + def get_protocol_isis_domain_trees_info(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_trees: + return self.isis_domain_trees[key] + + isis_domain_trees_mo = self.get_protocol_isis_domain_trees_mo( + pod_id, + node_id, + instance_name, + domain_name + ) + if isis_domain_trees_mo is not None: + self.isis_domain_trees[key] = [] + for isis_domain_tree_mo in isis_domain_trees_mo: + self.isis_domain_trees[key].append( + self.get_protocol_isis_domain_tree_info( + isis_domain_tree_mo + ) + ) + + return self.isis_domain_trees[key] + + def get_protocol_isis_domain_trees(self, pod_id, node_id, instance_name, domain_name): + trees = self.get_protocol_isis_domain_trees_info(pod_id, node_id, instance_name, domain_name) + if trees is None: + return None + + trees = sorted( + trees, + key=lambda i: int(i['id']) + ) + + return trees diff --git a/lib/aci/proto/isis/tree/main.py b/lib/aci/proto/isis/tree/main.py new file mode 100644 index 00000000..ae3b32ea --- /dev/null +++ b/lib/aci/proto/isis/tree/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.tree.api import ProtocolIsisTreeApi +from lib.aci.proto.isis.tree.info import ProtocolIsisTreeInfo + + +class ProtocolIsisTree(ProtocolIsisTreeApi, ProtocolIsisTreeInfo): + def __init__(self): + ProtocolIsisTreeApi.__init__(self) + ProtocolIsisTreeInfo.__init__(self) diff --git a/lib/aci/proto/isis/tunnel/__init__.py b/lib/aci/proto/isis/tunnel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/isis/tunnel/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/isis/tunnel/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0a5abcf4 Binary files /dev/null and b/lib/aci/proto/isis/tunnel/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tunnel/__pycache__/api.cpython-310.pyc b/lib/aci/proto/isis/tunnel/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..9bb65512 Binary files /dev/null and b/lib/aci/proto/isis/tunnel/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tunnel/__pycache__/info.cpython-310.pyc b/lib/aci/proto/isis/tunnel/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..686ea5c9 Binary files /dev/null and b/lib/aci/proto/isis/tunnel/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tunnel/__pycache__/main.cpython-310.pyc b/lib/aci/proto/isis/tunnel/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..30042049 Binary files /dev/null and b/lib/aci/proto/isis/tunnel/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/isis/tunnel/api.py b/lib/aci/proto/isis/tunnel/api.py new file mode 100644 index 00000000..cfe00300 --- /dev/null +++ b/lib/aci/proto/isis/tunnel/api.py @@ -0,0 +1,64 @@ +class ProtocolIsisTunnelApi(): + def __init__(self): + self.isis_domain_tunnels_mo = {} + + def get_protocol_isis_domain_tunnels_mo(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_tunnels_mo: + return self.isis_domain_tunnels_mo[key] + + cache = self.get_object_cache( + 'isisDTEp', + object_selector=key + ) + if cache is not None: + self.isis_domain_tunnels_mo[key] = cache + self.log.apic_mo( + 'isisDTEp.%s' % (key), + self.isis_domain_tunnels_mo[key] + ) + return self.isis_domain_tunnels_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/isis/inst-%s/dom-%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + query = 'query-target=subtree&target-subtree-class=isisDTEp' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_isis_domain_tunnels_mo', + 'API failed' + ) + return None + + self.isis_domain_tunnels_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.isis_domain_tunnels_mo[key].append( + managed_object['isisDTEp']['attributes'] + ) + + self.log.apic_mo( + 'isisDTEp.%s' % (key), + self.isis_domain_tunnels_mo[key] + ) + + self.set_object_cache( + 'isisDTEp', + self.isis_domain_tunnels_mo[key], + object_selector=key + ) + + return self.isis_domain_tunnels_mo[key] diff --git a/lib/aci/proto/isis/tunnel/info.py b/lib/aci/proto/isis/tunnel/info.py new file mode 100644 index 00000000..55ad9660 --- /dev/null +++ b/lib/aci/proto/isis/tunnel/info.py @@ -0,0 +1,75 @@ +from lib import ip_helper + + +class ProtocolIsisTunnelInfo(): + def __init__(self): + self.isis_domain_tunnels = {} + + def get_protocol_isis_domain_tunnel_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['instance'] = info['dn'].split('/')[5].split('-')[1] + info['domain'] = info['dn'].split('/')[6].split('-')[1] + + info['id_resolved'] = info['id'] + if ip_helper.is_valid_ipv4_address(info['id']): + destination_node_info = self.get_node( + node_ip=info['id'] + ) + if destination_node_info is not None: + info['dest_node'] = destination_node_info['pod_node_name'] + info['id_resolved'] = '%s (%s)' % ( + info['id'], + info['dest_node'] + ) + + return info + + def get_protocol_isis_domain_tunnels_info(self, pod_id, node_id, instance_name, domain_name): + key = '%s.%s.%s.%s' % ( + pod_id, + node_id, + instance_name, + domain_name + ) + if key in self.isis_domain_tunnels: + return self.isis_domain_tunnels[key] + + isis_domain_tunnels_mo = self.get_protocol_isis_domain_tunnels_mo( + pod_id, + node_id, + instance_name, + domain_name + ) + if isis_domain_tunnels_mo is not None: + self.isis_domain_tunnels[key] = [] + for isis_domain_tunnel_mo in isis_domain_tunnels_mo: + self.isis_domain_tunnels[key].append( + self.get_protocol_isis_domain_tunnel_info( + isis_domain_tunnel_mo + ) + ) + + return self.isis_domain_tunnels[key] + + def get_protocol_isis_domain_tunnels(self, pod_id, node_id, instance_name, domain_name): + tunnels = self.get_protocol_isis_domain_tunnels_info(pod_id, node_id, instance_name, domain_name) + if tunnels is None: + return None + + tunnels = sorted( + tunnels, + key=lambda i: i['id'].lower() + ) + + return tunnels diff --git a/lib/aci/proto/isis/tunnel/main.py b/lib/aci/proto/isis/tunnel/main.py new file mode 100644 index 00000000..186b121a --- /dev/null +++ b/lib/aci/proto/isis/tunnel/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.isis.tunnel.api import ProtocolIsisTunnelApi +from lib.aci.proto.isis.tunnel.info import ProtocolIsisTunnelInfo + + +class ProtocolIsisTunnel(ProtocolIsisTunnelApi, ProtocolIsisTunnelInfo): + def __init__(self): + ProtocolIsisTunnelApi.__init__(self) + ProtocolIsisTunnelInfo.__init__(self) diff --git a/lib/aci/proto/lacp/__init__.py b/lib/aci/proto/lacp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lacp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/lacp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d99a6462 Binary files /dev/null and b/lib/aci/proto/lacp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/lacp/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..69c9ec35 Binary files /dev/null and b/lib/aci/proto/lacp/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/__pycache__/interface.cpython-310.pyc b/lib/aci/proto/lacp/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..51c7a25e Binary files /dev/null and b/lib/aci/proto/lacp/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/lacp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..2d9b30ad Binary files /dev/null and b/lib/aci/proto/lacp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/__pycache__/output.cpython-310.pyc b/lib/aci/proto/lacp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..a923e11d Binary files /dev/null and b/lib/aci/proto/lacp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/bot_output.py b/lib/aci/proto/lacp/bot_output.py new file mode 100644 index 00000000..4927543e --- /dev/null +++ b/lib/aci/proto/lacp/bot_output.py @@ -0,0 +1,217 @@ +class ProtocolLacpBotOutput(): + def __init__(self): + pass + + def print_proto_lacp_instances(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Protocol LACP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'pod_node_name', + 'adminSt', + 'sysMac', + 'adminPrio', + 'operPrio', + 'summary.portUp', + 'summary.portDown', + 'summary.portCount' + ] + + headers = [ + 'Node', + 'Admin', + 'System MAC', + 'Admin Prio', + 'Oper Prio', + 'Intf Up', + 'Intf Down', + 'Intf Count' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Protocol LACP - Instance' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_proto_lacp_interfaces(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Protocol LACP - Port Channel [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'pod_node_name', + 'id', + 'name', + 'adminSt', + 'state.operSt', + 'lacp.id', + 'lacp.key', + 'lacp.adjacency.sysId', + 'lacp.adjacency.sysPrio', + 'lacp.adjacency.key', + 'lacp.adjacency.port', + 'lacp.adjacency.portPrio', + 'lacp.adjacency.activityFlags' + ] + + headers = [ + 'Node', + 'Intf Id', + 'Name', + 'Admin', + 'Oper', + 'Member', + 'Oper Key', + 'Nbr System MAC', + 'Nbr System Prio', + 'Nbr Oper Key', + 'Nbr Port', + 'Nbr Port Prio', + 'Nbr Port State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['lacp'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Protocol LACP - Port Channel' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_proto_lacp_interfaces_stats(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Protocol LACP - Interface Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'pod_node_name', + 'id', + 'name', + 'adminSt', + 'state.operSt', + 'lacp.id', + 'lacp.stats.pduSent', + 'lacp.stats.pduRcvd', + 'lacp.stats.errPktRcvd', + 'lacp.stats.markerSent', + 'lacp.stats.markerRcvd', + 'lacp.stats.markerRspSent', + 'lacp.stats.markerRspRcvd' + ] + + headers = [ + 'Node', + 'Intf Id', + 'Name', + 'Admin', + 'Oper', + 'Member', + 'PDU Sent', + 'PDU Recv', + 'PDU Recv Err', + 'Marker Sent', + 'Marker Recv', + 'Marker Response Sent', + 'Marker Response Recv' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['lacp'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Protocol LACP - Interface Stats' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/aci/proto/lacp/event/__init__.py b/lib/aci/proto/lacp/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lacp/event/api.py b/lib/aci/proto/lacp/event/api.py new file mode 100644 index 00000000..8bad6024 --- /dev/null +++ b/lib/aci/proto/lacp/event/api.py @@ -0,0 +1,55 @@ +class ProtocolLacpEventApi(): + def __init__(self): + self.proto_lacp_event_mo = {} + + def get_protocol_lacp_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_lacp_event_mo: + return self.proto_lacp_event_mo[key] + + cache = self.get_object_cache( + 'lacp.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_lacp_event_mo[key] = cache + self.log.apic_mo( + 'lacp.eventLog.%s' % (key), + self.proto_lacp_event_mo[key] + ) + return self.proto_lacp_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lacp/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lacp_event_mo', + 'API failed' + ) + return None + + self.proto_lacp_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_lacp_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lacp.eventLog.%s' % (key), + self.proto_lacp_event_mo[key] + ) + + self.set_object_cache( + 'lacp.eventLog', + self.proto_lacp_event_mo[key], + object_selector=key + ) + + return self.proto_lacp_event_mo[key] diff --git a/lib/aci/proto/lacp/event/info.py b/lib/aci/proto/lacp/event/info.py new file mode 100644 index 00000000..cadc7151 --- /dev/null +++ b/lib/aci/proto/lacp/event/info.py @@ -0,0 +1,91 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolLacpEventInfo(): + def __init__(self): + self.proto_lacp_event = {} + + def get_protocol_lacp_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/lacp/inst/if-[eth1/27] + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['interfaceId'] = None + if '/sys/lacp/inst/if-[' in info['affected']: + info['interfaceId'] = info['affected'].split('/sys/lacp/inst/if-[')[1].split(']')[0] + + info['interfaceT'] = info['interfaceId'] + if info['interfaceT'] is None: + info['interfaceT'] = '--' + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_lacp_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_lacp_event: + return self.proto_lacp_event[key] + + managed_objects = self.get_protocol_lacp_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_lacp_event[key] = [] + for managed_object in managed_objects: + self.proto_lacp_event[key].append( + self.get_protocol_lacp_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lacp.eventLog.info.%s' % (key), + self.proto_lacp_event[key] + ) + + return self.proto_lacp_event[key] diff --git a/lib/aci/proto/lacp/event/main.py b/lib/aci/proto/lacp/event/main.py new file mode 100644 index 00000000..65cff184 --- /dev/null +++ b/lib/aci/proto/lacp/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.lacp.event.api import ProtocolLacpEventApi +from lib.aci.proto.lacp.event.info import ProtocolLacpEventInfo + + +class ProtocolLacpEvent(ProtocolLacpEventApi, ProtocolLacpEventInfo): + def __init__(self): + ProtocolLacpEventApi.__init__(self) + ProtocolLacpEventInfo.__init__(self) diff --git a/lib/aci/proto/lacp/instance/__init__.py b/lib/aci/proto/lacp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lacp/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/lacp/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f3cce075 Binary files /dev/null and b/lib/aci/proto/lacp/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/lacp/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..82fd58be Binary files /dev/null and b/lib/aci/proto/lacp/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/lacp/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..13559c75 Binary files /dev/null and b/lib/aci/proto/lacp/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/lacp/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7f1c56a1 Binary files /dev/null and b/lib/aci/proto/lacp/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/instance/api.py b/lib/aci/proto/lacp/instance/api.py new file mode 100644 index 00000000..f3a59611 --- /dev/null +++ b/lib/aci/proto/lacp/instance/api.py @@ -0,0 +1,57 @@ +class ProtocolLacpInstanceApi(): + def __init__(self): + self.lacp_instance_mo = {} + + def get_protocol_lacp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lacp_instance_mo: + return self.lacp_instance_mo[key] + + cache = self.get_object_cache( + 'lacpInst', + object_selector=key + ) + if cache is not None: + self.lacp_instance_mo[key] = cache + self.log.apic_mo( + 'lacpInst.%s' % (key), + self.lacp_instance_mo[key] + ) + return self.lacp_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lacp/inst' % (pod_id, node_id) + managed_objects = self.get_managed_object( + distinguished_name + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lacp_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_lacp_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.lacp_instance_mo[key] = {} + else: + self.lacp_instance_mo[key] = managed_objects['imdata'][0]['lacpInst']['attributes'] + + self.log.apic_mo( + 'lacpInst.%s' % (key), + self.lacp_instance_mo[key] + ) + + self.set_object_cache( + 'lacpInst', + self.lacp_instance_mo[key], + object_selector=key + ) + + return self.lacp_instance_mo[key] diff --git a/lib/aci/proto/lacp/instance/info.py b/lib/aci/proto/lacp/instance/info.py new file mode 100644 index 00000000..e567a44e --- /dev/null +++ b/lib/aci/proto/lacp/instance/info.py @@ -0,0 +1,32 @@ +class ProtocolLacpInstanceInfo(): + def __init__(self): + pass + + def get_protocol_lacp_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + return info + + def get_protocol_lacp_instance(self, pod_id, node_id): + managed_object = self.get_protocol_lacp_instance_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_lacp_instance_info(managed_object) diff --git a/lib/aci/proto/lacp/instance/main.py b/lib/aci/proto/lacp/instance/main.py new file mode 100644 index 00000000..0ce9d505 --- /dev/null +++ b/lib/aci/proto/lacp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.lacp.instance.api import ProtocolLacpInstanceApi +from lib.aci.proto.lacp.instance.info import ProtocolLacpInstanceInfo + + +class ProtocolLacpInstance(ProtocolLacpInstanceApi, ProtocolLacpInstanceInfo): + def __init__(self): + ProtocolLacpInstanceApi.__init__(self) + ProtocolLacpInstanceInfo.__init__(self) diff --git a/lib/aci/proto/lacp/interface/__init__.py b/lib/aci/proto/lacp/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lacp/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/lacp/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0a5b5112 Binary files /dev/null and b/lib/aci/proto/lacp/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/interface/__pycache__/main.cpython-310.pyc b/lib/aci/proto/lacp/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0471b450 Binary files /dev/null and b/lib/aci/proto/lacp/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/lacp/interface/main.py b/lib/aci/proto/lacp/interface/main.py new file mode 100644 index 00000000..765886c5 --- /dev/null +++ b/lib/aci/proto/lacp/interface/main.py @@ -0,0 +1,3 @@ +class ProtocolLacpInterface(): + def __init__(self): + pass diff --git a/lib/aci/proto/lacp/main.py b/lib/aci/proto/lacp/main.py new file mode 100644 index 00000000..80f1894e --- /dev/null +++ b/lib/aci/proto/lacp/main.py @@ -0,0 +1,118 @@ +from lib import filter_helper + +from lib.aci.proto.lacp.instance.main import ProtocolLacpInstance +from lib.aci.proto.lacp.interface.main import ProtocolLacpInterface +from lib.aci.proto.lacp.event.main import ProtocolLacpEvent + + +class ProtocolLacp( + ProtocolLacpInstance, + ProtocolLacpInterface, + ProtocolLacpEvent + ): + def __init__(self): + ProtocolLacpInstance.__init__(self) + ProtocolLacpInterface.__init__(self) + ProtocolLacpEvent.__init__(self) + + def match_protocol_lacp_interface(self, interface_info, interface_filter): + if interface_filter is None or len(interface_filter) == 0: + return True + + for ap_rule in interface_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'mac': + key_found = True + found = False + for lacp_interface_info in interface_info['lacp']: + if 'adjacency' in lacp_interface_info and 'sysId' in lacp_interface_info['adjacency']: + for mac_address in value.split(','): + if filter_helper.match_mac(mac_address, lacp_interface_info['adjacency']['sysId']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_protocol_lacp_interface', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_protocol_lacp( + self, + pod_id, + node_id, + instance_info=False, + interface_info=False, + interface_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_lacp_instance( + pod_id, + node_id + ) + + if interface_info: + interfaces_info = self.get_interface_port_channel( + pod_id, + node_id + ) + + lacp_interfaces = self.get_interface_lacp( + pod_id, + node_id, + adjacency_info=True + ) + + for interface in interfaces_info: + interface['lacp'] = [] + for lacp_interface in lacp_interfaces: + if lacp_interface['id'] in interface['state']['portId']: + interface['lacp'].append( + lacp_interface + ) + + info['interfaces'] = [] + for interface in interfaces_info: + if not self.match_protocol_lacp_interface(interface, interface_filter): + continue + + info['interfaces'].append( + interface + ) + + if instance_info: + info['instance']['summary'] = self.get_interface_port_channel_summary( + pod_id, + node_id + ) + for key in info['instance']['summary']['__Output']: + info['instance']['__Output']['summary.%s' % (key)] = info['instance']['summary']['__Output'][key] + + if event_info: + all_events = self.get_protocol_lacp_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/lacp/output.py b/lib/aci/proto/lacp/output.py new file mode 100644 index 00000000..2e1866b3 --- /dev/null +++ b/lib/aci/proto/lacp/output.py @@ -0,0 +1,224 @@ +class ProtocolLacpOutput(): + def __init__(self): + pass + + def print_proto_lacp_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol LACP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'instance.pod_node_name', + 'instance.adminSt', + 'instance.sysMac', + 'instance.adminPrio', + 'instance.operPrio', + 'instance.summary.portUp', + 'instance.summary.portDown', + 'instance.summary.portCount' + ] + + headers = [ + 'Node', + 'Admin', + 'System MAC', + 'Admin Prio', + 'Oper Prio', + 'Intf Up', + 'Intf Down', + 'Intf Count' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_proto_lacp_interfaces(self, info, title=False): + if title: + self.my_output.default( + 'Protocol LACP - Port Channels [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'id', + 'name', + 'adminSt', + 'state.operSt', + 'lacp.id', + 'lacp.key', + 'lacp.adjacency.sysId', + 'lacp.adjacency.sysPrio', + 'lacp.adjacency.key', + 'lacp.adjacency.port', + 'lacp.adjacency.portPrio', + 'lacp.adjacency.activityFlags' + ] + + headers = [ + 'Node', + 'Intf Id', + 'Name', + 'Admin', + 'Oper', + 'Member', + 'Oper Key', + 'Nbr System MAC', + 'Nbr System Prio', + 'Nbr Oper Key', + 'Nbr Port', + 'Nbr Port Prio', + 'Nbr Port State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['lacp'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_proto_lacp_interfaces_stats(self, info, title=False): + if title: + self.my_output.default( + 'Protocol LACP - Interface Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'id', + 'name', + 'adminSt', + 'state.operSt', + 'lacp.id', + 'lacp.stats.pduSent', + 'lacp.stats.pduRcvd', + 'lacp.stats.errPktRcvd', + 'lacp.stats.markerSent', + 'lacp.stats.markerRcvd', + 'lacp.stats.markerRspSent', + 'lacp.stats.markerRspRcvd' + ] + + headers = [ + 'Node', + 'Intf Id', + 'Name', + 'Admin', + 'Oper', + 'Member', + 'PDU Sent', + 'PDU Recv', + 'PDU Recv Err', + 'Marker Sent', + 'Marker Recv', + 'Marker Response Sent', + 'Marker Response Recv' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['lacp'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_proto_lacp_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol LACP - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol LACP - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interfaceT', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Interface', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/lldp/__init__.py b/lib/aci/proto/lldp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lldp/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c7f02441 Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/__pycache__/context.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/context.cpython-310.pyc new file mode 100644 index 00000000..b6874bc8 Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/context.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/__pycache__/info.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..a3cd86ff Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..0242cb67 Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/__pycache__/instance_stats.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/instance_stats.cpython-310.pyc new file mode 100644 index 00000000..d22490ac Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/instance_stats.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/__pycache__/main.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5fe7e7b8 Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/__pycache__/output.cpython-310.pyc b/lib/aci/proto/lldp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..b37bff3e Binary files /dev/null and b/lib/aci/proto/lldp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/bot_output.py b/lib/aci/proto/lldp/bot_output.py new file mode 100644 index 00000000..463d45b3 --- /dev/null +++ b/lib/aci/proto/lldp/bot_output.py @@ -0,0 +1,212 @@ +from lib import filter_helper + + +class ProtocolLldpBotOutput(): + def __init__(self): + pass + + def print_proto_lldp_instances(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Protocol LLDP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'pod_node_name', + 'adminSt', + 'health', + 'faults', + 'holdTime', + 'initDelayTime', + 'txFreq', + 'adjacencyCount', + 'errorsTick' + ] + + headers = [ + 'Node', + 'Admin State', + 'Health', + 'Faults', + 'Hold Time', + 'Init Delay Time', + 'Transmission Frequency', + 'Neighbors', + 'Errors' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Protocol LLDP - Instance' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_proto_lldp_adjacency(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Protocol LLDP - Adjacency [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + for item in info: + item['portDescT'] = filter_helper.get_string_chunks( + item['portDesc'], + 30 + ) + + order = [ + 'pod_node_name', + 'health', + 'faults', + 'interface_id', + 'ttl', + 'sysName', + 'mac', + 'portId', + 'portVlan', + 'portDescT', + 'capability' + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'Intf', + 'Hold', + 'Neighbor', + 'MAC', + 'Port', + 'VLAN', + 'Description', + 'Cap' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['portDescT'] + ), + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Protocol LLDP - Adjacency' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_proto_lldp_interfaces_stats(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Protocol LLDP - Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'pod_node_name', + 'pktSent', + 'pktRcvd', + 'pktDiscarded', + 'errPktRcvd', + 'unrecogTLV', + 'numAdjAdded', + 'numAdjRemoved', + 'entriesAged' + ] + + headers = [ + 'Node', + 'Packets Sent', + 'Packets Received', + 'Packets Discarded', + 'Error Received Packets', + 'Unrecognized TLV', + 'Adjacencies Added', + 'Adjacencies Removed', + 'Entries Aged' + ] + + self.my_output.my_table( + info, + merge=True, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Protocol LLDP - Stats' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/aci/proto/lldp/context.py b/lib/aci/proto/lldp/context.py new file mode 100644 index 00000000..c62f765c --- /dev/null +++ b/lib/aci/proto/lldp/context.py @@ -0,0 +1,23 @@ +class ProtocolLldpContext(): + def __init__(self): + pass + + def add_protocol_lldp_adjacency_context(self, context, adjacency_info): + for item in adjacency_info: + node_name = self.get_node_name(item['node_id'].split('-')[1]) + if node_name not in context['node'][self.apic_name]: + context['node'][self.apic_name].append( + node_name + ) + + interface_name = '%s:%s:%s' % ( + item['pod_id'], + item['node_id'], + item['interface_id'] + ) + if interface_name not in context['interface'][self.apic_name]: + context['interface'][self.apic_name].append( + interface_name + ) + + return context diff --git a/lib/aci/proto/lldp/event/__init__.py b/lib/aci/proto/lldp/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lldp/event/api.py b/lib/aci/proto/lldp/event/api.py new file mode 100644 index 00000000..f8f5bad9 --- /dev/null +++ b/lib/aci/proto/lldp/event/api.py @@ -0,0 +1,55 @@ +class ProtocolLldpEventApi(): + def __init__(self): + self.lldp_event_mo = {} + + def get_protocol_lldp_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lldp_event_mo: + return self.lldp_event_mo[key] + + cache = self.get_object_cache( + 'lldpInst.eventLog', + object_selector=key + ) + if cache is not None: + self.lldp_event_mo[key] = cache + self.log.apic_mo( + 'lldpInst.eventLog.%s' % (key), + self.lldp_event_mo[key] + ) + return self.lldp_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lldp/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lldp_event_mo', + 'API failed' + ) + return None + + self.lldp_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.lldp_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lldpInst.eventLog.%s' % (key), + self.lldp_event_mo[key] + ) + + self.set_object_cache( + 'lldpInst.eventLog', + self.lldp_event_mo[key], + object_selector=key + ) + + return self.lldp_event_mo[key] diff --git a/lib/aci/proto/lldp/event/info.py b/lib/aci/proto/lldp/event/info.py new file mode 100644 index 00000000..3c49fcad --- /dev/null +++ b/lib/aci/proto/lldp/event/info.py @@ -0,0 +1,115 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolLldpEventInfo(): + def __init__(self): + self.lldp_event = {} + + def get_protocol_lldp_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/lldp/inst/if-[eth1/4/3]/adj-1" + info['interface_id'] = None + if 'affected' in info: + if 'sys/lldp/inst/if-' in info['affected']: + info['interface_id'] = info['affected'].split('sys/lldp/inst/if-[')[1].split(']')[0] + + # "dn": "subj-[topology/pod-1/node-2208/sys/lldp/inst/if-[eth1/4/3]/adj-1]/rec-12886869434", + if 'affected' not in info: + if 'sys/lldp/inst/if-' in info['dn']: + info['interface_id'] = info['dn'].split('sys/lldp/inst/if-[')[1].split(']')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['affected'] + ), + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_lldp_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lldp_event: + return self.lldp_event[key] + + managed_objects = self.get_protocol_lldp_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.lldp_event[key] = [] + for managed_object in managed_objects: + self.lldp_event[key].append( + self.get_protocol_lldp_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lldpInst.eventRecord.info.%s' % (key), + self.lldp_event[key] + ) + + return self.lldp_event[key] + + def get_protocol_lldp_adjacency_event(self, pod_id, node_id, interface_id, event_filter=None): + events = [] + + all_events = self.get_protocol_lldp_event( + pod_id, + node_id + ) + if all_events is None: + return events + + for event_info in all_events: + if event_info['interface_id'] is not None: + if event_info['interface_id'] == interface_id: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/proto/lldp/event/main.py b/lib/aci/proto/lldp/event/main.py new file mode 100644 index 00000000..bd054b4a --- /dev/null +++ b/lib/aci/proto/lldp/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.lldp.event.api import ProtocolLldpEventApi +from lib.aci.proto.lldp.event.info import ProtocolLldpEventInfo + + +class ProtocolLldpEvent(ProtocolLldpEventApi, ProtocolLldpEventInfo): + def __init__(self): + ProtocolLldpEventApi.__init__(self) + ProtocolLldpEventInfo.__init__(self) diff --git a/lib/aci/proto/lldp/fault/__init__.py b/lib/aci/proto/lldp/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lldp/fault/api.py b/lib/aci/proto/lldp/fault/api.py new file mode 100644 index 00000000..c28c2dcc --- /dev/null +++ b/lib/aci/proto/lldp/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolLldpFaultApi(): + def __init__(self): + self.lldp_fault_mo = {} + self.lldp_fault_record_mo = {} + + def get_protocol_lldp_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lldp_fault_mo: + return self.lldp_fault_mo[key] + + cache = self.get_object_cache( + 'lldpInst.fault', + object_selector=key + ) + if cache is not None: + self.lldp_fault_mo[key] = cache + self.log.apic_mo( + 'lldpInst.fault.%s' % (key), + self.lldp_fault_mo[key] + ) + return self.lldp_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lldp/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lldp_fault_mo', + 'API failed' + ) + return None + + self.lldp_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.lldp_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lldpInst.fault.%s' % (key), + self.lldp_fault_mo[key] + ) + + self.set_object_cache( + 'lldpInst.fault', + self.lldp_fault_mo[key], + object_selector=key + ) + + return self.lldp_fault_mo[key] + + def get_protocol_lldp_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lldp_fault_record_mo: + return self.lldp_fault_record_mo[key] + + cache = self.get_object_cache( + 'lldpInst.faultRecord', + object_selector=key + ) + if cache is not None: + self.lldp_fault_record_mo[key] = cache + self.log.apic_mo( + 'lldpInst.faultRecord.%s' % (key), + self.lldp_fault_record_mo[key] + ) + return self.lldp_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lldp/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lldp_fault_record_mo', + 'API failed' + ) + return None + + self.lldp_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.lldp_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'lldpInst.faultRecord.%s' % (key), + self.lldp_fault_record_mo[key] + ) + + self.set_object_cache( + 'lldpInst.faultRecord', + self.lldp_fault_record_mo[key], + object_selector=key + ) + + return self.lldp_fault_record_mo[key] diff --git a/lib/aci/proto/lldp/fault/info.py b/lib/aci/proto/lldp/fault/info.py new file mode 100644 index 00000000..7c7bdaf0 --- /dev/null +++ b/lib/aci/proto/lldp/fault/info.py @@ -0,0 +1,117 @@ +class ProtocolLldpFaultInfo(): + def __init__(self): + self.lldp_fault = {} + self.lldp_fault_record = {} + + def get_protocol_lldp_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # "affected": "topology/pod-1/node-2208/sys/lldp/inst/if-[eth1/4/3]/adj-1" + info['interface_id'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'sys/lldp/inst/if-[' in info['affected']: + info['interface_id'] = info['affected'].split('sys/lldp/inst/if-[')[1].split(']')[0] + + # "dn": "subj-[topology/pod-1/node-2208/sys/lldp/inst/if-[eth1/4/3]/adj-1]/rec-12886869434", + if info['interface_id'] is None: + if 'sys/lldp/inst/if-' in info['dn']: + info['interface_id'] = info['dn'].split('sys/lldp/inst/if-[')[1].split(']')[0] + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_lldp_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lldp_fault: + return self.lldp_fault[key] + + managed_objects = self.get_protocol_lldp_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.lldp_fault[key] = [] + for managed_object in managed_objects: + self.lldp_fault[key].append( + self.get_protocol_lldp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lldpInst.fault.info.%s' % (key), + self.lldp_fault[key] + ) + + return self.lldp_fault[key] + + def get_protocol_lldp_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.lldp_fault_record: + return self.lldp_fault_record[key] + + managed_objects = self.get_protocol_lldp_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.lldp_fault_record[key] = [] + for managed_object in managed_objects: + self.lldp_fault_record[key].append( + self.get_protocol_lldp_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'lldpInst.faultRecord.info.%s' % (key), + self.lldp_fault_record[key] + ) + + return self.lldp_fault_record[key] + + def get_protocol_lldp_adjacency_fault(self, pod_id, node_id, interface_id, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_protocol_lldp_fault( + pod_id, + node_id + ) + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_protocol_lldp_fault_record( + pod_id, + node_id + ) + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['interface_id'] is not None: + if fault_info['interface_id'] == interface_id: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/proto/lldp/fault/main.py b/lib/aci/proto/lldp/fault/main.py new file mode 100644 index 00000000..f57985e4 --- /dev/null +++ b/lib/aci/proto/lldp/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.lldp.fault.api import ProtocolLldpFaultApi +from lib.aci.proto.lldp.fault.info import ProtocolLldpFaultInfo + + +class ProtocolLldpFault(ProtocolLldpFaultApi, ProtocolLldpFaultInfo): + def __init__(self): + ProtocolLldpFaultApi.__init__(self) + ProtocolLldpFaultInfo.__init__(self) diff --git a/lib/aci/proto/lldp/info.py b/lib/aci/proto/lldp/info.py new file mode 100644 index 00000000..c36a354f --- /dev/null +++ b/lib/aci/proto/lldp/info.py @@ -0,0 +1,90 @@ +class ProtocolLldpInfo(): + def __init__(self): + pass + + def get_protocol_lldp( + self, + pod_id, + node_id, + adjacency_filter=None, + instance_info=True, + stats_info=True, + adjacency_info=True, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_lldp_instance( + pod_id, + node_id + ) + + if stats_info: + info['stats'] = self.get_protocol_lldp_stats( + pod_id, + node_id + ) + + if adjacency_info: + info['adjacency'] = self.get_lldp_adjacency_endpoint( + pod_id, + node_id, + adjacency_filter=adjacency_filter + ) + + if instance_info: + info['instance']['adjacencyCount'] = len(info['adjacency']) + + if stats_info: + info['instance']['__Output']['errorsTick'] = info['stats']['__Output']['errorsTick'] + info['instance']['errorsTick'] = info['stats']['errorsTick'] + + if fault_info: + info['faultInst'] = self.get_protocol_lldp_fault( + pod_id, + node_id + ) + if adjacency_info: + for adjacency in info['adjacency']: + adjacency['faultInst'] = self.get_protocol_lldp_adjacency_fault( + pod_id, + node_id, + adjacency['interface_id'], + 'faultInst' + ) + + if hfault_info: + info['faultRecord'] = self.get_protocol_lldp_fault( + pod_id, + node_id + ) + if adjacency_info: + for adjacency in info['adjacency']: + adjacency['faultRecord'] = self.get_protocol_lldp_adjacency_fault( + pod_id, + node_id, + adjacency['interface_id'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + info['eventLog'] = self.get_protocol_lldp_event( + pod_id, + node_id + ) + if adjacency_info: + for adjacency in info['adjacency']: + adjacency['eventLog'] = self.get_protocol_lldp_adjacency_event( + pod_id, + node_id, + adjacency['interface_id'], + event_filter=event_filter + ) + + return info diff --git a/lib/aci/proto/lldp/instance/__init__.py b/lib/aci/proto/lldp/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lldp/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/lldp/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..27db724c Binary files /dev/null and b/lib/aci/proto/lldp/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/lldp/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..2ccef556 Binary files /dev/null and b/lib/aci/proto/lldp/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/lldp/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..61eda5cd Binary files /dev/null and b/lib/aci/proto/lldp/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/lldp/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..cc9514c2 Binary files /dev/null and b/lib/aci/proto/lldp/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/instance/api.py b/lib/aci/proto/lldp/instance/api.py new file mode 100644 index 00000000..68565c3c --- /dev/null +++ b/lib/aci/proto/lldp/instance/api.py @@ -0,0 +1,70 @@ +class ProtocolLldpInstanceApi(): + def __init__(self): + self.protocol_lldp_instance_mo = {} + + def get_protocol_lldp_instance_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.protocol_lldp_instance_mo: + return self.protocol_lldp_instance_mo[key] + + cache = self.get_object_cache( + 'lldpInst', + object_selector=key + ) + if cache is not None: + self.protocol_lldp_instance_mo[key] = cache + self.log.apic_mo( + 'lldpInst.%s' % (key), + self.protocol_lldp_instance_mo[key] + ) + return self.protocol_lldp_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/lldp/inst' % (pod_id, node_id) + query = 'rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lldp_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_lldp_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.protocol_lldp_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['lldpInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'lldpInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'lldpInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.protocol_lldp_instance_mo[key] = attributes + + self.log.apic_mo( + 'lldpInst.%s' % (key), + self.protocol_lldp_instance_mo[key] + ) + + self.set_object_cache( + 'lldpInst', + self.protocol_lldp_instance_mo[key], + object_selector=key + ) + + return self.protocol_lldp_instance_mo[key] diff --git a/lib/aci/proto/lldp/instance/info.py b/lib/aci/proto/lldp/instance/info.py new file mode 100644 index 00000000..677029ab --- /dev/null +++ b/lib/aci/proto/lldp/instance/info.py @@ -0,0 +1,40 @@ +class ProtocolLldpInstanceInfo(): + def __init__(self): + pass + + def get_protocol_lldp_instance_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_lldp_instance(self, pod_id, node_id): + managed_object = self.get_protocol_lldp_instance_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_lldp_instance_info(managed_object) diff --git a/lib/aci/proto/lldp/instance/main.py b/lib/aci/proto/lldp/instance/main.py new file mode 100644 index 00000000..f26a22e3 --- /dev/null +++ b/lib/aci/proto/lldp/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.lldp.instance.api import ProtocolLldpInstanceApi +from lib.aci.proto.lldp.instance.info import ProtocolLldpInstanceInfo + + +class ProtocolLldpInstance(ProtocolLldpInstanceApi, ProtocolLldpInstanceInfo): + def __init__(self): + ProtocolLldpInstanceApi.__init__(self) + ProtocolLldpInstanceInfo.__init__(self) diff --git a/lib/aci/proto/lldp/main.py b/lib/aci/proto/lldp/main.py new file mode 100644 index 00000000..101d1bb0 --- /dev/null +++ b/lib/aci/proto/lldp/main.py @@ -0,0 +1,16 @@ +from lib.aci.proto.lldp.instance.main import ProtocolLldpInstance +from lib.aci.proto.lldp.stats.main import ProtocolLldpStats +from lib.aci.proto.lldp.context import ProtocolLldpContext +from lib.aci.proto.lldp.info import ProtocolLldpInfo +from lib.aci.proto.lldp.event.main import ProtocolLldpEvent +from lib.aci.proto.lldp.fault.main import ProtocolLldpFault + + +class ProtocolLldp(ProtocolLldpInstance, ProtocolLldpStats, ProtocolLldpContext, ProtocolLldpInfo, ProtocolLldpEvent, ProtocolLldpFault): + def __init__(self): + ProtocolLldpInstance.__init__(self) + ProtocolLldpStats.__init__(self) + ProtocolLldpContext.__init__(self) + ProtocolLldpInfo.__init__(self) + ProtocolLldpEvent.__init__(self) + ProtocolLldpFault.__init__(self) diff --git a/lib/aci/proto/lldp/output.py b/lib/aci/proto/lldp/output.py new file mode 100644 index 00000000..cfa5aae5 --- /dev/null +++ b/lib/aci/proto/lldp/output.py @@ -0,0 +1,256 @@ +class ProtocolLldpOutput(): + def __init__(self): + pass + + def print_proto_lldp_instance(self, info, title=False): + if title: + self.my_output.default( + 'Protocol LLDP - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'adminSt', + 'health', + 'faults', + 'holdTime', + 'initDelayTime', + 'txFreq', + 'adjacencyCount', + 'errorsTick' + ] + + headers = [ + 'Node', + 'Admin State', + 'Health', + 'Faults', + 'Hold Time', + 'Init Delay Time', + 'Transmission Frequency', + 'Neighbors', + 'Errors' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_proto_lldp_instances_stats(self, info, title=False): + if title: + self.my_output.default( + 'Protocol LLDP - Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'pktSent', + 'pktRcvd', + 'pktDiscarded', + 'errPktRcvd', + 'unrecogTLV', + 'numAdjAdded', + 'numAdjRemoved', + 'entriesAged' + ] + + headers = [ + 'Node', + 'Packets Sent', + 'Packets Received', + 'Packets Discarded', + 'Error Received Packets', + 'Unrecognized TLV', + 'Adjacencies Added', + 'Adjacencies Removed', + 'Entries Aged' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_proto_lldp_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol LLDP - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol LLDP - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interface_id', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Intf', + 'Severity', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_lldp_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol LLDP - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interface_id', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Intf', + 'Severity', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_lldp_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol LLDP - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol LLDP - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'interface_id', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Intf', + 'Severity', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/lldp/stats/__init__.py b/lib/aci/proto/lldp/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/lldp/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/lldp/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f0dfff9b Binary files /dev/null and b/lib/aci/proto/lldp/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/stats/__pycache__/api.cpython-310.pyc b/lib/aci/proto/lldp/stats/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..077f14fb Binary files /dev/null and b/lib/aci/proto/lldp/stats/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/stats/__pycache__/info.cpython-310.pyc b/lib/aci/proto/lldp/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..5ca2ffc7 Binary files /dev/null and b/lib/aci/proto/lldp/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/stats/__pycache__/main.cpython-310.pyc b/lib/aci/proto/lldp/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0a8acc5b Binary files /dev/null and b/lib/aci/proto/lldp/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/lldp/stats/api.py b/lib/aci/proto/lldp/stats/api.py new file mode 100644 index 00000000..d5e19112 --- /dev/null +++ b/lib/aci/proto/lldp/stats/api.py @@ -0,0 +1,57 @@ +class ProtocolLldpStatsApi(): + def __init__(self): + self.protocol_lldp_stats_mo = {} + + def get_protocol_lldp_stats_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.protocol_lldp_stats_mo: + return self.protocol_lldp_stats_mo[key] + + cache = self.get_object_cache( + 'lldpInstStats', + object_selector=key + ) + if cache is not None: + self.protocol_lldp_stats_mo[key] = cache + self.log.apic_mo( + 'lldpInstStats.%s' % (key), + self.protocol_lldp_stats_mo[key] + ) + return self.protocol_lldp_stats_mo[key] + + class_name = 'topology/pod-%s/node-%s/lldpInstStats' % (pod_id, node_id) + managed_objects = self.get_class( + class_name, + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_lldp_stats_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_lldp_stats_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.protocol_lldp_stats_mo[key] = {} + else: + self.protocol_lldp_stats_mo[key] = managed_objects['imdata'][0]['lldpInstStats']['attributes'] + + self.log.apic_mo( + 'lldpInstStats.%s' % (key), + self.protocol_lldp_stats_mo[key] + ) + + self.set_object_cache( + 'lldpInstStats', + self.protocol_lldp_stats_mo[key], + object_selector=key + ) + + return self.protocol_lldp_stats_mo[key] diff --git a/lib/aci/proto/lldp/stats/info.py b/lib/aci/proto/lldp/stats/info.py new file mode 100644 index 00000000..c9cb4b6e --- /dev/null +++ b/lib/aci/proto/lldp/stats/info.py @@ -0,0 +1,56 @@ +class ProtocolLldpStatsInfo(): + def __init__(self): + pass + + def get_protocol_lldp_stats_info(self, managed_object): + # "childAction": "", + # "dn": "topology/pod-1/node-205/sys/lldp/inst/inststats", + # "entriesAged": "0", + # "errPktRcvd": "0", + # "lastAdjChgTs": "2023-06-12T16:52:47.652+02:00", + # "modTs": "never", + # "numAdjAdded": "16", + # "numAdjRemoved": "0", + # "pktDiscarded": "0", + # "pktRcvd": "109173", + # "pktSent": "109091", + # "status": "", + # "unrecogTLV": "0" + + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # "dn": "topology/pod-1/node-205/sys/lldp/inst/inststats" + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['errors'] = False + info['errorsTick'] = '\u2717' + info['__Output']['errorsTick'] = 'Green' + + errors = [ + 'pktDiscarded', + 'errPktRcvd', + 'unrecogTLV' + ] + for key in errors: + if info[key] != '0': + info['__Output'][key] = 'Red' + info['errors'] = True + info['errorsTick'] = '\u2713' + info['__Output']['errorsTick'] = 'Red' + + return info + + def get_protocol_lldp_stats(self, pod_id, node_id): + managed_object = self.get_protocol_lldp_stats_mo(pod_id, node_id) + if managed_object is None or len(managed_object) == 0: + return None + + return self.get_protocol_lldp_stats_info(managed_object) diff --git a/lib/aci/proto/lldp/stats/main.py b/lib/aci/proto/lldp/stats/main.py new file mode 100644 index 00000000..12672c07 --- /dev/null +++ b/lib/aci/proto/lldp/stats/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.lldp.stats.api import ProtocolLldpStatsApi +from lib.aci.proto.lldp.stats.info import ProtocolLldpStatsInfo + + +class ProtocolLldpStats(ProtocolLldpStatsApi, ProtocolLldpStatsInfo): + def __init__(self): + ProtocolLldpStatsApi.__init__(self) + ProtocolLldpStatsInfo.__init__(self) diff --git a/lib/aci/proto/main.py b/lib/aci/proto/main.py new file mode 100644 index 00000000..014ccb52 --- /dev/null +++ b/lib/aci/proto/main.py @@ -0,0 +1,52 @@ +from lib.aci.proto.arp.main import ProtocolArp +from lib.aci.proto.bfd.main import ProtocolBfd +from lib.aci.proto.bgp.main import ProtocolBgp +from lib.aci.proto.cdp.main import ProtocolCdp +from lib.aci.proto.hsrp.main import ProtocolHsrp +from lib.aci.proto.ipv4.main import ProtocolIpv4 +from lib.aci.proto.ipv6.main import ProtocolIpv6 +from lib.aci.proto.isis.main import ProtocolIsis +from lib.aci.proto.lacp.main import ProtocolLacp +from lib.aci.proto.lldp.main import ProtocolLldp +from lib.aci.proto.nd.main import ProtocolNd + + +class Protocol( + ProtocolArp, + ProtocolBfd, + ProtocolBgp, + ProtocolCdp, + ProtocolHsrp, + ProtocolIpv4, + ProtocolIpv6, + ProtocolIsis, + ProtocolLacp, + ProtocolLldp, + ProtocolNd + ): + def __init__(self): + ProtocolArp.__init__(self) + ProtocolBfd.__init__(self) + ProtocolBgp.__init__(self) + ProtocolCdp.__init__(self) + ProtocolHsrp.__init__(self) + ProtocolIpv4.__init__(self) + ProtocolIpv6.__init__(self) + ProtocolIsis.__init__(self) + ProtocolLacp.__init__(self) + ProtocolLldp.__init__(self) + ProtocolNd.__init__(self) + + self.protocols = [ + 'arp', + 'bfd', + 'bgp', + 'cdp', + 'hsrp', + 'ipv4', + 'ipv6', + 'isis', + 'lacp', + 'lldp', + 'nd' + ] diff --git a/lib/aci/proto/nd/__init__.py b/lib/aci/proto/nd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9fee1207 Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/domain.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/domain.cpython-310.pyc new file mode 100644 index 00000000..73d69259 Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/domain.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/instance.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..f97dc1ec Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/interface.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..e0cb4568 Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/interface_stats.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/interface_stats.cpython-310.pyc new file mode 100644 index 00000000..6c376543 Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/interface_stats.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/main.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..864d9947 Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/neighbor.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/neighbor.cpython-310.pyc new file mode 100644 index 00000000..9f75a2e4 Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/neighbor.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/__pycache__/output.cpython-310.pyc b/lib/aci/proto/nd/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..403d480b Binary files /dev/null and b/lib/aci/proto/nd/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/domain/__init__.py b/lib/aci/proto/nd/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/domain/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/nd/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..26146f49 Binary files /dev/null and b/lib/aci/proto/nd/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/domain/__pycache__/api.cpython-310.pyc b/lib/aci/proto/nd/domain/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..75aa5ed1 Binary files /dev/null and b/lib/aci/proto/nd/domain/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/domain/__pycache__/info.cpython-310.pyc b/lib/aci/proto/nd/domain/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f0dbcbca Binary files /dev/null and b/lib/aci/proto/nd/domain/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/domain/__pycache__/main.cpython-310.pyc b/lib/aci/proto/nd/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..69db8d10 Binary files /dev/null and b/lib/aci/proto/nd/domain/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/domain/api.py b/lib/aci/proto/nd/domain/api.py new file mode 100644 index 00000000..7d1001ae --- /dev/null +++ b/lib/aci/proto/nd/domain/api.py @@ -0,0 +1,67 @@ +class ProtocolNdDomainApi(): + def __init__(self): + self.nd_domain_mo = {} + + def get_protocol_nd_domain_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.nd_domain_mo: + return self.nd_domain_mo[key] + + cache = self.get_object_cache( + 'ndDom', + object_selector=key + ) + if cache is not None: + self.nd_domain_mo[key] = cache + self.log.apic_mo( + 'ndDom.%s' % (key), + self.nd_domain_mo[key] + ) + return self.nd_domain_mo[key] + + class_name = 'topology/pod-%s/node-%s/ndDom' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_domain_mo', + 'API failed' + ) + return None + + self.nd_domain_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['ndDom']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'ndDom', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'ndDom', + managed_object, + 'faultCounts' + ) + self.nd_domain_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ndDom.%s' % (key), + self.nd_domain_mo[key] + ) + + self.set_object_cache( + 'ndDom', + self.nd_domain_mo[key], + object_selector=key + ) + + return self.nd_domain_mo[key] diff --git a/lib/aci/proto/nd/domain/info.py b/lib/aci/proto/nd/domain/info.py new file mode 100644 index 00000000..16cfc9cc --- /dev/null +++ b/lib/aci/proto/nd/domain/info.py @@ -0,0 +1,64 @@ +class ProtocolNdDomainInfo(): + def __init__(self): + pass + + def add_protocol_nd_domain_neighbor_info(self, domains, neighbors): + for domain in domains: + domain['neighborsCount'] = 0 + + return domains + + def add_protocol_nd_domain_interface_info(self, domains, interfaces): + for domain in domains: + domain['interfacesCount'] = 0 + + for interface in interfaces: + if interface['domainName'] == domain['name']: + domain['interfacesCount'] = domain['interfacesCount'] + 1 + + return domains + + def get_protocol_nd_domain_entry_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['name'] = 'Yellow' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_protocol_nd_domain_info(self, pod_id, node_id, nd_domain_name=None): + managed_objects = self.get_protocol_nd_domain_mo( + pod_id, + node_id + ) + + info = [] + for managed_object in managed_objects: + nd_domain_info = self.get_protocol_nd_domain_entry_info( + managed_object + ) + + info.append( + nd_domain_info + ) + + info = sorted( + info, + key=lambda i: i['name'].lower() + ) + + return info diff --git a/lib/aci/proto/nd/domain/main.py b/lib/aci/proto/nd/domain/main.py new file mode 100644 index 00000000..660ea1a7 --- /dev/null +++ b/lib/aci/proto/nd/domain/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.nd.domain.api import ProtocolNdDomainApi +from lib.aci.proto.nd.domain.info import ProtocolNdDomainInfo + + +class ProtocolNdDomain(ProtocolNdDomainApi, ProtocolNdDomainInfo): + def __init__(self): + ProtocolNdDomainApi.__init__(self) + ProtocolNdDomainInfo.__init__(self) diff --git a/lib/aci/proto/nd/event/__init__.py b/lib/aci/proto/nd/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/event/api.py b/lib/aci/proto/nd/event/api.py new file mode 100644 index 00000000..41d4a14e --- /dev/null +++ b/lib/aci/proto/nd/event/api.py @@ -0,0 +1,55 @@ +class ProtocolNdEventApi(): + def __init__(self): + self.proto_nd_event_mo = {} + + def get_protocol_nd_event_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_nd_event_mo: + return self.proto_nd_event_mo[key] + + cache = self.get_object_cache( + 'ndDom.eventLog', + object_selector=key + ) + if cache is not None: + self.proto_nd_event_mo[key] = cache + self.log.apic_mo( + 'ndDom.eventLog.%s' % (key), + self.proto_nd_event_mo[key] + ) + return self.proto_nd_event_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/nd' % (pod_id, node_id) + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_event_mo', + 'API failed' + ) + return None + + self.proto_nd_event_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.proto_nd_event_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ndDom.eventLog.%s' % (key), + self.proto_nd_event_mo[key] + ) + + self.set_object_cache( + 'ndDom.eventLog', + self.proto_nd_event_mo[key], + object_selector=key + ) + + return self.proto_nd_event_mo[key] diff --git a/lib/aci/proto/nd/event/info.py b/lib/aci/proto/nd/event/info.py new file mode 100644 index 00000000..d647c0f1 --- /dev/null +++ b/lib/aci/proto/nd/event/info.py @@ -0,0 +1,83 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class ProtocolNdEventInfo(): + def __init__(self): + self.proto_nd_event = {} + + def get_protocol_nd_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-2205/sys/nd/inst + info['podId'] = info['affected'].split('/')[1].split('-')[1] + info['nodeId'] = info['affected'].split('/')[2].split('-')[1] + info['pod_node_name'] = 'pod-%s/%s' % ( + info['podId'], + self.get_node_name( + info['nodeId'] + ) + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 40 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + info['affectedT'] = filter_helper.get_string_chunks( + info['affected'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_nd_event(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_nd_event: + return self.proto_nd_event[key] + + managed_objects = self.get_protocol_nd_event_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_nd_event[key] = [] + for managed_object in managed_objects: + self.proto_nd_event[key].append( + self.get_protocol_nd_event_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ndDom.eventLog.info.%s' % (key), + self.proto_nd_event[key] + ) + + return self.proto_nd_event[key] diff --git a/lib/aci/proto/nd/event/main.py b/lib/aci/proto/nd/event/main.py new file mode 100644 index 00000000..13d93980 --- /dev/null +++ b/lib/aci/proto/nd/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.nd.event.api import ProtocolNdEventApi +from lib.aci.proto.nd.event.info import ProtocolNdEventInfo + + +class ProtocolNdEvent(ProtocolNdEventApi, ProtocolNdEventInfo): + def __init__(self): + ProtocolNdEventApi.__init__(self) + ProtocolNdEventInfo.__init__(self) diff --git a/lib/aci/proto/nd/fault/__init__.py b/lib/aci/proto/nd/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/fault/api.py b/lib/aci/proto/nd/fault/api.py new file mode 100644 index 00000000..6f900977 --- /dev/null +++ b/lib/aci/proto/nd/fault/api.py @@ -0,0 +1,126 @@ +class ProtocolNdFaultApi(): + def __init__(self): + self.proto_nd_fault_mo = {} + self.proto_nd_fault_record_mo = {} + + def get_protocol_nd_fault_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_nd_fault_mo: + return self.proto_nd_fault_mo[key] + + cache = self.get_object_cache( + 'ndDom.fault', + object_selector=key + ) + if cache is not None: + self.proto_nd_fault_mo[key] = cache + self.log.apic_mo( + 'ndDom.fault.%s' % (key), + self.proto_nd_fault_mo[key] + ) + return self.proto_nd_fault_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/nd' % (pod_id, node_id) + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_fault_mo', + 'API failed' + ) + return None + + self.proto_nd_fault_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.proto_nd_fault_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ndDom.fault.%s' % (key), + self.proto_nd_fault_mo[key] + ) + + self.set_object_cache( + 'ndDom.fault', + self.proto_nd_fault_mo[key], + object_selector=key + ) + + return self.proto_nd_fault_mo[key] + + def get_protocol_nd_fault_record_mo(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_nd_fault_record_mo: + return self.proto_nd_fault_record_mo[key] + + cache = self.get_object_cache( + 'ndDom.faultRecord', + object_selector=key + ) + if cache is not None: + self.proto_nd_fault_record_mo[key] = cache + self.log.apic_mo( + 'ndDom.faultRecord.%s' % (key), + self.proto_nd_fault_record_mo[key] + ) + return self.proto_nd_fault_record_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/nd' % (pod_id, node_id) + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_fault_record_mo', + 'API failed' + ) + return None + + self.proto_nd_fault_record_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.proto_nd_fault_record_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'ndDom.faultRecord.%s' % (key), + self.proto_nd_fault_record_mo[key] + ) + + self.set_object_cache( + 'ndDom.faultRecord', + self.proto_nd_fault_record_mo[key], + object_selector=key + ) + + return self.proto_nd_fault_record_mo[key] diff --git a/lib/aci/proto/nd/fault/info.py b/lib/aci/proto/nd/fault/info.py new file mode 100644 index 00000000..8f4564df --- /dev/null +++ b/lib/aci/proto/nd/fault/info.py @@ -0,0 +1,69 @@ +class ProtocolNdFaultInfo(): + def __init__(self): + self.proto_nd_fault = {} + self.proto_nd_fault_record = {} + + def get_protocol_nd_fault_info(self, managed_object): + info = self.get_system_fault_info( + managed_object + ) + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_protocol_nd_fault(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_nd_fault: + return self.proto_nd_fault[key] + + managed_objects = self.get_protocol_nd_fault_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_nd_fault[key] = [] + for managed_object in managed_objects: + self.proto_nd_fault[key].append( + self.get_protocol_nd_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ndDom.fault.info.%s' % (key), + self.proto_nd_fault[key] + ) + + return self.proto_nd_fault[key] + + def get_protocol_nd_fault_record(self, pod_id, node_id): + key = '%s.%s' % (pod_id, node_id) + if key in self.proto_nd_fault_record: + return self.proto_nd_fault_record[key] + + managed_objects = self.get_protocol_nd_fault_record_mo(pod_id, node_id) + if managed_objects is None: + return None + + self.proto_nd_fault_record[key] = [] + for managed_object in managed_objects: + self.proto_nd_fault_record[key].append( + self.get_protocol_nd_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'ndDom.faultRecord.info.%s' % (key), + self.proto_nd_fault_record[key] + ) + + return self.proto_nd_fault_record[key] diff --git a/lib/aci/proto/nd/fault/main.py b/lib/aci/proto/nd/fault/main.py new file mode 100644 index 00000000..c9998920 --- /dev/null +++ b/lib/aci/proto/nd/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.nd.fault.api import ProtocolNdFaultApi +from lib.aci.proto.nd.fault.info import ProtocolNdFaultInfo + + +class ProtocolNdFault(ProtocolNdFaultApi, ProtocolNdFaultInfo): + def __init__(self): + ProtocolNdFaultApi.__init__(self) + ProtocolNdFaultInfo.__init__(self) diff --git a/lib/aci/proto/nd/instance/__init__.py b/lib/aci/proto/nd/instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/instance/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/nd/instance/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1b96c767 Binary files /dev/null and b/lib/aci/proto/nd/instance/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/instance/__pycache__/api.cpython-310.pyc b/lib/aci/proto/nd/instance/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..d45a8ed6 Binary files /dev/null and b/lib/aci/proto/nd/instance/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/instance/__pycache__/info.cpython-310.pyc b/lib/aci/proto/nd/instance/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..7c78f100 Binary files /dev/null and b/lib/aci/proto/nd/instance/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/instance/__pycache__/main.cpython-310.pyc b/lib/aci/proto/nd/instance/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..369e6615 Binary files /dev/null and b/lib/aci/proto/nd/instance/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/instance/api.py b/lib/aci/proto/nd/instance/api.py new file mode 100644 index 00000000..689d4fe6 --- /dev/null +++ b/lib/aci/proto/nd/instance/api.py @@ -0,0 +1,73 @@ +class ProtocolNdInstanceApi(): + def __init__(self): + self.nd_instance_mo = {} + + def get_protocol_nd_instance_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.nd_instance_mo: + return self.nd_instance_mo[key] + + cache = self.get_object_cache( + 'ndInst', + object_selector=key + ) + if cache is not None: + self.nd_instance_mo[key] = cache + self.log.apic_mo( + 'ndInst.%s' % (key), + self.nd_instance_mo[key] + ) + return self.nd_instance_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/nd' % (pod_id, node_id) + query = 'query-target=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_instance_mo', + 'API failed' + ) + return None + + if int(managed_objects['totalCount']) > 1: + self.log.error( + 'get_protocol_nd_instance_mo', + 'Unexpected object count: %s' % (key) + ) + return None + + if int(managed_objects['totalCount']) == 0: + self.nd_instance_mo[key] = {} + else: + attributes = managed_objects['imdata'][0]['ndInst']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'ndInst', + managed_objects['imdata'][0], + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'ndInst', + managed_objects['imdata'][0], + 'faultCounts' + ) + self.nd_instance_mo[key] = attributes + + self.log.apic_mo( + 'ndInst.%s' % (key), + self.nd_instance_mo[key] + ) + + self.set_object_cache( + 'ndInst', + self.nd_instance_mo[key], + object_selector=key + ) + + return self.nd_instance_mo[key] diff --git a/lib/aci/proto/nd/instance/info.py b/lib/aci/proto/nd/instance/info.py new file mode 100644 index 00000000..e4799c92 --- /dev/null +++ b/lib/aci/proto/nd/instance/info.py @@ -0,0 +1,42 @@ +class ProtocolNdInstanceInfo(): + def __init__(self): + pass + + def get_protocol_nd_instance_info(self, pod_id, node_id): + managed_object = self.get_protocol_nd_instance_mo(pod_id, node_id) + + if managed_object is None: + return None + + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + if info['adminSt'] == 'enabled': + info['enable'] = True + info['__Output']['adminSt'] = 'Green' + else: + info['enable'] = False + info['__Output']['adminSt'] = 'Red' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info diff --git a/lib/aci/proto/nd/instance/main.py b/lib/aci/proto/nd/instance/main.py new file mode 100644 index 00000000..1e26d66c --- /dev/null +++ b/lib/aci/proto/nd/instance/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.nd.instance.api import ProtocolNdInstanceApi +from lib.aci.proto.nd.instance.info import ProtocolNdInstanceInfo + + +class ProtocolNdInstance(ProtocolNdInstanceApi, ProtocolNdInstanceInfo): + def __init__(self): + ProtocolNdInstanceApi.__init__(self) + ProtocolNdInstanceInfo.__init__(self) diff --git a/lib/aci/proto/nd/interface/__init__.py b/lib/aci/proto/nd/interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/interface/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/nd/interface/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0df9a197 Binary files /dev/null and b/lib/aci/proto/nd/interface/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/__pycache__/api.cpython-310.pyc b/lib/aci/proto/nd/interface/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..7f2ff026 Binary files /dev/null and b/lib/aci/proto/nd/interface/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/__pycache__/info.cpython-310.pyc b/lib/aci/proto/nd/interface/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..0325da72 Binary files /dev/null and b/lib/aci/proto/nd/interface/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/__pycache__/main.cpython-310.pyc b/lib/aci/proto/nd/interface/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6a1fc6c5 Binary files /dev/null and b/lib/aci/proto/nd/interface/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/api.py b/lib/aci/proto/nd/interface/api.py new file mode 100644 index 00000000..cc6db7fc --- /dev/null +++ b/lib/aci/proto/nd/interface/api.py @@ -0,0 +1,63 @@ +class ProtocolNdInterfaceApi(): + def __init__(self): + self.nd_interface_mo = {} + + def get_protocol_nd_interface_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.nd_interface_mo: + return self.nd_interface_mo[key] + + cache = self.get_object_cache( + 'ndIf', + object_selector=key + ) + if cache is not None: + self.nd_interface_mo[key] = cache + self.log.apic_mo( + 'ndIf.%s' % (key), + self.nd_interface_mo[key] + ) + return self.nd_interface_mo[key] + + # url: https:///api/node/class/topology/pod-1/node-201/ndIf.json?rsp-subtree=children&rsp-subtree-class=ndIf,ndIfStats&rsp-subtree-include=required + class_name = 'topology/pod-%s/node-%s/ndIf' % (pod_id, node_id) + query = 'rsp-subtree=children&rsp-subtree-class=ndIf,ndIfStats&rsp-subtree-include=required' + managed_objects = self.get_class( + class_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_interface_mo', + 'API failed' + ) + return None + + self.nd_interface_mo[key] = [] + for managed_object in managed_objects['imdata']: + if 'ndIf' in managed_object: + nd_interface = managed_object['ndIf']['attributes'] + for child in managed_object['ndIf']['children']: + if 'ndIfStats' in child: + nd_interface['ndIfStats'] = child['ndIfStats']['attributes'] + + self.nd_interface_mo[key].append( + nd_interface + ) + + self.log.apic_mo( + 'ndIf.%s' % (key), + self.nd_interface_mo[key] + ) + + self.set_object_cache( + 'ndIf', + self.nd_interface_mo[key], + object_selector=key + ) + + return self.nd_interface_mo[key] diff --git a/lib/aci/proto/nd/interface/info.py b/lib/aci/proto/nd/interface/info.py new file mode 100644 index 00000000..e526febd --- /dev/null +++ b/lib/aci/proto/nd/interface/info.py @@ -0,0 +1,101 @@ +import copy + + +class ProtocolNdInterfaceInfo(): + def __init__(self): + pass + + def get_nd_active_interface_count(self, interfaces): + count = 0 + for interface in interfaces: + if 'neighborCount' in interface and interface['neighborCount'] > 0: + count = count + 1 + return count + + def add_protocol_nd_interface_neighbor_info(self, interfaces, neighbors, remove_no_neighbors=False): + for interface in interfaces: + interface['neighborCount'] = 0 + interface_neighbors = [] + + for neighbor in neighbors: + if neighbor['interfaceId'] == interface['id']: + interface['neighborCount'] = interface['neighborCount'] + 1 + interface_neighbors.append( + neighbor['sysName'] + ) + + interface['neighborList'] = ', '.join(interface_neighbors) + + if remove_no_neighbors: + new_interfaces = [] + for interface in interfaces: + if interface['neighborCount'] > 0: + new_interfaces.append( + interface + ) + + interfaces = copy.deepcopy(new_interfaces) + + return interfaces + + def get_protocol_nd_interface_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key == 'ndIfStats': + stats_info = self.get_protocol_nd_interface_stats_info(managed_object[key]) + for stats_key in stats_info: + if stats_key == '__Output': + for stats_output_key in stats_info['__Output']: + info['__Output'][stats_output_key] = stats_info['__Output'][stats_output_key] + continue + info[stats_key] = stats_info[stats_key] + + continue + + info[key] = managed_object[key] + + info['pod_node_name'] = '%s/%s' % ( + info['dn'].split('/')[1], + self.get_node_name( + info['dn'].split('/')[2].split('-')[1] + ) + ) + + # topology/pod-1/node-201/sys/nd/inst/dom-cvim4a:cvim4a_VRF/if-[vlan161] + info['domainName'] = info['dn'].split('/')[6][4:] + + info['__Output']['id'] = 'Yellow' + if info['adminSt'] == 'enabled': + info['__Output']['adminSt'] = 'Green' + else: + info['__Output']['adminSt'] = 'Red' + + return info + + def get_protocol_nd_interfaces_info(self, pod_id, node_id, interface_id=None): + managed_objects = self.get_protocol_nd_interface_mo(pod_id, node_id) + + info = [] + for managed_object in managed_objects: + nd_interface_info = self.get_protocol_nd_interface_info( + managed_object + ) + + if interface_id is None: + info.append( + nd_interface_info + ) + + if interface_id is not None and nd_interface_info['id'] == interface_id: + return nd_interface_info + + info = sorted( + info, + key=lambda i: ( + i['domainName'], + i['id'] + ) + ) + + return info diff --git a/lib/aci/proto/nd/interface/main.py b/lib/aci/proto/nd/interface/main.py new file mode 100644 index 00000000..b89b3ac2 --- /dev/null +++ b/lib/aci/proto/nd/interface/main.py @@ -0,0 +1,10 @@ +from lib.aci.proto.nd.interface.api import ProtocolNdInterfaceApi +from lib.aci.proto.nd.interface.info import ProtocolNdInterfaceInfo +from lib.aci.proto.nd.interface.stats.main import ProtocolNdInstanceStats + + +class ProtocolNdInterface(ProtocolNdInterfaceApi, ProtocolNdInterfaceInfo, ProtocolNdInstanceStats): + def __init__(self): + ProtocolNdInterfaceApi.__init__(self) + ProtocolNdInterfaceInfo.__init__(self) + ProtocolNdInstanceStats.__init__(self) diff --git a/lib/aci/proto/nd/interface/stats/__init__.py b/lib/aci/proto/nd/interface/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/interface/stats/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/nd/interface/stats/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f8a84b45 Binary files /dev/null and b/lib/aci/proto/nd/interface/stats/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/stats/__pycache__/info.cpython-310.pyc b/lib/aci/proto/nd/interface/stats/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..600b3a08 Binary files /dev/null and b/lib/aci/proto/nd/interface/stats/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/stats/__pycache__/main.cpython-310.pyc b/lib/aci/proto/nd/interface/stats/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..331131bd Binary files /dev/null and b/lib/aci/proto/nd/interface/stats/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/interface/stats/info.py b/lib/aci/proto/nd/interface/stats/info.py new file mode 100644 index 00000000..88e7384f --- /dev/null +++ b/lib/aci/proto/nd/interface/stats/info.py @@ -0,0 +1,11 @@ +class ProtocolNdInterfaceStatsInfo(): + def __init__(self): + pass + + def get_protocol_nd_interface_stats_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/aci/proto/nd/interface/stats/main.py b/lib/aci/proto/nd/interface/stats/main.py new file mode 100644 index 00000000..10c27b76 --- /dev/null +++ b/lib/aci/proto/nd/interface/stats/main.py @@ -0,0 +1,6 @@ +from lib.aci.proto.nd.interface.stats.info import ProtocolNdInterfaceStatsInfo + + +class ProtocolNdInstanceStats(ProtocolNdInterfaceStatsInfo): + def __init__(self): + ProtocolNdInterfaceStatsInfo.__init__(self) diff --git a/lib/aci/proto/nd/main.py b/lib/aci/proto/nd/main.py new file mode 100644 index 00000000..d49b61d1 --- /dev/null +++ b/lib/aci/proto/nd/main.py @@ -0,0 +1,125 @@ +from lib.aci.proto.nd.instance.main import ProtocolNdInstance +from lib.aci.proto.nd.domain.main import ProtocolNdDomain +from lib.aci.proto.nd.interface.main import ProtocolNdInterface +from lib.aci.proto.nd.neighbor.main import ProtocolNdNeighbor +from lib.aci.proto.nd.event.main import ProtocolNdEvent +from lib.aci.proto.nd.fault.main import ProtocolNdFault + + +class ProtocolNd( + ProtocolNdInstance, + ProtocolNdDomain, + ProtocolNdInterface, + ProtocolNdNeighbor, + ProtocolNdEvent, + ProtocolNdFault + ): + def __init__(self): + ProtocolNdInstance.__init__(self) + ProtocolNdDomain.__init__(self) + ProtocolNdInterface.__init__(self) + ProtocolNdNeighbor.__init__(self) + ProtocolNdEvent.__init__(self) + ProtocolNdFault.__init__(self) + + def get_protocol_nd( + self, + pod_id, + node_id, + instance_info=False, + domain_info=False, + neighbor_info=False, + interface_info=False, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ): + info = {} + + if instance_info: + info['instance'] = self.get_protocol_nd_instance_info( + pod_id=pod_id, + node_id=node_id + ) + + if domain_info: + info['domain'] = self.get_protocol_nd_domain_info( + pod_id, + node_id + ) + + if neighbor_info: + info['neighbor'] = self.get_protocol_nd_neighbors_info( + pod_id, + node_id + ) + if domain_info: + info['domain'] = self.add_protocol_nd_domain_neighbor_info( + info['domain'], + info['neighbor'] + ) + + if instance_info: + info['instance']['neighborCount'] = len(info['neighbor']) + + if interface_info: + info['interface'] = self.get_protocol_nd_interfaces_info( + pod_id, + node_id + ) + + if interface_info: + info['domain'] = self.add_protocol_nd_domain_interface_info( + info['domain'], + info['interface'] + ) + + if neighbor_info: + info['interface'] = self.add_protocol_nd_interface_neighbor_info( + info['interface'], + info['neighbor'], + remove_no_neighbors=False + ) + + if instance_info: + info['instance']['activeInterfaceCount'] = self.get_nd_active_interface_count( + info['interface'] + ) + + if fault_info: + info['faultInst'] = self.get_protocol_nd_fault( + pod_id, + node_id + ) + + if hfault_info: + all_faults = self.get_protocol_nd_fault_record( + pod_id, + node_id + ) + info['faultRecord'] = [] + for fault in all_faults: + if not self.match_system_fault(fault, hfault_filter, exclude_cleared=False): + continue + + info['faultRecord'].append( + fault + ) + + if event_info: + all_events = self.get_protocol_nd_event( + pod_id, + node_id + ) + info['eventLog'] = [] + for event in all_events: + if not self.match_system_fault(event, event_filter, exclude_cleared=False): + continue + + info['eventLog'].append( + event + ) + + return info diff --git a/lib/aci/proto/nd/neighbor/__init__.py b/lib/aci/proto/nd/neighbor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/proto/nd/neighbor/__pycache__/__init__.cpython-310.pyc b/lib/aci/proto/nd/neighbor/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3d81da94 Binary files /dev/null and b/lib/aci/proto/nd/neighbor/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/neighbor/__pycache__/api.cpython-310.pyc b/lib/aci/proto/nd/neighbor/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..3cba0957 Binary files /dev/null and b/lib/aci/proto/nd/neighbor/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/neighbor/__pycache__/info.cpython-310.pyc b/lib/aci/proto/nd/neighbor/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ff7bcc24 Binary files /dev/null and b/lib/aci/proto/nd/neighbor/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/neighbor/__pycache__/main.cpython-310.pyc b/lib/aci/proto/nd/neighbor/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1a0e3f32 Binary files /dev/null and b/lib/aci/proto/nd/neighbor/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/proto/nd/neighbor/api.py b/lib/aci/proto/nd/neighbor/api.py new file mode 100644 index 00000000..867aadb4 --- /dev/null +++ b/lib/aci/proto/nd/neighbor/api.py @@ -0,0 +1,56 @@ +class ProtocolNdNeighborApi(): + def __init__(self): + self.nd_neighbor_mo = {} + + def get_protocol_nd_neighbor_mo(self, pod_id, node_id): + key = '%s.%s' % ( + pod_id, + node_id + ) + if key in self.nd_neighbor_mo: + return self.nd_neighbor_mo[key] + + cache = self.get_object_cache( + 'ndAdjEp', + object_selector=key + ) + if cache is not None: + self.nd_neighbor_mo[key] = cache + self.log.apic_mo( + 'ndAdjEp.%s' % (key), + self.nd_neighbor_mo[key] + ) + return self.nd_neighbor_mo[key] + + distinguished_name = 'topology/pod-%s/node-%s/sys/nd/inst' % (pod_id, node_id) + query = 'query-target=subtree&target-subtree-class=ndAdjEp' + managed_objects = self.get_managed_object( + distinguished_name, + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_protocol_nd_neighbor_mo', + 'API failed' + ) + return None + + self.nd_neighbor_mo[key] = [] + for managed_object in managed_objects['imdata']: + self.nd_neighbor_mo[key].append( + managed_object['ndAdjEp']['attributes'] + ) + + self.log.apic_mo( + 'ndAdjEp.%s' % (key), + self.nd_neighbor_mo[key] + ) + + self.set_object_cache( + 'ndAdjEp', + self.nd_neighbor_mo[key], + object_selector=key + ) + + return self.nd_neighbor_mo[key] diff --git a/lib/aci/proto/nd/neighbor/info.py b/lib/aci/proto/nd/neighbor/info.py new file mode 100644 index 00000000..89df80d3 --- /dev/null +++ b/lib/aci/proto/nd/neighbor/info.py @@ -0,0 +1,46 @@ +class ProtocolNdNeighborInfo(): + def __init__(self): + pass + + def get_protocol_nd_neighbor_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + # topology/pod-1/node-201/sys/nd/inst/if-[mgmt0]/adj-1 + info['interfaceId'] = info['dn'].split('if-')[1].split(']')[0][1:] + info['__Output']['interfaceId'] = 'Yellow' + + if info['nativeVlan'] == 'unspecified': + info['nativeVlan'] = '' + + return info + + def get_protocol_nd_neighbors_info(self, pod_id, node_id, interface_id=None): + managed_objects = self.get_protocol_nd_neighbor_mo(pod_id, node_id) + if managed_objects is None: + return None + + info = [] + for managed_object in managed_objects: + nbr_info = self.get_protocol_nd_neighbor_info( + managed_object + ) + + if interface_id is None: + info.append( + nbr_info + ) + + if interface_id is not None and nbr_info['interfaceId'] == interface_id: + info.append( + nbr_info + ) + + info = sorted( + info, + key=lambda i: i['sysName'] + ) + + return info diff --git a/lib/aci/proto/nd/neighbor/main.py b/lib/aci/proto/nd/neighbor/main.py new file mode 100644 index 00000000..51af3d63 --- /dev/null +++ b/lib/aci/proto/nd/neighbor/main.py @@ -0,0 +1,8 @@ +from lib.aci.proto.nd.neighbor.api import ProtocolNdNeighborApi +from lib.aci.proto.nd.neighbor.info import ProtocolNdNeighborInfo + + +class ProtocolNdNeighbor(ProtocolNdNeighborApi, ProtocolNdNeighborInfo): + def __init__(self): + ProtocolNdNeighborApi.__init__(self) + ProtocolNdNeighborInfo.__init__(self) diff --git a/lib/aci/proto/nd/output.py b/lib/aci/proto/nd/output.py new file mode 100644 index 00000000..d384a085 --- /dev/null +++ b/lib/aci/proto/nd/output.py @@ -0,0 +1,372 @@ +import json + + +class ProtocolNdOutput(): + def __init__(self): + pass + + def print_proto_nd_instances(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ND - Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'health', + 'faults', + 'adminSt', + 'agingIntvl', + 'neighborCount', + 'activeInterfaceCount' + ] + + headers = [ + 'Node', + 'Health', + 'Faults', + 'Admin State', + 'Aging Interval', + 'Neighbor Count', + 'Active Interface Count' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_proto_nd_domains(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ND - Domain [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'name', + 'health', + 'faults', + 'interfacesCount', + 'neighborsCount' + ] + + headers = [ + 'VRF', + 'Health', + 'Faults', + 'Interfaces', + 'Neighbors' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_nd_interfaces(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ND - Interface [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainName', + 'id', + 'health', + 'faults', + 'adminSt', + 'hopLimit', + 'mtu', + 'nsIntvl', + 'nsRetries', + 'raIntvl', + 'raIntvlMin', + 'raLifetime', + 'reachableTime', + 'retransTimer' + ] + + headers = [ + 'Node', + 'VRF', + 'Interface', + 'Health', + 'Faults', + 'Admin', + 'Hop', + 'MTU', + 'NS Intvl', + 'NS Retr', + 'RA Intvl', + 'RA Min Int', + 'RA Life', + 'Reachable', + 'Retransmit' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_nd_interface_stats(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ND - Interface Stats [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'domainName', + 'id', + 'nsSent', + 'nsRcvd', + 'naSent', + 'naRcvd', + 'rsSent', + 'rsRcvd', + 'raSent', + 'raRcvd' + ] + + headers = [ + 'Node', + 'VRF', + 'Interface', + 'NS Sent', + 'NS Rcvd', + 'NA Sent', + 'NA Rcvd', + 'RS Sent', + 'RS Rcvd', + 'RA Sent', + 'RA Rcvd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_nd_neighbors(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ND - Neighbor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) + + def print_proto_nd_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Protocol ND - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_nd_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol ND - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol ND - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_proto_nd_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Protocol ND - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Protocol ND - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod_node_name', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT', + 'affectedT' + ] + + headers = [ + 'Node', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set', + 'Affected' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT', 'affectedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/proto/output.py b/lib/aci/proto/output.py new file mode 100644 index 00000000..097093aa --- /dev/null +++ b/lib/aci/proto/output.py @@ -0,0 +1,38 @@ +from lib.aci.proto.arp.output import ProtocolArpOutput +from lib.aci.proto.bfd.output import ProtocolBfdOutput +from lib.aci.proto.bgp.output import ProtocolBgpOutput +from lib.aci.proto.cdp.output import ProtocolCdpOutput +from lib.aci.proto.hsrp.output import ProtocolHsrpOutput +from lib.aci.proto.ipv4.output import ProtocolIpv4Output +from lib.aci.proto.ipv6.output import ProtocolIpv6Output +from lib.aci.proto.isis.output import ProtocolIsisOutput +from lib.aci.proto.lacp.output import ProtocolLacpOutput +from lib.aci.proto.lldp.output import ProtocolLldpOutput +from lib.aci.proto.nd.output import ProtocolNdOutput + + +class ProtocolOutput( + ProtocolArpOutput, + ProtocolBfdOutput, + ProtocolBgpOutput, + ProtocolCdpOutput, + ProtocolHsrpOutput, + ProtocolIpv4Output, + ProtocolIpv6Output, + ProtocolIsisOutput, + ProtocolLacpOutput, + ProtocolLldpOutput, + ProtocolNdOutput + ): + def __init__(self): + ProtocolArpOutput.__init__(self) + ProtocolBfdOutput.__init__(self) + ProtocolBgpOutput.__init__(self) + ProtocolCdpOutput.__init__(self) + ProtocolHsrpOutput.__init__(self) + ProtocolIpv4Output.__init__(self) + ProtocolIpv6Output.__init__(self) + ProtocolIsisOutput.__init__(self) + ProtocolLacpOutput.__init__(self) + ProtocolLldpOutput.__init__(self) + ProtocolNdOutput.__init__(self) diff --git a/lib/aci/server/__init__.py b/lib/aci/server/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/server/main.py b/lib/aci/server/main.py new file mode 100644 index 00000000..30d486db --- /dev/null +++ b/lib/aci/server/main.py @@ -0,0 +1,162 @@ +from lib import ip_helper + + +class Server(): + def __init__(self): + pass + + def get_macs_lacp(self, mac_address, nodes): + interface_filter = [] + if len(mac_address) > 0: + interface_filter.append( + 'mac:%s' % (','.join(mac_address)) + ) + + interfaces = [] + for node_info in nodes: + proto_info = self.get_protocol_lacp( + node_info['podId'], + node_info['id'], + instance_info=False, + interface_info=True, + interface_filter=interface_filter, + event_info=False, + event_filter=False + ) + + if proto_info is None: + continue + + if 'interfaces' in proto_info: + if proto_info['interfaces'] is not None: + interfaces = interfaces + proto_info['interfaces'] + + lacp = [] + for interface_info in interfaces: + for lacp_interface_info in interface_info['lacp']: + lacp.append( + lacp_interface_info + ) + + return lacp + + def get_server_endpoint(self, server): + endpoint_filter = [] + for mac_info in server['MacAddressInfo']: + endpoint_filter.append( + 'mac:%s' % (mac_info['MacAddress']) + ) + + endpoints_info = self.get_endpoints( + endpoint_filter=endpoint_filter, + fabric_info=True + ) + + for mac_info in server['MacAddressInfo']: + mac_info['endpoint'] = None + for endpoint_info in endpoints_info: + if ip_helper.is_mac_equal(mac_info['MacAddress'], endpoint_info['mac']): + mac_info['endpoint'] = endpoint_info + + return server + + def get_server_lacp(self, server, nodes): + mac_address = [] + for mac_info in server['MacAddressInfo']: + mac_address.append( + mac_info['MacAddress'] + ) + + interface_filter = [] + if len(mac_address) > 0: + interface_filter.append( + 'mac:%s' % (','.join(mac_address)) + ) + + interfaces = [] + for node_info in nodes: + proto_info = self.get_protocol_lacp( + node_info['podId'], + node_info['id'], + instance_info=False, + interface_info=True, + interface_filter=interface_filter, + event_info=False, + event_filter=False + ) + + if proto_info is None: + continue + + if 'interfaces' in proto_info: + if proto_info['interfaces'] is not None: + interfaces = interfaces + proto_info['interfaces'] + + for mac_info in server['MacAddressInfo']: + mac_info['lacp'] = [] + for interface_info in interfaces: + for lacp_interface_info in interface_info['lacp']: + if ip_helper.is_mac_equal(mac_info['MacAddress'], lacp_interface_info['adjacency']['sysId']): + mac_info['lacp'].append( + lacp_interface_info + ) + + return server + + def get_server_lldp(self, server, nodes): + adjacency_filter = [] + for mac_info in server['MacAddressInfo']: + adjacency_filter.append( + 'mac:%s' % (mac_info['MacAddress']) + ) + + adjacency = [] + + for node_info in nodes: + proto_info = self.get_protocol_lldp( + node_info['podId'], + node_info['id'], + adjacency_filter=adjacency_filter, + instance_info=True, + stats_info=False, + adjacency_info=True, + fault_info=False, + hfault_info=False, + hfault_filter=None, + event_info=False, + event_filter=None + ) + + if proto_info is None: + continue + + if proto_info['adjacency'] is not None: + adjacency = adjacency + proto_info['adjacency'] + + for mac_info in server['MacAddressInfo']: + mac_info['adjacency'] = None + for adj_info in adjacency: + if ip_helper.is_mac_equal(mac_info['MacAddress'], adj_info['mac']): + mac_info['adjacency'] = adj_info + + return server + + def get_server_connectivity(self, server, nodes, ep_info=True, lacp_info=True, lldp_info=True): + if ep_info: + server = self.get_server_endpoint( + server + ) + + if lacp_info: + server = self.get_server_lacp( + server, + nodes + ) + + if lldp_info: + server = self.get_server_lldp( + server, + nodes + ) + + return server diff --git a/lib/aci/settings.py b/lib/aci/settings.py new file mode 100644 index 00000000..a2cc092c --- /dev/null +++ b/lib/aci/settings.py @@ -0,0 +1,416 @@ +import copy +import os +import json +import traceback +from datetime import timedelta + +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class ApicSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log = log_helper.Log() + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.apic_settings_filename = os.path.join( + self.settings_dir, + 'apic' + ) + + self.apic_cache_directory = os.path.join( + self.settings_dir, + 'aci-switch' + ) + + if not self.initialize_apic_settings(): + raise ValueError('APIC settings initialization failed') + + def get_apic_offline_cache_settings(self): + settings = {} + settings['enabled'] = True + settings['ttl'] = -1 + settings['ttlT'] = '--' + settings['object'] = [] + return settings + + def get_apic_default_cache_settings(self): + settings = {} + settings['enabled'] = True + settings['ttl'] = 180 + settings['ttlT'] = '{}'.format(str(timedelta(seconds=settings['ttl']))) + settings['object'] = [] + return settings + + def get_apic_default_settings(self): + settings = {} + settings['enabled'] = True + settings['cache'] = self.get_apic_default_cache_settings() + settings['controllers'] = [] + settings['defaults'] = {} + settings['defaults']['controller'] = None + settings['defaults']['node'] = {} + return settings + + def initialize_apic_settings(self): + if not os.path.isfile(self.apic_settings_filename): + settings = self.get_apic_default_settings() + if not self.set_apic_settings(settings): + return False + + if not os.path.isdir(self.apic_cache_directory): + os.makedirs(self.apic_cache_directory, exist_ok=True) + + return True + + def fixup_apic_settings(self, settings): + fixup = False + + # upper case old-style + if 'Enabled' in settings: + settings['enabled'] = settings['Enabled'] + del settings['Enabled'] + fixup = True + + if 'Cache' in settings: + settings['cache'] = {} + settings['cache']['enabled'] = settings['Cache']['Enabled'] + if 'ttl' in settings['Cache']: + settings['cache']['ttl'] = settings['Cache']['ttl'] + else: + settings['cache']['ttl'] = 180 + settings['cache']['ttlT'] = '{}'.format(str(timedelta(seconds=settings['cache']['ttl']))) + + if 'Object' in settings['Cache']: + settings['cache']['object'] = copy.deepcopy( + settings['Cache']['Object'] + ) + else: + settings['cache']['object'] = {} + + del settings['Cache'] + fixup = True + + if 'Controllers' in settings: + settings['controllers'] = copy.deepcopy( + settings['Controllers'] + ) + del settings['Controllers'] + fixup = True + + if 'Defaults' in settings: + settings['defaults'] = {} + settings['defaults']['controller'] = settings['Defaults']['Controller'] + settings['defaults']['node'] = copy.deepcopy( + settings['Defaults']['Node'] + ) + del settings['Defaults'] + fixup = True + + # cache fix-up + + if 'cache' not in settings: + settings['cache'] = self.get_apic_default_cache_settings() + fixup = True + + if 'ttlT' not in settings['cache']: + if settings['cache']['ttl'] <= 0: + settings['cache']['ttlT'] = '--' + else: + settings['cache']['ttlT'] = '{}'.format(str(timedelta(seconds=settings['cache']['ttl']))) + fixup = True + + global_cache_settings = settings['cache'] + for controller in settings['controllers']: + if 'port' not in controller: + controller['port'] = 443 + + if 'cache' not in controller: + controller['cache'] = copy.deepcopy(global_cache_settings) + fixup = True + + if 'ttlT' not in controller['cache']: + if controller['cache']['ttl'] <= 0: + controller['cache']['ttlT'] = '--' + else: + controller['cache']['ttlT'] = '{}'.format(str(timedelta(seconds=controller['cache']['ttl']))) + fixup = True + + # online mode fix-up + for controller in settings['controllers']: + if 'online' not in controller: + controller['online'] = True + fixup = True + + if fixup: + return settings + + return None + + def get_apic_settings(self): + if not os.path.isfile(self.apic_settings_filename): + return None + + try: + with open(self.apic_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_apic_settings', traceback.format_exc()) + return None + + new_settings = self.fixup_apic_settings( + settings + ) + if new_settings is not None: + if not self.set_apic_settings(new_settings): + return None + return new_settings + + return settings + + def set_apic_settings(self, settings): + try: + with open(self.apic_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_apic_settings', traceback.format_exc()) + return False + + return True + + def set_apic_mode_online(self, apic_name=None): + settings = self.get_apic_settings() + + for controller in settings['controllers']: + if apic_name is None or controller['name'] == apic_name: + controller['online'] = True + controller['cache'] = settings['cache'] + + return self.set_apic_settings(settings) + + def set_apic_mode_offline(self, apic_name=None): + settings = self.get_apic_settings() + + for controller in settings['controllers']: + if apic_name is None or controller['name'] == apic_name: + controller['online'] = False + controller['cache'] = self.get_apic_offline_cache_settings() + + return self.set_apic_settings(settings) + + def get_apic_cache_base_directory(self): + return self.apic_cache_directory + + def get_apic_cache_default_settings(self): + settings = self.get_apic_settings() + return settings['cache'] + + def get_apic_cache_settings(self, apic_name): + settings = self.get_apic_settings() + for controller in settings['controllers']: + if controller['name'] == apic_name: + return controller['cache'] + + self.log.error( + 'get_apic_cache_settings', + 'apic not found: %s' % (apic_name) + ) + + return None + + def is_cache_enabled(self, apic_name): + cache_settings = self.get_apic_cache_settings( + apic_name + ) + if cache_settings is None: + return False + + return cache_settings['enabled'] + + def set_apic_cache_on(self, apic_name=None): + settings = self.get_apic_settings() + for controller in settings['controllers']: + if apic_name is None or controller['name'] == apic_name: + controller['cache']['enabled'] = True + + return self.set_apic_settings(settings) + + def set_apic_cache_off(self, apic_name=None): + settings = self.get_apic_settings() + for controller in settings['controllers']: + if apic_name is None or controller['name'] == apic_name: + if controller['online']: + controller['cache']['enabled'] = False + return self.set_apic_settings(settings) + + def set_apic_cache_ttl(self, ttl, apic_name=None): + settings = self.get_apic_settings() + for controller in settings['controllers']: + if apic_name is None or controller['name'] == apic_name: + controller['cache']['ttl'] = ttl + if ttl <= 0: + controller['cache']['ttlT'] = '--' + else: + controller['cache']['ttlT'] = '{}'.format(str(timedelta(seconds=controller['cache']['ttl']))) + return self.set_apic_settings(settings) + + def get_default_node(self, controller_name): + settings = self.get_apic_settings() + if settings is None: + return None + + if controller_name not in settings['defaults']['node']: + return None + + default_node_name = settings['defaults']['node'][controller_name] + return default_node_name + + def set_default_node(self, controller_name, node_name): + settings = self.get_apic_settings() + if settings is None: + return False + + settings['defaults']['node'][controller_name] = node_name + return self.set_apic_settings(settings) + + def get_default_controller(self): + settings = self.get_apic_settings() + if settings is None: + return None + + default_controller_name = settings['defaults']['controller'] + return default_controller_name + + def set_default_controller(self, name): + settings = self.get_apic_settings() + if settings is None: + return False + + settings['defaults']['controller'] = name + return self.set_apic_settings(settings) + + def get_apic_controller_names(self): + controllers = self.get_apic_controllers() + if controllers is None: + return None + + names = [] + for controller in controllers: + names.append( + controller['name'] + ) + + return names + + def get_apic_controllers(self): + settings = self.get_apic_settings() + if settings is None: + return None + + return settings['controllers'] + + def get_apic_domain_controllers(self, domain_name): + settings = self.get_apic_settings() + if settings is None: + return None + + domain_controllers = [] + for controller in settings['controllers']: + if controller['domain'] == domain_name: + domain_controllers.append( + controller + ) + + return domain_controllers + + def is_apic_online(self, apic_name): + controller = self.get_apic_controller(apic_name) + if controller is None: + return False + return controller['online'] + + def get_apic_controller_label(self, apic_name): + controller = self.get_apic_controller(apic_name) + if controller is None: + return 'Apic: %s (adhoc, mode:online, cache:off)' % (apic_name) + + label = 'Apic: %s (' % (apic_name) + if self.is_apic_online(apic_name): + label = '%smode:online, ' % (label) + else: + label = '%smode:offline, ' % (label) + + if self.is_cache_enabled(apic_name): + label = '%scache:on)' % (label) + else: + label = '%scache:off)' % (label) + + return label + + def get_apic_controller(self, apic_name): + controllers = self.get_apic_controllers() + if controllers is None: + return None + + for controller in controllers: + if controller['name'] == apic_name: + return controller + + return None + + def set_apic_controllers(self, controllers): + settings = self.get_apic_settings() + if settings is None: + return False + + settings['controllers'] = controllers + return self.set_apic_settings(settings) + + def set_apic_controller(self, apic_name, apic_ip, apic_port, apic_username, apic_password, domain=''): + controllers = self.get_apic_controllers() + if controllers is None: + return False + + new_controllers = [] + cache_settings = self.get_apic_cache_default_settings() + online_mode = True + for controller in controllers: + if controller['name'] == apic_name: + cache_settings = controller['cache'] + online_mode = controller['online'] + else: + new_controllers.append(controller) + + new_controller = {} + new_controller['name'] = apic_name + new_controller['ip'] = apic_ip + new_controller['port'] = apic_port + new_controller['username'] = apic_username + new_controller['password'] = apic_password + new_controller['domain'] = domain + new_controller['cache'] = cache_settings + new_controller['online'] = online_mode + new_controllers.append(new_controller) + + return self.set_apic_controllers(new_controllers) + + def delete_apic_controller(self, apic_name): + controllers = self.get_apic_controllers() + if controllers is None: + return False + + new_controllers = [] + for controller in controllers: + if controller['name'] != apic_name: + new_controllers.append(controller) + + return self.set_apic_controllers(new_controllers) diff --git a/lib/aci/system/__init__.py b/lib/aci/system/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/system/__pycache__/__init__.cpython-310.pyc b/lib/aci/system/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9715785e Binary files /dev/null and b/lib/aci/system/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/system/__pycache__/main.cpython-310.pyc b/lib/aci/system/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..48bd556a Binary files /dev/null and b/lib/aci/system/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/system/__pycache__/output.cpython-310.pyc b/lib/aci/system/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..c4d23fe2 Binary files /dev/null and b/lib/aci/system/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/system/fault/__init__.py b/lib/aci/system/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/system/fault/__pycache__/__init__.cpython-310.pyc b/lib/aci/system/fault/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..10b9bdb4 Binary files /dev/null and b/lib/aci/system/fault/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/system/fault/__pycache__/api.cpython-310.pyc b/lib/aci/system/fault/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6fbe6cbe Binary files /dev/null and b/lib/aci/system/fault/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/system/fault/__pycache__/info.cpython-310.pyc b/lib/aci/system/fault/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..79f9ad0c Binary files /dev/null and b/lib/aci/system/fault/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/system/fault/__pycache__/main.cpython-310.pyc b/lib/aci/system/fault/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..46de5133 Binary files /dev/null and b/lib/aci/system/fault/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/system/fault/__pycache__/output.cpython-310.pyc b/lib/aci/system/fault/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..014adad7 Binary files /dev/null and b/lib/aci/system/fault/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/system/fault/api.py b/lib/aci/system/fault/api.py new file mode 100644 index 00000000..7dae8dba --- /dev/null +++ b/lib/aci/system/fault/api.py @@ -0,0 +1,43 @@ +class SystemFaultApi(): + def __init__(self): + self.system_fault_mo = None + + def get_system_fault_mo(self): + if self.system_fault_mo is not None: + return self.system_fault_mo + + cache = self.get_object_cache( + 'faultInst' + ) + if cache is not None: + self.system_fault_mo = cache + self.log.apic_mo( + 'faultInst', + self.system_fault_mo + ) + return self.system_fault_mo + + managed_objects = self.get_class( + 'faultInst', + node_class=True + ) + if managed_objects is None: + return None + + self.system_fault_mo = [] + for managed_object in managed_objects['imdata']: + self.system_fault_mo.append( + managed_object['faultInst']['attributes'] + ) + + self.log.apic_mo( + 'faultInst', + self.system_fault_mo + ) + + self.set_object_cache( + 'faultInst', + self.system_fault_mo + ) + + return self.system_fault_mo diff --git a/lib/aci/system/fault/code/.gitignore b/lib/aci/system/fault/code/.gitignore new file mode 100644 index 00000000..9c25f277 --- /dev/null +++ b/lib/aci/system/fault/code/.gitignore @@ -0,0 +1 @@ +source.html \ No newline at end of file diff --git a/lib/aci/system/fault/code/__init__.py b/lib/aci/system/fault/code/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/system/fault/code/__pycache__/__init__.cpython-310.pyc b/lib/aci/system/fault/code/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..6f6fe0b5 Binary files /dev/null and b/lib/aci/system/fault/code/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/system/fault/code/__pycache__/main.cpython-310.pyc b/lib/aci/system/fault/code/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f55eb8f2 Binary files /dev/null and b/lib/aci/system/fault/code/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/system/fault/code/generate.py b/lib/aci/system/fault/code/generate.py new file mode 100644 index 00000000..9c695448 --- /dev/null +++ b/lib/aci/system/fault/code/generate.py @@ -0,0 +1,40 @@ +import re + + +def sanitize_string(value): + value = value.strip() + value = re.sub(' +', ' ', value) + return value + + +# https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/all/syslog/guide/b_ACI_System_Messages_Guide/b_ACI_System_Messages_Guide_chapter_011.html +with open('source.html', 'rb') as file_handler: + content = file_handler.read() + +codes = {} +current = None + +for line in content.decode('utf-8').split('\n'): + line = sanitize_string(line) + if line.startswith('

F'): + current = line.split('

')[1].split(':')[0] + continue + + if line.startswith('Explanation:'): + explanation = sanitize_string( + line.split('Explanation:')[1] + ) + if current is None: + print('Explanation hanging:%s' % (explanation)) + continue + + codes[current] = explanation.replace('"', "'") + +print('class SystemFaultCode():') +print(' def __init__(self):') +print(' self.system_fault_code = {}') +for code in codes: + print(' self.system_fault_code["%s"] = "%s"' % ( + code, + codes[code] + )) diff --git a/lib/aci/system/fault/code/main.py b/lib/aci/system/fault/code/main.py new file mode 100644 index 00000000..57925b4b --- /dev/null +++ b/lib/aci/system/fault/code/main.py @@ -0,0 +1,45836 @@ +class SystemFaultCode(): + def __init__(self): + self.system_fault_code = {} + self.system_fault_code["F0020"] = "This fault occurs when a fabric selector (port selector, card selector, node selector etc.) is incorrectly configured." + self.system_fault_code["F0021"] = "This fault occurs when the Radius Provider is not operational." + self.system_fault_code["F0022"] = "This fault occurs when the LDAP provider is not operational." + self.system_fault_code["F0023"] = "This fault occurs when the TACACS+ provider is not operational." + self.system_fault_code["F0048"] = "This fault occurs due to a Stats Export Policy session failure." + self.system_fault_code["F0051"] = "This fault occurs when a significant number of packet drops are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F0052"] = "This fault occurs when a significant number of excess packets are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F0053"] = "This fault occurs when a configuration export/import job fails." + self.system_fault_code["F0058"] = "This fault occurs when a firmware download fails" + self.system_fault_code["F0080"] = "This fault is raised when the DHCP server runs out of IP address to allocate to clients" + self.system_fault_code["F0098"] = "This fault occurs due to a Stats Export Policy session failure." + self.system_fault_code["F0101"] = "This fault occurs when a storage device fails on a controller" + self.system_fault_code["F0103"] = "This fault occurs when a physical interface on a controller is in the link-down state." + self.system_fault_code["F0104"] = "This fault occurs when a bond interface on a controller is in the link-down state." + self.system_fault_code["F0105"] = "This fault occurs when a software upgrade fails on a controller" + self.system_fault_code["F0106"] = "This fault occurs when a port is out-of-service because of a wiring error." + self.system_fault_code["F0111"] = "This fault occurs when operational issues are detected on a LooseNode (Unmanaged switch)" + self.system_fault_code["F0130"] = "This fault is raised when the VMM Controller is marked offline. Recovery is in process." + self.system_fault_code["F0132"] = "This fault is raised when Remote or External disruptive operations on VMM Controller are detected." + self.system_fault_code["F0133"] = "This fault is raised when deployment of given configuration fails for a Controller." + self.system_fault_code["F0134"] = "This fault is raised when LooseNode (Unmanaged switch) has config issues such as missing Management Address config." + self.system_fault_code["F0135"] = "This fault is raised when remote or external disruptive EPG operations are performed on the Controller." + self.system_fault_code["F0214"] = "This fault is raised when there is an issue with respect to the OpFlex device" + self.system_fault_code["F0256"] = "This fault occurs when the coop domain has inconsistent configuration in the council" + self.system_fault_code["F0299"] = "This fault occurs when the peer state is not established" + self.system_fault_code["F0309"] = "This fault occurs when a controller reports some data for service failed to initialize." + self.system_fault_code["F0310"] = "This fault occurs when a controller reports some data for a service has been corrupted." + self.system_fault_code["F0317"] = "This fault occurs when a controller reports data in the internal datastore for a given service has been corrupted." + self.system_fault_code["F0320"] = "This fault occurs when the L4-L7 service returns a minor fault" + self.system_fault_code["F0321"] = "This fault occurs when a controller reports the distributed internal database (data layer) of the controller cluster is" + self.system_fault_code["F0323"] = "This fault occurs when a controller reports it has lost connectivity to the replica leader for one or more data subsets" + self.system_fault_code["F0324"] = "This fault occurs when the L4-L7 service returns a major fault" + self.system_fault_code["F0325"] = "This fault occurs when a controller reports it has lost connectivity to the cluster replica leader for one or more data" + self.system_fault_code["F0329"] = "This fault occurs when the there is a failure in starting the service script" + self.system_fault_code["F0330"] = "This fault occurs when there is missing function in device package" + self.system_fault_code["F0338"] = "This fault occurs when the ospf instance memory alert is critical" + self.system_fault_code["F0341"] = "This fault occurs when the operational state of the dhcp client interface changes to failed state" + self.system_fault_code["F0344"] = "This fault occurs when the igmp snooping local learning is disabled" + self.system_fault_code["F0345"] = "This fault occurs when the igmp snooping fabric learning is disabled" + self.system_fault_code["F0350"] = "This fault occurs when multiple neighbors are discovered on the interface" + self.system_fault_code["F0360"] = "This event occurs when the oper state of a Mcast tree changes to inactive." + self.system_fault_code["F0361"] = "This event occurs when the tree diameter of a Mcast tree is deemed large." + self.system_fault_code["F0377"] = "This fault occurs when the isis instance memory alert is critical" + self.system_fault_code["F0391"] = "This fault usually occurs when ISIS interface specific initaliztion fails." + self.system_fault_code["F0394"] = "This fault usually occurs when ISIS interface specific protocol handling fails." + self.system_fault_code["F0397"] = "This fault occurs when the Radius Provider is not operational." + self.system_fault_code["F0398"] = "This fault occurs when the LDAP provider is not operational." + self.system_fault_code["F0400"] = "This fault occurs when the TACACS+ provider is not operational." + self.system_fault_code["F0401"] = "This fault occurs when a diagnostic test is not supported." + self.system_fault_code["F0402"] = "This fault occurs when a diagnostic test subject is not accessible." + self.system_fault_code["F0403"] = "This fault occurs when a on-demand diagnostic test is not supported." + self.system_fault_code["F0404"] = "This fault occurs when a on-demand diagnostic test subject is not accessible." + self.system_fault_code["F0411"] = "This fault occurs when psu is failed" + self.system_fault_code["F0412"] = "This fault occurs when the fan in the psu is failed" + self.system_fault_code["F0413"] = "This fault occurs when the the psu is missing" + self.system_fault_code["F0415"] = "This fault typically occurs when the SUP is inserted in the wrong slot" + self.system_fault_code["F0416"] = "This fault typically occurs when a card with an unknown card id is inserted in the chassis" + self.system_fault_code["F0418"] = "This fault occurs when a Contract, with a scope set as something other than Context, is added to an 'EPG Collection for" + self.system_fault_code["F0440"] = "This fault usually occurs if the backplane sprom is corrupted" + self.system_fault_code["F0441"] = "This fault would occur if the backplane IDPROM contents become invalid or corrupted" + self.system_fault_code["F0449"] = "This fault usually occurs if sensor fails" + self.system_fault_code["F0454"] = "This fault occurs when a port is out-of-service because of a wiring error." + self.system_fault_code["F0467"] = "This fault occurs when an End Point Group is incompletely or incorrectly configured." + self.system_fault_code["F0468"] = "This fault occurs when an A given Ctx configured to use a DNS Profile which doesn't configured In Fabric. Only DNS Profiles" + self.system_fault_code["F0469"] = "This fault occurs when there is one or more duplicate Subnets defined for BDs or/and AEpGs associated with the Ctx." + self.system_fault_code["F0471"] = "This fault occurs when an ASIC on a card sees a fatal failure during runtime" + self.system_fault_code["F0474"] = "This fault occurs when tunnel manager fails to create a tunnel due to hardware failure." + self.system_fault_code["F0475"] = "This fault occurs when destination becomes unreachable." + self.system_fault_code["F0482"] = "This fault occurs when destination IP address is unresolved." + self.system_fault_code["F0507"] = "This fault occurs when vpc domain bringup fails due to all fabric links being down." + self.system_fault_code["F0508"] = "This fault occurs when vpc domain bringup fails because there is no route to peer." + self.system_fault_code["F0509"] = "This fault occurs when vpc domain bringup fails due to peer being unreachable." + self.system_fault_code["F0510"] = "This fault occurs when vpc domain bringup fails due to domain compatibility failure." + self.system_fault_code["F0511"] = "This fault occurs when vpc domain bringup fails due to election error." + self.system_fault_code["F0512"] = "This fault occurs when vpc domain bringup fails due to keepalive being inoperational." + self.system_fault_code["F0513"] = "This fault occurs when global configuration on the peers is not consistent." + self.system_fault_code["F0518"] = "This fault occurs when vPC configuration on the peers is not consistent." + self.system_fault_code["F0520"] = "This event occurs when vPC peer keep-alive send has failed." + self.system_fault_code["F0522"] = "This event occurs when peer keep-alive receive has failed." + self.system_fault_code["F0523"] = "This fault occurs when an End Point Group is incompletely or incorrectly configured." + self.system_fault_code["F0524"] = "This fault occurs when Static Endpoing is incompletely configured." + self.system_fault_code["F0532"] = "This fault occurs when a port is down and is in use for epg" + self.system_fault_code["F0543"] = "This fault occurs when a port is down and is in use for infra and no epg" + self.system_fault_code["F0546"] = "This fault occurs when a port goes down" + self.system_fault_code["F0564"] = "This fault is raised when the VMM Controller cannot be deployed due to a missing or invalid configuration." + self.system_fault_code["F0565"] = "This fault is raised when the Endpoint Group cannot be deployed due to a missing or invalid configuration." + self.system_fault_code["F0600"] = "This fault occurs when port has been suspended." + self.system_fault_code["F0603"] = "This fault occurs when port becomes operationally individual." + self.system_fault_code["F0618"] = "This fault occurs when a management node address is not allocated to a node." + self.system_fault_code["F0650"] = "This fault occurs when the source Endpoint IP address that the traceroute policy is configured to run with is not found" + self.system_fault_code["F0657"] = "This fault occurs when the destination Endpoint IP address that the traceroute policy is configured to run with is not" + self.system_fault_code["F0699"] = ": All policies associated with the configured Fex/Port Policy Group should get deployed to all nodes associated with the" + self.system_fault_code["F0701"] = "Infra Policy fault is raised when the configured Domain cannot be deployed due to a missing or invalid configuration." + self.system_fault_code["F0721"] = "This fault is raised when a VLAN/VxLAN/NVGRE pool cannot be deployed due to a missing or invalid configuration." + self.system_fault_code["F0749"] = "This fault occurs when a virtual Port Channel (vPC) policy is created but it has not been deployed yet (for example in" + self.system_fault_code["F0750"] = "This fault is occurs when a vPC policy has been deployed to a fabric node, then at least one of the following conditions" + self.system_fault_code["F0751"] = "This fault occurs when a virtual Port Channel (vPC) policy is no longer deployed because both of the member fabric nodes" + self.system_fault_code["F0756"] = "This fault occurs when a configured target of a named relationship cannot be resolved." + self.system_fault_code["F0757"] = "This fault occurs due to an invalid service graph configuration." + self.system_fault_code["F0758"] = "This fault occurs when a service graph could not be instantiated." + self.system_fault_code["F0759"] = "This fault occurs when a service graph could not be instantiated." + self.system_fault_code["F0760"] = "This fault occurs when a service graph could not be instantiated." + self.system_fault_code["F0761"] = "This fault occurs when a cfg parameter has an error.." + self.system_fault_code["F0762"] = "This fault occurs when a cfg parameter has an error.." + self.system_fault_code["F0763"] = "This fault occurs when a cfg parameter has an error.." + self.system_fault_code["F0764"] = "This fault occurs when a logical device is being configured in a way which is not compatible with the meta device information" + self.system_fault_code["F0765"] = "This fault occurs when a user provided Concrete device configuration is invalid. The config issues indicate the exact reason" + self.system_fault_code["F0766"] = "This fault occurs when a config folder has an error. The config issues indicate the exact reason for the error." + self.system_fault_code["F0768"] = "This fault occurs when a config GRel has an an error. The config issues indicate the exact reason for the error." + self.system_fault_code["F0769"] = "This fault occurs when a Function Connector (FuncConnInst) has an error.The config issues the exact reason for the error." + self.system_fault_code["F0770"] = "This fault occurs when a Terminal Connector (TermConnInst) has an error.The config issues the exact reason for the error." + self.system_fault_code["F0771"] = "This fault occurs when a Connection Inst (ConnectionInst) has an error.The config issues the exact reason for the error." + self.system_fault_code["F0772"] = "This fault occurs when a Logical Interface configuration is invalid.The config issues the exact reason for the error." + self.system_fault_code["F0843"] = "None set." + self.system_fault_code["F0844"] = "None set." + self.system_fault_code["F0845"] = "None set." + self.system_fault_code["F0846"] = "None set." + self.system_fault_code["F0847"] = "None set." + self.system_fault_code["F0848"] = "None set." + self.system_fault_code["F0849"] = "This fault occurs when a infra selector (port selector, card selector, node selector etc.) is incorrectly configured." + self.system_fault_code["F0853"] = "The object refers to an object that was not found." + self.system_fault_code["F0854"] = "This fault is raised when the inventory policy refers to a scheduler that does not exist." + self.system_fault_code["F0855"] = "The object refers to an object that was not found." + self.system_fault_code["F0856"] = "The object refers to an object that was not found." + self.system_fault_code["F0857"] = "The object refers to an object that was not found." + self.system_fault_code["F0859"] = "The object refers to an object that was not found." + self.system_fault_code["F0860"] = "The object refers to an object that was not found." + self.system_fault_code["F0861"] = "The object refers to an object that was not found." + self.system_fault_code["F0862"] = "The object refers to an object that was not found." + self.system_fault_code["F0864"] = "The object refers to an object that was not found." + self.system_fault_code["F0865"] = "The object refers to an object that was not found." + self.system_fault_code["F0866"] = "The object refers to an object that was not found." + self.system_fault_code["F0867"] = "The object refers to an object that was not found." + self.system_fault_code["F0868"] = "The object refers to an object that was not found." + self.system_fault_code["F0869"] = "The object refers to an object that was not found." + self.system_fault_code["F0870"] = "The object refers to an object that was not found." + self.system_fault_code["F0871"] = "The object refers to an object that was not found." + self.system_fault_code["F0872"] = "The object refers to an object that was not found." + self.system_fault_code["F0873"] = "The object refers to an object that was not found." + self.system_fault_code["F0874"] = "The object refers to an object that was not found." + self.system_fault_code["F0875"] = "The object refers to an object that was not found." + self.system_fault_code["F0876"] = "The object refers to an object that was not found." + self.system_fault_code["F0878"] = "The object refers to an object that was not found." + self.system_fault_code["F0879"] = "The object refers to an object that was not found." + self.system_fault_code["F0880"] = "The object refers to an object that was not found." + self.system_fault_code["F0881"] = "The object refers to an object that was not found." + self.system_fault_code["F0882"] = "The object refers to an object that was not found." + self.system_fault_code["F0883"] = "The object refers to an object that was not found." + self.system_fault_code["F0885"] = "The object refers to an object that was not found." + self.system_fault_code["F0886"] = "The object refers to an object that was not found." + self.system_fault_code["F0887"] = "The object refers to an object that was not found." + self.system_fault_code["F0888"] = "The object refers to an object that was not found." + self.system_fault_code["F0889"] = "The object refers to an object that was not found." + self.system_fault_code["F0897"] = "The object refers to an object that was not found." + self.system_fault_code["F0898"] = "The object refers to an object that was not found." + self.system_fault_code["F0899"] = "The object refers to an object that was not found." + self.system_fault_code["F0900"] = "The object refers to an object that was not found." + self.system_fault_code["F0901"] = "The object refers to an object that was not found." + self.system_fault_code["F0902"] = "The object refers to an object that was not found." + self.system_fault_code["F0903"] = "The object refers to an object that was not found." + self.system_fault_code["F0904"] = "The object refers to an object that was not found." + self.system_fault_code["F0905"] = "The object refers to an object that was not found." + self.system_fault_code["F0906"] = "The object refers to an object that was not found." + self.system_fault_code["F0907"] = "The object refers to an object that was not found." + self.system_fault_code["F0909"] = "The object refers to an object that was not found." + self.system_fault_code["F0913"] = "The object refers to an object that was not found." + self.system_fault_code["F0916"] = "The object refers to an object that was not found." + self.system_fault_code["F0917"] = "The object refers to an object that was not found." + self.system_fault_code["F0918"] = "The object refers to an object that was not found." + self.system_fault_code["F0919"] = "The object refers to an object that was not found." + self.system_fault_code["F0920"] = "The object refers to an object that was not found." + self.system_fault_code["F0921"] = "The object refers to an object that was not found." + self.system_fault_code["F0922"] = "The object refers to an object that was not found." + self.system_fault_code["F0923"] = "The object refers to an object that was not found." + self.system_fault_code["F0924"] = "The object refers to an object that was not found." + self.system_fault_code["F0925"] = "The object refers to an object that was not found." + self.system_fault_code["F0926"] = "The object refers to an object that was not found." + self.system_fault_code["F0927"] = "The object refers to an object that was not found." + self.system_fault_code["F0940"] = "The object refers to an object that was not found." + self.system_fault_code["F0943"] = "The object refers to an object that was not found." + self.system_fault_code["F0944"] = "The object refers to an object that was not found." + self.system_fault_code["F0945"] = "The object refers to an object that was not found." + self.system_fault_code["F0946"] = "The object refers to an object that was not found." + self.system_fault_code["F0947"] = "The object refers to an object that was not found." + self.system_fault_code["F0948"] = "The object refers to an object that was not found." + self.system_fault_code["F0949"] = "The object refers to an object that was not found." + self.system_fault_code["F0950"] = "The object refers to an object that was not found." + self.system_fault_code["F0951"] = "The object refers to an object that was not found." + self.system_fault_code["F0952"] = "The object refers to an object that was not found." + self.system_fault_code["F0953"] = "The object refers to an object that was not found." + self.system_fault_code["F0954"] = "The object refers to an object that was not found." + self.system_fault_code["F0955"] = "The object refers to an object that was not found." + self.system_fault_code["F0956"] = "The object refers to an object that was not found." + self.system_fault_code["F0957"] = "The object refers to an object that was not found." + self.system_fault_code["F0959"] = "The object refers to an object that was not found." + self.system_fault_code["F0960"] = "The object refers to an object that was not found." + self.system_fault_code["F0963"] = "The object refers to an object that was not found." + self.system_fault_code["F0964"] = "The object refers to an object that was not found." + self.system_fault_code["F0965"] = "The object refers to an object that was not found." + self.system_fault_code["F0966"] = "The object refers to an object that was not found." + self.system_fault_code["F0967"] = "The object refers to an object that was not found." + self.system_fault_code["F0970"] = "The object refers to an object that was not found." + self.system_fault_code["F0971"] = "The object refers to an object that was not found." + self.system_fault_code["F0973"] = "The object refers to an object that was not found." + self.system_fault_code["F0974"] = "The object refers to an object that was not found." + self.system_fault_code["F0976"] = "The object refers to an object that was not found." + self.system_fault_code["F0977"] = "The object refers to an object that was not found." + self.system_fault_code["F0978"] = "The object refers to an object that was not found." + self.system_fault_code["F0979"] = "The object refers to an object that was not found." + self.system_fault_code["F0981"] = "The object refers to an object that was not found." + self.system_fault_code["F0982"] = "The object refers to an object that was not found." + self.system_fault_code["F0983"] = "The object refers to an object that was not found." + self.system_fault_code["F0984"] = "The object refers to an object that was not found." + self.system_fault_code["F0988"] = "The object refers to an object that was not found." + self.system_fault_code["F0989"] = "The object refers to an object that was not found." + self.system_fault_code["F0990"] = "The object refers to an object that was not found." + self.system_fault_code["F0991"] = "The object refers to an object that was not found." + self.system_fault_code["F0992"] = "The object refers to an object that was not found." + self.system_fault_code["F0993"] = "The object refers to an object that was not found." + self.system_fault_code["F0994"] = "The object refers to an object that was not found." + self.system_fault_code["F0995"] = "The object refers to an object that was not found." + self.system_fault_code["F0996"] = "The object refers to an object that was not found." + self.system_fault_code["F0997"] = "The object refers to an object that was not found." + self.system_fault_code["F0998"] = "The object refers to an object that was not found." + self.system_fault_code["F0999"] = "The object refers to an object that was not found." + self.system_fault_code["F100008"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100009"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100010"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100011"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100012"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100013"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100014"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100015"] = "This fault is caused by 'Ingress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F100016"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100017"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100018"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100019"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100020"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100021"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100022"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100023"] = "This fault is caused by 'Ingress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F100024"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100025"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100026"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100027"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100028"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100029"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100030"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100031"] = "This fault is caused by 'Ingress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F100032"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100033"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100034"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100035"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100036"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100037"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100038"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100039"] = "This fault is caused by 'Ingress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F100072"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100073"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100074"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100075"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100076"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100077"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100078"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100079"] = "This fault is caused by 'Ingress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F100176"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100177"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100178"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100179"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100180"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100181"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100182"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100183"] = "This fault is caused by 'Ingress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100192"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100193"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100194"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100195"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100196"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100197"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100198"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100199"] = "This fault is caused by 'Ingress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100200"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100201"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100202"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100203"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100204"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100205"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100206"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100207"] = "This fault is caused by 'Ingress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100208"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100209"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100210"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100211"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100212"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100213"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100214"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100215"] = "This fault is caused by 'Ingress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100216"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100217"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100218"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100219"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100220"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100221"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100222"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100223"] = "This fault is caused by 'Ingress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100224"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100225"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100226"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100227"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100228"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100229"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100230"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100231"] = "This fault is caused by 'Ingress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100256"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100257"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100258"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100259"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100260"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100261"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100262"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100263"] = "This fault is caused by 'Ingress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100264"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100265"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100266"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100267"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100268"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100269"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100270"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100271"] = "This fault is caused by 'Ingress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1003"] = "The object refers to an object that was not found." + self.system_fault_code["F100392"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100393"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100394"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100395"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100396"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100397"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100398"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100399"] = "This fault is caused by 'Ingress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F1004"] = "The object refers to an object that was not found." + self.system_fault_code["F100408"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100409"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100410"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100411"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100412"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100413"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100414"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100415"] = "This fault is caused by 'Ingress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100416"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100417"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100418"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100419"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100420"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100421"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100422"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100423"] = "This fault is caused by 'Ingress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100424"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100425"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100426"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100427"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100428"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100429"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100430"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100431"] = "This fault is caused by 'Ingress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100432"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100433"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100434"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100435"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100436"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100437"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100438"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100439"] = "This fault is caused by 'Ingress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100440"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100441"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100442"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100443"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100444"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100445"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100446"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100447"] = "This fault is caused by 'Ingress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100472"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100473"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100474"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100475"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100476"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100477"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100478"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100479"] = "This fault is caused by 'Ingress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100480"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100481"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100482"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100483"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100484"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100485"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100486"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100487"] = "This fault is caused by 'Ingress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1005"] = "The object refers to an object that was not found." + self.system_fault_code["F1006"] = "The object refers to an object that was not found." + self.system_fault_code["F100608"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100609"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100610"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100611"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100612"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100613"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100614"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100615"] = "This fault is caused by 'Ingress Forwarding Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100624"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100625"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100626"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100627"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100628"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100629"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100630"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100631"] = "This fault is caused by 'Ingress Forwarding Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100632"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100633"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100634"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100635"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100636"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100637"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100638"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100639"] = "This fault is caused by 'Ingress Forwarding Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100640"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100641"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100642"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100643"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100644"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100645"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100646"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100647"] = "This fault is caused by 'Ingress Forwarding Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100648"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100649"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100650"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100651"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100652"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100653"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100654"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100655"] = "This fault is caused by 'Ingress Forwarding Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100656"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100657"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100658"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100659"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100660"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100661"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100662"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100663"] = "This fault is caused by 'Ingress Forwarding Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100688"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100689"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100690"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100691"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100692"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100693"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100694"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100695"] = "This fault is caused by 'Ingress Forwarding Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100696"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100697"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100698"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100699"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1007"] = "The object refers to an object that was not found." + self.system_fault_code["F100700"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100701"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100702"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100703"] = "This fault is caused by 'Ingress Forwarding Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1008"] = "The object refers to an object that was not found." + self.system_fault_code["F100824"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100825"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100826"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100827"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100828"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100829"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100830"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100831"] = "This fault is caused by 'Ingress Load Balancer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F100840"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100841"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100842"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100843"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100844"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100845"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100846"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100847"] = "This fault is caused by 'Ingress Load Balancer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F100848"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100849"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100850"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100851"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100852"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100853"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100854"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100855"] = "This fault is caused by 'Ingress Load Balancer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F100856"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100857"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100858"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100859"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100860"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100861"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100862"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100863"] = "This fault is caused by 'Ingress Load Balancer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F100864"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100865"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100866"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100867"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100868"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100869"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100870"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100871"] = "This fault is caused by 'Ingress Load Balancer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F100872"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100873"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100874"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100875"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100876"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100877"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100878"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F100879"] = "This fault is caused by 'Ingress Load Balancer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F1009"] = "The object refers to an object that was not found." + self.system_fault_code["F100904"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100905"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100906"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100907"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100908"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100909"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100910"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100911"] = "This fault is caused by 'Ingress Load Balancer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F100912"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100913"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100914"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100915"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100916"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100917"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100918"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F100919"] = "This fault is caused by 'Ingress Load Balancer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1010"] = "The object refers to an object that was not found." + self.system_fault_code["F101040"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101041"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101042"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101043"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101044"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101045"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101046"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101047"] = "This fault is caused by 'Ingress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101056"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101057"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101058"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101059"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101060"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101061"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101062"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101063"] = "This fault is caused by 'Ingress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101064"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101065"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101066"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101067"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101068"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101069"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101070"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101071"] = "This fault is caused by 'Ingress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101072"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101073"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101074"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101075"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101076"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101077"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101078"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101079"] = "This fault is caused by 'Ingress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101080"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101081"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101082"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101083"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101084"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101085"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101086"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101087"] = "This fault is caused by 'Ingress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101088"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101089"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101090"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101091"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101092"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101093"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101094"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101095"] = "This fault is caused by 'Ingress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F1011"] = "The object refers to an object that was not found." + self.system_fault_code["F101120"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101121"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101122"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101123"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101124"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101125"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101126"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101127"] = "This fault is caused by 'Ingress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101128"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101129"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101130"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101131"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101132"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101133"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101134"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101135"] = "This fault is caused by 'Ingress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1012"] = "The object refers to an object that was not found." + self.system_fault_code["F101256"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101257"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101258"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101259"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101260"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101261"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101262"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101263"] = "This fault is caused by 'Ingress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101272"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101273"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101274"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101275"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101276"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101277"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101278"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101279"] = "This fault is caused by 'Ingress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101280"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101281"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101282"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101283"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101284"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101285"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101286"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101287"] = "This fault is caused by 'Ingress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101288"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101289"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101290"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101291"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101292"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101293"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101294"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101295"] = "This fault is caused by 'Ingress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101296"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101297"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101298"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101299"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F1013"] = "The object refers to an object that was not found." + self.system_fault_code["F101300"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101301"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101302"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101303"] = "This fault is caused by 'Ingress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101304"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101305"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101306"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101307"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101308"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101309"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101310"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101311"] = "This fault is caused by 'Ingress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101336"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101337"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101338"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101339"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101340"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101341"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101342"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101343"] = "This fault is caused by 'Ingress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101344"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101345"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101346"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101347"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101348"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101349"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101350"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101351"] = "This fault is caused by 'Ingress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1014"] = "The object refers to an object that was not found." + self.system_fault_code["F101472"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101473"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101474"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101475"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101476"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101477"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101478"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101479"] = "This fault is caused by 'Ingress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F101488"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101489"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101490"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101491"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101492"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101493"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101494"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101495"] = "This fault is caused by 'Ingress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F101496"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101497"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101498"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101499"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F1015"] = "The object refers to an object that was not found." + self.system_fault_code["F101500"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101501"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101502"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101503"] = "This fault is caused by 'Ingress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F101504"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101505"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101506"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101507"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101508"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101509"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101510"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101511"] = "This fault is caused by 'Ingress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F101512"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101513"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101514"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101515"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101516"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101517"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101518"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101519"] = "This fault is caused by 'Ingress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F101520"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101521"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101522"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101523"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101524"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101525"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101526"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101527"] = "This fault is caused by 'Ingress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F101552"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101553"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101554"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101555"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101556"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101557"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101558"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101559"] = "This fault is caused by 'Ingress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F101560"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101561"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101562"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101563"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101564"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101565"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101566"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F101567"] = "This fault is caused by 'Ingress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1016"] = "The object refers to an object that was not found." + self.system_fault_code["F101688"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101689"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101690"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101691"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101692"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101693"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101694"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F101695"] = "This fault is caused by 'Total Ingress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F1017"] = "The object refers to an object that was not found." + self.system_fault_code["F101704"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101705"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101706"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101707"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101708"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101709"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101710"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101711"] = "This fault is caused by 'Total Ingress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F101712"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101713"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101714"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101715"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101716"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101717"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101718"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101719"] = "This fault is caused by 'Total Ingress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F101720"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101721"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101722"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101723"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101724"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101725"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101726"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101727"] = "This fault is caused by 'Total Ingress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F101728"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101729"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101730"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101731"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101732"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101733"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101734"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101735"] = "This fault is caused by 'Total Ingress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F101736"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101737"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101738"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101739"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101740"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101741"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101742"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101743"] = "This fault is caused by 'Total Ingress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F101768"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101769"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101770"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101771"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101772"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101773"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101774"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101775"] = "This fault is caused by 'Total Ingress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F101776"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101777"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101778"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101779"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101780"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101781"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101782"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F101783"] = "This fault is caused by 'Total Ingress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1018"] = "The object refers to an object that was not found." + self.system_fault_code["F1019"] = "The object refers to an object that was not found." + self.system_fault_code["F101904"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101905"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101906"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101907"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101908"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101909"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101910"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101911"] = "This fault is caused by 'Total Ingress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F101912"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101913"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101914"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101915"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101916"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101917"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101918"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101919"] = "This fault is caused by 'Total Ingress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F101920"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101921"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101922"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101923"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101924"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101925"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101926"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101927"] = "This fault is caused by 'Total Ingress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F101928"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101929"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101930"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101931"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101932"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101933"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101934"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101935"] = "This fault is caused by 'Total Ingress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F101968"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101969"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101970"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101971"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101972"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101973"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101974"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F101975"] = "This fault is caused by 'Total Ingress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F1020"] = "The object refers to an object that was not found." + self.system_fault_code["F102072"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102073"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102074"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102075"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102076"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102077"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102078"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102079"] = "This fault is caused by 'Total Ingress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102088"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102089"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102090"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102091"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102092"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102093"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102094"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102095"] = "This fault is caused by 'Total Ingress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102096"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102097"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102098"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102099"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F1021"] = "The object refers to an object that was not found." + self.system_fault_code["F102100"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102101"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102102"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102103"] = "This fault is caused by 'Total Ingress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102104"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102105"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102106"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102107"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102108"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102109"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102110"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102111"] = "This fault is caused by 'Total Ingress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102112"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102113"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102114"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102115"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102116"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102117"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102118"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102119"] = "This fault is caused by 'Total Ingress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102120"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102121"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102122"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102123"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102124"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102125"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102126"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102127"] = "This fault is caused by 'Total Ingress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102152"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102153"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102154"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102155"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102156"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102157"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102158"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102159"] = "This fault is caused by 'Total Ingress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102160"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102161"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102162"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102163"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102164"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102165"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102166"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102167"] = "This fault is caused by 'Total Ingress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102288"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102289"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102290"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102291"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102292"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102293"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102294"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102295"] = "This fault is caused by 'Ingress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F102296"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102297"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102298"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102299"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F1023"] = "The object refers to an object that was not found." + self.system_fault_code["F102300"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102301"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102302"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102303"] = "This fault is caused by 'Ingress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F102304"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102305"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102306"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102307"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102308"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102309"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102310"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102311"] = "This fault is caused by 'Ingress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F102312"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102313"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102314"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102315"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102316"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102317"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102318"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102319"] = "This fault is caused by 'Ingress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F102352"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102353"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102354"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102355"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102356"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102357"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102358"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F102359"] = "This fault is caused by 'Ingress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F1024"] = "The object refers to an object that was not found." + self.system_fault_code["F102456"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102457"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102458"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102459"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102460"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102461"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102462"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102463"] = "This fault is caused by 'Ingress Unclassfied Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102472"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102473"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102474"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102475"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102476"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102477"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102478"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102479"] = "This fault is caused by 'Ingress Unclassfied Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102480"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102481"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102482"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102483"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102484"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102485"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102486"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102487"] = "This fault is caused by 'Ingress Unclassfied Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102488"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102489"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102490"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102491"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102492"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102493"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102494"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102495"] = "This fault is caused by 'Ingress Unclassfied Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102496"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102497"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102498"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102499"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F1025"] = "The object refers to an object that was not found." + self.system_fault_code["F102500"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102501"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102502"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102503"] = "This fault is caused by 'Ingress Unclassfied Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102504"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102505"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102506"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102507"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102508"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102509"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102510"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102511"] = "This fault is caused by 'Ingress Unclassfied Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102536"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102537"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102538"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102539"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102540"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102541"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102542"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102543"] = "This fault is caused by 'Ingress Unclassfied Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102544"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102545"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102546"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102547"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102548"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102549"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102550"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102551"] = "This fault is caused by 'Ingress Unclassfied Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1026"] = "The object refers to an object that was not found." + self.system_fault_code["F102672"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102673"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102674"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102675"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102676"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102677"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102678"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102679"] = "This fault is caused by 'Ingress Unknown Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F102688"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102689"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102690"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102691"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102692"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102693"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102694"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102695"] = "This fault is caused by 'Ingress Unknown Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F102696"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102697"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102698"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102699"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F1027"] = "The object refers to an object that was not found." + self.system_fault_code["F102700"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102701"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102702"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102703"] = "This fault is caused by 'Ingress Unknown Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F102704"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102705"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102706"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102707"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102708"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102709"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102710"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102711"] = "This fault is caused by 'Ingress Unknown Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F102712"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102713"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102714"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102715"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102716"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102717"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102718"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102719"] = "This fault is caused by 'Ingress Unknown Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F102720"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102721"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102722"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102723"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102724"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102725"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102726"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102727"] = "This fault is caused by 'Ingress Unknown Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F102752"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102753"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102754"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102755"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102756"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102757"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102758"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102759"] = "This fault is caused by 'Ingress Unknown Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F102760"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102761"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102762"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102763"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102764"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102765"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102766"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F102767"] = "This fault is caused by 'Ingress Unknown Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1028"] = "The object refers to an object that was not found." + self.system_fault_code["F102888"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102889"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102890"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102891"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102892"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102893"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102894"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F102895"] = "This fault is caused by 'Ingress Unclassified Packets current value' statistical property crossing threshold level." + self.system_fault_code["F1029"] = "The object refers to an object that was not found." + self.system_fault_code["F102904"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102905"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102906"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102907"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102908"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102909"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102910"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102911"] = "This fault is caused by 'Ingress Unclassified Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F102912"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102913"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102914"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102915"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102916"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102917"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102918"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102919"] = "This fault is caused by 'Ingress Unclassified Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F102920"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102921"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102922"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102923"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102924"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102925"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102926"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102927"] = "This fault is caused by 'Ingress Unclassified Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F102928"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102929"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102930"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102931"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102932"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102933"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102934"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102935"] = "This fault is caused by 'Ingress Unclassified Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F102936"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102937"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102938"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102939"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102940"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102941"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102942"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102943"] = "This fault is caused by 'Ingress Unclassified Packets average value' statistical property crossing threshold level." + self.system_fault_code["F102968"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102969"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102970"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102971"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102972"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102973"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102974"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102975"] = "This fault is caused by 'Ingress Unclassified Packets trend' statistical property crossing threshold level." + self.system_fault_code["F102976"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102977"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102978"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102979"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102980"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102981"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102982"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F102983"] = "This fault is caused by 'Ingress Unclassified Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1030"] = "The object refers to an object that was not found." + self.system_fault_code["F1031"] = "The object refers to an object that was not found." + self.system_fault_code["F103104"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103105"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103106"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103107"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103108"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103109"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103110"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103111"] = "This fault is caused by 'Ingress Unknown Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F103120"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103121"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103122"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103123"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103124"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103125"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103126"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103127"] = "This fault is caused by 'Ingress Unknown Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F103128"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103129"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103130"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103131"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103132"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103133"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103134"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103135"] = "This fault is caused by 'Ingress Unknown Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F103136"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103137"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103138"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103139"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103140"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103141"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103142"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103143"] = "This fault is caused by 'Ingress Unknown Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F103144"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103145"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103146"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103147"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103148"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103149"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103150"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103151"] = "This fault is caused by 'Ingress Unknown Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F103152"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103153"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103154"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103155"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103156"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103157"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103158"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103159"] = "This fault is caused by 'Ingress Unknown Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F103184"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103185"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103186"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103187"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103188"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103189"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103190"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103191"] = "This fault is caused by 'Ingress Unknown Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F103192"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103193"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103194"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103195"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103196"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103197"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103198"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F103199"] = "This fault is caused by 'Ingress Unknown Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F1032"] = "The object refers to an object that was not found." + self.system_fault_code["F1033"] = "The object refers to an object that was not found." + self.system_fault_code["F103320"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103321"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103322"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103323"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103324"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103325"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103326"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103327"] = "This fault is caused by 'power drawn current value' statistical property crossing threshold level." + self.system_fault_code["F103328"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103329"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103330"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103331"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103332"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103333"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103334"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103335"] = "This fault is caused by 'power drawn minimum value' statistical property crossing threshold level." + self.system_fault_code["F103336"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103337"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103338"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103339"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103340"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103341"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103342"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103343"] = "This fault is caused by 'power drawn maximum value' statistical property crossing threshold level." + self.system_fault_code["F103344"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103345"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103346"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103347"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103348"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103349"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103350"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103351"] = "This fault is caused by 'power drawn average value' statistical property crossing threshold level." + self.system_fault_code["F103384"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103385"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103386"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103387"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103388"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103389"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103390"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F103391"] = "This fault is caused by 'power drawn trend' statistical property crossing threshold level." + self.system_fault_code["F1034"] = "The object refers to an object that was not found." + self.system_fault_code["F103488"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103489"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103490"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103491"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103492"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103493"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103494"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103495"] = "This fault is caused by 'power supplied current value' statistical property crossing threshold level." + self.system_fault_code["F103496"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103497"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103498"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103499"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103500"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103501"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103502"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103503"] = "This fault is caused by 'power supplied minimum value' statistical property crossing threshold level." + self.system_fault_code["F103504"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103505"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103506"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103507"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103508"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103509"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103510"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103511"] = "This fault is caused by 'power supplied maximum value' statistical property crossing threshold level." + self.system_fault_code["F103512"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103513"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103514"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103515"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103516"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103517"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103518"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103519"] = "This fault is caused by 'power supplied average value' statistical property crossing threshold level." + self.system_fault_code["F103552"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103553"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103554"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103555"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103556"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103557"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103558"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103559"] = "This fault is caused by 'power supplied trend' statistical property crossing threshold level." + self.system_fault_code["F103656"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103657"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103658"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103659"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103660"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103661"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103662"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103663"] = "This fault is caused by 'current temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103664"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103665"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103666"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103667"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103668"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103669"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103670"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103671"] = "This fault is caused by 'current temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103672"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103673"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103674"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103675"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103676"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103677"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103678"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103679"] = "This fault is caused by 'current temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103680"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103681"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103682"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103683"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103684"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103685"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103686"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103687"] = "This fault is caused by 'current temperature average value' statistical property crossing threshold level." + self.system_fault_code["F1037"] = "The object refers to an object that was not found." + self.system_fault_code["F103720"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103721"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103722"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103723"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103724"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103725"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103726"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103727"] = "This fault is caused by 'current temperature trend' statistical property crossing threshold level." + self.system_fault_code["F1038"] = "The object refers to an object that was not found." + self.system_fault_code["F103824"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103825"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103826"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103827"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103828"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103829"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103830"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103831"] = "This fault is caused by 'normalized temperature current value' statistical property crossing threshold level." + self.system_fault_code["F103832"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103833"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103834"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103835"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103836"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103837"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103838"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103839"] = "This fault is caused by 'normalized temperature minimum value' statistical property crossing threshold level." + self.system_fault_code["F103840"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103841"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103842"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103843"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103844"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103845"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103846"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103847"] = "This fault is caused by 'normalized temperature maximum value' statistical property crossing threshold level." + self.system_fault_code["F103848"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103849"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103850"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103851"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103852"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103853"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103854"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103855"] = "This fault is caused by 'normalized temperature average value' statistical property crossing threshold level." + self.system_fault_code["F103888"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103889"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103890"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103891"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103892"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103893"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103894"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F103895"] = "This fault is caused by 'normalized temperature trend' statistical property crossing threshold level." + self.system_fault_code["F1040"] = "The object refers to an object that was not found." + self.system_fault_code["F1041"] = "The object refers to an object that was not found." + self.system_fault_code["F104160"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104161"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104162"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104163"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104164"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104165"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104166"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104167"] = "This fault is caused by 'bridge domain entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104168"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104169"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104170"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104171"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104172"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104173"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104174"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104175"] = "This fault is caused by 'bridge domain entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104176"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104177"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104178"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104179"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104180"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104181"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104182"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104183"] = "This fault is caused by 'bridge domain entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104184"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104185"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104186"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104187"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104188"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104189"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104190"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104191"] = "This fault is caused by 'bridge domain entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104224"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104225"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104226"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104227"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104228"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104229"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104230"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104231"] = "This fault is caused by 'bridge domain entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104496"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104497"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104498"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104499"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104500"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104501"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104502"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104503"] = "This fault is caused by 'Layer2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104504"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104505"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104506"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104507"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104508"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104509"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104510"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104511"] = "This fault is caused by 'Layer2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104512"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104513"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104514"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104515"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104516"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104517"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104518"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104519"] = "This fault is caused by 'Layer2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104520"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104521"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104522"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104523"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104524"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104525"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104526"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104527"] = "This fault is caused by 'Layer2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104560"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104561"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104562"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104563"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104564"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104565"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104566"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104567"] = "This fault is caused by 'Layer2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F1048"] = "The object refers to an object that was not found." + self.system_fault_code["F104832"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104833"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104834"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104835"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104836"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104837"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104838"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104839"] = "This fault is caused by 'Layer3 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F104840"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104841"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104842"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104843"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104844"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104845"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104846"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104847"] = "This fault is caused by 'Layer3 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F104848"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104849"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104850"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104851"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104852"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104853"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104854"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104855"] = "This fault is caused by 'Layer3 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F104856"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104857"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104858"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104859"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104860"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104861"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104862"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104863"] = "This fault is caused by 'Layer3 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F104896"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104897"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104898"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104899"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F1049"] = "The object refers to an object that was not found." + self.system_fault_code["F104900"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104901"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104902"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F104903"] = "This fault is caused by 'Layer3 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105168"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105169"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105170"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105171"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105172"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105173"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105174"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105175"] = "This fault is caused by 'Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105176"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105177"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105178"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105179"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105180"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105181"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105182"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105183"] = "This fault is caused by 'Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105184"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105185"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105186"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105187"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105188"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105189"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105190"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105191"] = "This fault is caused by 'Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105192"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105193"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105194"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105195"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105196"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105197"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105198"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105199"] = "This fault is caused by 'Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105232"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105233"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105234"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105235"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105236"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105237"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105238"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105239"] = "This fault is caused by 'Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F1053"] = "The object refers to an object that was not found." + self.system_fault_code["F1054"] = "The object refers to an object that was not found." + self.system_fault_code["F1055"] = "The object refers to an object that was not found." + self.system_fault_code["F105504"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105505"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105506"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105507"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105508"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105509"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105510"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105511"] = "This fault is caused by 'Policy CAM entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F105512"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105513"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105514"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105515"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105516"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105517"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105518"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105519"] = "This fault is caused by 'Policy CAM entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105520"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105521"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105522"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105523"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105524"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105525"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105526"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105527"] = "This fault is caused by 'Policy CAM entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105528"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105529"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105530"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105531"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105532"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105533"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105534"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105535"] = "This fault is caused by 'Policy CAM entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F105568"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105569"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105570"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105571"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105572"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105573"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105574"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F105575"] = "This fault is caused by 'Policy CAM entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F1056"] = "The object refers to an object that was not found." + self.system_fault_code["F105672"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105673"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105674"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105675"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105676"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105677"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105678"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105679"] = "This fault is caused by 'dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F105688"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105689"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105690"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105691"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105692"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105693"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105694"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105695"] = "This fault is caused by 'dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F105696"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105697"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105698"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105699"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105700"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105701"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105702"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105703"] = "This fault is caused by 'dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F105704"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105705"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105706"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105707"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105708"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105709"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105710"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105711"] = "This fault is caused by 'dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F105712"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105713"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105714"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105715"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105716"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105717"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105718"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105719"] = "This fault is caused by 'dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F105720"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105721"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105722"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105723"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105724"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105725"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105726"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105727"] = "This fault is caused by 'dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F105752"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105753"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105754"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105755"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105756"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105757"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105758"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105759"] = "This fault is caused by 'dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F105760"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105761"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105762"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105763"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105764"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105765"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105766"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F105767"] = "This fault is caused by 'dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F1058"] = "The object refers to an object that was not found." + self.system_fault_code["F105888"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105889"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105890"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105891"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105892"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105893"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105894"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105895"] = "This fault is caused by 'drop percentage current value' statistical property crossing threshold level." + self.system_fault_code["F105896"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105897"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105898"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105899"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F1059"] = "The object refers to an object that was not found." + self.system_fault_code["F105900"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105901"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105902"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105903"] = "This fault is caused by 'drop percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F105904"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105905"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105906"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105907"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105908"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105909"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105910"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105911"] = "This fault is caused by 'drop percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F105912"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105913"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105914"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105915"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105916"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105917"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105918"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105919"] = "This fault is caused by 'drop percentage average value' statistical property crossing threshold level." + self.system_fault_code["F105952"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105953"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105954"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105955"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105956"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105957"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105958"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F105959"] = "This fault is caused by 'drop percentage trend' statistical property crossing threshold level." + self.system_fault_code["F1060"] = "The object refers to an object that was not found." + self.system_fault_code["F106056"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106057"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106058"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106059"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106060"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106061"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106062"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106063"] = "This fault is caused by 'excess packets current value' statistical property crossing threshold level." + self.system_fault_code["F106072"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106073"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106074"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106075"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106076"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106077"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106078"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106079"] = "This fault is caused by 'excess packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106080"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106081"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106082"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106083"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106084"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106085"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106086"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106087"] = "This fault is caused by 'excess packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106088"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106089"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106090"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106091"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106092"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106093"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106094"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106095"] = "This fault is caused by 'excess packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106096"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106097"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106098"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106099"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106100"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106101"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106102"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106103"] = "This fault is caused by 'excess packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106104"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106105"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106106"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106107"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106108"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106109"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106110"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106111"] = "This fault is caused by 'excess packets average value' statistical property crossing threshold level." + self.system_fault_code["F106136"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106137"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106138"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106139"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106140"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106141"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106142"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106143"] = "This fault is caused by 'excess packets trend' statistical property crossing threshold level." + self.system_fault_code["F106144"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106145"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106146"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106147"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106148"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106149"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106150"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F106151"] = "This fault is caused by 'excess packets rate' statistical property crossing threshold level." + self.system_fault_code["F1062"] = "The object refers to an object that was not found." + self.system_fault_code["F106272"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106273"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106274"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106275"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106276"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106277"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106278"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106279"] = "This fault is caused by 'excess percentage current value' statistical property crossing threshold level." + self.system_fault_code["F106280"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106281"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106282"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106283"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106284"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106285"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106286"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106287"] = "This fault is caused by 'excess percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F106288"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106289"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106290"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106291"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106292"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106293"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106294"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106295"] = "This fault is caused by 'excess percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F106296"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106297"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106298"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106299"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F1063"] = "The object refers to an object that was not found." + self.system_fault_code["F106300"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106301"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106302"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106303"] = "This fault is caused by 'excess percentage average value' statistical property crossing threshold level." + self.system_fault_code["F106336"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106337"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106338"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106339"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106340"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106341"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106342"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F106343"] = "This fault is caused by 'excess percentage trend' statistical property crossing threshold level." + self.system_fault_code["F1064"] = "The object refers to an object that was not found." + self.system_fault_code["F106440"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106441"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106442"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106443"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106444"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106445"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106446"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106447"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F106456"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106457"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106458"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106459"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106460"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106461"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106462"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106463"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106464"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106465"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106466"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106467"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106468"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106469"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106470"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106471"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106472"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106473"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106474"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106475"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106476"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106477"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106478"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106479"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106480"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106481"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106482"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106483"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106484"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106485"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106486"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106487"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106488"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106489"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106490"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106491"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106492"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106493"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106494"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F106495"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F1065"] = "The object refers to an object that was not found." + self.system_fault_code["F106520"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106521"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106522"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106523"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106524"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106525"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106526"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106527"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F106528"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106529"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106530"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106531"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106532"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106533"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106534"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F106535"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F1066"] = "The object refers to an object that was not found." + self.system_fault_code["F106656"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106657"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106658"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106659"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106660"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106661"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106662"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106663"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F106672"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106673"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106674"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106675"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106676"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106677"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106678"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106679"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F106680"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106681"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106682"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106683"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106684"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106685"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106686"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106687"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F106688"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106689"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106690"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106691"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106692"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106693"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106694"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106695"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F106696"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106697"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106698"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106699"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F1067"] = "The object refers to an object that was not found." + self.system_fault_code["F106700"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106701"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106702"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106703"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F106704"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106705"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106706"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106707"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106708"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106709"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106710"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106711"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F106736"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106737"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106738"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106739"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106740"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106741"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106742"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106743"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F106744"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106745"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106746"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106747"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106748"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106749"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106750"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F106751"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F1068"] = "The object refers to an object that was not found." + self.system_fault_code["F106872"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106873"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106874"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106875"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106876"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106877"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106878"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106879"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F106880"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106881"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106882"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106883"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106884"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106885"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106886"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106887"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F106888"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106889"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106890"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106891"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106892"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106893"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106894"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106895"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F106896"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106897"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106898"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106899"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F1069"] = "The object refers to an object that was not found." + self.system_fault_code["F106900"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106901"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106902"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106903"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F106936"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106937"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106938"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106939"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106940"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106941"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106942"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F106943"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F1070"] = "The object refers to an object that was not found." + self.system_fault_code["F107040"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107041"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107042"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107043"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107044"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107045"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107046"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107047"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107048"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107049"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107050"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107051"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107052"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107053"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107054"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107055"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107056"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107057"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107058"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107059"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107060"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107061"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107062"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107063"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107064"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107065"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107066"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107067"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107068"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107069"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107070"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107071"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F1071"] = "The object refers to an object that was not found." + self.system_fault_code["F107104"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107105"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107106"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107107"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107108"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107109"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107110"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107111"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107160"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107161"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107162"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107163"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107164"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107165"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107166"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107167"] = "This fault is caused by 'health score current value' statistical property crossing threshold level." + self.system_fault_code["F107168"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107169"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107170"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107171"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107172"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107173"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107174"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107175"] = "This fault is caused by 'health score minimum value' statistical property crossing threshold level." + self.system_fault_code["F107176"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107177"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107178"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107179"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107180"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107181"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107182"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107183"] = "This fault is caused by 'health score maximum value' statistical property crossing threshold level." + self.system_fault_code["F107184"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107185"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107186"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107187"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107188"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107189"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107190"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107191"] = "This fault is caused by 'health score average value' statistical property crossing threshold level." + self.system_fault_code["F107224"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107225"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107226"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107227"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107228"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107229"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107230"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107231"] = "This fault is caused by 'health score trend' statistical property crossing threshold level." + self.system_fault_code["F107280"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107281"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107282"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107283"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107284"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107285"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107286"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107287"] = "This fault is caused by 'active to unavailable transitions current value' statistical property crossing threshold level." + self.system_fault_code["F107296"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107297"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107298"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107299"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F1073"] = "The object refers to an object that was not found." + self.system_fault_code["F107300"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107301"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107302"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107303"] = "This fault is caused by 'active to unavailable transitions cumulative' statistical property crossing threshold level." + self.system_fault_code["F107304"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107305"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107306"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107307"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107308"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107309"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107310"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107311"] = "This fault is caused by 'active to unavailable transitions periodic' statistical property crossing threshold level." + self.system_fault_code["F107312"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107313"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107314"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107315"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107316"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107317"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107318"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107319"] = "This fault is caused by 'active to unavailable transitions minimum value' statistical property crossing threshold level." + self.system_fault_code["F107320"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107321"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107322"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107323"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107324"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107325"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107326"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107327"] = "This fault is caused by 'active to unavailable transitions maximum value' statistical property crossing threshold level." + self.system_fault_code["F107328"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107329"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107330"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107331"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107332"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107333"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107334"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107335"] = "This fault is caused by 'active to unavailable transitions average value' statistical property crossing threshold level." + self.system_fault_code["F107360"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107361"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107362"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107363"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107364"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107365"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107366"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107367"] = "This fault is caused by 'active to unavailable transitions trend' statistical property crossing threshold level." + self.system_fault_code["F107368"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107369"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107370"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107371"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107372"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107373"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107374"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107375"] = "This fault is caused by 'active to unavailable transitions rate' statistical property crossing threshold level." + self.system_fault_code["F107496"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107497"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107498"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107499"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F1075"] = "The object refers to an object that was not found." + self.system_fault_code["F107500"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107501"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107502"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107503"] = "This fault is caused by 'time in unavailable state current value' statistical property crossing threshold level." + self.system_fault_code["F107528"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107529"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107530"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107531"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107532"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107533"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107534"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107535"] = "This fault is caused by 'time in unavailable state minimum value' statistical property crossing threshold level." + self.system_fault_code["F107536"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107537"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107538"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107539"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107540"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107541"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107542"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107543"] = "This fault is caused by 'time in unavailable state maximum value' statistical property crossing threshold level." + self.system_fault_code["F107544"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107545"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107546"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107547"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107548"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107549"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107550"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107551"] = "This fault is caused by 'time in unavailable state average value' statistical property crossing threshold level." + self.system_fault_code["F107576"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107577"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107578"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107579"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107580"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107581"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107582"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F107583"] = "This fault is caused by 'time in unavailable state trend' statistical property crossing threshold level." + self.system_fault_code["F1076"] = "The object refers to an object that was not found." + self.system_fault_code["F1077"] = "The object refers to an object that was not found." + self.system_fault_code["F107712"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107713"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107714"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107715"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107716"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107717"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107718"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107719"] = "This fault is caused by 'time in persistification current value' statistical property crossing threshold level." + self.system_fault_code["F107728"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107729"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107730"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107731"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107732"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107733"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107734"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107735"] = "This fault is caused by 'time in persistification cumulative' statistical property crossing threshold level." + self.system_fault_code["F107736"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107737"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107738"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107739"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107740"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107741"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107742"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107743"] = "This fault is caused by 'time in persistification periodic' statistical property crossing threshold level." + self.system_fault_code["F107744"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107745"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107746"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107747"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107748"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107749"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107750"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107751"] = "This fault is caused by 'time in persistification minimum value' statistical property crossing threshold level." + self.system_fault_code["F107752"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107753"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107754"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107755"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107756"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107757"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107758"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107759"] = "This fault is caused by 'time in persistification maximum value' statistical property crossing threshold level." + self.system_fault_code["F107760"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107761"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107762"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107763"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107764"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107765"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107766"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107767"] = "This fault is caused by 'time in persistification average value' statistical property crossing threshold level." + self.system_fault_code["F107792"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107793"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107794"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107795"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107796"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107797"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107798"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107799"] = "This fault is caused by 'time in persistification trend' statistical property crossing threshold level." + self.system_fault_code["F107800"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107801"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107802"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107803"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107804"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107805"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107806"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F107807"] = "This fault is caused by 'time in persistification rate' statistical property crossing threshold level." + self.system_fault_code["F1079"] = "The object refers to an object that was not found." + self.system_fault_code["F107928"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107929"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107930"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107931"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107932"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107933"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107934"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107935"] = "This fault is caused by 'time in replication current value' statistical property crossing threshold level." + self.system_fault_code["F107944"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107945"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107946"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107947"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107948"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107949"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107950"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107951"] = "This fault is caused by 'time in replication cumulative' statistical property crossing threshold level." + self.system_fault_code["F107952"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107953"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107954"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107955"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107956"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107957"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107958"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107959"] = "This fault is caused by 'time in replication periodic' statistical property crossing threshold level." + self.system_fault_code["F107960"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107961"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107962"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107963"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107964"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107965"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107966"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107967"] = "This fault is caused by 'time in replication minimum value' statistical property crossing threshold level." + self.system_fault_code["F107968"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107969"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107970"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107971"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107972"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107973"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107974"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107975"] = "This fault is caused by 'time in replication maximum value' statistical property crossing threshold level." + self.system_fault_code["F107976"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107977"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107978"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107979"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107980"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107981"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107982"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F107983"] = "This fault is caused by 'time in replication average value' statistical property crossing threshold level." + self.system_fault_code["F1080"] = "The object refers to an object that was not found." + self.system_fault_code["F108008"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108009"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108010"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108011"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108012"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108013"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108014"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108015"] = "This fault is caused by 'time in replication trend' statistical property crossing threshold level." + self.system_fault_code["F108016"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108017"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108018"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108019"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108020"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108021"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108022"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F108023"] = "This fault is caused by 'time in replication rate' statistical property crossing threshold level." + self.system_fault_code["F1081"] = "The object refers to an object that was not found." + self.system_fault_code["F108144"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108145"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108146"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108147"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108148"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108149"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108150"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108151"] = "This fault is caused by 'average average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108160"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108161"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108162"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108163"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108164"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108165"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108166"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108167"] = "This fault is caused by 'average average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108168"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108169"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108170"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108171"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108172"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108173"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108174"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108175"] = "This fault is caused by 'average average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108176"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108177"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108178"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108179"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108180"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108181"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108182"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108183"] = "This fault is caused by 'average average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108184"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108185"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108186"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108187"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108188"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108189"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108190"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108191"] = "This fault is caused by 'average average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108192"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108193"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108194"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108195"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108196"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108197"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108198"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108199"] = "This fault is caused by 'average average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F1082"] = "The object refers to an object that was not found." + self.system_fault_code["F108224"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108225"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108226"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108227"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108228"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108229"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108230"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108231"] = "This fault is caused by 'average average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108232"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108233"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108234"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108235"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108236"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108237"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108238"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108239"] = "This fault is caused by 'average average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F1083"] = "The object refers to an object that was not found." + self.system_fault_code["F108360"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108361"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108362"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108363"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108364"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108365"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108366"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108367"] = "This fault is caused by 'average maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108376"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108377"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108378"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108379"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108380"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108381"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108382"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108383"] = "This fault is caused by 'average maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108384"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108385"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108386"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108387"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108388"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108389"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108390"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108391"] = "This fault is caused by 'average maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108392"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108393"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108394"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108395"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108396"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108397"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108398"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108399"] = "This fault is caused by 'average maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F1084"] = "The object refers to an object that was not found." + self.system_fault_code["F108400"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108401"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108402"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108403"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108404"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108405"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108406"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108407"] = "This fault is caused by 'average maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108408"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108409"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108410"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108411"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108412"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108413"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108414"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108415"] = "This fault is caused by 'average maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108440"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108441"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108442"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108443"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108444"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108445"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108446"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108447"] = "This fault is caused by 'average maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108448"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108449"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108450"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108451"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108452"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108453"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108454"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108455"] = "This fault is caused by 'average maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F1085"] = "The object refers to an object that was not found." + self.system_fault_code["F108576"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108577"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108578"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108579"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108580"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108581"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108582"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108583"] = "This fault is caused by 'current average penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108592"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108593"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108594"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108595"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108596"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108597"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108598"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108599"] = "This fault is caused by 'current average penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F1086"] = "The object refers to an object that was not found." + self.system_fault_code["F108600"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108601"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108602"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108603"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108604"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108605"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108606"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108607"] = "This fault is caused by 'current average penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108608"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108609"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108610"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108611"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108612"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108613"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108614"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108615"] = "This fault is caused by 'current average penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108616"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108617"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108618"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108619"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108620"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108621"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108622"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108623"] = "This fault is caused by 'current average penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108624"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108625"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108626"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108627"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108628"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108629"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108630"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108631"] = "This fault is caused by 'current average penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108656"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108657"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108658"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108659"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108660"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108661"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108662"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108663"] = "This fault is caused by 'current average penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108664"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108665"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108666"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108667"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108668"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108669"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108670"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108671"] = "This fault is caused by 'current average penalty rate' statistical property crossing threshold level." + self.system_fault_code["F1087"] = "The object refers to an object that was not found." + self.system_fault_code["F108792"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108793"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108794"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108795"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108796"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108797"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108798"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F108799"] = "This fault is caused by 'current maximum penalty current value' statistical property crossing threshold level." + self.system_fault_code["F1088"] = "The object refers to an object that was not found." + self.system_fault_code["F108808"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108809"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108810"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108811"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108812"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108813"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108814"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108815"] = "This fault is caused by 'current maximum penalty cumulative' statistical property crossing threshold level." + self.system_fault_code["F108816"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108817"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108818"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108819"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108820"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108821"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108822"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108823"] = "This fault is caused by 'current maximum penalty periodic' statistical property crossing threshold level." + self.system_fault_code["F108824"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108825"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108826"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108827"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108828"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108829"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108830"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108831"] = "This fault is caused by 'current maximum penalty minimum value' statistical property crossing threshold level." + self.system_fault_code["F108832"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108833"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108834"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108835"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108836"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108837"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108838"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108839"] = "This fault is caused by 'current maximum penalty maximum value' statistical property crossing threshold level." + self.system_fault_code["F108840"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108841"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108842"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108843"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108844"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108845"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108846"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108847"] = "This fault is caused by 'current maximum penalty average value' statistical property crossing threshold level." + self.system_fault_code["F108872"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108873"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108874"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108875"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108876"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108877"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108878"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108879"] = "This fault is caused by 'current maximum penalty trend' statistical property crossing threshold level." + self.system_fault_code["F108880"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108881"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108882"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108883"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108884"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108885"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108886"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F108887"] = "This fault is caused by 'current maximum penalty rate' statistical property crossing threshold level." + self.system_fault_code["F1089"] = "The object refers to an object that was not found." + self.system_fault_code["F1090"] = "The object refers to an object that was not found." + self.system_fault_code["F109008"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109009"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109010"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109011"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109012"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109013"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109014"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109015"] = "This fault is caused by 'leaf count current value' statistical property crossing threshold level." + self.system_fault_code["F109024"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109025"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109026"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109027"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109028"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109029"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109030"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109031"] = "This fault is caused by 'leaf count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109032"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109033"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109034"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109035"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109036"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109037"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109038"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109039"] = "This fault is caused by 'leaf count periodic' statistical property crossing threshold level." + self.system_fault_code["F109040"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109041"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109042"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109043"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109044"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109045"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109046"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109047"] = "This fault is caused by 'leaf count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109048"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109049"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109050"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109051"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109052"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109053"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109054"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109055"] = "This fault is caused by 'leaf count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109056"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109057"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109058"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109059"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109060"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109061"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109062"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109063"] = "This fault is caused by 'leaf count average value' statistical property crossing threshold level." + self.system_fault_code["F109088"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109089"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109090"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109091"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109092"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109093"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109094"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109095"] = "This fault is caused by 'leaf count trend' statistical property crossing threshold level." + self.system_fault_code["F109096"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F109097"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F109098"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F109099"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F1091"] = "The object refers to an object that was not found." + self.system_fault_code["F109100"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F109101"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F109102"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F109103"] = "This fault is caused by 'leaf count rate' statistical property crossing threshold level." + self.system_fault_code["F1092"] = "The object refers to an object that was not found." + self.system_fault_code["F109224"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109225"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109226"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109227"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109228"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109229"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109230"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109231"] = "This fault is caused by 'spine count current value' statistical property crossing threshold level." + self.system_fault_code["F109240"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109241"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109242"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109243"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109244"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109245"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109246"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109247"] = "This fault is caused by 'spine count cumulative' statistical property crossing threshold level." + self.system_fault_code["F109248"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109249"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109250"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109251"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109252"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109253"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109254"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109255"] = "This fault is caused by 'spine count periodic' statistical property crossing threshold level." + self.system_fault_code["F109256"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109257"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109258"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109259"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109260"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109261"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109262"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109263"] = "This fault is caused by 'spine count minimum value' statistical property crossing threshold level." + self.system_fault_code["F109264"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109265"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109266"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109267"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109268"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109269"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109270"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109271"] = "This fault is caused by 'spine count maximum value' statistical property crossing threshold level." + self.system_fault_code["F109272"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109273"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109274"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109275"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109276"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109277"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109278"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109279"] = "This fault is caused by 'spine count average value' statistical property crossing threshold level." + self.system_fault_code["F109304"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109305"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109306"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109307"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109308"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109309"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109310"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109311"] = "This fault is caused by 'spine count trend' statistical property crossing threshold level." + self.system_fault_code["F109312"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109313"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109314"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109315"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109316"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109317"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109318"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F109319"] = "This fault is caused by 'spine count rate' statistical property crossing threshold level." + self.system_fault_code["F1094"] = "The object refers to an object that was not found." + self.system_fault_code["F109440"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109441"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109442"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109443"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109444"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109445"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109446"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109447"] = "This fault is caused by 'average effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109456"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109457"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109458"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109459"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109460"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109461"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109462"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109463"] = "This fault is caused by 'average effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109464"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109465"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109466"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109467"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109468"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109469"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109470"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109471"] = "This fault is caused by 'average effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109472"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109473"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109474"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109475"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109476"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109477"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109478"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109479"] = "This fault is caused by 'average effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109480"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109481"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109482"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109483"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109484"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109485"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109486"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109487"] = "This fault is caused by 'average effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109488"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109489"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109490"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109491"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109492"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109493"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109494"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109495"] = "This fault is caused by 'average effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F1095"] = "The object refers to an object that was not found." + self.system_fault_code["F109520"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109521"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109522"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109523"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109524"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109525"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109526"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109527"] = "This fault is caused by 'average effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109528"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109529"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109530"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109531"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109532"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109533"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109534"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109535"] = "This fault is caused by 'average effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F1096"] = "The object refers to an object that was not found." + self.system_fault_code["F109656"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109657"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109658"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109659"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109660"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109661"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109662"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109663"] = "This fault is caused by 'effective calculations current value' statistical property crossing threshold level." + self.system_fault_code["F109672"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109673"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109674"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109675"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109676"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109677"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109678"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109679"] = "This fault is caused by 'effective calculations cumulative' statistical property crossing threshold level." + self.system_fault_code["F109680"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109681"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109682"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109683"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109684"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109685"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109686"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109687"] = "This fault is caused by 'effective calculations periodic' statistical property crossing threshold level." + self.system_fault_code["F109688"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109689"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109690"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109691"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109692"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109693"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109694"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109695"] = "This fault is caused by 'effective calculations minimum value' statistical property crossing threshold level." + self.system_fault_code["F109696"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109697"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109698"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109699"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F1097"] = "The object refers to an object that was not found." + self.system_fault_code["F109700"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109701"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109702"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109703"] = "This fault is caused by 'effective calculations maximum value' statistical property crossing threshold level." + self.system_fault_code["F109704"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109705"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109706"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109707"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109708"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109709"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109710"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109711"] = "This fault is caused by 'effective calculations average value' statistical property crossing threshold level." + self.system_fault_code["F109736"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109737"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109738"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109739"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109740"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109741"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109742"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109743"] = "This fault is caused by 'effective calculations trend' statistical property crossing threshold level." + self.system_fault_code["F109744"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109745"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109746"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109747"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109748"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109749"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109750"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F109751"] = "This fault is caused by 'effective calculations rate' statistical property crossing threshold level." + self.system_fault_code["F1098"] = "The object refers to an object that was not found." + self.system_fault_code["F109872"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109873"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109874"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109875"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109876"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109877"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109878"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109879"] = "This fault is caused by 'runs current value' statistical property crossing threshold level." + self.system_fault_code["F109888"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109889"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109890"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109891"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109892"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109893"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109894"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109895"] = "This fault is caused by 'runs cumulative' statistical property crossing threshold level." + self.system_fault_code["F109896"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109897"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109898"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109899"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F1099"] = "The object refers to an object that was not found." + self.system_fault_code["F109900"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109901"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109902"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109903"] = "This fault is caused by 'runs periodic' statistical property crossing threshold level." + self.system_fault_code["F109904"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109905"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109906"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109907"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109908"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109909"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109910"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109911"] = "This fault is caused by 'runs minimum value' statistical property crossing threshold level." + self.system_fault_code["F109912"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109913"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109914"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109915"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109916"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109917"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109918"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109919"] = "This fault is caused by 'runs maximum value' statistical property crossing threshold level." + self.system_fault_code["F109920"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109921"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109922"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109923"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109924"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109925"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109926"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109927"] = "This fault is caused by 'runs average value' statistical property crossing threshold level." + self.system_fault_code["F109952"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109953"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109954"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109955"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109956"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109957"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109958"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109959"] = "This fault is caused by 'runs trend' statistical property crossing threshold level." + self.system_fault_code["F109960"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109961"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109962"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109963"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109964"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109965"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109966"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F109967"] = "This fault is caused by 'runs rate' statistical property crossing threshold level." + self.system_fault_code["F1100"] = "The object refers to an object that was not found." + self.system_fault_code["F110088"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110089"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110090"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110091"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110092"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110093"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110094"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110095"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F1101"] = "The object refers to an object that was not found." + self.system_fault_code["F110104"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110105"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110106"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110107"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110108"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110109"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110110"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110111"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110112"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110113"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110114"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110115"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110116"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110117"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110118"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110119"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110120"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110121"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110122"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110123"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110124"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110125"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110126"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110127"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110128"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110129"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110130"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110131"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110132"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110133"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110134"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110135"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110136"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110137"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110138"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110139"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110140"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110141"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110142"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110143"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110168"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110169"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110170"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110171"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110172"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110173"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110174"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110175"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110176"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110177"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110178"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110179"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110180"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110181"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110182"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110183"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1102"] = "The object refers to an object that was not found." + self.system_fault_code["F110256"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110257"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110258"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110259"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110260"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110261"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110262"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110263"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110272"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110273"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110274"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110275"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110276"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110277"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110278"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110279"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110280"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110281"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110282"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110283"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110284"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110285"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110286"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110287"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110288"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110289"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110290"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110291"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110292"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110293"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110294"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110295"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110296"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110297"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110298"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110299"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F1103"] = "The object refers to an object that was not found." + self.system_fault_code["F110300"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110301"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110302"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110303"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110304"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110305"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110306"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110307"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110308"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110309"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110310"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110311"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110336"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110337"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110338"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110339"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110340"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110341"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110342"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110343"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110344"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110345"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110346"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110347"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110348"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110349"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110350"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110351"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1104"] = "The object refers to an object that was not found." + self.system_fault_code["F110424"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110425"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110426"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110427"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110428"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110429"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110430"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110431"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110432"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110433"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110434"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110435"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110436"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110437"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110438"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110439"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110464"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110465"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110466"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110467"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110468"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110469"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110470"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110471"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110472"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110473"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110474"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110475"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110476"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110477"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110478"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110479"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1105"] = "The object refers to an object that was not found." + self.system_fault_code["F110576"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110577"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110578"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110579"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110580"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110581"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110582"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110583"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110592"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110593"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110594"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110595"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110596"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110597"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110598"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110599"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110600"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110601"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110602"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110603"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110604"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110605"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110606"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110607"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110608"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110609"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110610"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110611"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110612"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110613"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110614"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110615"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110616"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110617"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110618"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110619"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110620"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110621"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110622"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110623"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110624"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110625"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110626"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110627"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110628"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110629"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110630"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110631"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110656"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110657"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110658"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110659"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110660"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110661"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110662"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110663"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110664"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110665"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110666"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110667"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110668"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110669"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110670"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110671"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1107"] = "The object refers to an object that was not found." + self.system_fault_code["F110744"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110745"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110746"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110747"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110748"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110749"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110750"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110751"] = "This fault is caused by 'ingress flood bytes current value' statistical property crossing threshold level." + self.system_fault_code["F110760"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110761"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110762"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110763"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110764"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110765"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110766"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110767"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110768"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110769"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110770"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110771"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110772"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110773"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110774"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110775"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110776"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110777"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110778"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110779"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110780"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110781"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110782"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110783"] = "This fault is caused by 'ingress flood bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F110784"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110785"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110786"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110787"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110788"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110789"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110790"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110791"] = "This fault is caused by 'ingress flood bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F110792"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110793"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110794"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110795"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110796"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110797"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110798"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110799"] = "This fault is caused by 'ingress flood bytes average value' statistical property crossing threshold level." + self.system_fault_code["F110824"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110825"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110826"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110827"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110828"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110829"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110830"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110831"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110832"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110833"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110834"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110835"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110836"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110837"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110838"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110839"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110912"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110913"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110914"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110915"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110916"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110917"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110918"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110919"] = "This fault is caused by 'ingress flood bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F110920"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110921"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110922"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110923"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110924"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110925"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110926"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110927"] = "This fault is caused by 'ingress flood bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F110952"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110953"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110954"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110955"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110956"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110957"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110958"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110959"] = "This fault is caused by 'ingress flood bytes trend' statistical property crossing threshold level." + self.system_fault_code["F110960"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110961"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110962"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110963"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110964"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110965"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110966"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F110967"] = "This fault is caused by 'ingress flood bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1110"] = "The object refers to an object that was not found." + self.system_fault_code["F111064"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111065"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111066"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111067"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111068"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111069"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111070"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111071"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111080"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111081"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111082"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111083"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111084"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111085"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111086"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111087"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111088"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111089"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111090"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111091"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111092"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111093"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111094"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111095"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111096"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111097"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111098"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111099"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F1111"] = "The object refers to an object that was not found." + self.system_fault_code["F111100"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111101"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111102"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111103"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111104"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111105"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111106"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111107"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111108"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111109"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111110"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111111"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111112"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111113"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111114"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111115"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111116"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111117"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111118"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111119"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111144"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111145"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111146"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111147"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111148"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111149"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111150"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111151"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111152"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111153"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111154"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111155"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111156"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111157"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111158"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111159"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1112"] = "The object refers to an object that was not found." + self.system_fault_code["F111232"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111233"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111234"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111235"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111236"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111237"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111238"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111239"] = "This fault is caused by 'ingress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111248"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111249"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111250"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111251"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111252"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111253"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111254"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111255"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111256"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111257"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111258"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111259"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111260"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111261"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111262"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111263"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111264"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111265"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111266"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111267"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111268"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111269"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111270"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111271"] = "This fault is caused by 'ingress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111272"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111273"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111274"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111275"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111276"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111277"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111278"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111279"] = "This fault is caused by 'ingress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111280"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111281"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111282"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111283"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111284"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111285"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111286"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111287"] = "This fault is caused by 'ingress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111312"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111313"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111314"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111315"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111316"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111317"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111318"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111319"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111320"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111321"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111322"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111323"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111324"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111325"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111326"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111327"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111400"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111401"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111402"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111403"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111404"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111405"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111406"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111407"] = "This fault is caused by 'ingress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111408"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111409"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111410"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111411"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111412"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111413"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111414"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111415"] = "This fault is caused by 'ingress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111440"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111441"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111442"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111443"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111444"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111445"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111446"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111447"] = "This fault is caused by 'ingress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111448"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111449"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111450"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111451"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111452"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111453"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111454"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111455"] = "This fault is caused by 'ingress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1115"] = "The object refers to an object that was not found." + self.system_fault_code["F111552"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111553"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111554"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111555"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111556"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111557"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111558"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111559"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111568"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111569"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111570"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111571"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111572"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111573"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111574"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111575"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111576"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111577"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111578"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111579"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111580"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111581"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111582"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111583"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111584"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111585"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111586"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111587"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111588"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111589"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111590"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111591"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111592"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111593"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111594"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111595"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111596"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111597"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111598"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111599"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111600"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111601"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111602"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111603"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111604"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111605"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111606"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111607"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111632"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111633"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111634"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111635"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111636"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111637"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111638"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111639"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111640"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111641"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111642"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111643"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111644"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111645"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111646"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111647"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F1117"] = "The object refers to an object that was not found." + self.system_fault_code["F111720"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111721"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111722"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111723"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111724"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111725"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111726"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111727"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F111736"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111737"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111738"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111739"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111740"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111741"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111742"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111743"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111744"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111745"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111746"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111747"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111748"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111749"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111750"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111751"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111752"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111753"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111754"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111755"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111756"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111757"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111758"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111759"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F111760"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111761"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111762"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111763"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111764"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111765"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111766"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111767"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F111768"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111769"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111770"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111771"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111772"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111773"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111774"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111775"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F111800"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111801"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111802"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111803"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111804"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111805"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111806"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111807"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111808"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111809"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111810"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111811"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111812"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111813"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111814"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111815"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111888"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111889"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111890"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111891"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111892"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111893"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111894"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111895"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F111896"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111897"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111898"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111899"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111900"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111901"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111902"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111903"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F111928"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111929"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111930"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111931"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111932"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111933"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111934"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111935"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F111936"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111937"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111938"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111939"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111940"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111941"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111942"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F111943"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F112040"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112041"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112042"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112043"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112044"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112045"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112046"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112047"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112056"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112057"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112058"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112059"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112060"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112061"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112062"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112063"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112064"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112065"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112066"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112067"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112068"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112069"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112070"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112071"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112072"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112073"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112074"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112075"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112076"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112077"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112078"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112079"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112080"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112081"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112082"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112083"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112084"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112085"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112086"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112087"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112088"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112089"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112090"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112091"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112092"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112093"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112094"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112095"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F1121"] = "The object refers to an object that was not found." + self.system_fault_code["F112120"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112121"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112122"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112123"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112124"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112125"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112126"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112127"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112128"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112129"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112130"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112131"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112132"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112133"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112134"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112135"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112208"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112209"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112210"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112211"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112212"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112213"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112214"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112215"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F112224"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112225"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112226"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112227"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112228"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112229"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112230"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112231"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112232"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112233"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112234"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112235"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112236"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112237"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112238"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112239"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112240"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112241"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112242"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112243"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112244"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112245"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112246"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112247"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112248"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112249"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112250"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112251"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112252"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112253"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112254"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112255"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112256"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112257"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112258"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112259"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112260"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112261"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112262"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112263"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F112288"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112289"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112290"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112291"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112292"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112293"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112294"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112295"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112296"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112297"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112298"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112299"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F1123"] = "The object refers to an object that was not found." + self.system_fault_code["F112300"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112301"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112302"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112303"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112376"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112377"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112378"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112379"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112380"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112381"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112382"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112383"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112384"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112385"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112386"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112387"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112388"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112389"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112390"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112391"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112416"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112417"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112418"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112419"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112420"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112421"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112422"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112423"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F112424"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112425"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112426"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112427"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112428"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112429"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112430"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F112431"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F1125"] = "The object refers to an object that was not found." + self.system_fault_code["F112528"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112529"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112530"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112531"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112532"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112533"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112534"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112535"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112544"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112545"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112546"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112547"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112548"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112549"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112550"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112551"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112552"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112553"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112554"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112555"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112556"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112557"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112558"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112559"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112560"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112561"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112562"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112563"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112564"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112565"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112566"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112567"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112568"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112569"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112570"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112571"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112572"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112573"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112574"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112575"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112576"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112577"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112578"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112579"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112580"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112581"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112582"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112583"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F1126"] = "The object refers to an object that was not found." + self.system_fault_code["F112608"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112609"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112610"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112611"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112612"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112613"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112614"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112615"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112616"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112617"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112618"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112619"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112620"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112621"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112622"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112623"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112696"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112697"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112698"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112699"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F1127"] = "The object refers to an object that was not found." + self.system_fault_code["F112700"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112701"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112702"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112703"] = "This fault is caused by 'ingress flood packets current value' statistical property crossing threshold level." + self.system_fault_code["F112712"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112713"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112714"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112715"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112716"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112717"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112718"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112719"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112720"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112721"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112722"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112723"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112724"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112725"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112726"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112727"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112728"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112729"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112730"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112731"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112732"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112733"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112734"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112735"] = "This fault is caused by 'ingress flood packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F112736"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112737"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112738"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112739"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112740"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112741"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112742"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112743"] = "This fault is caused by 'ingress flood packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F112744"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112745"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112746"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112747"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112748"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112749"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112750"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112751"] = "This fault is caused by 'ingress flood packets average value' statistical property crossing threshold level." + self.system_fault_code["F112776"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112777"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112778"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112779"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112780"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112781"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112782"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112783"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112784"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112785"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112786"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112787"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112788"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112789"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112790"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112791"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F1128"] = "The object refers to an object that was not found." + self.system_fault_code["F112864"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112865"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112866"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112867"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112868"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112869"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112870"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112871"] = "This fault is caused by 'ingress flood packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F112872"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112873"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112874"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112875"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112876"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112877"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112878"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F112879"] = "This fault is caused by 'ingress flood packets periodic' statistical property crossing threshold level." + self.system_fault_code["F1129"] = "The object refers to an object that was not found." + self.system_fault_code["F112904"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112905"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112906"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112907"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112908"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112909"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112910"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112911"] = "This fault is caused by 'ingress flood packets trend' statistical property crossing threshold level." + self.system_fault_code["F112912"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112913"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112914"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112915"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112916"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112917"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112918"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F112919"] = "This fault is caused by 'ingress flood packets rate' statistical property crossing threshold level." + self.system_fault_code["F113016"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113017"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113018"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113019"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113020"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113021"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113022"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113023"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113032"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113033"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113034"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113035"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113036"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113037"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113038"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113039"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113040"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113041"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113042"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113043"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113044"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113045"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113046"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113047"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113048"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113049"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113050"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113051"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113052"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113053"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113054"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113055"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113056"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113057"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113058"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113059"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113060"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113061"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113062"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113063"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113064"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113065"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113066"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113067"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113068"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113069"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113070"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113071"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113096"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113097"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113098"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113099"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113100"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113101"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113102"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113103"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113104"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113105"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113106"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113107"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113108"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113109"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113110"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113111"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113184"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113185"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113186"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113187"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113188"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113189"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113190"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113191"] = "This fault is caused by 'ingress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113200"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113201"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113202"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113203"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113204"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113205"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113206"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113207"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113208"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113209"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113210"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113211"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113212"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113213"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113214"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113215"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113216"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113217"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113218"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113219"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113220"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113221"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113222"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113223"] = "This fault is caused by 'ingress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113224"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113225"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113226"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113227"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113228"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113229"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113230"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113231"] = "This fault is caused by 'ingress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113232"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113233"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113234"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113235"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113236"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113237"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113238"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113239"] = "This fault is caused by 'ingress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113264"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113265"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113266"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113267"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113268"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113269"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113270"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113271"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113272"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113273"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113274"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113275"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113276"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113277"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113278"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113279"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113352"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113353"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113354"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113355"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113356"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113357"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113358"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113359"] = "This fault is caused by 'ingress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113360"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113361"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113362"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113363"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113364"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113365"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113366"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113367"] = "This fault is caused by 'ingress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113392"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113393"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113394"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113395"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113396"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113397"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113398"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113399"] = "This fault is caused by 'ingress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113400"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113401"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113402"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113403"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113404"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113405"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113406"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113407"] = "This fault is caused by 'ingress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113504"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113505"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113506"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113507"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113508"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113509"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113510"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113511"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113520"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113521"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113522"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113523"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113524"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113525"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113526"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113527"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113528"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113529"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113530"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113531"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113532"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113533"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113534"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113535"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113536"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113537"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113538"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113539"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113540"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113541"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113542"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113543"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113544"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113545"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113546"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113547"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113548"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113549"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113550"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113551"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113552"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113553"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113554"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113555"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113556"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113557"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113558"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113559"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113584"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113585"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113586"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113587"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113588"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113589"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113590"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113591"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113592"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113593"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113594"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113595"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113596"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113597"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113598"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113599"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113672"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113673"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113674"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113675"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113676"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113677"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113678"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113679"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F113688"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113689"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113690"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113691"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113692"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113693"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113694"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113695"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113696"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113697"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113698"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113699"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113700"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113701"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113702"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113703"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113704"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113705"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113706"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113707"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113708"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113709"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113710"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113711"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F113712"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113713"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113714"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113715"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113716"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113717"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113718"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113719"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F113720"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113721"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113722"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113723"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113724"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113725"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113726"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113727"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F113752"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113753"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113754"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113755"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113756"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113757"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113758"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113759"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113760"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113761"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113762"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113763"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113764"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113765"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113766"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113767"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113840"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113841"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113842"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113843"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113844"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113845"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113846"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113847"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F113848"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113849"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113850"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113851"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113852"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113853"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113854"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113855"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F113880"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113881"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113882"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113883"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113884"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113885"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113886"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113887"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F113888"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113889"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113890"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113891"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113892"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113893"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113894"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F113895"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114328"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114329"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114330"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114331"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114332"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114333"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114334"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114335"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F114344"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114345"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114346"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114347"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114348"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114349"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114350"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114351"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F114352"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114353"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114354"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114355"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114356"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114357"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114358"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114359"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F114360"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114361"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114362"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114363"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114364"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114365"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114366"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114367"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F114368"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114369"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114370"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114371"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114372"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114373"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114374"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114375"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F114376"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114377"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114378"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114379"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114380"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114381"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114382"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114383"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F114408"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114409"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114410"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114411"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114412"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114413"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114414"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114415"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F114416"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114417"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114418"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114419"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114420"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114421"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114422"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114423"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F114544"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114545"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114546"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114547"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114548"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114549"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114550"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114551"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F114560"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114561"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114562"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114563"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114564"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114565"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114566"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114567"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114568"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114569"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114570"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114571"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114572"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114573"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114574"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114575"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114576"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114577"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114578"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114579"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114580"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114581"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114582"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114583"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114584"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114585"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114586"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114587"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114588"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114589"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114590"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114591"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114592"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114593"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114594"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114595"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114596"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114597"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114598"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114599"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F114624"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114625"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114626"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114627"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114628"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114629"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114630"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114631"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F114632"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114633"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114634"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114635"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114636"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114637"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114638"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114639"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F114760"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114761"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114762"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114763"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114764"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114765"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114766"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114767"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F114776"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114777"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114778"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114779"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114780"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114781"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114782"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114783"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114784"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114785"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114786"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114787"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114788"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114789"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114790"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114791"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F114792"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114793"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114794"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114795"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114796"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114797"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114798"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114799"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F114800"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114801"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114802"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114803"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114804"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114805"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114806"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114807"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F114808"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114809"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114810"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114811"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114812"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114813"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114814"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114815"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F114840"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114841"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114842"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114843"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114844"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114845"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114846"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114847"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F114848"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114849"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114850"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114851"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114852"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114853"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114854"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114855"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F114976"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114977"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114978"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114979"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114980"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114981"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114982"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114983"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F114992"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114993"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114994"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114995"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114996"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114997"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114998"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F114999"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115000"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115001"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115002"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115003"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115004"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115005"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115006"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115007"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115008"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115009"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115010"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115011"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115012"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115013"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115014"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115015"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115016"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115017"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115018"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115019"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115020"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115021"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115022"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115023"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115024"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115025"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115026"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115027"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115028"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115029"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115030"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115031"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F115056"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115057"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115058"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115059"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115060"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115061"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115062"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115063"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F115064"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115065"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115066"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115067"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115068"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115069"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115070"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115071"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F115192"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115193"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115194"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115195"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115196"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115197"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115198"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115199"] = "This fault is caused by 'received unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115208"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115209"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115210"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115211"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115212"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115213"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115214"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115215"] = "This fault is caused by 'received unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115216"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115217"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115218"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115219"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115220"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115221"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115222"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115223"] = "This fault is caused by 'received unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115224"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115225"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115226"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115227"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115228"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115229"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115230"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115231"] = "This fault is caused by 'received unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115232"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115233"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115234"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115235"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115236"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115237"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115238"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115239"] = "This fault is caused by 'received unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115240"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115241"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115242"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115243"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115244"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115245"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115246"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115247"] = "This fault is caused by 'received unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115272"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115273"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115274"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115275"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115276"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115277"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115278"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115279"] = "This fault is caused by 'received unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115280"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115281"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115282"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115283"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115284"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115285"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115286"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115287"] = "This fault is caused by 'received unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115408"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115409"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115410"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115411"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115412"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115413"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115414"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115415"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F115424"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115425"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115426"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115427"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115428"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115429"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115430"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115431"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F115432"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115433"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115434"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115435"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115436"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115437"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115438"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115439"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F115440"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115441"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115442"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115443"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115444"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115445"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115446"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115447"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F115448"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115449"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115450"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115451"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115452"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115453"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115454"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115455"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F115456"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115457"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115458"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115459"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115460"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115461"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115462"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115463"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F115488"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115489"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115490"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115491"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115492"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115493"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115494"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115495"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F115496"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115497"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115498"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115499"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115500"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115501"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115502"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115503"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F115624"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115625"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115626"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115627"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115628"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115629"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115630"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115631"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F115640"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115641"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115642"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115643"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115644"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115645"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115646"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115647"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115648"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115649"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115650"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115651"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115652"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115653"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115654"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115655"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115656"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115657"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115658"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115659"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115660"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115661"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115662"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115663"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115664"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115665"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115666"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115667"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115668"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115669"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115670"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115671"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115672"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115673"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115674"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115675"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115676"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115677"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115678"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115679"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F115704"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115705"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115706"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115707"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115708"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115709"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115710"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115711"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F115712"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115713"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115714"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115715"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115716"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115717"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115718"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115719"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F115840"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115841"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115842"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115843"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115844"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115845"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115846"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115847"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F115856"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115857"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115858"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115859"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115860"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115861"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115862"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115863"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F115864"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115865"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115866"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115867"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115868"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115869"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115870"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115871"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F115872"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115873"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115874"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115875"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115876"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115877"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115878"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115879"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F115880"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115881"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115882"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115883"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115884"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115885"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115886"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115887"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F115888"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115889"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115890"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115891"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115892"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115893"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115894"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115895"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F115920"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115921"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115922"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115923"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115924"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115925"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115926"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115927"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F115928"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115929"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115930"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115931"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115932"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115933"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115934"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F115935"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116056"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116057"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116058"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116059"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116060"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116061"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116062"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116063"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F116072"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116073"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116074"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116075"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116076"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116077"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116078"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116079"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116080"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116081"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116082"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116083"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116084"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116085"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116086"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116087"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116088"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116089"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116090"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116091"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116092"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116093"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116094"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116095"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116096"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116097"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116098"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116099"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116100"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116101"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116102"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116103"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116104"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116105"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116106"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116107"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116108"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116109"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116110"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116111"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F116136"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116137"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116138"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116139"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116140"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116141"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116142"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116143"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F116144"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116145"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116146"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116147"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116148"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116149"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116150"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116151"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F116272"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116273"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116274"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116275"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116276"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116277"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116278"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116279"] = "This fault is caused by 'transmitted unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F116288"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116289"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116290"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116291"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116292"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116293"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116294"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116295"] = "This fault is caused by 'transmitted unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F116296"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116297"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116298"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116299"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116300"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116301"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116302"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116303"] = "This fault is caused by 'transmitted unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F116304"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116305"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116306"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116307"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116308"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116309"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116310"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116311"] = "This fault is caused by 'transmitted unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F116312"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116313"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116314"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116315"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116316"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116317"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116318"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116319"] = "This fault is caused by 'transmitted unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F116320"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116321"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116322"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116323"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116324"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116325"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116326"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116327"] = "This fault is caused by 'transmitted unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F116352"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116353"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116354"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116355"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116356"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116357"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116358"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116359"] = "This fault is caused by 'transmitted unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F116360"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116361"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116362"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116363"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116364"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116365"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116366"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116367"] = "This fault is caused by 'transmitted unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F116488"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116489"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116490"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116491"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116492"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116493"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116494"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116495"] = "This fault is caused by 'CPU Usage current value' statistical property crossing threshold level." + self.system_fault_code["F116496"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116497"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116498"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116499"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116500"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116501"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116502"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116503"] = "This fault is caused by 'CPU Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F116504"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116505"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116506"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116507"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116508"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116509"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116510"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116511"] = "This fault is caused by 'CPU Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F116512"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116513"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116514"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116515"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116516"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116517"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116518"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116519"] = "This fault is caused by 'CPU Usage average value' statistical property crossing threshold level." + self.system_fault_code["F116552"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116553"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116554"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116555"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116556"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116557"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116558"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116559"] = "This fault is caused by 'CPU Usage trend' statistical property crossing threshold level." + self.system_fault_code["F116656"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116657"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116658"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116659"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116660"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116661"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116662"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116663"] = "This fault is caused by 'Memory Allocated current value' statistical property crossing threshold level." + self.system_fault_code["F116664"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116665"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116666"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116667"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116668"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116669"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116670"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116671"] = "This fault is caused by 'Memory Allocated minimum value' statistical property crossing threshold level." + self.system_fault_code["F116672"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116673"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116674"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116675"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116676"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116677"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116678"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116679"] = "This fault is caused by 'Memory Allocated maximum value' statistical property crossing threshold level." + self.system_fault_code["F116680"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116681"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116682"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116683"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116684"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116685"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116686"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116687"] = "This fault is caused by 'Memory Allocated average value' statistical property crossing threshold level." + self.system_fault_code["F116720"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116721"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116722"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116723"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116724"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116725"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116726"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116727"] = "This fault is caused by 'Memory Allocated trend' statistical property crossing threshold level." + self.system_fault_code["F116824"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116825"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116826"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116827"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116828"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116829"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116830"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116831"] = "This fault is caused by 'average execution time current value' statistical property crossing threshold level." + self.system_fault_code["F116832"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116833"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116834"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116835"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116836"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116837"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116838"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116839"] = "This fault is caused by 'average execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F116840"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116841"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116842"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116843"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116844"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116845"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116846"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116847"] = "This fault is caused by 'average execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F116848"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116849"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116850"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116851"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116852"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116853"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116854"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116855"] = "This fault is caused by 'average execution time average value' statistical property crossing threshold level." + self.system_fault_code["F116888"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116889"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116890"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116891"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116892"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116893"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116894"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116895"] = "This fault is caused by 'average execution time trend' statistical property crossing threshold level." + self.system_fault_code["F116992"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116993"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116994"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116995"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116996"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116997"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116998"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F116999"] = "This fault is caused by 'invoked current value' statistical property crossing threshold level." + self.system_fault_code["F117000"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117001"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117002"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117003"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117004"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117005"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117006"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117007"] = "This fault is caused by 'invoked minimum value' statistical property crossing threshold level." + self.system_fault_code["F117008"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117009"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117010"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117011"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117012"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117013"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117014"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117015"] = "This fault is caused by 'invoked maximum value' statistical property crossing threshold level." + self.system_fault_code["F117016"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117017"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117018"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117019"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117020"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117021"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117022"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117023"] = "This fault is caused by 'invoked average value' statistical property crossing threshold level." + self.system_fault_code["F117056"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117057"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117058"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117059"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117060"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117061"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117062"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117063"] = "This fault is caused by 'invoked trend' statistical property crossing threshold level." + self.system_fault_code["F117160"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117161"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117162"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117163"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117164"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117165"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117166"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117167"] = "This fault is caused by 'maximum execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117168"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117169"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117170"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117171"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117172"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117173"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117174"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117175"] = "This fault is caused by 'maximum execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117176"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117177"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117178"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117179"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117180"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117181"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117182"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117183"] = "This fault is caused by 'maximum execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117184"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117185"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117186"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117187"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117188"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117189"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117190"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117191"] = "This fault is caused by 'maximum execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117224"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117225"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117226"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117227"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117228"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117229"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117230"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117231"] = "This fault is caused by 'maximum execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117328"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117329"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117330"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117331"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117332"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117333"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117334"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117335"] = "This fault is caused by 'total execution time current value' statistical property crossing threshold level." + self.system_fault_code["F117336"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117337"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117338"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117339"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117340"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117341"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117342"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117343"] = "This fault is caused by 'total execution time minimum value' statistical property crossing threshold level." + self.system_fault_code["F117344"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117345"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117346"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117347"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117348"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117349"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117350"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117351"] = "This fault is caused by 'total execution time maximum value' statistical property crossing threshold level." + self.system_fault_code["F117352"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117353"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117354"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117355"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117356"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117357"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117358"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117359"] = "This fault is caused by 'total execution time average value' statistical property crossing threshold level." + self.system_fault_code["F117392"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117393"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117394"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117395"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117396"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117397"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117398"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117399"] = "This fault is caused by 'total execution time trend' statistical property crossing threshold level." + self.system_fault_code["F117496"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117497"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117498"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117499"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117500"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117501"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117502"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117503"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F117504"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117505"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117506"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117507"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117508"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117509"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117510"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117511"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F117512"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117513"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117514"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117515"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117516"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117517"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117518"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117519"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F117520"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117521"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117522"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117523"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117524"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117525"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117526"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117527"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F117560"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117561"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117562"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117563"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117564"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117565"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117566"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117567"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F117664"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117665"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117666"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117667"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117668"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117669"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117670"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117671"] = "This fault is caused by 'Allocated memory current value' statistical property crossing threshold level." + self.system_fault_code["F117672"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117673"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117674"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117675"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117676"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117677"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117678"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117679"] = "This fault is caused by 'Allocated memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117680"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117681"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117682"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117683"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117684"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117685"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117686"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117687"] = "This fault is caused by 'Allocated memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117688"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117689"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117690"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117691"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117692"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117693"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117694"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117695"] = "This fault is caused by 'Allocated memory average value' statistical property crossing threshold level." + self.system_fault_code["F117728"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117729"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117730"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117731"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117732"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117733"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117734"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117735"] = "This fault is caused by 'Allocated memory trend' statistical property crossing threshold level." + self.system_fault_code["F117832"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117833"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117834"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117835"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117836"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117837"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117838"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117839"] = "This fault is caused by 'Used memory current value' statistical property crossing threshold level." + self.system_fault_code["F117840"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117841"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117842"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117843"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117844"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117845"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117846"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117847"] = "This fault is caused by 'Used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F117848"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117849"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117850"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117851"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117852"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117853"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117854"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117855"] = "This fault is caused by 'Used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F117856"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117857"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117858"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117859"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117860"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117861"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117862"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117863"] = "This fault is caused by 'Used memory average value' statistical property crossing threshold level." + self.system_fault_code["F117896"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117897"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117898"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117899"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117900"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117901"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117902"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F117903"] = "This fault is caused by 'Used memory trend' statistical property crossing threshold level." + self.system_fault_code["F118000"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118001"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118002"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118003"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118004"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118005"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118006"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118007"] = "This fault is caused by 'idle CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118008"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118009"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118010"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118011"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118012"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118013"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118014"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118015"] = "This fault is caused by 'idle CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118016"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118017"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118018"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118019"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118020"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118021"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118022"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118023"] = "This fault is caused by 'idle CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118024"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118025"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118026"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118027"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118028"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118029"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118030"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118031"] = "This fault is caused by 'idle CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118064"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118065"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118066"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118067"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118068"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118069"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118070"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118071"] = "This fault is caused by 'idle CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118168"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118169"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118170"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118171"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118172"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118173"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118174"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118175"] = "This fault is caused by 'kernel CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118176"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118177"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118178"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118179"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118180"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118181"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118182"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118183"] = "This fault is caused by 'kernel CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118184"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118185"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118186"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118187"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118188"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118189"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118190"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118191"] = "This fault is caused by 'kernel CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118192"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118193"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118194"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118195"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118196"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118197"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118198"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118199"] = "This fault is caused by 'kernel CPU average value' statistical property crossing threshold level." + self.system_fault_code["F1182"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118232"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118233"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118234"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118235"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118236"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118237"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118238"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118239"] = "This fault is caused by 'kernel CPU trend' statistical property crossing threshold level." + self.system_fault_code["F1183"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118336"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118337"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118338"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118339"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118340"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118341"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118342"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118343"] = "This fault is caused by 'user CPU current value' statistical property crossing threshold level." + self.system_fault_code["F118344"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118345"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118346"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118347"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118348"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118349"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118350"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118351"] = "This fault is caused by 'user CPU minimum value' statistical property crossing threshold level." + self.system_fault_code["F118352"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118353"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118354"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118355"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118356"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118357"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118358"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118359"] = "This fault is caused by 'user CPU maximum value' statistical property crossing threshold level." + self.system_fault_code["F118360"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118361"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118362"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118363"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118364"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118365"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118366"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F118367"] = "This fault is caused by 'user CPU average value' statistical property crossing threshold level." + self.system_fault_code["F1184"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118400"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118401"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118402"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118403"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118404"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118405"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118406"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F118407"] = "This fault is caused by 'user CPU trend' statistical property crossing threshold level." + self.system_fault_code["F1185"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118504"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118505"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118506"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118507"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118508"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118509"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118510"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118511"] = "This fault is caused by '15 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118512"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118513"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118514"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118515"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118516"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118517"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118518"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118519"] = "This fault is caused by '15 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118520"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118521"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118522"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118523"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118524"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118525"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118526"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118527"] = "This fault is caused by '15 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118528"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118529"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118530"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118531"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118532"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118533"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118534"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118535"] = "This fault is caused by '15 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118568"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118569"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118570"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118571"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118572"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118573"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118574"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118575"] = "This fault is caused by '15 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F1186"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118672"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118673"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118674"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118675"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118676"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118677"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118678"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118679"] = "This fault is caused by '1 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118680"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118681"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118682"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118683"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118684"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118685"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118686"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118687"] = "This fault is caused by '1 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118688"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118689"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118690"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118691"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118692"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118693"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118694"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118695"] = "This fault is caused by '1 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118696"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118697"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118698"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118699"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F1187"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118700"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118701"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118702"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118703"] = "This fault is caused by '1 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118736"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118737"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118738"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118739"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118740"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118741"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118742"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118743"] = "This fault is caused by '1 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F1188"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118840"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118841"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118842"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118843"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118844"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118845"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118846"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118847"] = "This fault is caused by '5 minute average load current value' statistical property crossing threshold level." + self.system_fault_code["F118848"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118849"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118850"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118851"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118852"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118853"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118854"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118855"] = "This fault is caused by '5 minute average load minimum value' statistical property crossing threshold level." + self.system_fault_code["F118856"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118857"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118858"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118859"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118860"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118861"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118862"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118863"] = "This fault is caused by '5 minute average load maximum value' statistical property crossing threshold level." + self.system_fault_code["F118864"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118865"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118866"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118867"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118868"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118869"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118870"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F118871"] = "This fault is caused by '5 minute average load average value' statistical property crossing threshold level." + self.system_fault_code["F1189"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F118904"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118905"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118906"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118907"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118908"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118909"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118910"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F118911"] = "This fault is caused by '5 minute average load trend' statistical property crossing threshold level." + self.system_fault_code["F1190"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F119008"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119009"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119010"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119011"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119012"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119013"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119014"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119015"] = "This fault is caused by 'running processes current value' statistical property crossing threshold level." + self.system_fault_code["F119016"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119017"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119018"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119019"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119020"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119021"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119022"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119023"] = "This fault is caused by 'running processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119024"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119025"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119026"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119027"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119028"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119029"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119030"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119031"] = "This fault is caused by 'running processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119032"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119033"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119034"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119035"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119036"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119037"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119038"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119039"] = "This fault is caused by 'running processes average value' statistical property crossing threshold level." + self.system_fault_code["F119072"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119073"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119074"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119075"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119076"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119077"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119078"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F119079"] = "This fault is caused by 'running processes trend' statistical property crossing threshold level." + self.system_fault_code["F1191"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F119176"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119177"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119178"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119179"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119180"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119181"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119182"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119183"] = "This fault is caused by 'total processes current value' statistical property crossing threshold level." + self.system_fault_code["F119184"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119185"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119186"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119187"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119188"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119189"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119190"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119191"] = "This fault is caused by 'total processes minimum value' statistical property crossing threshold level." + self.system_fault_code["F119192"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119193"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119194"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119195"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119196"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119197"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119198"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F119199"] = "This fault is caused by 'total processes maximum value' statistical property crossing threshold level." + self.system_fault_code["F1192"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F119200"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119201"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119202"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119203"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119204"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119205"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119206"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119207"] = "This fault is caused by 'total processes average value' statistical property crossing threshold level." + self.system_fault_code["F119240"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119241"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119242"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119243"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119244"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119245"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119246"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119247"] = "This fault is caused by 'total processes trend' statistical property crossing threshold level." + self.system_fault_code["F119344"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119345"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119346"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119347"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119348"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119349"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119350"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119351"] = "This fault is caused by 'free memory current value' statistical property crossing threshold level." + self.system_fault_code["F119352"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119353"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119354"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119355"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119356"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119357"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119358"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119359"] = "This fault is caused by 'free memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119360"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119361"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119362"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119363"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119364"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119365"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119366"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119367"] = "This fault is caused by 'free memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119368"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119369"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119370"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119371"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119372"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119373"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119374"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F119375"] = "This fault is caused by 'free memory average value' statistical property crossing threshold level." + self.system_fault_code["F1194"] = "This fault occurs when qos manager fails to activate a class due to hardware programming failure" + self.system_fault_code["F119408"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119409"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119410"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119411"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119412"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119413"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119414"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F119415"] = "This fault is caused by 'free memory trend' statistical property crossing threshold level." + self.system_fault_code["F1195"] = "This fault occurs when qos manager fails to activate a dscp rule due to hardware programming failure" + self.system_fault_code["F119512"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119513"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119514"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119515"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119516"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119517"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119518"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119519"] = "This fault is caused by 'total memory current value' statistical property crossing threshold level." + self.system_fault_code["F119520"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119521"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119522"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119523"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119524"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119525"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119526"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119527"] = "This fault is caused by 'total memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119528"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119529"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119530"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119531"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119532"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119533"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119534"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119535"] = "This fault is caused by 'total memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119536"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119537"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119538"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119539"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119540"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119541"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119542"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119543"] = "This fault is caused by 'total memory average value' statistical property crossing threshold level." + self.system_fault_code["F119576"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119577"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119578"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119579"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119580"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119581"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119582"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F119583"] = "This fault is caused by 'total memory trend' statistical property crossing threshold level." + self.system_fault_code["F1196"] = "This fault occurs when qos manager fails to activate a dot1p rule due to hardware programming failure" + self.system_fault_code["F119680"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119681"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119682"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119683"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119684"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119685"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119686"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119687"] = "This fault is caused by 'used memory current value' statistical property crossing threshold level." + self.system_fault_code["F119688"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119689"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119690"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119691"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119692"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119693"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119694"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119695"] = "This fault is caused by 'used memory minimum value' statistical property crossing threshold level." + self.system_fault_code["F119696"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119697"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119698"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119699"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F1197"] = "This fault occurs when the ep learning is disabled" + self.system_fault_code["F119700"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119701"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119702"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119703"] = "This fault is caused by 'used memory maximum value' statistical property crossing threshold level." + self.system_fault_code["F119704"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119705"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119706"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119707"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119708"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119709"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119710"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119711"] = "This fault is caused by 'used memory average value' statistical property crossing threshold level." + self.system_fault_code["F119744"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119745"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119746"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119747"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119748"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119749"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119750"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119751"] = "This fault is caused by 'used memory trend' statistical property crossing threshold level." + self.system_fault_code["F119848"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119849"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119850"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119851"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119852"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119853"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119854"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119855"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F119864"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119865"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119866"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119867"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119868"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119869"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119870"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119871"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F119872"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119873"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119874"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119875"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119876"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119877"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119878"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119879"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F119880"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119881"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119882"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119883"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119884"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119885"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119886"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119887"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F119888"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119889"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119890"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119891"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119892"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119893"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119894"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119895"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F119896"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119897"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119898"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119899"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F1199"] = "This fault occurs when span source on a port goes to failed state" + self.system_fault_code["F119900"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119901"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119902"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119903"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F119928"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119929"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119930"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119931"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119932"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119933"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119934"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119935"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F119936"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119937"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119938"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119939"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119940"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119941"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119942"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F119943"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F1200"] = "This fault occurs when span source on a circuit goes to failed state" + self.system_fault_code["F120064"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120065"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120066"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120067"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120068"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120069"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120070"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120071"] = "This fault is caused by 'ingress admit packets current value' statistical property crossing threshold level." + self.system_fault_code["F120080"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120081"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120082"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120083"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120084"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120085"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120086"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120087"] = "This fault is caused by 'ingress admit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120088"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120089"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120090"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120091"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120092"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120093"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120094"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120095"] = "This fault is caused by 'ingress admit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120096"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120097"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120098"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120099"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F1201"] = "This fault occurs when span destination goes to failed state" + self.system_fault_code["F120100"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120101"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120102"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120103"] = "This fault is caused by 'ingress admit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120104"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120105"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120106"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120107"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120108"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120109"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120110"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120111"] = "This fault is caused by 'ingress admit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120112"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120113"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120114"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120115"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120116"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120117"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120118"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120119"] = "This fault is caused by 'ingress admit packets average value' statistical property crossing threshold level." + self.system_fault_code["F120144"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120145"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120146"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120147"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120148"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120149"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120150"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120151"] = "This fault is caused by 'ingress admit packets trend' statistical property crossing threshold level." + self.system_fault_code["F120152"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120153"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120154"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120155"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120156"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120157"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120158"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120159"] = "This fault is caused by 'ingress admit packets rate' statistical property crossing threshold level." + self.system_fault_code["F120280"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120281"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120282"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120283"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120284"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120285"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120286"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120287"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F120296"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120297"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120298"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120299"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120300"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120301"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120302"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120303"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F120304"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120305"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120306"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120307"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120308"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120309"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120310"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120311"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F120312"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120313"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120314"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120315"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120316"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120317"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120318"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120319"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F120320"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120321"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120322"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120323"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120324"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120325"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120326"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120327"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F120328"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120329"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120330"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120331"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120332"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120333"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120334"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120335"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F120360"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120361"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120362"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120363"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120364"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120365"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120366"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120367"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F120368"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120369"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120370"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120371"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120372"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120373"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120374"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F120375"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F1207"] = "This fault occurs when the operational state of the arp adjacency is down" + self.system_fault_code["F1209"] = "This fault occurs when an out-of-service policy is incorrectly configured." + self.system_fault_code["F120928"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120929"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120930"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120931"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120932"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120933"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120934"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120935"] = "This fault is caused by 'Rx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F120944"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120945"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120946"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120947"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120948"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120949"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120950"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120951"] = "This fault is caused by 'Rx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F120952"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120953"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120954"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120955"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120956"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120957"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120958"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120959"] = "This fault is caused by 'Rx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F120960"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120961"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120962"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120963"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120964"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120965"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120966"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120967"] = "This fault is caused by 'Rx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F120968"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120969"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120970"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120971"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120972"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120973"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120974"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120975"] = "This fault is caused by 'Rx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F120976"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120977"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120978"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120979"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120980"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120981"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120982"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F120983"] = "This fault is caused by 'Rx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121008"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121009"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121010"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121011"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121012"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121013"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121014"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121015"] = "This fault is caused by 'Rx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121016"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121017"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121018"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121019"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121020"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121021"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121022"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121023"] = "This fault is caused by 'Rx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121144"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121145"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121146"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121147"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121148"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121149"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121150"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121151"] = "This fault is caused by 'Rx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121160"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121161"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121162"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121163"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121164"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121165"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121166"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121167"] = "This fault is caused by 'Rx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121168"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121169"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121170"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121171"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121172"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121173"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121174"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121175"] = "This fault is caused by 'Rx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121176"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121177"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121178"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121179"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121180"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121181"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121182"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121183"] = "This fault is caused by 'Rx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121184"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121185"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121186"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121187"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121188"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121189"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121190"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121191"] = "This fault is caused by 'Rx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121192"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121193"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121194"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121195"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121196"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121197"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121198"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121199"] = "This fault is caused by 'Rx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121224"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121225"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121226"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121227"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121228"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121229"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121230"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121231"] = "This fault is caused by 'Rx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121232"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121233"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121234"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121235"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121236"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121237"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121238"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121239"] = "This fault is caused by 'Rx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F1213"] = "This fault occurs when the bgp instance memory alert is critical" + self.system_fault_code["F121360"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121361"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121362"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121363"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121364"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121365"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121366"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121367"] = "This fault is caused by 'Rx current value' statistical property crossing threshold level." + self.system_fault_code["F121376"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121377"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121378"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121379"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121380"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121381"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121382"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121383"] = "This fault is caused by 'Rx cumulative' statistical property crossing threshold level." + self.system_fault_code["F121384"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121385"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121386"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121387"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121388"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121389"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121390"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121391"] = "This fault is caused by 'Rx periodic' statistical property crossing threshold level." + self.system_fault_code["F121392"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121393"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121394"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121395"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121396"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121397"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121398"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F121399"] = "This fault is caused by 'Rx minimum value' statistical property crossing threshold level." + self.system_fault_code["F1214"] = "This fault occurs when the peer is shut down because the prefix limit is exceeded or no memory" + self.system_fault_code["F121400"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121401"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121402"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121403"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121404"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121405"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121406"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121407"] = "This fault is caused by 'Rx maximum value' statistical property crossing threshold level." + self.system_fault_code["F121408"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121409"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121410"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121411"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121412"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121413"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121414"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121415"] = "This fault is caused by 'Rx average value' statistical property crossing threshold level." + self.system_fault_code["F121440"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121441"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121442"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121443"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121444"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121445"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121446"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121447"] = "This fault is caused by 'Rx trend' statistical property crossing threshold level." + self.system_fault_code["F121448"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121449"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121450"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121451"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121452"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121453"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121454"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F121455"] = "This fault is caused by 'Rx rate' statistical property crossing threshold level." + self.system_fault_code["F1215"] = "This fault occurs when the accepted prefixes from the peer is greater than the configured limit" + self.system_fault_code["F121576"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121577"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121578"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121579"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121580"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121581"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121582"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121583"] = "This fault is caused by 'Tx Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F121592"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121593"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121594"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121595"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121596"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121597"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121598"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121599"] = "This fault is caused by 'Tx Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F121600"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121601"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121602"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121603"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121604"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121605"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121606"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121607"] = "This fault is caused by 'Tx Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F121608"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121609"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121610"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121611"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121612"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121613"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121614"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121615"] = "This fault is caused by 'Tx Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F121616"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121617"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121618"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121619"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121620"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121621"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121622"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121623"] = "This fault is caused by 'Tx Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F121624"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121625"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121626"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121627"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121628"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121629"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121630"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121631"] = "This fault is caused by 'Tx Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F121656"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121657"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121658"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121659"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121660"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121661"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121662"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121663"] = "This fault is caused by 'Tx Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F121664"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121665"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121666"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121667"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121668"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121669"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121670"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121671"] = "This fault is caused by 'Tx Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F121792"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121793"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121794"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121795"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121796"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121797"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121798"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121799"] = "This fault is caused by 'Tx Errors current value' statistical property crossing threshold level." + self.system_fault_code["F121808"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121809"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121810"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121811"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121812"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121813"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121814"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121815"] = "This fault is caused by 'Tx Errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F121816"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121817"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121818"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121819"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121820"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121821"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121822"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121823"] = "This fault is caused by 'Tx Errors periodic' statistical property crossing threshold level." + self.system_fault_code["F121824"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121825"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121826"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121827"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121828"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121829"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121830"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121831"] = "This fault is caused by 'Tx Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F121832"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121833"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121834"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121835"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121836"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121837"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121838"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121839"] = "This fault is caused by 'Tx Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F121840"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121841"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121842"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121843"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121844"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121845"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121846"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121847"] = "This fault is caused by 'Tx Errors average value' statistical property crossing threshold level." + self.system_fault_code["F121872"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121873"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121874"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121875"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121876"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121877"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121878"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121879"] = "This fault is caused by 'Tx Errors trend' statistical property crossing threshold level." + self.system_fault_code["F121880"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121881"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121882"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121883"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121884"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121885"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121886"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F121887"] = "This fault is caused by 'Tx Errors rate' statistical property crossing threshold level." + self.system_fault_code["F122008"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122009"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122010"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122011"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122012"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122013"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122014"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122015"] = "This fault is caused by 'Tx current value' statistical property crossing threshold level." + self.system_fault_code["F122024"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122025"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122026"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122027"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122028"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122029"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122030"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122031"] = "This fault is caused by 'Tx cumulative' statistical property crossing threshold level." + self.system_fault_code["F122032"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122033"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122034"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122035"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122036"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122037"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122038"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122039"] = "This fault is caused by 'Tx periodic' statistical property crossing threshold level." + self.system_fault_code["F122040"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122041"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122042"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122043"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122044"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122045"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122046"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122047"] = "This fault is caused by 'Tx minimum value' statistical property crossing threshold level." + self.system_fault_code["F122048"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122049"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122050"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122051"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122052"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122053"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122054"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122055"] = "This fault is caused by 'Tx maximum value' statistical property crossing threshold level." + self.system_fault_code["F122056"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122057"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122058"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122059"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122060"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122061"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122062"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122063"] = "This fault is caused by 'Tx average value' statistical property crossing threshold level." + self.system_fault_code["F122088"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122089"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122090"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122091"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122092"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122093"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122094"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122095"] = "This fault is caused by 'Tx trend' statistical property crossing threshold level." + self.system_fault_code["F122096"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122097"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122098"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122099"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122100"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122101"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122102"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F122103"] = "This fault is caused by 'Tx rate' statistical property crossing threshold level." + self.system_fault_code["F1224"] = "This fault occurs when the svi bring up failed because of hardware programming failure" + self.system_fault_code["F1233"] = "Infra Policy fault is raised when both CDP and LLDP policies are configured for the same Attached Entity Profile." + self.system_fault_code["F1236"] = "The object refers to an object that was not found." + self.system_fault_code["F1237"] = "The object refers to an object that was not found." + self.system_fault_code["F1239"] = "This fault occurs when a link state is not ok" + self.system_fault_code["F1240"] = "This fault occurs when a Taboo list is incompletely / incorrectly configured." + self.system_fault_code["F1241"] = "The object refers to an object that was not found." + self.system_fault_code["F1258"] = "The object refers to an object that was not found." + self.system_fault_code["F1259"] = "This fault occurs when policy manager fails to activate a management rule due to software programming failure" + self.system_fault_code["F1261"] = "This fault occurs when a encap namespace (VLAN/VXLAN namespace etc.) is incorrectly configured." + self.system_fault_code["F1262"] = "This fault occurs when a controller reports some services do not have ideal replica leaders for some of the internal database" + self.system_fault_code["F1284"] = "The object refers to an object that was not found." + self.system_fault_code["F1286"] = "This fault occurs when a Spine node is used as a source or destination in a traceroute." + self.system_fault_code["F1295"] = "This fault is raised when a Date and Time Policy (datetime:Pol) fails to apply due to configuration issues." + self.system_fault_code["F1296"] = "This fault occurs when vpc interface goes down while peer interface is also down." + self.system_fault_code["F1297"] = "The object refers to an object that was not found." + self.system_fault_code["F1298"] = ": This fault occurs when deliverying EPg policies to a node has failed" + self.system_fault_code["F1299"] = "This fault occurs when a selector level policy has been created, all policies in the corresponding policy group should" + self.system_fault_code["F1300"] = "This fault occurs when a Fabric Node Group (fabricNodeGrp) has been created, all the policies targeted by the policy group" + self.system_fault_code["F1305"] = "This fault occurs when SNMP policy configuration failed to apply." + self.system_fault_code["F1307"] = "The object refers to an object that was not found." + self.system_fault_code["F1310"] = "The object refers to an object that was not found." + self.system_fault_code["F1313"] = "This fault is raised when remote or external disruptive operations are performed on Host Physical NIC from within the Controller." + self.system_fault_code["F1314"] = "This fault occurs when the L4-L7 service returns a warning fault" + self.system_fault_code["F1315"] = "This fault occurs when the L4-L7 service returns a critical fault" + self.system_fault_code["F1317"] = "This fault occurs when there is a single power supply in the chassis or there are mismatchd power supplies in the chassis" + self.system_fault_code["F1318"] = "This fault occurs when PSU are not detected correctly" + self.system_fault_code["F1321"] = "This fault occurs when a fan tray fails" + self.system_fault_code["F1322"] = "This fault occurs when a fan fails" + self.system_fault_code["F1323"] = "This fault occurs when a fan tray is missing" + self.system_fault_code["F1324"] = "This fault occurs when the there is a failure in setting up the management interface to a service node" + self.system_fault_code["F1325"] = "This fault occurs when the there is a failure in setting up the management interface on the controller which is used" + self.system_fault_code["F1329"] = "This fault occurs due to a Stats Export Policy session failure." + self.system_fault_code["F1330"] = "This fault occurs due to a Stats Export Policy session failure." + self.system_fault_code["F1332"] = "This fault occurs when sending a callhome message to destination does not succeed." + self.system_fault_code["F1336"] = "This fault occurs due to an invalid abstract function profile configuration." + self.system_fault_code["F1339"] = "This fault occurs when a Subject has a Label, but there is no EPG associated to a Contract that is also associated to" + self.system_fault_code["F1340"] = "This fault is raised when a Multicast Address pool cannot be deployed due to a missing or invalid configuration." + self.system_fault_code["F1342"] = "This fault occurs when qos manager fails to activate a dot1p rule due to hardware programming failure" + self.system_fault_code["F1343"] = "This fault occurs when qos manager fails to activate a dscp rule due to hardware programming failure" + self.system_fault_code["F1344"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F1345"] = "The object refers to an object that was not found." + self.system_fault_code["F1346"] = "The object refers to an object that was not found." + self.system_fault_code["F1347"] = "The object refers to an object that was not found." + self.system_fault_code["F1348"] = "The object refers to an object that was not found." + self.system_fault_code["F1349"] = "The object refers to an object that was not found." + self.system_fault_code["F1350"] = "The object refers to an object that was not found." + self.system_fault_code["F1351"] = "The object refers to an object that was not found." + self.system_fault_code["F1353"] = "The object refers to an object that was not found." + self.system_fault_code["F1360"] = "This fault occurs when the operational state of the coop adjacency is down" + self.system_fault_code["F1362"] = "This fault occurs when there is an incompatibility between the leaf and the attached FEX" + self.system_fault_code["F1364"] = "This fault occurs when the arp flood knob is not set in bridge only mode" + self.system_fault_code["F1368"] = "This fault occurs when snmp client security programming fails" + self.system_fault_code["F1369"] = "This fault occurs when snmp user programming fails" + self.system_fault_code["F1370"] = "This fault occurs when keepalive messages arrive periodically from controllers that are considered illegitimate by the" + self.system_fault_code["F1371"] = "This fault occurs when deployment of policy to a leaf/spine fails." + self.system_fault_code["F1373"] = "This fault is raised when the Endpoint Group cannot be deployed on a VMM Controller due to a missing or invalid configuration." + self.system_fault_code["F1374"] = "The object refers to an object that was not found." + self.system_fault_code["F1377"] = "This fault occurs when a Folder configuration is invalid.The config issues indicate the exact reason for the error." + self.system_fault_code["F1378"] = "This fault occurs when a Parameter configuration is invalid.The config issues indicate the exact reason for the error." + self.system_fault_code["F1379"] = "This fault occurs when a Relation configuration is invalid.The config issues indicate the exact reason for the error." + self.system_fault_code["F1385"] = "This fault occurs when the adjacency state is not up" + self.system_fault_code["F1386"] = "This fault occurs when the bridge domain ARP flood is not enabled and the L2 unknown unicast is set to flood" + self.system_fault_code["F1387"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F1394"] = "This fault occurs when a port is down and is in use for fabric" + self.system_fault_code["F1397"] = "The object refers to an object that was not found." + self.system_fault_code["F1399"] = "The object refers to an object that was not found." + self.system_fault_code["F1400"] = "The object refers to an object that was not found." + self.system_fault_code["F1410"] = "This fault occurs when the operational size for a controller cluster can not reach the configured target size." + self.system_fault_code["F1414"] = "This fault occurs when a configured syslog server is not resolvable." + self.system_fault_code["F1416"] = "This fault occurs when an Abstract Function Connector (AbsFuncConn) has an error.The config issues the exact reason for" + self.system_fault_code["F1419"] = "This fault occurs when a Data Management Engine (DME) process fails on a controller" + self.system_fault_code["F1425"] = "This fault occurs when the operational state of the ipv4 address state is changed to subnet-overlap/no primary/addr already" + self.system_fault_code["F1427"] = "The object refers to an object that was not found." + self.system_fault_code["F1432"] = "This fault occurs when upgrade is paused on a group due to one or more members of the group failing to be upgraded and" + self.system_fault_code["F1433"] = "This fault occurs when upgrade is paused due to cluster not being healthy" + self.system_fault_code["F1434"] = "The object refers to an object that was not found." + self.system_fault_code["F1435"] = "The object refers to an object that was not found." + self.system_fault_code["F1436"] = "The object refers to an object that was not found." + self.system_fault_code["F1449"] = "This fault occurs when the configured SNMP trap destination endpoint cannot be resolved by the switch." + self.system_fault_code["F1450"] = "This fault occurs when SNMP Trap Destination does not have a valid Endpoint Group Destination configured." + self.system_fault_code["F1451"] = "This fault occurs when psu is shut down" + self.system_fault_code["F1467"] = "The object refers to an object that was not found." + self.system_fault_code["F1471"] = "This fault is raised when the SCVMM plugin encounters an exception." + self.system_fault_code["F1472"] = "The object refers to an object that was not found." + self.system_fault_code["F1473"] = "This fault occurs when there is missing function in device package" + self.system_fault_code["F1477"] = "This fault occurs when the operational state of the ipv4 Nexthop is down due to Nexthop configured as local address or" + self.system_fault_code["F1480"] = "This fault occurs when a software upgrade fails on a fabric node." + self.system_fault_code["F1483"] = "This fault occurs when a bfd session goes down." + self.system_fault_code["F1484"] = "This fault occurs when the ospfv3 instance memory alert is critical" + self.system_fault_code["F1486"] = "The object refers to an object that was not found." + self.system_fault_code["F1487"] = "The object refers to an object that was not found." + self.system_fault_code["F1500"] = "The object refers to an object that was not found." + self.system_fault_code["F1501"] = "The object refers to an object that was not found." + self.system_fault_code["F1507"] = "This fault occurs when all the external L3 interfaces (created for external connectivity) are not configured with the" + self.system_fault_code["F1509"] = "This fault occurs when APIC inband management encap vlan is invalid/missing" + self.system_fault_code["F1510"] = "The object refers to an object that was not found." + self.system_fault_code["F1511"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F1526"] = "This fault occurs when a card sees a fatal error during runtime. The card is put in a fail state and cannot be put back" + self.system_fault_code["F1527"] = "This fault occurs when the utilization of storage capacity on a controller is greater than 75%" + self.system_fault_code["F1528"] = "This fault occurs when storage capacity utilization is between 85% and 90%" + self.system_fault_code["F1529"] = "This fault occurs when storage capacity utilization is greater than 90%" + self.system_fault_code["F1534"] = "The object refers to an object that was not found." + self.system_fault_code["F1539"] = "The object refers to an object that was not found." + self.system_fault_code["F1543"] = "This fault occurs when a node is not reachable" + self.system_fault_code["F1544"] = "This fault occurs when an unsupprted node is connected to the fabric" + self.system_fault_code["F1545"] = "This fault occurs when a significant number of packet drops are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1546"] = "This fault occurs when a small number of packet drops are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1547"] = "This fault occurs when a significant number of excess packets are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F154712"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154713"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154714"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154715"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154716"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154717"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154718"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154719"] = "This fault is caused by 'Total Ingress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F154720"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154721"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154722"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154723"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154724"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154725"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154726"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154727"] = "This fault is caused by 'Total Ingress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F154728"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154729"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154730"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154731"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154732"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154733"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154734"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154735"] = "This fault is caused by 'Total Ingress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F154736"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154737"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154738"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154739"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154740"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154741"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154742"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154743"] = "This fault is caused by 'Total Ingress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F154776"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154777"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154778"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154779"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154780"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154781"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154782"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F154783"] = "This fault is caused by 'Total Ingress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F1548"] = "This fault occurs when a small number of excess packets are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1549"] = "This fault occurs when a significant number of packet drops are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1550"] = "This fault occurs when a small number of packet drops are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1551"] = "This fault occurs when a significant number of excess packets are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1552"] = "This fault occurs when a small number of excess packets are detected by a configured and enabled Atomic Counter" + self.system_fault_code["F1553"] = "This fault is raised when the span policy failed to get deployed." + self.system_fault_code["F1554"] = "This fault is raised when the fabric span policy failed to get deployed due to missing Ctx." + self.system_fault_code["F1555"] = "This fault is raised when the fabric span policy failed to get deployed due to missing BD." + self.system_fault_code["F1556"] = "This fault is raised when the span policy failed to get deployed." + self.system_fault_code["F1557"] = "This fault is raised when the span policy failed to get deployed." + self.system_fault_code["F1558"] = "This fault is raised when the number of span sessions deployed exceeds the maximum number allowed ." + self.system_fault_code["F1559"] = "This fault is raised when there is a SPAN destination related configuration issue." + self.system_fault_code["F1560"] = "This fault is raised when there is a SPAN source group related configuration issue." + self.system_fault_code["F1561"] = "This fault is raised when there is an individual SPAN source related configuration issue." + self.system_fault_code["F1562"] = "This fault is raised when there is an individual RsSrcToPathEp related configuration issue." + self.system_fault_code["F1563"] = "None set." + self.system_fault_code["F1564"] = "None set." + self.system_fault_code["F1565"] = "This fault occurs when the L4-L7 service node configuration fails" + self.system_fault_code["F1566"] = "This fault occurs when the L4-L7 service node configuration fails" + self.system_fault_code["F1567"] = "This fault occurs when the L4-L7 service node configuration fails" + self.system_fault_code["F1569"] = "This fault occurs when a wrong type of card is inserted in the chassis" + self.system_fault_code["F1570"] = "This fault occurs when a Span Policy fails to deploy due to a missing or invalid source EPG" + self.system_fault_code["F1571"] = "This fault occurs when a Span Policy fails to deploy due to a missing or invalid destination EPG" + self.system_fault_code["F1572"] = "None set." + self.system_fault_code["F1573"] = "None set." + self.system_fault_code["F1574"] = "This fault occurs when a ntp provider in the ntp configuration on a controller has problems" + self.system_fault_code["F1582"] = "This fault occurs when running FPGA firmware version is not an expected version." + self.system_fault_code["F1583"] = "This fault occurs when running BIOS firmware is not an expected version." + self.system_fault_code["F159880"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159881"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159882"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159883"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159884"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159885"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159886"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159887"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F159896"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159897"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159898"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159899"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159900"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159901"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159902"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159903"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F159904"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159905"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159906"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159907"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159908"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159909"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159910"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159911"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F159912"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159913"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159914"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159915"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159916"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159917"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159918"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159919"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F159920"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159921"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159922"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159923"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159924"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159925"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159926"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159927"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F159928"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159929"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159930"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159931"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159932"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159933"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159934"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159935"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F159960"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159961"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159962"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159963"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159964"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159965"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159966"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159967"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F159968"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159969"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159970"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159971"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159972"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159973"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159974"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F159975"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F1600"] = "The object refers to an object that was not found." + self.system_fault_code["F160048"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160049"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160050"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160051"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160052"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160053"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160054"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160055"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F160064"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160065"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160066"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160067"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160068"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160069"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160070"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160071"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F160072"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160073"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160074"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160075"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160076"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160077"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160078"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160079"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F160080"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160081"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160082"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160083"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160084"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160085"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160086"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160087"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F160088"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160089"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160090"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160091"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160092"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160093"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160094"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160095"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F160096"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160097"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160098"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160099"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F1601"] = "The object refers to an object that was not found." + self.system_fault_code["F160100"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160101"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160102"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160103"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F160128"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160129"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160130"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160131"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160132"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160133"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160134"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160135"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F160136"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160137"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160138"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160139"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160140"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160141"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160142"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F160143"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F1603"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F1604"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F1606"] = "This fault is raised when issues are detected with portgroups learned from vCenter. E.g. missing EPg policy" + self.system_fault_code["F1613"] = "This fault occurs when the inband mgmt policy posted by the user is incorrect. The config issues indicate the exact reason" + self.system_fault_code["F1614"] = "The object refers to an object that was not found." + self.system_fault_code["F1615"] = "This fault occurs when the operational state of the ipv6 address state is changed to subnet-overlap/no primary/addr already" + self.system_fault_code["F1616"] = "This fault occurs when the operational state of the next hop is changed to down due to various config or operational" + self.system_fault_code["F1617"] = "The object refers to an object that was not found." + self.system_fault_code["F1629"] = "The object refers to an object that was not found." + self.system_fault_code["F1630"] = "The object refers to an object that was not found." + self.system_fault_code["F1631"] = "The object refers to an object that was not found." + self.system_fault_code["F1639"] = "The object refers to an object that was not found." + self.system_fault_code["F1640"] = "The object refers to an object that was not found." + self.system_fault_code["F16438"] = "This fault is raised when Subscribe Events Stage fails." + self.system_fault_code["F1648"] = "The object refers to an object that was not found." + self.system_fault_code["F1649"] = "This fault occurs when an operation on device package fails. The config issues indicate the exact reason for the error." + self.system_fault_code["F1651"] = "This fault occurs when export operation for techsupport or core files did not succeed." + self.system_fault_code["F1654"] = "The object refers to an object that was not found." + self.system_fault_code["F1655"] = "The object refers to an object that was not found." + self.system_fault_code["F1656"] = "The object refers to an object that was not found." + self.system_fault_code["F1657"] = "The object refers to an object that was not found." + self.system_fault_code["F1658"] = "The object refers to an object that was not found." + self.system_fault_code["F1659"] = "The object refers to an object that was not found." + self.system_fault_code["F1660"] = "The object refers to an object that was not found." + self.system_fault_code["F166024"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166025"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166026"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166027"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166028"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166029"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166030"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166031"] = "This fault is caused by 'Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166040"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166041"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166042"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166043"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166044"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166045"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166046"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166047"] = "This fault is caused by 'Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166048"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166049"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166050"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166051"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166052"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166053"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166054"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166055"] = "This fault is caused by 'Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166056"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166057"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166058"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166059"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166060"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166061"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166062"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166063"] = "This fault is caused by 'Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166064"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166065"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166066"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166067"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166068"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166069"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166070"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166071"] = "This fault is caused by 'Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166072"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166073"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166074"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166075"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166076"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166077"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166078"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166079"] = "This fault is caused by 'Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F1661"] = "The object refers to an object that was not found." + self.system_fault_code["F166104"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166105"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166106"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166107"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166108"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166109"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166110"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166111"] = "This fault is caused by 'Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166112"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166113"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166114"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166115"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166116"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166117"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166118"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166119"] = "This fault is caused by 'Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166192"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166193"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166194"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166195"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166196"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166197"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166198"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166199"] = "This fault is caused by 'Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F1662"] = "This fault occurs when the version of the Council Of Oracles Protocol (COOP) running on a leaf (citizen node) is determined" + self.system_fault_code["F166200"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166201"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166202"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166203"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166204"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166205"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166206"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166207"] = "This fault is caused by 'Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166208"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166209"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166210"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166211"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166212"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166213"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166214"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166215"] = "This fault is caused by 'Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166216"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166217"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166218"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166219"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166220"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166221"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166222"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166223"] = "This fault is caused by 'Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166256"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166257"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166258"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166259"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166260"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166261"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166262"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166263"] = "This fault is caused by 'Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F1663"] = "This fault occurs when the version of the Council Of Oracles Protocol (COOP) running on a spine (oracle node) is determined" + self.system_fault_code["F166312"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166313"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166314"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166315"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166316"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166317"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166318"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166319"] = "This fault is caused by 'Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166328"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166329"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166330"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166331"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166332"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166333"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166334"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166335"] = "This fault is caused by 'Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166336"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166337"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166338"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166339"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166340"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166341"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166342"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166343"] = "This fault is caused by 'Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166344"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166345"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166346"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166347"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166348"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166349"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166350"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166351"] = "This fault is caused by 'Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166352"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166353"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166354"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166355"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166356"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166357"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166358"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166359"] = "This fault is caused by 'Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166360"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166361"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166362"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166363"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166364"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166365"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166366"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166367"] = "This fault is caused by 'Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166392"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166393"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166394"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166395"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166396"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166397"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166398"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166399"] = "This fault is caused by 'Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F1664"] = "This fault occurs when the version of the Council Of Oracles Protocol (COOP) running on a leaf (citizen node) or spine" + self.system_fault_code["F166400"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166401"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166402"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166403"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166404"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166405"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166406"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166407"] = "This fault is caused by 'Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166480"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166481"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166482"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166483"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166484"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166485"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166486"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166487"] = "This fault is caused by 'Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F166488"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166489"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166490"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166491"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166492"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166493"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166494"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166495"] = "This fault is caused by 'Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166496"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166497"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166498"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166499"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F1665"] = "The object refers to an object that was not found." + self.system_fault_code["F166500"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166501"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166502"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166503"] = "This fault is caused by 'Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166504"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166505"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166506"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166507"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166508"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166509"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166510"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166511"] = "This fault is caused by 'Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F166544"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166545"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166546"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166547"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166548"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166549"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166550"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166551"] = "This fault is caused by 'Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F166600"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166601"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166602"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166603"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166604"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166605"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166606"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166607"] = "This fault is caused by 'Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F166616"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166617"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166618"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166619"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166620"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166621"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166622"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166623"] = "This fault is caused by 'Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F166624"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166625"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166626"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166627"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166628"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166629"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166630"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166631"] = "This fault is caused by 'Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F166632"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166633"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166634"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166635"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166636"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166637"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166638"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166639"] = "This fault is caused by 'Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F166640"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166641"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166642"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166643"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166644"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166645"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166646"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166647"] = "This fault is caused by 'Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F166648"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166649"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166650"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166651"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166652"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166653"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166654"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166655"] = "This fault is caused by 'Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F166680"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166681"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166682"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166683"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166684"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166685"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166686"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166687"] = "This fault is caused by 'Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F166688"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166689"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166690"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166691"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166692"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166693"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166694"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166695"] = "This fault is caused by 'Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F166768"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166769"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166770"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166771"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166772"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166773"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166774"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166775"] = "This fault is caused by 'Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F166776"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166777"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166778"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166779"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166780"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166781"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166782"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166783"] = "This fault is caused by 'Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F166784"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166785"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166786"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166787"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166788"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166789"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166790"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166791"] = "This fault is caused by 'Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F166792"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166793"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166794"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166795"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166796"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166797"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166798"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166799"] = "This fault is caused by 'Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F166832"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166833"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166834"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166835"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166836"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166837"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166838"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166839"] = "This fault is caused by 'Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F166888"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166889"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166890"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166891"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166892"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166893"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166894"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F166895"] = "This fault is caused by 'Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F1669"] = "This fault is raised when the SCVMM plugin encounters an exception in provisioning vmmCtrlrP." + self.system_fault_code["F166904"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166905"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166906"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166907"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166908"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166909"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166910"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166911"] = "This fault is caused by 'Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F166912"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166913"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166914"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166915"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166916"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166917"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166918"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166919"] = "This fault is caused by 'Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F166920"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166921"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166922"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166923"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166924"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166925"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166926"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166927"] = "This fault is caused by 'Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F166928"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166929"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166930"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166931"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166932"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166933"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166934"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166935"] = "This fault is caused by 'Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F166936"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166937"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166938"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166939"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166940"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166941"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166942"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166943"] = "This fault is caused by 'Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F166968"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166969"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166970"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166971"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166972"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166973"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166974"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166975"] = "This fault is caused by 'Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F166976"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166977"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166978"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166979"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166980"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166981"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166982"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F166983"] = "This fault is caused by 'Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F167056"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167057"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167058"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167059"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167060"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167061"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167062"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167063"] = "This fault is caused by 'Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F167064"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167065"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167066"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167067"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167068"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167069"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167070"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167071"] = "This fault is caused by 'Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F167072"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167073"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167074"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167075"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167076"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167077"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167078"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167079"] = "This fault is caused by 'Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F167080"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167081"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167082"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167083"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167084"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167085"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167086"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167087"] = "This fault is caused by 'Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F167120"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167121"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167122"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167123"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167124"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167125"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167126"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F167127"] = "This fault is caused by 'Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F1674"] = "The object refers to an object that was not found." + self.system_fault_code["F1676"] = "This fault is raised when the VMM Controller Agent is not able to communicate with the APIC." + self.system_fault_code["F1678"] = "The object refers to an object that was not found." + self.system_fault_code["F1680"] = "This fault occurs when either the total Atomic Counter or Latency rule reaches maximum programmable limit or an unsupported" + self.system_fault_code["F1686"] = "The object refers to an object that was not found." + self.system_fault_code["F1688"] = "This fault occurs when a transceiver is defective and unable to be used in the system" + self.system_fault_code["F1690"] = "This fault occurs when there is incomplete or incorrect configuration, intermittent system errors." + self.system_fault_code["F1691"] = "The object refers to an object that was not found." + self.system_fault_code["F1692"] = "The object refers to an object that was not found." + self.system_fault_code["F1693"] = "The object refers to an object that was not found." + self.system_fault_code["F1696"] = "This fault occurs when a port is set to epg and also a span destination which is invalid." + self.system_fault_code["F1698"] = "This fault is raised when there is an issue with respect to the OpFlex device" + self.system_fault_code["F1699"] = "This fault occurs when a ntp configuration on a switch has problems" + self.system_fault_code["F1700"] = "This fault occurs when a ntp configuration on a controller has problems" + self.system_fault_code["F1703"] = "The object refers to an object that was not found." + self.system_fault_code["F1706"] = "The object refers to an object that was not found." + self.system_fault_code["F1707"] = "The object refers to an object that was not found." + self.system_fault_code["F1712"] = "This fault occurs when an IP Address could not be allocated from the IP Address Pool." + self.system_fault_code["F1722"] = "The object refers to an object that was not found." + self.system_fault_code["F1726"] = "This fault occurs when the same IP address is configured on multiple nodes." + self.system_fault_code["F1729"] = "This fault occurs when the adjacency state is not up" + self.system_fault_code["F1731"] = "The object refers to an object that was not found." + self.system_fault_code["F177088"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177089"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177090"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177091"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177092"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177093"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177094"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177095"] = "This fault is caused by 'Storm Ctrl Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F177104"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177105"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177106"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177107"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177108"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177109"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177110"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177111"] = "This fault is caused by 'Storm Ctrl Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F177112"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177113"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177114"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177115"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177116"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177117"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177118"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177119"] = "This fault is caused by 'Storm Ctrl Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F177120"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177121"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177122"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177123"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177124"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177125"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177126"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177127"] = "This fault is caused by 'Storm Ctrl Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F177128"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177129"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177130"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177131"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177132"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177133"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177134"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177135"] = "This fault is caused by 'Storm Ctrl Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F177136"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177137"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177138"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177139"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177140"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177141"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177142"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177143"] = "This fault is caused by 'Storm Ctrl Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F177168"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177169"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177170"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177171"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177172"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177173"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177174"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177175"] = "This fault is caused by 'Storm Ctrl Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F177176"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177177"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177178"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177179"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177180"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177181"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177182"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177183"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F177256"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177257"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177258"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177259"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177260"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177261"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177262"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177263"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F177264"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177265"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177266"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177267"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177268"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177269"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177270"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177271"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F177272"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177273"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177274"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177275"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177276"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177277"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177278"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177279"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F177280"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177281"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177282"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177283"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177284"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177285"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177286"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177287"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F177320"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177321"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177322"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177323"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177324"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177325"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177326"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F177327"] = "This fault is caused by 'Storm Ctrl Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F1778"] = "The object refers to an object that was not found." + self.system_fault_code["F1781"] = "This fault occurs when the same node is configured with mulitple addresses." + self.system_fault_code["F1782"] = "This is a custom explanation for a relation fault." + self.system_fault_code["F1783"] = "This fault occurs when the system could not allocate an ip address for one or more nodes in the cluster. The configIssues" + self.system_fault_code["F1786"] = "The object refers to an object that was not found." + self.system_fault_code["F1787"] = "The object refers to an object that was not found." + self.system_fault_code["F1792"] = "This fault occurs when the number of non-self-originated LSAs from the neighbor is greater than the configured limit" + self.system_fault_code["F1793"] = "This fault occurs when the number of non-self-originated LSAs from the neighbor is greater than the configured limit" + self.system_fault_code["F1794"] = "This fault occurs when the optimized flood mode is ignored on the BD because of resource limitations. The current limit" + self.system_fault_code["F1798"] = "This fault occurs when the operational state of the ipv6 LL address state is changed to subnet-overlap/no primary/addr" + self.system_fault_code["F1799"] = "The object refers to an object that was not found." + self.system_fault_code["F1806"] = "The object refers to an object that was not found." + self.system_fault_code["F1807"] = "The object refers to an object that was not found." + self.system_fault_code["F1808"] = "The object refers to an object that was not found." + self.system_fault_code["F1809"] = "The object refers to an object that was not found." + self.system_fault_code["F1810"] = "The object refers to an object that was not found." + self.system_fault_code["F1811"] = "The object refers to an object that was not found." + self.system_fault_code["F1812"] = "The object refers to an object that was not found." + self.system_fault_code["F1813"] = "The object refers to an object that was not found." + self.system_fault_code["F1815"] = "This fault occurs when a transceiver is invalid or has hardware issues." + self.system_fault_code["F1816"] = "This fault usually occurs when protocol bring up on a VRF fails." + self.system_fault_code["F1817"] = "This fault is raised when the span policy failed to get deployed." + self.system_fault_code["F1819"] = "This fault occurs when an unsupported transceiver is used to attach to to the fabric link of a fex" + self.system_fault_code["F1820"] = "This fault occurs when the disk usage of a partiton increases beyond its threshold" + self.system_fault_code["F1821"] = "This fault occurs when the disk usage of a partiton increases beyond its threshold" + self.system_fault_code["F1822"] = "This fault occurs when the disk usage of a partiton increases beyond its threshold" + self.system_fault_code["F1823"] = "The object refers to an object that was not found." + self.system_fault_code["F1824"] = "This fault occurs when a controller is recognized as incompatible." + self.system_fault_code["F1827"] = "The object refers to an object that was not found." + self.system_fault_code["F1828"] = "The object refers to an object that was not found." + self.system_fault_code["F1830"] = "The object refers to an object that was not found." + self.system_fault_code["F1831"] = "The object refers to an object that was not found." + self.system_fault_code["F1832"] = "The object refers to an object that was not found." + self.system_fault_code["F1833"] = "The object refers to an object that was not found." + self.system_fault_code["F1834"] = "The object refers to an object that was not found." + self.system_fault_code["F1835"] = "The object refers to an object that was not found." + self.system_fault_code["F1836"] = "The object refers to an object that was not found." + self.system_fault_code["F1837"] = "The object refers to an object that was not found." + self.system_fault_code["F1838"] = "The object refers to an object that was not found." + self.system_fault_code["F1839"] = "The object refers to an object that was not found." + self.system_fault_code["F1840"] = "The object refers to an object that was not found." + self.system_fault_code["F1852"] = "The object refers to an object that was not found." + self.system_fault_code["F1853"] = "This fault occurs when the number of policies of this type exceed the supported fabric-wide limit." + self.system_fault_code["F1859"] = "The object refers to an object that was not found." + self.system_fault_code["F185984"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185985"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185986"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185987"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185988"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185989"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185990"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F185991"] = "This fault is caused by 'aged connections current value' statistical property crossing threshold level." + self.system_fault_code["F186000"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186001"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186002"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186003"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186004"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186005"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186006"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186007"] = "This fault is caused by 'aged connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186008"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186009"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186010"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186011"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186012"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186013"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186014"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186015"] = "This fault is caused by 'aged connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186016"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186017"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186018"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186019"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186020"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186021"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186022"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186023"] = "This fault is caused by 'aged connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186024"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186025"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186026"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186027"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186028"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186029"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186030"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186031"] = "This fault is caused by 'aged connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186032"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186033"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186034"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186035"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186036"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186037"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186038"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186039"] = "This fault is caused by 'aged connections average value' statistical property crossing threshold level." + self.system_fault_code["F186064"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186065"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186066"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186067"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186068"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186069"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186070"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186071"] = "This fault is caused by 'aged connections trend' statistical property crossing threshold level." + self.system_fault_code["F186072"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186073"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186074"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186075"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186076"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186077"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186078"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F186079"] = "This fault is caused by 'aged connections rate' statistical property crossing threshold level." + self.system_fault_code["F1861"] = "The object refers to an object that was not found." + self.system_fault_code["F186152"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186153"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186154"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186155"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186156"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186157"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186158"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186159"] = "This fault is caused by 'created connections current value' statistical property crossing threshold level." + self.system_fault_code["F186168"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186169"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186170"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186171"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186172"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186173"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186174"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186175"] = "This fault is caused by 'created connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186176"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186177"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186178"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186179"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186180"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186181"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186182"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186183"] = "This fault is caused by 'created connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186184"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186185"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186186"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186187"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186188"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186189"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186190"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186191"] = "This fault is caused by 'created connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186192"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186193"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186194"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186195"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186196"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186197"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186198"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186199"] = "This fault is caused by 'created connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F1862"] = "The object refers to an object that was not found." + self.system_fault_code["F186200"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186201"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186202"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186203"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186204"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186205"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186206"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186207"] = "This fault is caused by 'created connections average value' statistical property crossing threshold level." + self.system_fault_code["F186232"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186233"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186234"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186235"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186236"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186237"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186238"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186239"] = "This fault is caused by 'created connections trend' statistical property crossing threshold level." + self.system_fault_code["F186240"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186241"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186242"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186243"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186244"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186245"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186246"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F186247"] = "This fault is caused by 'created connections rate' statistical property crossing threshold level." + self.system_fault_code["F1863"] = "The object refers to an object that was not found." + self.system_fault_code["F186320"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186321"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186322"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186323"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186324"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186325"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186326"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186327"] = "This fault is caused by 'destroyed connections current value' statistical property crossing threshold level." + self.system_fault_code["F186336"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186337"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186338"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186339"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186340"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186341"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186342"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186343"] = "This fault is caused by 'destroyed connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186344"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186345"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186346"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186347"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186348"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186349"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186350"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186351"] = "This fault is caused by 'destroyed connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186352"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186353"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186354"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186355"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186356"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186357"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186358"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186359"] = "This fault is caused by 'destroyed connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186360"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186361"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186362"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186363"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186364"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186365"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186366"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186367"] = "This fault is caused by 'destroyed connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186368"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186369"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186370"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186371"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186372"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186373"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186374"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186375"] = "This fault is caused by 'destroyed connections average value' statistical property crossing threshold level." + self.system_fault_code["F186400"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186401"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186402"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186403"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186404"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186405"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186406"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186407"] = "This fault is caused by 'destroyed connections trend' statistical property crossing threshold level." + self.system_fault_code["F186408"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186409"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186410"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186411"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186412"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186413"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186414"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186415"] = "This fault is caused by 'destroyed connections rate' statistical property crossing threshold level." + self.system_fault_code["F186488"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186489"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186490"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186491"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186492"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186493"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186494"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186495"] = "This fault is caused by 'denied global limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F1865"] = "The object refers to an object that was not found." + self.system_fault_code["F186504"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186505"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186506"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186507"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186508"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186509"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186510"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186511"] = "This fault is caused by 'denied global limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186512"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186513"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186514"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186515"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186516"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186517"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186518"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186519"] = "This fault is caused by 'denied global limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186520"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186521"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186522"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186523"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186524"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186525"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186526"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186527"] = "This fault is caused by 'denied global limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186528"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186529"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186530"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186531"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186532"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186533"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186534"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186535"] = "This fault is caused by 'denied global limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186536"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186537"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186538"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186539"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186540"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186541"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186542"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186543"] = "This fault is caused by 'denied global limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186568"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186569"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186570"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186571"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186572"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186573"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186574"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186575"] = "This fault is caused by 'denied global limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186576"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186577"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186578"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186579"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186580"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186581"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186582"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186583"] = "This fault is caused by 'denied global limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186656"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186657"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186658"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186659"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186660"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186661"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186662"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186663"] = "This fault is caused by 'denied per port limit connections current value' statistical property crossing threshold level." + self.system_fault_code["F186672"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186673"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186674"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186675"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186676"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186677"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186678"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186679"] = "This fault is caused by 'denied per port limit connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F186680"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186681"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186682"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186683"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186684"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186685"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186686"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186687"] = "This fault is caused by 'denied per port limit connections periodic' statistical property crossing threshold level." + self.system_fault_code["F186688"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186689"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186690"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186691"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186692"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186693"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186694"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186695"] = "This fault is caused by 'denied per port limit connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F186696"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186697"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186698"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186699"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F1867"] = "This fault occurs when a fabric is in recovery mode" + self.system_fault_code["F186700"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186701"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186702"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186703"] = "This fault is caused by 'denied per port limit connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F186704"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186705"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186706"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186707"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186708"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186709"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186710"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186711"] = "This fault is caused by 'denied per port limit connections average value' statistical property crossing threshold level." + self.system_fault_code["F186736"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186737"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186738"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186739"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186740"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186741"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186742"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186743"] = "This fault is caused by 'denied per port limit connections trend' statistical property crossing threshold level." + self.system_fault_code["F186744"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186745"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186746"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186747"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186748"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186749"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186750"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186751"] = "This fault is caused by 'denied per port limit connections rate' statistical property crossing threshold level." + self.system_fault_code["F186824"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186825"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186826"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186827"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186828"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186829"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186830"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186831"] = "This fault is caused by 'invalid connection packets current value' statistical property crossing threshold level." + self.system_fault_code["F186840"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186841"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186842"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186843"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186844"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186845"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186846"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186847"] = "This fault is caused by 'invalid connection packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F186848"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186849"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186850"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186851"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186852"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186853"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186854"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186855"] = "This fault is caused by 'invalid connection packets periodic' statistical property crossing threshold level." + self.system_fault_code["F186856"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186857"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186858"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186859"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186860"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186861"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186862"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186863"] = "This fault is caused by 'invalid connection packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F186864"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186865"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186866"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186867"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186868"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186869"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186870"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186871"] = "This fault is caused by 'invalid connection packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F186872"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186873"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186874"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186875"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186876"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186877"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186878"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F186879"] = "This fault is caused by 'invalid connection packets average value' statistical property crossing threshold level." + self.system_fault_code["F1869"] = "None set." + self.system_fault_code["F186904"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186905"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186906"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186907"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186908"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186909"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186910"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186911"] = "This fault is caused by 'invalid connection packets trend' statistical property crossing threshold level." + self.system_fault_code["F186912"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186913"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186914"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186915"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186916"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186917"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186918"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186919"] = "This fault is caused by 'invalid connection packets rate' statistical property crossing threshold level." + self.system_fault_code["F186992"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186993"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186994"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186995"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186996"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186997"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186998"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F186999"] = "This fault is caused by 'invalid ftp SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187008"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187009"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187010"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187011"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187012"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187013"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187014"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187015"] = "This fault is caused by 'invalid ftp SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187016"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187017"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187018"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187019"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187020"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187021"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187022"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187023"] = "This fault is caused by 'invalid ftp SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187024"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187025"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187026"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187027"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187028"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187029"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187030"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187031"] = "This fault is caused by 'invalid ftp SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187032"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187033"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187034"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187035"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187036"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187037"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187038"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187039"] = "This fault is caused by 'invalid ftp SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187040"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187041"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187042"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187043"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187044"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187045"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187046"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187047"] = "This fault is caused by 'invalid ftp SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187072"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187073"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187074"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187075"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187076"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187077"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187078"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187079"] = "This fault is caused by 'invalid ftp SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187080"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187081"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187082"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187083"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187084"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187085"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187086"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187087"] = "This fault is caused by 'invalid ftp SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187160"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187161"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187162"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187163"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187164"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187165"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187166"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187167"] = "This fault is caused by 'invalid SYN ACK packets current value' statistical property crossing threshold level." + self.system_fault_code["F187176"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187177"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187178"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187179"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187180"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187181"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187182"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187183"] = "This fault is caused by 'invalid SYN ACK packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187184"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187185"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187186"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187187"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187188"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187189"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187190"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187191"] = "This fault is caused by 'invalid SYN ACK packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187192"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187193"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187194"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187195"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187196"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187197"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187198"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187199"] = "This fault is caused by 'invalid SYN ACK packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187200"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187201"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187202"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187203"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187204"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187205"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187206"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187207"] = "This fault is caused by 'invalid SYN ACK packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187208"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187209"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187210"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187211"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187212"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187213"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187214"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187215"] = "This fault is caused by 'invalid SYN ACK packets average value' statistical property crossing threshold level." + self.system_fault_code["F187240"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187241"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187242"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187243"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187244"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187245"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187246"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187247"] = "This fault is caused by 'invalid SYN ACK packets trend' statistical property crossing threshold level." + self.system_fault_code["F187248"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187249"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187250"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187251"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187252"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187253"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187254"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187255"] = "This fault is caused by 'invalid SYN ACK packets rate' statistical property crossing threshold level." + self.system_fault_code["F187328"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187329"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187330"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187331"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187332"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187333"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187334"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187335"] = "This fault is caused by 'invalid SYN packets current value' statistical property crossing threshold level." + self.system_fault_code["F187344"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187345"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187346"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187347"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187348"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187349"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187350"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187351"] = "This fault is caused by 'invalid SYN packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F187352"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187353"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187354"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187355"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187356"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187357"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187358"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187359"] = "This fault is caused by 'invalid SYN packets periodic' statistical property crossing threshold level." + self.system_fault_code["F187360"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187361"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187362"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187363"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187364"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187365"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187366"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187367"] = "This fault is caused by 'invalid SYN packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F187368"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187369"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187370"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187371"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187372"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187373"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187374"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187375"] = "This fault is caused by 'invalid SYN packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F187376"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187377"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187378"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187379"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187380"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187381"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187382"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187383"] = "This fault is caused by 'invalid SYN packets average value' statistical property crossing threshold level." + self.system_fault_code["F187408"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187409"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187410"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187411"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187412"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187413"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187414"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187415"] = "This fault is caused by 'invalid SYN packets trend' statistical property crossing threshold level." + self.system_fault_code["F187416"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187417"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187418"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187419"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187420"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187421"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187422"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F187423"] = "This fault is caused by 'invalid SYN packets rate' statistical property crossing threshold level." + self.system_fault_code["F188528"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188529"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188530"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188531"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188532"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188533"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188534"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188535"] = "This fault is caused by 'total accepted connections current value' statistical property crossing threshold level." + self.system_fault_code["F188544"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188545"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188546"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188547"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188548"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188549"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188550"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188551"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188552"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188553"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188554"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188555"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188556"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188557"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188558"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188559"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188560"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188561"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188562"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188563"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188564"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188565"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188566"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188567"] = "This fault is caused by 'total accepted connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188568"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188569"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188570"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188571"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188572"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188573"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188574"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188575"] = "This fault is caused by 'total accepted connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188576"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188577"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188578"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188579"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188580"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188581"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188582"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188583"] = "This fault is caused by 'total accepted connections average value' statistical property crossing threshold level." + self.system_fault_code["F188608"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188609"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188610"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188611"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188612"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188613"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188614"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188615"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188616"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188617"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188618"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188619"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188620"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188621"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188622"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188623"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F1887"] = "The object refers to an object that was not found." + self.system_fault_code["F1888"] = "This fault occurs when the native vlan is not configured on the interface but it is receiving MST (802.1s) BPDUs. It" + self.system_fault_code["F188864"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188865"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188866"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188867"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188868"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188869"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188870"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188871"] = "This fault is caused by 'total accepted connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F188872"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188873"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188874"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188875"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188876"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188877"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188878"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F188879"] = "This fault is caused by 'total accepted connections periodic' statistical property crossing threshold level." + self.system_fault_code["F1889"] = "This fault occurs when configuration import fails to decrypt secure fields." + self.system_fault_code["F188904"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188905"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188906"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188907"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188908"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188909"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188910"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188911"] = "This fault is caused by 'total accepted connections trend' statistical property crossing threshold level." + self.system_fault_code["F188912"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188913"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188914"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188915"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188916"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188917"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188918"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188919"] = "This fault is caused by 'total accepted connections rate' statistical property crossing threshold level." + self.system_fault_code["F188968"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188969"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188970"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188971"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188972"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188973"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188974"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188975"] = "This fault is caused by 'current active connections current value' statistical property crossing threshold level." + self.system_fault_code["F188976"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188977"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188978"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188979"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188980"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188981"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188982"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188983"] = "This fault is caused by 'current active connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F188984"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188985"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188986"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188987"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188988"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188989"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188990"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188991"] = "This fault is caused by 'current active connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F188992"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188993"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188994"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188995"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188996"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188997"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188998"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F188999"] = "This fault is caused by 'current active connections average value' statistical property crossing threshold level." + self.system_fault_code["F1890"] = "This fault typically occurs when the switch detects insufficient power for a card to power up and puts card in power denied" + self.system_fault_code["F189032"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189033"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189034"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189035"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189036"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189037"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189038"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F189039"] = "This fault is caused by 'current active connections trend' statistical property crossing threshold level." + self.system_fault_code["F1891"] = "The object refers to an object that was not found." + self.system_fault_code["F189208"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189209"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189210"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189211"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189212"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189213"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189214"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189215"] = "This fault is caused by 'total handled connections current value' statistical property crossing threshold level." + self.system_fault_code["F189224"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189225"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189226"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189227"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189228"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189229"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189230"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189231"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189232"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189233"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189234"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189235"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189236"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189237"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189238"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189239"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189240"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189241"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189242"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189243"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189244"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189245"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189246"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189247"] = "This fault is caused by 'total handled connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189248"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189249"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189250"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189251"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189252"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189253"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189254"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189255"] = "This fault is caused by 'total handled connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189256"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189257"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189258"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189259"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189260"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189261"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189262"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189263"] = "This fault is caused by 'total handled connections average value' statistical property crossing threshold level." + self.system_fault_code["F189288"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189289"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189290"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189291"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189292"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189293"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189294"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189295"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189296"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189297"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189298"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189299"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F1893"] = "This fault occurs when a leaf is marked as a BGP route reflector" + self.system_fault_code["F189300"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189301"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189302"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189303"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189544"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189545"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189546"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189547"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189548"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189549"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189550"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189551"] = "This fault is caused by 'total handled connections cumulative' statistical property crossing threshold level." + self.system_fault_code["F189552"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189553"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189554"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189555"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189556"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189557"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189558"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189559"] = "This fault is caused by 'total handled connections periodic' statistical property crossing threshold level." + self.system_fault_code["F189584"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189585"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189586"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189587"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189588"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189589"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189590"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189591"] = "This fault is caused by 'total handled connections trend' statistical property crossing threshold level." + self.system_fault_code["F189592"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189593"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189594"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189595"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189596"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189597"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189598"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189599"] = "This fault is caused by 'total handled connections rate' statistical property crossing threshold level." + self.system_fault_code["F189648"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189649"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189650"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189651"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189652"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189653"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189654"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189655"] = "This fault is caused by 'current reading connections current value' statistical property crossing threshold level." + self.system_fault_code["F189656"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189657"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189658"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189659"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189660"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189661"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189662"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189663"] = "This fault is caused by 'current reading connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189664"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189665"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189666"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189667"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189668"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189669"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189670"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189671"] = "This fault is caused by 'current reading connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189672"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189673"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189674"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189675"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189676"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189677"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189678"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189679"] = "This fault is caused by 'current reading connections average value' statistical property crossing threshold level." + self.system_fault_code["F189712"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189713"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189714"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189715"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189716"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189717"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189718"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189719"] = "This fault is caused by 'current reading connections trend' statistical property crossing threshold level." + self.system_fault_code["F189888"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189889"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189890"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189891"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189892"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189893"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189894"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189895"] = "This fault is caused by 'current waiting connections current value' statistical property crossing threshold level." + self.system_fault_code["F189896"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189897"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189898"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189899"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189900"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189901"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189902"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189903"] = "This fault is caused by 'current waiting connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F189904"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189905"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189906"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189907"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189908"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189909"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189910"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189911"] = "This fault is caused by 'current waiting connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F189912"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189913"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189914"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189915"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189916"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189917"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189918"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189919"] = "This fault is caused by 'current waiting connections average value' statistical property crossing threshold level." + self.system_fault_code["F189952"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189953"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189954"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189955"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189956"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189957"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189958"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F189959"] = "This fault is caused by 'current waiting connections trend' statistical property crossing threshold level." + self.system_fault_code["F190128"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190129"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190130"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190131"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190132"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190133"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190134"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190135"] = "This fault is caused by 'current writing connections current value' statistical property crossing threshold level." + self.system_fault_code["F190136"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190137"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190138"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190139"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190140"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190141"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190142"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190143"] = "This fault is caused by 'current writing connections minimum value' statistical property crossing threshold level." + self.system_fault_code["F190144"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190145"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190146"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190147"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190148"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190149"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190150"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190151"] = "This fault is caused by 'current writing connections maximum value' statistical property crossing threshold level." + self.system_fault_code["F190152"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190153"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190154"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190155"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190156"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190157"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190158"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190159"] = "This fault is caused by 'current writing connections average value' statistical property crossing threshold level." + self.system_fault_code["F190192"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190193"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190194"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190195"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190196"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190197"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190198"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190199"] = "This fault is caused by 'current writing connections trend' statistical property crossing threshold level." + self.system_fault_code["F190368"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190369"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190370"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190371"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190372"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190373"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190374"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190375"] = "This fault is caused by 'total requests current value' statistical property crossing threshold level." + self.system_fault_code["F190384"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190385"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190386"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190387"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190388"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190389"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190390"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190391"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190392"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190393"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190394"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190395"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190396"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190397"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190398"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190399"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F1904"] = "The object refers to an object that was not found." + self.system_fault_code["F190400"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190401"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190402"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190403"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190404"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190405"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190406"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190407"] = "This fault is caused by 'total requests minimum value' statistical property crossing threshold level." + self.system_fault_code["F190408"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190409"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190410"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190411"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190412"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190413"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190414"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190415"] = "This fault is caused by 'total requests maximum value' statistical property crossing threshold level." + self.system_fault_code["F190416"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190417"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190418"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190419"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190420"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190421"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190422"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190423"] = "This fault is caused by 'total requests average value' statistical property crossing threshold level." + self.system_fault_code["F190448"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190449"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190450"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190451"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190452"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190453"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190454"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190455"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190456"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190457"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190458"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190459"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190460"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190461"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190462"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190463"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F1905"] = "The object refers to an object that was not found." + self.system_fault_code["F1907"] = "This fault occurs when a port is set to up but the operational state is down" + self.system_fault_code["F190704"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190705"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190706"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190707"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190708"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190709"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190710"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190711"] = "This fault is caused by 'total requests cumulative' statistical property crossing threshold level." + self.system_fault_code["F190712"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190713"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190714"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190715"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190716"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190717"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190718"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190719"] = "This fault is caused by 'total requests periodic' statistical property crossing threshold level." + self.system_fault_code["F190744"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190745"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190746"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190747"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190748"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190749"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190750"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190751"] = "This fault is caused by 'total requests trend' statistical property crossing threshold level." + self.system_fault_code["F190752"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190753"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190754"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190755"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190756"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190757"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190758"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F190759"] = "This fault is caused by 'total requests rate' statistical property crossing threshold level." + self.system_fault_code["F1909"] = "The object refers to an object that was not found." + self.system_fault_code["F1911"] = "This fault occurs when a firewall syslog source refers to a syslog group containing more remote destinations than the firewall" + self.system_fault_code["F1912"] = "The object refers to an object that was not found." + self.system_fault_code["F191536"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191537"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191538"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191539"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191540"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191541"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191542"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191543"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F191544"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191545"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191546"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191547"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191548"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191549"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191550"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191551"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F191552"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191553"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191554"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191555"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191556"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191557"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191558"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191559"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F191560"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191561"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191562"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191563"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191564"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191565"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191566"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191567"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F191600"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191601"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191602"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191603"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191604"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191605"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191606"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F191607"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F1925"] = "This fault occurs when the IpCktEP configuration fails" + self.system_fault_code["F192760"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192761"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192762"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192763"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192764"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192765"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192766"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192767"] = "This fault is caused by 'Local L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192792"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192793"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192794"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192795"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192796"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192797"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192798"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192799"] = "This fault is caused by 'Local L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192800"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192801"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192802"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192803"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192804"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192805"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192806"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192807"] = "This fault is caused by 'Local L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192808"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192809"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192810"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192811"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192812"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192813"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192814"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192815"] = "This fault is caused by 'Local L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192840"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192841"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192842"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192843"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192844"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192845"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192846"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192847"] = "This fault is caused by 'Local L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F192928"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192929"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192930"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192931"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192932"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192933"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192934"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192935"] = "This fault is caused by 'Local L3 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F192960"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192961"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192962"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192963"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192964"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192965"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192966"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192967"] = "This fault is caused by 'Local L3 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F192968"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192969"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192970"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192971"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192972"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192973"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192974"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192975"] = "This fault is caused by 'Local L3 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F192976"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192977"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192978"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192979"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192980"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192981"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192982"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F192983"] = "This fault is caused by 'Local L3 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193008"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193009"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193010"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193011"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193012"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193013"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193014"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193015"] = "This fault is caused by 'Local L3 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193096"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193097"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193098"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193099"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193100"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193101"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193102"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193103"] = "This fault is caused by 'Local Multicast Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F193112"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193113"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193114"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193115"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193116"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193117"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193118"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193119"] = "This fault is caused by 'Local Multicast Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F193120"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193121"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193122"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193123"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193124"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193125"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193126"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193127"] = "This fault is caused by 'Local Multicast Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F193128"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193129"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193130"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193131"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193132"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193133"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193134"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193135"] = "This fault is caused by 'Local Multicast Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F193136"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193137"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193138"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193139"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193140"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193141"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193142"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193143"] = "This fault is caused by 'Local Multicast Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F193144"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193145"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193146"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193147"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193148"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193149"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193150"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193151"] = "This fault is caused by 'Local Multicast Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F193176"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193177"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193178"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193179"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193180"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193181"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193182"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193183"] = "This fault is caused by 'Local Multicast Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F193184"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193185"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193186"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193187"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193188"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193189"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193190"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193191"] = "This fault is caused by 'Local Multicast Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F193264"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193265"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193266"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193267"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193268"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193269"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193270"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193271"] = "This fault is caused by 'Policy Usage current value' statistical property crossing threshold level." + self.system_fault_code["F193280"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193281"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193282"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193283"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193284"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193285"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193286"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193287"] = "This fault is caused by 'Policy Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F193288"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193289"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193290"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193291"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193292"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193293"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193294"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193295"] = "This fault is caused by 'Policy Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F193296"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193297"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193298"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193299"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193300"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193301"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193302"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193303"] = "This fault is caused by 'Policy Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193304"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193305"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193306"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193307"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193308"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193309"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193310"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193311"] = "This fault is caused by 'Policy Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193312"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193313"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193314"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193315"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193316"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193317"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193318"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193319"] = "This fault is caused by 'Policy Usage average value' statistical property crossing threshold level." + self.system_fault_code["F193344"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193345"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193346"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193347"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193348"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193349"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193350"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193351"] = "This fault is caused by 'Policy Usage trend' statistical property crossing threshold level." + self.system_fault_code["F193352"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193353"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193354"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193355"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193356"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193357"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193358"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193359"] = "This fault is caused by 'Policy Usage rate' statistical property crossing threshold level." + self.system_fault_code["F193432"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193433"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193434"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193435"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193436"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193437"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193438"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193439"] = "This fault is caused by 'Router IP (v4 and v6) entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F193440"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193441"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193442"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193443"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193444"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193445"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193446"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193447"] = "This fault is caused by 'Router IP (v4 and v6) entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F193448"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193449"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193450"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193451"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193452"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193453"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193454"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193455"] = "This fault is caused by 'Router IP (v4 and v6) entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F193456"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193457"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193458"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193459"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193460"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193461"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193462"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193463"] = "This fault is caused by 'Router IP (v4 and v6) entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F193496"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193497"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193498"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193499"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193500"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193501"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193502"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193503"] = "This fault is caused by 'Router IP (v4 and v6) entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F193552"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193553"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193554"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193555"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193556"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193557"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193558"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193559"] = "This fault is caused by 'Total vlan entries current value' statistical property crossing threshold level." + self.system_fault_code["F193568"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193569"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193570"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193571"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193572"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193573"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193574"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193575"] = "This fault is caused by 'Total vlan entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F193576"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193577"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193578"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193579"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193580"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193581"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193582"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193583"] = "This fault is caused by 'Total vlan entries periodic' statistical property crossing threshold level." + self.system_fault_code["F193584"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193585"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193586"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193587"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193588"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193589"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193590"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193591"] = "This fault is caused by 'Total vlan entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F193592"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193593"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193594"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193595"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193596"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193597"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193598"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193599"] = "This fault is caused by 'Total vlan entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F193600"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193601"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193602"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193603"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193604"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193605"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193606"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193607"] = "This fault is caused by 'Total vlan entries average value' statistical property crossing threshold level." + self.system_fault_code["F193632"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193633"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193634"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193635"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193636"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193637"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193638"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193639"] = "This fault is caused by 'Total vlan entries trend' statistical property crossing threshold level." + self.system_fault_code["F193640"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193641"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193642"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193643"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193644"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193645"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193646"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F193647"] = "This fault is caused by 'Total vlan entries rate' statistical property crossing threshold level." + self.system_fault_code["F1940"] = "This fault occurs when the Power Supply Unit is in fail state" + self.system_fault_code["F195136"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195137"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195138"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195139"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195140"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195141"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195142"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195143"] = "This fault is caused by 'Local v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195168"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195169"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195170"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195171"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195172"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195173"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195174"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195175"] = "This fault is caused by 'Local v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195176"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195177"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195178"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195179"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195180"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195181"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195182"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195183"] = "This fault is caused by 'Local v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195184"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195185"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195186"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195187"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195188"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195189"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195190"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195191"] = "This fault is caused by 'Local v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195216"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195217"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195218"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195219"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195220"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195221"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195222"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195223"] = "This fault is caused by 'Local v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195304"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195305"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195306"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195307"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195308"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195309"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195310"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195311"] = "This fault is caused by 'Local v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F195336"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195337"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195338"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195339"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195340"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195341"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195342"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195343"] = "This fault is caused by 'Local v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F195344"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195345"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195346"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195347"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195348"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195349"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195350"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195351"] = "This fault is caused by 'Local v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F195352"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195353"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195354"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195355"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195356"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195357"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195358"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195359"] = "This fault is caused by 'Local v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F195384"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195385"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195386"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195387"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195388"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195389"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195390"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F195391"] = "This fault is caused by 'Local v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F1957"] = "This fault occurs when it operator is expected to approve, reject or erase a controller's serial number ." + self.system_fault_code["F19600"] = "This fault is raised when Event Unsubscribe Stage fails." + self.system_fault_code["F196568"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196569"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196570"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196571"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196572"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196573"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196574"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196575"] = "This fault is caused by 'Local L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196600"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196601"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196602"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196603"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196604"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196605"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196606"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196607"] = "This fault is caused by 'Local L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196608"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196609"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196610"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196611"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196612"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196613"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196614"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196615"] = "This fault is caused by 'Local L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196616"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196617"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196618"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196619"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196620"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196621"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196622"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196623"] = "This fault is caused by 'Local L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196648"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196649"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196650"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196651"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196652"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196653"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196654"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196655"] = "This fault is caused by 'Local L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196736"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196737"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196738"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196739"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196740"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196741"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196742"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196743"] = "This fault is caused by 'Local v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196768"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196769"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196770"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196771"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196772"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196773"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196774"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196775"] = "This fault is caused by 'Local v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196776"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196777"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196778"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196779"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196780"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196781"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196782"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196783"] = "This fault is caused by 'Local v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196784"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196785"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196786"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196787"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196788"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196789"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196790"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196791"] = "This fault is caused by 'Local v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196816"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196817"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196818"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196819"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196820"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196821"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196822"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196823"] = "This fault is caused by 'Local v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196904"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196905"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196906"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196907"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196908"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196909"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196910"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196911"] = "This fault is caused by 'Local v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F196936"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196937"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196938"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196939"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196940"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196941"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196942"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196943"] = "This fault is caused by 'Local v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F196944"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196945"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196946"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196947"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196948"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196949"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196950"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196951"] = "This fault is caused by 'Local v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F196952"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196953"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196954"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196955"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196956"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196957"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196958"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196959"] = "This fault is caused by 'Local v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F196984"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196985"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196986"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196987"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196988"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196989"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196990"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F196991"] = "This fault is caused by 'Local v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197072"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197073"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197074"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197075"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197076"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197077"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197078"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197079"] = "This fault is caused by 'Local Multicast Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197088"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197089"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197090"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197091"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197092"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197093"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197094"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197095"] = "This fault is caused by 'Local Multicast Endpoints capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197096"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197097"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197098"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197099"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197100"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197101"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197102"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197103"] = "This fault is caused by 'Local Multicast Endpoints capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197104"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197105"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197106"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197107"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197108"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197109"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197110"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197111"] = "This fault is caused by 'Local Multicast Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197112"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197113"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197114"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197115"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197116"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197117"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197118"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197119"] = "This fault is caused by 'Local Multicast Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197120"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197121"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197122"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197123"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197124"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197125"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197126"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197127"] = "This fault is caused by 'Local Multicast Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197152"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197153"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197154"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197155"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197156"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197157"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197158"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197159"] = "This fault is caused by 'Local Multicast Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197160"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197161"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197162"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197163"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197164"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197165"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197166"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197167"] = "This fault is caused by 'Local Multicast Endpoints capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197240"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197241"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197242"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197243"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197244"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197245"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197246"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197247"] = "This fault is caused by 'Policy Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197256"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197257"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197258"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197259"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197260"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197261"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197262"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197263"] = "This fault is caused by 'Policy Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197264"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197265"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197266"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197267"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197268"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197269"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197270"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197271"] = "This fault is caused by 'Policy Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197272"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197273"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197274"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197275"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197276"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197277"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197278"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197279"] = "This fault is caused by 'Policy Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197280"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197281"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197282"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197283"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197284"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197285"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197286"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197287"] = "This fault is caused by 'Policy Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197288"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197289"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197290"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197291"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197292"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197293"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197294"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197295"] = "This fault is caused by 'Policy Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197320"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197321"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197322"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197323"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197324"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197325"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197326"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197327"] = "This fault is caused by 'Policy Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197328"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197329"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197330"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197331"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197332"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197333"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197334"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197335"] = "This fault is caused by 'Policy Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F1974"] = "The object refers to an object that was not found." + self.system_fault_code["F197408"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197409"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197410"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197411"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197412"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197413"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197414"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197415"] = "This fault is caused by 'Vlan entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F197424"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197425"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197426"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197427"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197428"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197429"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197430"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197431"] = "This fault is caused by 'Vlan entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F197432"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197433"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197434"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197435"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197436"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197437"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197438"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197439"] = "This fault is caused by 'Vlan entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F197440"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197441"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197442"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197443"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197444"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197445"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197446"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197447"] = "This fault is caused by 'Vlan entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F197448"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197449"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197450"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197451"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197452"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197453"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197454"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197455"] = "This fault is caused by 'Vlan entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F197456"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197457"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197458"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197459"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197460"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197461"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197462"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197463"] = "This fault is caused by 'Vlan entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F197488"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197489"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197490"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197491"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197492"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197493"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197494"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197495"] = "This fault is caused by 'Vlan entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F197496"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197497"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197498"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197499"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F1975"] = "The object refers to an object that was not found." + self.system_fault_code["F197500"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197501"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197502"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F197503"] = "This fault is caused by 'Vlan entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F1976"] = "This fault occurs when there is incomplete or incorrect configuration, intermittent system errors." + self.system_fault_code["F1991"] = "The object refers to an object that was not found." + self.system_fault_code["F199144"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199145"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199146"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199147"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199148"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199149"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199150"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199151"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199152"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199153"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199154"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199155"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199156"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199157"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199158"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199159"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199160"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199161"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199162"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199163"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199164"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199165"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199166"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199167"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199168"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199169"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199170"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199171"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199172"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199173"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199174"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199175"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F1992"] = "The object refers to an object that was not found." + self.system_fault_code["F199208"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199209"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199210"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199211"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199212"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199213"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199214"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199215"] = "This fault is caused by 'External Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F199264"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199265"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199266"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199267"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199268"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199269"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199270"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199271"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage current value' statistical property crossing threshold" + self.system_fault_code["F199272"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199273"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199274"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199275"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199276"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199277"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199278"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199279"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage minimum value' statistical property crossing threshold" + self.system_fault_code["F199280"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199281"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199282"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199283"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199284"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199285"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199286"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199287"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage maximum value' statistical property crossing threshold" + self.system_fault_code["F199288"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199289"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199290"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199291"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199292"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199293"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199294"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F199295"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage average value' statistical property crossing threshold" + self.system_fault_code["F1993"] = "The object refers to an object that was not found." + self.system_fault_code["F199328"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199329"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199330"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199331"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199332"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199333"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199334"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F199335"] = "This fault is caused by 'Fabric Subnet (v4 and v6) prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F1999"] = "The object refers to an object that was not found." + self.system_fault_code["F2000"] = "The object refers to an object that was not found." + self.system_fault_code["F2001"] = "The object refers to an object that was not found." + self.system_fault_code["F2002"] = "The object refers to an object that was not found." + self.system_fault_code["F200304"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200305"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200306"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200307"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200308"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200309"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200310"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200311"] = "This fault is caused by 'Vlan Xlate Entries Usage current value' statistical property crossing threshold level." + self.system_fault_code["F200312"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200313"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200314"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200315"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200316"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200317"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200318"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200319"] = "This fault is caused by 'Vlan Xlate Entries Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F200320"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200321"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200322"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200323"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200324"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200325"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200326"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200327"] = "This fault is caused by 'Vlan Xlate Entries Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F200328"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200329"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200330"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200331"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200332"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200333"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200334"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200335"] = "This fault is caused by 'Vlan Xlate Entries Usage average value' statistical property crossing threshold level." + self.system_fault_code["F200368"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200369"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200370"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200371"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200372"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200373"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200374"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F200375"] = "This fault is caused by 'Vlan Xlate Entries Usage trend' statistical property crossing threshold level." + self.system_fault_code["F2008"] = "This fault occurs when DPP manager fails to activate a class due to hardware programming failure" + self.system_fault_code["F2009"] = "The object refers to an object that was not found." + self.system_fault_code["F2011"] = "The object refers to an object that was not found." + self.system_fault_code["F2012"] = "The object refers to an object that was not found." + self.system_fault_code["F2013"] = "The object refers to an object that was not found." + self.system_fault_code["F2014"] = "The object refers to an object that was not found." + self.system_fault_code["F2015"] = "The object refers to an object that was not found." + self.system_fault_code["F2016"] = "The object refers to an object that was not found." + self.system_fault_code["F2031"] = "The object refers to an object that was not found." + self.system_fault_code["F2041"] = "The object refers to an object that was not found." + self.system_fault_code["F2042"] = "The object refers to an object that was not found." + self.system_fault_code["F2043"] = "The object refers to an object that was not found." + self.system_fault_code["F2044"] = "The object refers to an object that was not found." + self.system_fault_code["F2060"] = "The object refers to an object that was not found." + self.system_fault_code["F206120"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206121"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206122"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206123"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206124"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206125"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206126"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206127"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206136"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206137"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206138"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206139"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206140"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206141"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206142"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206143"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206144"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206145"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206146"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206147"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206148"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206149"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206150"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206151"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206152"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206153"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206154"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206155"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206156"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206157"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206158"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206159"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206160"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206161"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206162"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206163"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206164"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206165"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206166"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206167"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206168"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206169"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206170"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206171"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206172"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206173"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206174"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206175"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206200"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206201"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206202"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206203"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206204"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206205"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206206"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206207"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206208"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206209"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206210"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206211"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206212"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206213"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206214"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206215"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206288"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206289"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206290"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206291"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206292"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206293"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206294"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206295"] = "This fault is caused by 'egress multicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206304"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206305"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206306"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206307"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206308"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206309"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206310"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206311"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206312"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206313"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206314"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206315"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206316"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206317"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206318"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206319"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206320"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206321"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206322"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206323"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206324"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206325"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206326"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206327"] = "This fault is caused by 'egress multicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206328"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206329"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206330"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206331"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206332"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206333"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206334"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206335"] = "This fault is caused by 'egress multicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206336"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206337"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206338"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206339"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206340"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206341"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206342"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206343"] = "This fault is caused by 'egress multicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206368"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206369"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206370"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206371"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206372"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206373"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206374"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206375"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206376"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206377"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206378"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206379"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206380"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206381"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206382"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206383"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206456"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206457"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206458"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206459"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206460"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206461"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206462"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206463"] = "This fault is caused by 'egress multicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206464"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206465"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206466"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206467"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206468"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206469"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206470"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206471"] = "This fault is caused by 'egress multicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206496"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206497"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206498"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206499"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F2065"] = "The object refers to an object that was not found." + self.system_fault_code["F206500"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206501"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206502"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206503"] = "This fault is caused by 'egress multicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206504"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206505"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206506"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206507"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206508"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206509"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206510"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206511"] = "This fault is caused by 'egress multicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206560"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206561"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206562"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206563"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206564"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206565"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206566"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206567"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206576"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206577"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206578"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206579"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206580"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206581"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206582"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206583"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206584"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206585"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206586"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206587"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206588"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206589"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206590"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206591"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206592"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206593"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206594"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206595"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206596"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206597"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206598"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206599"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206600"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206601"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206602"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206603"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206604"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206605"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206606"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206607"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206608"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206609"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206610"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206611"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206612"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206613"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206614"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206615"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206640"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206641"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206642"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206643"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206644"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206645"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206646"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206647"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206648"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206649"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206650"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206651"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206652"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206653"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206654"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206655"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2067"] = "The object refers to an object that was not found." + self.system_fault_code["F206728"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206729"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206730"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206731"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206732"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206733"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206734"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206735"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F206744"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206745"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206746"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206747"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206748"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206749"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206750"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206751"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206752"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206753"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206754"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206755"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206756"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206757"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206758"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206759"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206760"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206761"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206762"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206763"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206764"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206765"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206766"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206767"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F206768"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206769"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206770"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206771"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206772"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206773"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206774"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206775"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F206776"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206777"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206778"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206779"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206780"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206781"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206782"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206783"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F206808"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206809"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206810"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206811"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206812"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206813"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206814"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206815"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206816"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206817"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206818"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206819"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206820"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206821"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206822"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206823"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206896"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206897"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206898"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206899"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F2069"] = "This fault occurs when under a given l3extLNodeP either one of following conditions is present: - there is a node deployment" + self.system_fault_code["F206900"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206901"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206902"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206903"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F206904"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206905"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206906"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206907"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206908"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206909"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206910"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206911"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F206936"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206937"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206938"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206939"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206940"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206941"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206942"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206943"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F206944"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206945"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206946"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206947"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206948"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206949"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206950"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F206951"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F207000"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207001"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207002"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207003"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207004"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207005"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207006"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207007"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207016"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207017"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207018"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207019"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207020"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207021"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207022"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207023"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207024"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207025"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207026"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207027"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207028"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207029"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207030"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207031"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207032"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207033"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207034"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207035"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207036"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207037"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207038"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207039"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207040"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207041"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207042"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207043"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207044"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207045"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207046"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207047"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207048"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207049"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207050"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207051"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207052"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207053"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207054"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207055"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207080"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207081"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207082"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207083"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207084"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207085"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207086"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207087"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207088"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207089"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207090"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207091"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207092"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207093"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207094"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207095"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207168"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207169"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207170"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207171"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207172"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207173"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207174"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207175"] = "This fault is caused by 'egress multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207184"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207185"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207186"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207187"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207188"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207189"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207190"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207191"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207192"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207193"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207194"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207195"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207196"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207197"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207198"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207199"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207200"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207201"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207202"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207203"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207204"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207205"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207206"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207207"] = "This fault is caused by 'egress multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207208"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207209"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207210"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207211"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207212"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207213"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207214"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207215"] = "This fault is caused by 'egress multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207216"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207217"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207218"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207219"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207220"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207221"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207222"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207223"] = "This fault is caused by 'egress multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207248"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207249"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207250"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207251"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207252"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207253"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207254"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207255"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207256"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207257"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207258"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207259"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207260"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207261"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207262"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207263"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207336"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207337"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207338"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207339"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207340"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207341"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207342"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207343"] = "This fault is caused by 'egress multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207344"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207345"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207346"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207347"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207348"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207349"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207350"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207351"] = "This fault is caused by 'egress multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207376"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207377"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207378"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207379"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207380"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207381"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207382"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207383"] = "This fault is caused by 'egress multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207384"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207385"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207386"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207387"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207388"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207389"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207390"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207391"] = "This fault is caused by 'egress multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207440"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207441"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207442"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207443"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207444"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207445"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207446"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207447"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207456"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207457"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207458"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207459"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207460"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207461"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207462"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207463"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207464"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207465"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207466"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207467"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207468"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207469"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207470"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207471"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207472"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207473"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207474"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207475"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207476"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207477"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207478"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207479"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207480"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207481"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207482"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207483"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207484"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207485"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207486"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207487"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207488"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207489"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207490"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207491"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207492"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207493"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207494"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207495"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207520"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207521"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207522"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207523"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207524"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207525"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207526"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207527"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207528"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207529"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207530"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207531"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207532"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207533"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207534"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207535"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207608"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207609"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207610"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207611"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207612"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207613"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207614"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207615"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F207624"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207625"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207626"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207627"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207628"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207629"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207630"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207631"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207632"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207633"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207634"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207635"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207636"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207637"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207638"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207639"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207640"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207641"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207642"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207643"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207644"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207645"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207646"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207647"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F207648"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207649"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207650"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207651"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207652"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207653"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207654"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207655"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F207656"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207657"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207658"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207659"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207660"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207661"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207662"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207663"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F207688"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207689"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207690"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207691"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207692"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207693"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207694"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207695"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207696"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207697"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207698"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207699"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207700"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207701"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207702"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207703"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207776"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207777"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207778"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207779"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207780"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207781"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207782"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207783"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F207784"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207785"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207786"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207787"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207788"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207789"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207790"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207791"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F207816"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207817"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207818"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207819"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207820"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207821"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207822"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207823"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F207824"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207825"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207826"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207827"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207828"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207829"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207830"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207831"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F207952"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207953"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207954"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207955"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207956"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207957"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207958"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207959"] = "This fault is caused by '1 minute idle CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F207960"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207961"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207962"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207963"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207964"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207965"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207966"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207967"] = "This fault is caused by '1 minute idle CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F207968"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207969"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207970"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207971"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207972"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207973"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207974"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207975"] = "This fault is caused by '1 minute idle CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F207976"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207977"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207978"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207979"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207980"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207981"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207982"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F207983"] = "This fault is caused by '1 minute idle CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208016"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208017"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208018"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208019"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208020"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208021"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208022"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208023"] = "This fault is caused by '1 minute idle CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208072"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208073"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208074"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208075"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208076"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208077"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208078"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208079"] = "This fault is caused by '1 minute kernel CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208080"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208081"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208082"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208083"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208084"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208085"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208086"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208087"] = "This fault is caused by '1 minute kernel CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208088"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208089"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208090"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208091"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208092"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208093"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208094"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208095"] = "This fault is caused by '1 minute kernel CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208096"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208097"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208098"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208099"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F2081"] = "This fault is raised when issues are detected with security group learned from vShield/NSX." + self.system_fault_code["F208100"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208101"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208102"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208103"] = "This fault is caused by '1 minute kernel CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208136"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208137"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208138"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208139"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208140"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208141"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208142"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208143"] = "This fault is caused by '1 minute kernel CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208192"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208193"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208194"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208195"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208196"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208197"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208198"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208199"] = "This fault is caused by '1 minute user CPU average current value' statistical property crossing threshold level." + self.system_fault_code["F208200"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208201"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208202"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208203"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208204"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208205"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208206"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208207"] = "This fault is caused by '1 minute user CPU average minimum value' statistical property crossing threshold level." + self.system_fault_code["F208208"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208209"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208210"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208211"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208212"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208213"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208214"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208215"] = "This fault is caused by '1 minute user CPU average maximum value' statistical property crossing threshold level." + self.system_fault_code["F208216"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208217"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208218"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208219"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208220"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208221"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208222"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208223"] = "This fault is caused by '1 minute user CPU average average value' statistical property crossing threshold level." + self.system_fault_code["F208256"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208257"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208258"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208259"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208260"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208261"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208262"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F208263"] = "This fault is caused by '1 minute user CPU average trend' statistical property crossing threshold level." + self.system_fault_code["F2100"] = "The object refers to an object that was not found." + self.system_fault_code["F2105"] = "The object refers to an object that was not found." + self.system_fault_code["F2107"] = "This fault occurs when Data Plane Policer policy fails." + self.system_fault_code["F2108"] = "This fault occurs when a image is being replicated across all ifcs" + self.system_fault_code["F2109"] = "This fault occurs when a image is not synced across all ifcs" + self.system_fault_code["F2110"] = "The object refers to an object that was not found." + self.system_fault_code["F2111"] = "The object refers to an object that was not found." + self.system_fault_code["F2121"] = "This fault occurs when a virtual Port Channel (vPC) policy is created but nodes are not part of same zone." + self.system_fault_code["F2123"] = "The object refers to an object that was not found." + self.system_fault_code["F2132"] = "This fault is raised when issues are detected with security group learned from vShield/NSX." + self.system_fault_code["F2133"] = "This fault is raised when multiple security groups match the same VNic." + self.system_fault_code["F2145"] = "The object refers to an object that was not found." + self.system_fault_code["F2147"] = "The object refers to an object that was not found." + self.system_fault_code["F2148"] = "The object refers to an object that was not found." + self.system_fault_code["F2149"] = "The object refers to an object that was not found." + self.system_fault_code["F2167"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2168"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2169"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2170"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2185"] = "The object refers to an object that was not found." + self.system_fault_code["F2190"] = "This fault is raised when the configured node role doesn't match the role advertized by the node" + self.system_fault_code["F2194"] = "This fault occurs when deployment of policy to another process fails." + self.system_fault_code["F221656"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221657"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221658"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221659"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221660"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221661"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221662"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221663"] = "This fault is caused by 'policy dropped multicast/broadcast packets current value' statistical property crossing threshold" + self.system_fault_code["F221672"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221673"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221674"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221675"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221676"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221677"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221678"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221679"] = "This fault is caused by 'policy dropped multicast/broadcast packets cumulative' statistical property crossing threshold" + self.system_fault_code["F221680"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221681"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221682"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221683"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221684"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221685"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221686"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221687"] = "This fault is caused by 'policy dropped multicast/broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221688"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221689"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221690"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221691"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221692"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221693"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221694"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221695"] = "This fault is caused by 'policy dropped multicast/broadcast packets minimum value' statistical property crossing threshold" + self.system_fault_code["F221696"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221697"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221698"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221699"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221700"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221701"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221702"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221703"] = "This fault is caused by 'policy dropped multicast/broadcast packets maximum value' statistical property crossing threshold" + self.system_fault_code["F221704"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221705"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221706"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221707"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221708"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221709"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221710"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221711"] = "This fault is caused by 'policy dropped multicast/broadcast packets average value' statistical property crossing threshold" + self.system_fault_code["F221736"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221737"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221738"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221739"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221740"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221741"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221742"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221743"] = "This fault is caused by 'policy dropped multicast/broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221744"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221745"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221746"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221747"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221748"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221749"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221750"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221751"] = "This fault is caused by 'policy dropped multicast/broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221824"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221825"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221826"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221827"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221828"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221829"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221830"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221831"] = "This fault is caused by 'policy dropped unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F221840"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221841"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221842"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221843"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221844"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221845"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221846"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221847"] = "This fault is caused by 'policy dropped unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F221848"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221849"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221850"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221851"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221852"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221853"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221854"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221855"] = "This fault is caused by 'policy dropped unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F221856"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221857"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221858"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221859"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221860"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221861"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221862"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221863"] = "This fault is caused by 'policy dropped unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F221864"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221865"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221866"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221867"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221868"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221869"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221870"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221871"] = "This fault is caused by 'policy dropped unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F221872"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221873"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221874"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221875"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221876"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221877"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221878"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221879"] = "This fault is caused by 'policy dropped unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F221904"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221905"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221906"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221907"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221908"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221909"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221910"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221911"] = "This fault is caused by 'policy dropped unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F221912"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221913"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221914"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221915"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221916"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221917"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221918"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F221919"] = "This fault is caused by 'policy dropped unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F222432"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222433"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222434"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222435"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222436"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222437"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222438"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222439"] = "This fault is caused by 'Egress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F222448"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222449"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222450"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222451"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222452"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222453"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222454"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222455"] = "This fault is caused by 'Egress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F222456"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222457"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222458"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222459"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222460"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222461"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222462"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222463"] = "This fault is caused by 'Egress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F222464"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222465"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222466"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222467"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222468"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222469"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222470"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222471"] = "This fault is caused by 'Egress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F222472"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222473"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222474"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222475"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222476"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222477"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222478"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222479"] = "This fault is caused by 'Egress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F222480"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222481"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222482"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222483"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222484"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222485"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222486"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222487"] = "This fault is caused by 'Egress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F222512"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222513"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222514"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222515"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222516"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222517"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222518"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222519"] = "This fault is caused by 'Egress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F222520"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222521"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222522"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222523"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222524"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222525"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222526"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F222527"] = "This fault is caused by 'Egress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2226"] = "The object refers to an object that was not found." + self.system_fault_code["F222600"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222601"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222602"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222603"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222604"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222605"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222606"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222607"] = "This fault is caused by 'Egress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F222608"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222609"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222610"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222611"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222612"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222613"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222614"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222615"] = "This fault is caused by 'Egress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222616"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222617"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222618"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222619"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222620"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222621"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222622"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222623"] = "This fault is caused by 'Egress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222624"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222625"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222626"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222627"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222628"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222629"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222630"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222631"] = "This fault is caused by 'Egress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F222664"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222665"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222666"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222667"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222668"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222669"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222670"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222671"] = "This fault is caused by 'Egress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F222720"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222721"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222722"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222723"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222724"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222725"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222726"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222727"] = "This fault is caused by 'Egress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F222736"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222737"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222738"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222739"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222740"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222741"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222742"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222743"] = "This fault is caused by 'Egress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F222744"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222745"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222746"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222747"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222748"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222749"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222750"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222751"] = "This fault is caused by 'Egress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F222752"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222753"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222754"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222755"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222756"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222757"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222758"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222759"] = "This fault is caused by 'Egress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F222760"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222761"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222762"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222763"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222764"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222765"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222766"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222767"] = "This fault is caused by 'Egress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F222768"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222769"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222770"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222771"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222772"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222773"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222774"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222775"] = "This fault is caused by 'Egress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F222800"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222801"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222802"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222803"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222804"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222805"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222806"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222807"] = "This fault is caused by 'Egress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F222808"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222809"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222810"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222811"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222812"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222813"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222814"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222815"] = "This fault is caused by 'Egress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F222888"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222889"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222890"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222891"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222892"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222893"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222894"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222895"] = "This fault is caused by 'Egress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F222896"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222897"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222898"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222899"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F2229"] = "The object refers to an object that was not found." + self.system_fault_code["F222900"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222901"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222902"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222903"] = "This fault is caused by 'Egress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F222904"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222905"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222906"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222907"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222908"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222909"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222910"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222911"] = "This fault is caused by 'Egress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F222912"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222913"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222914"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222915"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222916"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222917"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222918"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222919"] = "This fault is caused by 'Egress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F222952"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222953"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222954"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222955"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222956"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222957"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222958"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F222959"] = "This fault is caused by 'Egress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223008"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223009"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223010"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223011"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223012"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223013"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223014"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223015"] = "This fault is caused by 'Egress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223024"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223025"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223026"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223027"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223028"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223029"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223030"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223031"] = "This fault is caused by 'Egress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223032"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223033"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223034"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223035"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223036"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223037"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223038"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223039"] = "This fault is caused by 'Egress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223040"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223041"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223042"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223043"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223044"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223045"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223046"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223047"] = "This fault is caused by 'Egress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223048"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223049"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223050"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223051"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223052"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223053"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223054"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223055"] = "This fault is caused by 'Egress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223056"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223057"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223058"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223059"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223060"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223061"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223062"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223063"] = "This fault is caused by 'Egress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223088"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223089"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223090"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223091"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223092"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223093"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223094"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223095"] = "This fault is caused by 'Egress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223096"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223097"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223098"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223099"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223100"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223101"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223102"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223103"] = "This fault is caused by 'Egress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223176"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223177"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223178"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223179"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223180"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223181"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223182"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223183"] = "This fault is caused by 'Egress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223184"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223185"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223186"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223187"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223188"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223189"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223190"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223191"] = "This fault is caused by 'Egress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223192"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223193"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223194"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223195"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223196"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223197"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223198"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223199"] = "This fault is caused by 'Egress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F2232"] = "The object refers to an object that was not found." + self.system_fault_code["F223200"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223201"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223202"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223203"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223204"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223205"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223206"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223207"] = "This fault is caused by 'Egress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223240"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223241"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223242"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223243"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223244"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223245"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223246"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223247"] = "This fault is caused by 'Egress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223296"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223297"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223298"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223299"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223300"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223301"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223302"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223303"] = "This fault is caused by 'Egress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223312"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223313"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223314"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223315"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223316"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223317"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223318"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223319"] = "This fault is caused by 'Egress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223320"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223321"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223322"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223323"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223324"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223325"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223326"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223327"] = "This fault is caused by 'Egress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223328"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223329"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223330"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223331"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223332"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223333"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223334"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223335"] = "This fault is caused by 'Egress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223336"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223337"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223338"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223339"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223340"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223341"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223342"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223343"] = "This fault is caused by 'Egress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223344"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223345"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223346"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223347"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223348"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223349"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223350"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223351"] = "This fault is caused by 'Egress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223376"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223377"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223378"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223379"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223380"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223381"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223382"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223383"] = "This fault is caused by 'Egress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223384"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223385"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223386"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223387"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223388"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223389"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223390"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223391"] = "This fault is caused by 'Egress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2234"] = "The object refers to an object that was not found." + self.system_fault_code["F223464"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223465"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223466"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223467"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223468"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223469"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223470"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223471"] = "This fault is caused by 'Egress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F223472"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223473"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223474"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223475"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223476"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223477"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223478"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223479"] = "This fault is caused by 'Egress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223480"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223481"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223482"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223483"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223484"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223485"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223486"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223487"] = "This fault is caused by 'Egress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223488"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223489"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223490"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223491"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223492"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223493"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223494"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F223495"] = "This fault is caused by 'Egress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F2235"] = "The object refers to an object that was not found." + self.system_fault_code["F223528"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223529"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223530"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223531"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223532"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223533"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223534"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223535"] = "This fault is caused by 'Egress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F223584"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223585"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223586"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223587"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223588"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223589"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223590"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223591"] = "This fault is caused by 'Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F223600"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223601"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223602"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223603"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223604"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223605"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223606"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223607"] = "This fault is caused by 'Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F223608"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223609"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223610"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223611"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223612"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223613"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223614"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223615"] = "This fault is caused by 'Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F223616"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223617"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223618"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223619"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223620"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223621"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223622"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223623"] = "This fault is caused by 'Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F223624"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223625"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223626"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223627"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223628"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223629"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223630"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223631"] = "This fault is caused by 'Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F223632"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223633"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223634"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223635"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223636"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223637"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223638"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223639"] = "This fault is caused by 'Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F223664"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223665"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223666"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223667"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223668"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223669"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223670"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223671"] = "This fault is caused by 'Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F223672"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223673"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223674"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223675"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223676"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223677"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223678"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223679"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F223752"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223753"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223754"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223755"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223756"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223757"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223758"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223759"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F223760"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223761"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223762"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223763"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223764"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223765"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223766"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223767"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F223768"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223769"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223770"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223771"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223772"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223773"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223774"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223775"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F223776"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223777"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223778"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223779"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223780"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223781"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223782"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F223783"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F2238"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F223816"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223817"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223818"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223819"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223820"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223821"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223822"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223823"] = "This fault is caused by 'Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F223872"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223873"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223874"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223875"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223876"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223877"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223878"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223879"] = "This fault is caused by 'Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F223888"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223889"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223890"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223891"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223892"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223893"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223894"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223895"] = "This fault is caused by 'Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F223896"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223897"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223898"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223899"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F2239"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F223900"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223901"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223902"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223903"] = "This fault is caused by 'Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F223904"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223905"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223906"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223907"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223908"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223909"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223910"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223911"] = "This fault is caused by 'Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F223912"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223913"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223914"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223915"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223916"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223917"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223918"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223919"] = "This fault is caused by 'Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F223920"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223921"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223922"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223923"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223924"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223925"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223926"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223927"] = "This fault is caused by 'Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F223952"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223953"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223954"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223955"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223956"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223957"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223958"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223959"] = "This fault is caused by 'Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F223960"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223961"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223962"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223963"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223964"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223965"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223966"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F223967"] = "This fault is caused by 'Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224040"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224041"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224042"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224043"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224044"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224045"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224046"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224047"] = "This fault is caused by 'Ingress Policer Allowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224048"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224049"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224050"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224051"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224052"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224053"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224054"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224055"] = "This fault is caused by 'Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224056"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224057"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224058"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224059"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224060"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224061"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224062"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224063"] = "This fault is caused by 'Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224064"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224065"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224066"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224067"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224068"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224069"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224070"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224071"] = "This fault is caused by 'Ingress Policer Allowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224104"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224105"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224106"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224107"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224108"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224109"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224110"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224111"] = "This fault is caused by 'Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224160"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224161"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224162"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224163"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224164"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224165"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224166"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224167"] = "This fault is caused by 'Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F224176"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224177"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224178"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224179"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224180"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224181"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224182"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224183"] = "This fault is caused by 'Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F224184"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224185"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224186"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224187"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224188"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224189"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224190"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224191"] = "This fault is caused by 'Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F224192"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224193"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224194"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224195"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224196"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224197"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224198"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224199"] = "This fault is caused by 'Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F224200"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224201"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224202"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224203"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224204"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224205"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224206"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224207"] = "This fault is caused by 'Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F224208"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224209"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224210"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224211"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224212"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224213"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224214"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224215"] = "This fault is caused by 'Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F224240"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224241"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224242"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224243"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224244"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224245"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224246"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224247"] = "This fault is caused by 'Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F224248"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224249"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224250"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224251"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224252"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224253"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224254"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224255"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F224328"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224329"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224330"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224331"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224332"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224333"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224334"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224335"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F224336"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224337"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224338"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224339"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224340"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224341"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224342"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224343"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224344"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224345"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224346"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224347"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224348"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224349"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224350"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224351"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224352"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224353"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224354"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224355"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224356"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224357"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224358"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224359"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F224392"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224393"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224394"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224395"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224396"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224397"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224398"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224399"] = "This fault is caused by 'Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F224448"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224449"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224450"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224451"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224452"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224453"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224454"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224455"] = "This fault is caused by 'Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F224464"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224465"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224466"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224467"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224468"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224469"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224470"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224471"] = "This fault is caused by 'Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F224472"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224473"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224474"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224475"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224476"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224477"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224478"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224479"] = "This fault is caused by 'Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F224480"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224481"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224482"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224483"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224484"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224485"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224486"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224487"] = "This fault is caused by 'Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F224488"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224489"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224490"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224491"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224492"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224493"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224494"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224495"] = "This fault is caused by 'Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F224496"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224497"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224498"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224499"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224500"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224501"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224502"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224503"] = "This fault is caused by 'Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F224528"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224529"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224530"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224531"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224532"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224533"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224534"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224535"] = "This fault is caused by 'Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F224536"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224537"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224538"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224539"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224540"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224541"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224542"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224543"] = "This fault is caused by 'Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F224616"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224617"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224618"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224619"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224620"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224621"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224622"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224623"] = "This fault is caused by 'Ingress Policer Dropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F224624"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224625"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224626"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224627"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224628"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224629"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224630"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224631"] = "This fault is caused by 'Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F224632"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224633"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224634"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224635"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224636"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224637"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224638"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224639"] = "This fault is caused by 'Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F224640"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224641"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224642"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224643"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224644"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224645"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224646"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224647"] = "This fault is caused by 'Ingress Policer Dropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F224680"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224681"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224682"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224683"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224684"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224685"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224686"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F224687"] = "This fault is caused by 'Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2247"] = "This fault is raised when the trunk Endpoint Group cannot be deployed due to a missing or invalid configuration." + self.system_fault_code["F2250"] = "The object refers to an object that was not found." + self.system_fault_code["F2251"] = "The object refers to an object that was not found." + self.system_fault_code["F225880"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225881"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225882"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225883"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225884"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225885"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225886"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225887"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F225896"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225897"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225898"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225899"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225900"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225901"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225902"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225903"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F225904"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225905"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225906"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225907"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225908"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225909"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225910"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225911"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F225912"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225913"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225914"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225915"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225916"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225917"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225918"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225919"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F225920"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225921"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225922"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225923"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225924"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225925"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225926"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225927"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F225928"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225929"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225930"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225931"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225932"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225933"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225934"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225935"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F225960"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225961"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225962"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225963"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225964"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225965"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225966"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225967"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F225968"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225969"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225970"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225971"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225972"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225973"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225974"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F225975"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226048"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226049"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226050"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226051"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226052"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226053"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226054"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226055"] = "This fault is caused by 'hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226064"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226065"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226066"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226067"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226068"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226069"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226070"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226071"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226072"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226073"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226074"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226075"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226076"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226077"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226078"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226079"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226080"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226081"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226082"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226083"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226084"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226085"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226086"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226087"] = "This fault is caused by 'hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226088"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226089"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226090"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226091"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226092"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226093"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226094"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226095"] = "This fault is caused by 'hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226096"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226097"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226098"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226099"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226100"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226101"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226102"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226103"] = "This fault is caused by 'hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226128"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226129"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226130"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226131"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226132"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226133"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226134"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226135"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226136"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226137"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226138"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226139"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226140"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226141"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226142"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226143"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226216"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226217"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226218"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226219"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226220"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226221"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226222"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226223"] = "This fault is caused by 'hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226224"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226225"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226226"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226227"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226228"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226229"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226230"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226231"] = "This fault is caused by 'hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226256"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226257"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226258"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226259"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226260"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226261"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226262"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226263"] = "This fault is caused by 'hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226264"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226265"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226266"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226267"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226268"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226269"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226270"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226271"] = "This fault is caused by 'hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226320"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226321"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226322"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226323"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226324"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226325"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226326"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226327"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226336"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226337"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226338"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226339"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226340"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226341"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226342"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226343"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226344"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226345"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226346"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226347"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226348"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226349"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226350"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226351"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226352"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226353"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226354"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226355"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226356"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226357"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226358"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226359"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226360"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226361"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226362"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226363"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226364"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226365"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226366"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226367"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226368"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226369"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226370"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226371"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226372"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226373"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226374"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226375"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226400"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226401"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226402"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226403"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226404"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226405"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226406"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226407"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226408"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226409"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226410"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226411"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226412"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226413"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226414"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226415"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226488"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226489"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226490"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226491"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226492"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226493"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226494"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226495"] = "This fault is caused by 'reverse hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F226504"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226505"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226506"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226507"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226508"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226509"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226510"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226511"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226512"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226513"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226514"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226515"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226516"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226517"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226518"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226519"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226520"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226521"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226522"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226523"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226524"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226525"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226526"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226527"] = "This fault is caused by 'reverse hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F226528"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226529"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226530"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226531"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226532"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226533"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226534"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226535"] = "This fault is caused by 'reverse hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F226536"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226537"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226538"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226539"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226540"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226541"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226542"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226543"] = "This fault is caused by 'reverse hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F226568"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226569"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226570"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226571"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226572"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226573"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226574"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226575"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226576"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226577"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226578"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226579"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226580"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226581"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226582"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226583"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226656"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226657"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226658"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226659"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226660"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226661"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226662"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226663"] = "This fault is caused by 'reverse hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F226664"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226665"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226666"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226667"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226668"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226669"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226670"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226671"] = "This fault is caused by 'reverse hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F226696"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226697"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226698"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226699"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226700"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226701"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226702"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226703"] = "This fault is caused by 'reverse hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F226704"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226705"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226706"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226707"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226708"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226709"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226710"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F226711"] = "This fault is caused by 'reverse hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F2274"] = "The object refers to an object that was not found." + self.system_fault_code["F2275"] = "The object refers to an object that was not found." + self.system_fault_code["F2281"] = "The object refers to an object that was not found." + self.system_fault_code["F2282"] = "The object refers to an object that was not found." + self.system_fault_code["F2283"] = "The object refers to an object that was not found." + self.system_fault_code["F2284"] = "The object refers to an object that was not found." + self.system_fault_code["F2299"] = "This fault occurs due to missing RP group range configuration." + self.system_fault_code["F2300"] = "The object refers to an object that was not found." + self.system_fault_code["F2301"] = "The object refers to an object that was not found." + self.system_fault_code["F2302"] = "The object refers to an object that was not found." + self.system_fault_code["F2305"] = "This fault occurs when multicast is allowed on a bridge domain for which L3 routing is disabled." + self.system_fault_code["F2307"] = "This fault occurs due to invalid route map configuraiton. Only source specific route map is allowed." + self.system_fault_code["F2308"] = "This fault occurs due to invalid route map configuraiton. Only source specific route map is allowed." + self.system_fault_code["F2327"] = ": This fault occurs when there is a mic-configuration for a given EPg/external vlan mode on a given node" + self.system_fault_code["F2328"] = "The object refers to an object that was not found." + self.system_fault_code["F2330"] = "This fault occurs due to PIM is enabled on a layer 3 out that has external SVI interfaces." + self.system_fault_code["F2331"] = "This fault occurs when the state limit regular entries exceeds 80% of the maximum limit" + self.system_fault_code["F2332"] = "This fault occurs when the state limit reserved entries exceeds 80% of the maximum limit" + self.system_fault_code["F2333"] = "This fault occurs when the regular limit entries are exhausted but the reserved entries are still available. If a group" + self.system_fault_code["F2334"] = "This fault occurs when the regular and reserved entries get exhausted or when the user configures the state limit value" + self.system_fault_code["F233680"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233681"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233682"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233683"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233684"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233685"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233686"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233687"] = "This fault is caused by 'Hits Counter current value' statistical property crossing threshold level." + self.system_fault_code["F233696"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233697"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233698"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233699"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233700"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233701"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233702"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233703"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233704"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233705"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233706"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233707"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233708"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233709"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233710"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233711"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233712"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233713"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233714"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233715"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233716"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233717"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233718"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233719"] = "This fault is caused by 'Hits Counter minimum value' statistical property crossing threshold level." + self.system_fault_code["F233720"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233721"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233722"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233723"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233724"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233725"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233726"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233727"] = "This fault is caused by 'Hits Counter maximum value' statistical property crossing threshold level." + self.system_fault_code["F233728"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233729"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233730"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233731"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233732"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233733"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233734"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233735"] = "This fault is caused by 'Hits Counter average value' statistical property crossing threshold level." + self.system_fault_code["F233760"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233761"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233762"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233763"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233764"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233765"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233766"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233767"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233768"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233769"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233770"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233771"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233772"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233773"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233774"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233775"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233848"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233849"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233850"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233851"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233852"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233853"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233854"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233855"] = "This fault is caused by 'Hits Counter cumulative' statistical property crossing threshold level." + self.system_fault_code["F233856"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233857"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233858"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233859"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233860"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233861"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233862"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233863"] = "This fault is caused by 'Hits Counter periodic' statistical property crossing threshold level." + self.system_fault_code["F233888"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233889"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233890"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233891"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233892"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233893"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233894"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233895"] = "This fault is caused by 'Hits Counter trend' statistical property crossing threshold level." + self.system_fault_code["F233896"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233897"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233898"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233899"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233900"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233901"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233902"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F233903"] = "This fault is caused by 'Hits Counter rate' statistical property crossing threshold level." + self.system_fault_code["F237328"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237329"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237330"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237331"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237332"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237333"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237334"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237335"] = "This fault is caused by 'Egress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237344"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237345"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237346"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237347"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237348"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237349"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237350"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237351"] = "This fault is caused by 'Egress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237352"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237353"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237354"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237355"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237356"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237357"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237358"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237359"] = "This fault is caused by 'Egress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237360"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237361"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237362"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237363"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237364"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237365"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237366"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237367"] = "This fault is caused by 'Egress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237368"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237369"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237370"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237371"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237372"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237373"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237374"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237375"] = "This fault is caused by 'Egress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237376"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237377"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237378"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237379"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237380"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237381"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237382"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237383"] = "This fault is caused by 'Egress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237408"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237409"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237410"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237411"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237412"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237413"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237414"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237415"] = "This fault is caused by 'Egress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237416"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237417"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237418"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237419"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237420"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237421"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237422"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237423"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237496"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237497"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237498"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237499"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237500"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237501"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237502"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237503"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237504"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237505"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237506"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237507"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237508"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237509"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237510"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237511"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237512"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237513"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237514"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237515"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237516"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237517"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237518"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237519"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237520"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237521"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237522"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237523"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237524"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237525"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237526"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237527"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237560"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237561"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237562"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237563"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237564"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237565"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237566"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237567"] = "This fault is caused by 'Egress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237616"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237617"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237618"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237619"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237620"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237621"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237622"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237623"] = "This fault is caused by 'Egress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F237632"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237633"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237634"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237635"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237636"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237637"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237638"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237639"] = "This fault is caused by 'Egress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F237640"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237641"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237642"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237643"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237644"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237645"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237646"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237647"] = "This fault is caused by 'Egress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F237648"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237649"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237650"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237651"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237652"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237653"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237654"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237655"] = "This fault is caused by 'Egress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F237656"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237657"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237658"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237659"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237660"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237661"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237662"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237663"] = "This fault is caused by 'Egress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F237664"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237665"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237666"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237667"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237668"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237669"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237670"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237671"] = "This fault is caused by 'Egress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F237696"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237697"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237698"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237699"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237700"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237701"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237702"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237703"] = "This fault is caused by 'Egress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F237704"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237705"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237706"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237707"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237708"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237709"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237710"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237711"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F237784"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237785"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237786"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237787"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237788"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237789"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237790"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237791"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F237792"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237793"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237794"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237795"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237796"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237797"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237798"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237799"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F237800"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237801"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237802"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237803"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237804"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237805"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237806"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237807"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F237808"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237809"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237810"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237811"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237812"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237813"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237814"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237815"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F237848"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237849"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237850"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237851"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237852"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237853"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237854"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237855"] = "This fault is caused by 'Egress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F237904"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237905"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237906"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237907"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237908"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237909"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237910"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237911"] = "This fault is caused by 'Egress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F237920"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237921"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237922"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237923"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237924"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237925"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237926"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237927"] = "This fault is caused by 'Egress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F237928"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237929"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237930"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237931"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237932"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237933"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237934"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237935"] = "This fault is caused by 'Egress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F237936"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237937"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237938"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237939"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237940"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237941"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237942"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237943"] = "This fault is caused by 'Egress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F237944"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237945"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237946"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237947"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237948"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237949"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237950"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237951"] = "This fault is caused by 'Egress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F237952"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237953"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237954"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237955"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237956"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237957"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237958"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237959"] = "This fault is caused by 'Egress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F237984"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237985"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237986"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237987"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237988"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237989"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237990"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237991"] = "This fault is caused by 'Egress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F237992"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237993"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237994"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237995"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237996"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237997"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237998"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F237999"] = "This fault is caused by 'Egress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238072"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238073"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238074"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238075"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238076"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238077"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238078"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238079"] = "This fault is caused by 'Egress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238088"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238089"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238090"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238091"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238092"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238093"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238094"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238095"] = "This fault is caused by 'Egress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238096"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238097"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238098"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238099"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238100"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238101"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238102"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238103"] = "This fault is caused by 'Egress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238104"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238105"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238106"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238107"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238108"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238109"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238110"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238111"] = "This fault is caused by 'Egress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238112"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238113"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238114"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238115"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238116"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238117"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238118"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238119"] = "This fault is caused by 'Egress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238120"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238121"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238122"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238123"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238124"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238125"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238126"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238127"] = "This fault is caused by 'Egress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238152"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238153"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238154"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238155"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238156"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238157"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238158"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238159"] = "This fault is caused by 'Egress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238160"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238161"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238162"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238163"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238164"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238165"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238166"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238167"] = "This fault is caused by 'Egress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238240"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238241"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238242"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238243"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238244"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238245"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238246"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238247"] = "This fault is caused by 'Ingress Aggregated Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238256"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238257"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238258"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238259"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238260"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238261"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238262"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238263"] = "This fault is caused by 'Ingress Aggregated Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238264"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238265"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238266"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238267"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238268"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238269"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238270"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238271"] = "This fault is caused by 'Ingress Aggregated Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238272"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238273"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238274"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238275"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238276"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238277"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238278"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238279"] = "This fault is caused by 'Ingress Aggregated Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238280"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238281"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238282"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238283"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238284"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238285"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238286"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238287"] = "This fault is caused by 'Ingress Aggregated Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238288"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238289"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238290"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238291"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238292"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238293"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238294"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238295"] = "This fault is caused by 'Ingress Aggregated Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238320"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238321"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238322"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238323"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238324"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238325"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238326"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238327"] = "This fault is caused by 'Ingress Aggregated Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238328"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238329"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238330"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238331"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238332"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238333"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238334"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238335"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238408"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238409"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238410"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238411"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238412"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238413"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238414"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238415"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238416"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238417"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238418"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238419"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238420"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238421"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238422"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238423"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238424"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238425"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238426"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238427"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238428"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238429"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238430"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238431"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238432"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238433"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238434"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238435"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238436"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238437"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238438"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238439"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238472"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238473"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238474"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238475"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238476"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238477"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238478"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238479"] = "This fault is caused by 'Ingress Aggregated Drop Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238528"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238529"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238530"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238531"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238532"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238533"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238534"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238535"] = "This fault is caused by 'Ingress Aggregated Forward Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F238544"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238545"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238546"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238547"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238548"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238549"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238550"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238551"] = "This fault is caused by 'Ingress Aggregated Forward Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F238552"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238553"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238554"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238555"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238556"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238557"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238558"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238559"] = "This fault is caused by 'Ingress Aggregated Forward Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F238560"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238561"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238562"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238563"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238564"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238565"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238566"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238567"] = "This fault is caused by 'Ingress Aggregated Forward Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F238568"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238569"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238570"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238571"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238572"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238573"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238574"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238575"] = "This fault is caused by 'Ingress Aggregated Forward Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F238576"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238577"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238578"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238579"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238580"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238581"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238582"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238583"] = "This fault is caused by 'Ingress Aggregated Forward Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F238608"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238609"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238610"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238611"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238612"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238613"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238614"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238615"] = "This fault is caused by 'Ingress Aggregated Forward Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F238616"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238617"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238618"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238619"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238620"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238621"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238622"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238623"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F238696"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238697"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238698"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238699"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238700"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238701"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238702"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238703"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F238704"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238705"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238706"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238707"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238708"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238709"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238710"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238711"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F238712"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238713"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238714"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238715"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238716"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238717"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238718"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238719"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F238720"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238721"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238722"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238723"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238724"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238725"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238726"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238727"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F238760"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238761"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238762"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238763"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238764"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238765"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238766"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238767"] = "This fault is caused by 'Ingress Aggregated Forward Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F238816"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238817"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238818"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238819"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238820"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238821"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238822"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238823"] = "This fault is caused by 'Ingress Aggregated Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238832"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238833"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238834"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238835"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238836"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238837"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238838"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238839"] = "This fault is caused by 'Ingress Aggregated Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F238840"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238841"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238842"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238843"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238844"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238845"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238846"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238847"] = "This fault is caused by 'Ingress Aggregated Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F238848"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238849"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238850"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238851"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238852"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238853"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238854"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238855"] = "This fault is caused by 'Ingress Aggregated Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F238856"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238857"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238858"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238859"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238860"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238861"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238862"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238863"] = "This fault is caused by 'Ingress Aggregated Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F238864"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238865"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238866"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238867"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238868"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238869"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238870"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238871"] = "This fault is caused by 'Ingress Aggregated Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F238896"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238897"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238898"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238899"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238900"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238901"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238902"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238903"] = "This fault is caused by 'Ingress Aggregated Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F238904"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238905"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238906"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238907"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238908"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238909"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238910"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238911"] = "This fault is caused by 'Ingress Aggregated Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F238984"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238985"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238986"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238987"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238988"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238989"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238990"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F238991"] = "This fault is caused by 'Ingress Aggregated Forward Packets current value' statistical property crossing threshold level." + self.system_fault_code["F239000"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239001"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239002"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239003"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239004"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239005"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239006"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239007"] = "This fault is caused by 'Ingress Aggregated Forward Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F239008"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239009"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239010"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239011"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239012"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239013"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239014"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239015"] = "This fault is caused by 'Ingress Aggregated Forward Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F239016"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239017"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239018"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239019"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239020"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239021"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239022"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239023"] = "This fault is caused by 'Ingress Aggregated Forward Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F239024"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239025"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239026"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239027"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239028"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239029"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239030"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239031"] = "This fault is caused by 'Ingress Aggregated Forward Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F239032"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239033"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239034"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239035"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239036"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239037"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239038"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239039"] = "This fault is caused by 'Ingress Aggregated Forward Packets average value' statistical property crossing threshold level." + self.system_fault_code["F239064"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239065"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239066"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239067"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239068"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239069"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239070"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239071"] = "This fault is caused by 'Ingress Aggregated Forward Packets trend' statistical property crossing threshold level." + self.system_fault_code["F239072"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239073"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239074"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239075"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239076"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239077"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239078"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F239079"] = "This fault is caused by 'Ingress Aggregated Forward Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2397"] = "This fault occurs when PBR service destination goes to failed state" + self.system_fault_code["F2398"] = "This fault occurs when copy service destination goes to failed state" + self.system_fault_code["F2399"] = "This fault occurs when an End Point Group is incompletely or incorrectly configured." + self.system_fault_code["F2404"] = "This fault occurs because PIM is enabled on a VRF which is deployed on a a leaf which does not support multicast configuration." + self.system_fault_code["F2405"] = "This fault occurs when a VFC port is down" + self.system_fault_code["F2406"] = "This fault occurs when the ep learning is disabled on interface" + self.system_fault_code["F2407"] = "This fault occurs when the MacCktEP configuration fails" + self.system_fault_code["F2409"] = "This fault occurs when there are specific configuration errors on a bridge domain, but the igmpsnoop is disabled." + self.system_fault_code["F2421"] = "This fault occurs when a diagnostic test fails." + self.system_fault_code["F2428"] = "This fault is raised when both the opflex channels for the host are down." + self.system_fault_code["F2431"] = "The object refers to an object that was not found." + self.system_fault_code["F2437"] = "This fault occurs when a VFC portVsan is down" + self.system_fault_code["F2438"] = "This fault occurs when a Created Vsan count exceeds allowed limit on node" + self.system_fault_code["F2444"] = "This fault occurs when max-path configuration exceeds the recommended value" + self.system_fault_code["F2445"] = "This fault occurs when traffic map configuration failed" + self.system_fault_code["F2447"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2451"] = "This fault occurs when under a given hsrpGroupP VIP doesn't match subnet of the interface: - there is a hsrpGroupP configuration" + self.system_fault_code["F2459"] = "The object refers to an object that was not found." + self.system_fault_code["F2460"] = "The object refers to an object that was not found." + self.system_fault_code["F2467"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2469"] = "The object refers to an object that was not found." + self.system_fault_code["F2470"] = "The object refers to an object that was not found." + self.system_fault_code["F2471"] = "The object refers to an object that was not found." + self.system_fault_code["F2472"] = "The object refers to an object that was not found." + self.system_fault_code["F2473"] = "The object refers to an object that was not found." + self.system_fault_code["F2474"] = "The object refers to an object that was not found." + self.system_fault_code["F2475"] = "The object refers to an object that was not found." + self.system_fault_code["F2476"] = "The object refers to an object that was not found." + self.system_fault_code["F2477"] = "The object refers to an object that was not found." + self.system_fault_code["F2481"] = "The object refers to an object that was not found." + self.system_fault_code["F250152"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250153"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250154"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250155"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250156"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250157"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250158"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250159"] = "This fault is caused by 'Local L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250160"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250161"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250162"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250163"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250164"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250165"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250166"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250167"] = "This fault is caused by 'Local L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250168"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250169"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250170"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250171"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250172"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250173"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250174"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250175"] = "This fault is caused by 'Local L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250176"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250177"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250178"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250179"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250180"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250181"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250182"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250183"] = "This fault is caused by 'Local L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250216"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250217"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250218"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250219"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250220"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250221"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250222"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250223"] = "This fault is caused by 'Local L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250272"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250273"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250274"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250275"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250276"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250277"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250278"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250279"] = "This fault is caused by 'Local v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250280"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250281"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250282"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250283"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250284"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250285"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250286"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250287"] = "This fault is caused by 'Local v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250288"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250289"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250290"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250291"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250292"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250293"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250294"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250295"] = "This fault is caused by 'Local v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250296"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250297"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250298"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250299"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250300"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250301"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250302"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250303"] = "This fault is caused by 'Local v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250336"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250337"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250338"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250339"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250340"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250341"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250342"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250343"] = "This fault is caused by 'Local v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250392"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250393"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250394"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250395"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250396"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250397"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250398"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F250399"] = "This fault is caused by 'Local v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F2504"] = "The object refers to an object that was not found." + self.system_fault_code["F250400"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250401"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250402"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250403"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250404"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250405"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250406"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250407"] = "This fault is caused by 'Local v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250408"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250409"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250410"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250411"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250412"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250413"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250414"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250415"] = "This fault is caused by 'Local v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250416"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250417"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250418"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250419"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250420"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250421"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250422"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250423"] = "This fault is caused by 'Local v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F250456"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250457"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250458"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250459"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250460"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250461"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250462"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250463"] = "This fault is caused by 'Local v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F250512"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250513"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250514"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250515"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250516"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250517"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250518"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250519"] = "This fault is caused by 'Local Multicast entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F250520"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250521"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250522"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250523"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250524"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250525"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250526"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250527"] = "This fault is caused by 'Local Multicast entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F250528"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250529"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250530"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250531"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250532"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250533"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250534"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250535"] = "This fault is caused by 'Local Multicast entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F250536"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250537"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250538"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250539"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250540"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250541"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250542"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250543"] = "This fault is caused by 'Local Multicast entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F250576"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250577"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250578"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250579"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250580"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250581"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250582"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F250583"] = "This fault is caused by 'Local Multicast entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F2506"] = "This fault occurs when Allow Microsegmentation is enabled for an EPG in an unsupported platform" + self.system_fault_code["F2507"] = "This fault occurs when Proxy Arp is enabled for an EPG in an unsupported platform" + self.system_fault_code["F2508"] = "This fault occurs when intra-epg isolation is not enforced, but Proxy Arp is enabled for an EPG." + self.system_fault_code["F2511"] = "This fault occurs when the switch querier is the same as the BD SVI querier" + self.system_fault_code["F2514"] = "This fault occurs when an out of service policy has been created, but those policies have not been deployed to one or" + self.system_fault_code["F2531"] = "This fault occurs when there are specific configuration errors on EPG to VMM Domain Association." + self.system_fault_code["F2532"] = "This fault occurs when the IGMP static group policy has group mask of less than 24" + self.system_fault_code["F2533"] = "This fault occurs when a loop is detected" + self.system_fault_code["F2534"] = "This fault occurs when a loop is detected" + self.system_fault_code["F2542"] = "This fault occurs when Analytics agent Image installation failed on the switch" + self.system_fault_code["F2543"] = "This fault is raised when there are DHCP issues" + self.system_fault_code["F2547"] = "This fault occurs when node-id to pod-id mapping is wrong." + self.system_fault_code["F2548"] = "This fault occurs due to an invalid app meta data or incorrectly packaging the app." + self.system_fault_code["F2551"] = "The object refers to an object that was not found." + self.system_fault_code["F2554"] = "The object refers to an object that was not found." + self.system_fault_code["F2558"] = "The object refers to an object that was not found." + self.system_fault_code["F2560"] = "This fault occurs when FIPS 140-2 is enabled or disabled on the node" + self.system_fault_code["F2562"] = "The object refers to an object that was not found." + self.system_fault_code["F2563"] = "This fault occurs when sending a callhome message to destination does not succeed." + self.system_fault_code["F2570"] = "This fault occurs when the number of exporters are more than two and the version is 9" + self.system_fault_code["F2571"] = "This fault occurs when the flow monitor application on interface/BD fails." + self.system_fault_code["F2572"] = "This fault occurs when the record application on interface/BD fails" + self.system_fault_code["F2573"] = "This fault occurs when the controller out-of-band management IP address cannot be assigned as it is in use (local or remote)." + self.system_fault_code["F2574"] = "This fault occurs when group config conflicts." + self.system_fault_code["F257472"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257473"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257474"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257475"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257476"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257477"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257478"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257479"] = "This fault is caused by 'Dropped Packets - No Route To Host current value' statistical property crossing threshold level." + self.system_fault_code["F257488"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257489"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257490"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257491"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257492"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257493"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257494"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257495"] = "This fault is caused by 'Dropped Packets - No Route To Host cumulative' statistical property crossing threshold level." + self.system_fault_code["F257496"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257497"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257498"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257499"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257500"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257501"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257502"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257503"] = "This fault is caused by 'Dropped Packets - No Route To Host periodic' statistical property crossing threshold level." + self.system_fault_code["F257504"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257505"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257506"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257507"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257508"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257509"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257510"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257511"] = "This fault is caused by 'Dropped Packets - No Route To Host minimum value' statistical property crossing threshold level." + self.system_fault_code["F257512"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257513"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257514"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257515"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257516"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257517"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257518"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257519"] = "This fault is caused by 'Dropped Packets - No Route To Host maximum value' statistical property crossing threshold level." + self.system_fault_code["F257520"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257521"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257522"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257523"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257524"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257525"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257526"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257527"] = "This fault is caused by 'Dropped Packets - No Route To Host average value' statistical property crossing threshold level." + self.system_fault_code["F257552"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257553"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257554"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257555"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257556"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257557"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257558"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257559"] = "This fault is caused by 'Dropped Packets - No Route To Host trend' statistical property crossing threshold level." + self.system_fault_code["F257560"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257561"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257562"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257563"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257564"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257565"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257566"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257567"] = "This fault is caused by 'Dropped Packets - No Route To Host rate' statistical property crossing threshold level." + self.system_fault_code["F257640"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257641"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257642"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257643"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257644"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257645"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257646"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257647"] = "This fault is caused by 'Other Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257656"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257657"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257658"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257659"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257660"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257661"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257662"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257663"] = "This fault is caused by 'Other Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257664"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257665"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257666"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257667"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257668"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257669"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257670"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257671"] = "This fault is caused by 'Other Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257672"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257673"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257674"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257675"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257676"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257677"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257678"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257679"] = "This fault is caused by 'Other Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257680"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257681"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257682"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257683"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257684"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257685"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257686"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257687"] = "This fault is caused by 'Other Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257688"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257689"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257690"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257691"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257692"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257693"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257694"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257695"] = "This fault is caused by 'Other Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F2577"] = "This fault occurs when applying breakout policy on a port fails." + self.system_fault_code["F257720"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257721"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257722"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257723"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257724"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257725"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257726"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257727"] = "This fault is caused by 'Other Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257728"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257729"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257730"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257731"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257732"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257733"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257734"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257735"] = "This fault is caused by 'Other Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257808"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257809"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257810"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257811"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257812"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257813"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257814"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257815"] = "This fault is caused by 'Dropped Output Packets current value' statistical property crossing threshold level." + self.system_fault_code["F257824"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257825"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257826"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257827"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257828"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257829"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257830"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257831"] = "This fault is caused by 'Dropped Output Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F257832"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257833"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257834"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257835"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257836"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257837"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257838"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257839"] = "This fault is caused by 'Dropped Output Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F257840"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257841"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257842"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257843"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257844"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257845"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257846"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257847"] = "This fault is caused by 'Dropped Output Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F257848"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257849"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257850"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257851"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257852"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257853"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257854"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257855"] = "This fault is caused by 'Dropped Output Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F257856"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257857"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257858"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257859"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257860"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257861"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257862"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257863"] = "This fault is caused by 'Dropped Output Packets average value' statistical property crossing threshold level." + self.system_fault_code["F257888"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257889"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257890"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257891"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257892"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257893"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257894"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257895"] = "This fault is caused by 'Dropped Output Packets trend' statistical property crossing threshold level." + self.system_fault_code["F257896"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257897"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257898"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257899"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2579"] = "The object refers to an object that was not found." + self.system_fault_code["F257900"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257901"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257902"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257903"] = "This fault is caused by 'Dropped Output Packets rate' statistical property crossing threshold level." + self.system_fault_code["F257976"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257977"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257978"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257979"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257980"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257981"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257982"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257983"] = "This fault is caused by 'Exported Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F257992"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257993"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257994"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257995"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257996"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257997"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257998"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F257999"] = "This fault is caused by 'Exported Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F2580"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F258000"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258001"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258002"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258003"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258004"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258005"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258006"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258007"] = "This fault is caused by 'Exported Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F258008"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258009"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258010"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258011"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258012"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258013"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258014"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258015"] = "This fault is caused by 'Exported Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F258016"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258017"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258018"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258019"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258020"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258021"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258022"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258023"] = "This fault is caused by 'Exported Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F258024"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258025"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258026"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258027"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258028"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258029"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258030"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258031"] = "This fault is caused by 'Exported Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F258056"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258057"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258058"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258059"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258060"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258061"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258062"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258063"] = "This fault is caused by 'Exported Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F258064"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258065"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258066"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258067"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258068"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258069"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258070"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F258071"] = "This fault is caused by 'Exported Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2581"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F258144"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258145"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258146"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258147"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258148"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258149"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258150"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258151"] = "This fault is caused by 'Exported Flow Records current value' statistical property crossing threshold level." + self.system_fault_code["F258160"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258161"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258162"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258163"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258164"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258165"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258166"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258167"] = "This fault is caused by 'Exported Flow Records cumulative' statistical property crossing threshold level." + self.system_fault_code["F258168"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258169"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258170"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258171"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258172"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258173"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258174"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258175"] = "This fault is caused by 'Exported Flow Records periodic' statistical property crossing threshold level." + self.system_fault_code["F258176"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258177"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258178"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258179"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258180"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258181"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258182"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258183"] = "This fault is caused by 'Exported Flow Records minimum value' statistical property crossing threshold level." + self.system_fault_code["F258184"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258185"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258186"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258187"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258188"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258189"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258190"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258191"] = "This fault is caused by 'Exported Flow Records maximum value' statistical property crossing threshold level." + self.system_fault_code["F258192"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258193"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258194"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258195"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258196"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258197"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258198"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F258199"] = "This fault is caused by 'Exported Flow Records average value' statistical property crossing threshold level." + self.system_fault_code["F2582"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F258224"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258225"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258226"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258227"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258228"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258229"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258230"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258231"] = "This fault is caused by 'Exported Flow Records trend' statistical property crossing threshold level." + self.system_fault_code["F258232"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258233"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258234"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258235"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258236"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258237"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258238"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F258239"] = "This fault is caused by 'Exported Flow Records rate' statistical property crossing threshold level." + self.system_fault_code["F2583"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F258312"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258313"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258314"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258315"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258316"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258317"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258318"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258319"] = "This fault is caused by 'Exported Packets current value' statistical property crossing threshold level." + self.system_fault_code["F258328"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258329"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258330"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258331"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258332"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258333"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258334"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258335"] = "This fault is caused by 'Exported Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F258336"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258337"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258338"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258339"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258340"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258341"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258342"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258343"] = "This fault is caused by 'Exported Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F258344"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258345"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258346"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258347"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258348"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258349"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258350"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258351"] = "This fault is caused by 'Exported Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F258352"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258353"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258354"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258355"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258356"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258357"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258358"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258359"] = "This fault is caused by 'Exported Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F258360"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258361"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258362"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258363"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258364"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258365"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258366"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258367"] = "This fault is caused by 'Exported Packets average value' statistical property crossing threshold level." + self.system_fault_code["F258392"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258393"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258394"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258395"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258396"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258397"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258398"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F258399"] = "This fault is caused by 'Exported Packets trend' statistical property crossing threshold level." + self.system_fault_code["F2584"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F258400"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258401"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258402"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258403"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258404"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258405"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258406"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258407"] = "This fault is caused by 'Exported Packets rate' statistical property crossing threshold level." + self.system_fault_code["F258480"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258481"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258482"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258483"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258484"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258485"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258486"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258487"] = "This fault is caused by 'Exported Templates current value' statistical property crossing threshold level." + self.system_fault_code["F258496"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258497"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258498"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258499"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F2585"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F258500"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258501"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258502"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258503"] = "This fault is caused by 'Exported Templates cumulative' statistical property crossing threshold level." + self.system_fault_code["F258504"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258505"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258506"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258507"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258508"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258509"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258510"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258511"] = "This fault is caused by 'Exported Templates periodic' statistical property crossing threshold level." + self.system_fault_code["F258512"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258513"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258514"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258515"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258516"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258517"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258518"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258519"] = "This fault is caused by 'Exported Templates minimum value' statistical property crossing threshold level." + self.system_fault_code["F258520"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258521"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258522"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258523"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258524"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258525"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258526"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258527"] = "This fault is caused by 'Exported Templates maximum value' statistical property crossing threshold level." + self.system_fault_code["F258528"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258529"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258530"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258531"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258532"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258533"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258534"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258535"] = "This fault is caused by 'Exported Templates average value' statistical property crossing threshold level." + self.system_fault_code["F258560"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258561"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258562"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258563"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258564"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258565"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258566"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258567"] = "This fault is caused by 'Exported Templates trend' statistical property crossing threshold level." + self.system_fault_code["F258568"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258569"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258570"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258571"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258572"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258573"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258574"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F258575"] = "This fault is caused by 'Exported Templates rate' statistical property crossing threshold level." + self.system_fault_code["F2589"] = "This fault occurs when the collector becomes unreachable" + self.system_fault_code["F2593"] = "This fault is raised when the number of MO of class specified exceed the maximum configured numbers in the containerDn" + self.system_fault_code["F2595"] = "This fault occurs when operation, to replace an APIC by standby APIC, errors out." + self.system_fault_code["F2596"] = "This fault occurs when the L4-L7 service node configuration fails" + self.system_fault_code["F2597"] = "This fault occurs when the L4-L7 service node configuration fails" + self.system_fault_code["F2598"] = "This fault occurs when HSRP Group goes down." + self.system_fault_code["F2599"] = "This fault occurs when HSRP vip provisioning fails ." + self.system_fault_code["F2603"] = "The object refers to an object that was not found." + self.system_fault_code["F2629"] = "This fault occurs when port mode is configured as NP for VFC over FEX interfaces" + self.system_fault_code["F2630"] = "This fault occurs when the Collector Configuration Parameters mismatch" + self.system_fault_code["F2631"] = "The object refers to an object that was not found." + self.system_fault_code["F2632"] = "The object refers to an object that was not found." + self.system_fault_code["F2633"] = "The object refers to an object that was not found." + self.system_fault_code["F2634"] = "The object refers to an object that was not found." + self.system_fault_code["F2635"] = "The object refers to an object that was not found." + self.system_fault_code["F2636"] = "The object refers to an object that was not found." + self.system_fault_code["F2637"] = "The object refers to an object that was not found." + self.system_fault_code["F2638"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F2639"] = "This fault occurs when hsrp version conflicts." + self.system_fault_code["F2640"] = "This fault occurs when under a given hsrpSecVip VIP doesn't match subnet of the interface: - there is a SecVip configuration" + self.system_fault_code["F2641"] = "This fault occurs when a flushthr programming for a nodrop class exceed 4." + self.system_fault_code["F2642"] = "This fault occurs when VFC interface is created onver span destination port" + self.system_fault_code["F2647"] = "This fault occurs when NP port is configured as server interface or F port is configured as External interface" + self.system_fault_code["F2650"] = "Plugin has failed to start." + self.system_fault_code["F265392"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265393"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265394"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265395"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265396"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265397"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265398"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265399"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265408"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265409"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265410"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265411"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265412"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265413"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265414"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265415"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265416"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265417"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265418"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265419"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265420"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265421"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265422"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265423"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265424"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265425"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265426"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265427"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265428"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265429"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265430"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265431"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265432"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265433"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265434"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265435"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265436"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265437"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265438"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265439"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265440"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265441"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265442"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265443"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265444"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265445"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265446"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265447"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265472"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265473"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265474"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265475"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265476"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265477"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265478"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265479"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265480"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265481"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265482"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265483"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265484"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265485"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265486"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265487"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265560"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265561"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265562"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265563"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265564"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265565"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265566"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265567"] = "This fault is caused by 'cumulative average delay current value' statistical property crossing threshold level." + self.system_fault_code["F265576"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265577"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265578"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265579"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265580"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265581"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265582"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265583"] = "This fault is caused by 'cumulative average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265584"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265585"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265586"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265587"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265588"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265589"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265590"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265591"] = "This fault is caused by 'cumulative average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265592"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265593"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265594"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265595"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265596"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265597"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265598"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265599"] = "This fault is caused by 'cumulative average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F2656"] = "User is trying to downgrade an app, which is not allowed." + self.system_fault_code["F265600"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265601"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265602"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265603"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265604"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265605"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265606"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265607"] = "This fault is caused by 'cumulative average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265608"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265609"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265610"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265611"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265612"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265613"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265614"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265615"] = "This fault is caused by 'cumulative average delay average value' statistical property crossing threshold level." + self.system_fault_code["F265640"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265641"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265642"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265643"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265644"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265645"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265646"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265647"] = "This fault is caused by 'cumulative average delay trend' statistical property crossing threshold level." + self.system_fault_code["F265648"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265649"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265650"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265651"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265652"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265653"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265654"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265655"] = "This fault is caused by 'cumulative average delay rate' statistical property crossing threshold level." + self.system_fault_code["F265728"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265729"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265730"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265731"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265732"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265733"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265734"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265735"] = "This fault is caused by 'maximum delay current value' statistical property crossing threshold level." + self.system_fault_code["F265744"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265745"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265746"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265747"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265748"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265749"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265750"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265751"] = "This fault is caused by 'maximum delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F265752"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265753"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265754"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265755"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265756"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265757"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265758"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265759"] = "This fault is caused by 'maximum delay periodic' statistical property crossing threshold level." + self.system_fault_code["F265760"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265761"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265762"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265763"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265764"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265765"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265766"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265767"] = "This fault is caused by 'maximum delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F265768"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265769"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265770"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265771"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265772"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265773"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265774"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265775"] = "This fault is caused by 'maximum delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F265776"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265777"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265778"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265779"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265780"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265781"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265782"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F265783"] = "This fault is caused by 'maximum delay average value' statistical property crossing threshold level." + self.system_fault_code["F2658"] = "The object refers to an object that was not found." + self.system_fault_code["F265808"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265809"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265810"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265811"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265812"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265813"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265814"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265815"] = "This fault is caused by 'maximum delay trend' statistical property crossing threshold level." + self.system_fault_code["F265816"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265817"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265818"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265819"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265820"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265821"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265822"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265823"] = "This fault is caused by 'maximum delay rate' statistical property crossing threshold level." + self.system_fault_code["F265896"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265897"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265898"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265899"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F2659"] = "The object refers to an object that was not found." + self.system_fault_code["F265900"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265901"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265902"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265903"] = "This fault is caused by 'packet count current value' statistical property crossing threshold level." + self.system_fault_code["F265912"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265913"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265914"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265915"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265916"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265917"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265918"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265919"] = "This fault is caused by 'packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F265920"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265921"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265922"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265923"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265924"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265925"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265926"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265927"] = "This fault is caused by 'packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F265928"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265929"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265930"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265931"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265932"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265933"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265934"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265935"] = "This fault is caused by 'packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F265936"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265937"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265938"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265939"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265940"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265941"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265942"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265943"] = "This fault is caused by 'packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F265944"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265945"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265946"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265947"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265948"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265949"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265950"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265951"] = "This fault is caused by 'packet count average value' statistical property crossing threshold level." + self.system_fault_code["F265976"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265977"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265978"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265979"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265980"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265981"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265982"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265983"] = "This fault is caused by 'packet count trend' statistical property crossing threshold level." + self.system_fault_code["F265984"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265985"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265986"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265987"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265988"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265989"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265990"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F265991"] = "This fault is caused by 'packet count rate' statistical property crossing threshold level." + self.system_fault_code["F2660"] = "The object refers to an object that was not found." + self.system_fault_code["F266064"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266065"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266066"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266067"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266068"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266069"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266070"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266071"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F266080"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266081"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266082"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266083"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266084"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266085"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266086"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266087"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F266088"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266089"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266090"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266091"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266092"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266093"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266094"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266095"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F266096"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266097"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266098"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266099"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F2661"] = "The object refers to an object that was not found." + self.system_fault_code["F266100"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266101"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266102"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266103"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F266104"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266105"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266106"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266107"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266108"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266109"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266110"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266111"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F266112"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266113"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266114"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266115"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266116"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266117"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266118"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266119"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F266144"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266145"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266146"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266147"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266148"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266149"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266150"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266151"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F266152"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266153"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266154"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266155"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266156"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266157"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266158"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F266159"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F2662"] = "The object refers to an object that was not found." + self.system_fault_code["F266232"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266233"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266234"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266235"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266236"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266237"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266238"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266239"] = "This fault is caused by 'standard deviation current value' statistical property crossing threshold level." + self.system_fault_code["F266248"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266249"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266250"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266251"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266252"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266253"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266254"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266255"] = "This fault is caused by 'standard deviation cumulative' statistical property crossing threshold level." + self.system_fault_code["F266256"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266257"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266258"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266259"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266260"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266261"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266262"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266263"] = "This fault is caused by 'standard deviation periodic' statistical property crossing threshold level." + self.system_fault_code["F266264"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266265"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266266"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266267"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266268"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266269"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266270"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266271"] = "This fault is caused by 'standard deviation minimum value' statistical property crossing threshold level." + self.system_fault_code["F266272"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266273"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266274"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266275"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266276"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266277"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266278"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266279"] = "This fault is caused by 'standard deviation maximum value' statistical property crossing threshold level." + self.system_fault_code["F266280"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266281"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266282"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266283"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266284"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266285"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266286"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266287"] = "This fault is caused by 'standard deviation average value' statistical property crossing threshold level." + self.system_fault_code["F266312"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266313"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266314"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266315"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266316"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266317"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266318"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266319"] = "This fault is caused by 'standard deviation trend' statistical property crossing threshold level." + self.system_fault_code["F266320"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266321"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266322"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266323"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266324"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266325"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266326"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266327"] = "This fault is caused by 'standard deviation rate' statistical property crossing threshold level." + self.system_fault_code["F266400"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266401"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266402"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266403"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266404"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266405"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266406"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266407"] = "This fault is caused by 'total packet count current value' statistical property crossing threshold level." + self.system_fault_code["F266416"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266417"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266418"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266419"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266420"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266421"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266422"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266423"] = "This fault is caused by 'total packet count cumulative' statistical property crossing threshold level." + self.system_fault_code["F266424"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266425"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266426"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266427"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266428"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266429"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266430"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266431"] = "This fault is caused by 'total packet count periodic' statistical property crossing threshold level." + self.system_fault_code["F266432"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266433"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266434"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266435"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266436"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266437"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266438"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266439"] = "This fault is caused by 'total packet count minimum value' statistical property crossing threshold level." + self.system_fault_code["F266440"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266441"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266442"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266443"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266444"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266445"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266446"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266447"] = "This fault is caused by 'total packet count maximum value' statistical property crossing threshold level." + self.system_fault_code["F266448"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266449"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266450"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266451"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266452"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266453"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266454"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266455"] = "This fault is caused by 'total packet count average value' statistical property crossing threshold level." + self.system_fault_code["F266480"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266481"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266482"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266483"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266484"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266485"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266486"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266487"] = "This fault is caused by 'total packet count trend' statistical property crossing threshold level." + self.system_fault_code["F266488"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266489"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266490"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266491"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266492"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266493"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266494"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266495"] = "This fault is caused by 'total packet count rate' statistical property crossing threshold level." + self.system_fault_code["F266568"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266569"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266570"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266571"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266572"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266573"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266574"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266575"] = "This fault is caused by 'average delay current value' statistical property crossing threshold level." + self.system_fault_code["F266584"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266585"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266586"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266587"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266588"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266589"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266590"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266591"] = "This fault is caused by 'average delay cumulative' statistical property crossing threshold level." + self.system_fault_code["F266592"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266593"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266594"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266595"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266596"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266597"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266598"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266599"] = "This fault is caused by 'average delay periodic' statistical property crossing threshold level." + self.system_fault_code["F266600"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266601"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266602"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266603"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266604"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266605"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266606"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266607"] = "This fault is caused by 'average delay minimum value' statistical property crossing threshold level." + self.system_fault_code["F266608"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266609"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266610"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266611"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266612"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266613"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266614"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266615"] = "This fault is caused by 'average delay maximum value' statistical property crossing threshold level." + self.system_fault_code["F266616"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266617"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266618"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266619"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266620"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266621"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266622"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266623"] = "This fault is caused by 'average delay average value' statistical property crossing threshold level." + self.system_fault_code["F266648"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266649"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266650"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266651"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266652"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266653"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266654"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266655"] = "This fault is caused by 'average delay trend' statistical property crossing threshold level." + self.system_fault_code["F266656"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266657"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266658"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266659"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266660"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266661"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266662"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266663"] = "This fault is caused by 'average delay rate' statistical property crossing threshold level." + self.system_fault_code["F266736"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266737"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266738"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266739"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266740"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266741"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266742"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266743"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266752"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266753"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266754"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266755"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266756"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266757"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266758"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266759"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266760"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266761"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266762"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266763"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266764"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266765"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266766"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266767"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266768"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266769"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266770"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266771"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266772"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266773"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266774"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266775"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266776"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266777"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266778"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266779"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266780"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266781"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266782"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266783"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266784"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266785"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266786"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266787"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266788"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266789"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266790"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266791"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F2668"] = "The object refers to an object that was not found." + self.system_fault_code["F266816"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266817"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266818"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266819"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266820"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266821"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266822"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266823"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266824"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266825"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266826"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266827"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266828"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266829"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266830"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266831"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2669"] = "This fault occurs when there is a signature verification failure for Cisco signed app." + self.system_fault_code["F266904"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266905"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266906"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266907"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266908"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266909"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266910"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266911"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F266920"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266921"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266922"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266923"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266924"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266925"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266926"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266927"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F266928"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266929"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266930"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266931"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266932"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266933"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266934"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266935"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F266936"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266937"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266938"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266939"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266940"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266941"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266942"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266943"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F266944"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266945"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266946"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266947"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266948"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266949"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266950"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266951"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F266952"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266953"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266954"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266955"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266956"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266957"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266958"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266959"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F266984"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266985"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266986"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266987"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266988"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266989"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266990"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266991"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F266992"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266993"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266994"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266995"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266996"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266997"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266998"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F266999"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267072"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267073"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267074"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267075"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267076"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267077"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267078"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267079"] = "This fault is caused by 'sequence number current value' statistical property crossing threshold level." + self.system_fault_code["F267088"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267089"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267090"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267091"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267092"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267093"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267094"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267095"] = "This fault is caused by 'sequence number cumulative' statistical property crossing threshold level." + self.system_fault_code["F267096"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267097"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267098"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267099"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267100"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267101"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267102"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267103"] = "This fault is caused by 'sequence number periodic' statistical property crossing threshold level." + self.system_fault_code["F267104"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267105"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267106"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267107"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267108"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267109"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267110"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267111"] = "This fault is caused by 'sequence number minimum value' statistical property crossing threshold level." + self.system_fault_code["F267112"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267113"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267114"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267115"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267116"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267117"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267118"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267119"] = "This fault is caused by 'sequence number maximum value' statistical property crossing threshold level." + self.system_fault_code["F267120"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267121"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267122"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267123"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267124"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267125"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267126"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267127"] = "This fault is caused by 'sequence number average value' statistical property crossing threshold level." + self.system_fault_code["F267152"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267153"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267154"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267155"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267156"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267157"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267158"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267159"] = "This fault is caused by 'sequence number trend' statistical property crossing threshold level." + self.system_fault_code["F267160"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267161"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267162"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267163"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267164"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267165"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267166"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267167"] = "This fault is caused by 'sequence number rate' statistical property crossing threshold level." + self.system_fault_code["F267240"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267241"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267242"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267243"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267244"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267245"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267246"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267247"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267256"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267257"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267258"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267259"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267260"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267261"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267262"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267263"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267264"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267265"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267266"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267267"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267268"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267269"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267270"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267271"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267272"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267273"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267274"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267275"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267276"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267277"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267278"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267279"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267280"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267281"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267282"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267283"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267284"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267285"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267286"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267287"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267288"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267289"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267290"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267291"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267292"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267293"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267294"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267295"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F2673"] = "This fault occurs when user tries to configure granular storm control for unicast multicast and broadcast pkts on unsupported" + self.system_fault_code["F267320"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267321"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267322"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267323"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267324"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267325"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267326"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267327"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267328"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267329"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267330"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267331"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267332"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267333"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267334"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267335"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2674"] = "This fault occurs when the operational state of the ip inspect feature is changed to due to either cfg-err or bd-max-binding-limit-exceeded" + self.system_fault_code["F267408"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267409"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267410"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267411"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267412"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267413"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267414"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267415"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267424"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267425"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267426"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267427"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267428"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267429"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267430"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267431"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267432"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267433"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267434"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267435"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267436"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267437"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267438"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267439"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267440"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267441"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267442"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267443"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267444"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267445"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267446"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267447"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267448"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267449"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267450"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267451"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267452"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267453"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267454"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267455"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267456"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267457"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267458"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267459"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267460"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267461"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267462"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267463"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267488"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267489"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267490"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267491"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267492"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267493"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267494"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267495"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267496"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267497"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267498"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267499"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2675"] = "This fault occurs when the operational state of the ip inspect protocol subfeature is changed to due to either cfg-err" + self.system_fault_code["F267500"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267501"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267502"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267503"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267576"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267577"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267578"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267579"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267580"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267581"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267582"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267583"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267592"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267593"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267594"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267595"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267596"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267597"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267598"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267599"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F2676"] = "This fault occurs when the operational state of the Trust control is changed to due to cfg-err reason on the leaf" + self.system_fault_code["F267600"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267601"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267602"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267603"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267604"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267605"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267606"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267607"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267608"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267609"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267610"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267611"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267612"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267613"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267614"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267615"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267616"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267617"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267618"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267619"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267620"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267621"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267622"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267623"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267624"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267625"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267626"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267627"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267628"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267629"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267630"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267631"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267656"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267657"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267658"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267659"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267660"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267661"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267662"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267663"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267664"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267665"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267666"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267667"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267668"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267669"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267670"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267671"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2677"] = "This fault occurs when the operational state of the RA Guard fhs feature is changed to due to cfg-err or bd-vlan-down" + self.system_fault_code["F267744"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267745"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267746"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267747"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267748"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267749"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267750"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267751"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267760"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267761"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267762"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267763"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267764"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267765"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267766"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267767"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267768"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267769"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267770"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267771"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267772"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267773"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267774"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267775"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267776"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267777"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267778"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267779"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267780"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267781"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267782"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267783"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267784"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267785"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267786"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267787"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267788"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267789"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267790"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267791"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267792"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267793"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267794"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267795"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267796"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267797"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267798"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267799"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F2678"] = "This fault occurs when the operational state of the Source Guard fhs feature is changed to due to cfg-err or bd-vlan-down" + self.system_fault_code["F267824"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267825"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267826"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267827"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267828"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267829"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267830"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267831"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267832"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267833"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267834"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267835"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267836"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267837"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267838"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267839"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F267912"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267913"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267914"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267915"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267916"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267917"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267918"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267919"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F267928"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267929"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267930"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267931"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267932"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267933"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267934"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267935"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F267936"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267937"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267938"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267939"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267940"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267941"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267942"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267943"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F267944"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267945"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267946"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267947"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267948"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267949"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267950"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267951"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F267952"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267953"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267954"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267955"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267956"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267957"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267958"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267959"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F267960"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267961"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267962"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267963"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267964"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267965"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267966"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267967"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F267992"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267993"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267994"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267995"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267996"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267997"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267998"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F267999"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268000"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268001"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268002"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268003"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268004"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268005"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268006"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268007"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268080"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268081"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268082"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268083"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268084"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268085"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268086"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268087"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268096"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268097"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268098"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268099"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268100"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268101"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268102"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268103"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268104"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268105"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268106"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268107"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268108"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268109"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268110"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268111"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268112"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268113"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268114"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268115"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268116"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268117"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268118"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268119"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268120"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268121"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268122"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268123"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268124"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268125"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268126"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268127"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268128"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268129"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268130"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268131"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268132"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268133"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268134"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268135"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268160"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268161"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268162"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268163"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268164"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268165"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268166"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268167"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268168"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268169"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268170"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268171"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268172"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268173"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268174"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268175"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268248"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268249"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268250"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268251"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268252"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268253"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268254"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268255"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268264"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268265"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268266"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268267"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268268"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268269"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268270"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268271"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268272"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268273"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268274"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268275"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268276"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268277"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268278"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268279"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268280"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268281"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268282"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268283"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268284"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268285"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268286"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268287"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268288"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268289"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268290"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268291"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268292"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268293"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268294"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268295"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268296"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268297"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268298"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268299"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268300"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268301"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268302"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268303"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268328"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268329"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268330"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268331"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268332"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268333"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268334"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268335"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268336"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268337"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268338"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268339"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268340"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268341"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268342"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268343"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268416"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268417"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268418"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268419"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268420"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268421"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268422"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268423"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268432"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268433"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268434"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268435"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268436"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268437"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268438"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268439"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268440"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268441"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268442"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268443"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268444"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268445"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268446"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268447"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268448"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268449"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268450"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268451"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268452"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268453"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268454"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268455"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268456"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268457"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268458"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268459"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268460"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268461"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268462"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268463"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268464"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268465"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268466"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268467"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268468"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268469"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268470"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268471"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268496"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268497"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268498"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268499"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268500"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268501"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268502"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268503"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268504"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268505"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268506"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268507"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268508"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268509"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268510"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268511"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268584"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268585"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268586"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268587"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268588"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268589"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268590"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268591"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268600"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268601"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268602"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268603"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268604"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268605"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268606"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268607"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268608"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268609"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268610"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268611"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268612"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268613"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268614"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268615"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268616"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268617"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268618"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268619"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268620"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268621"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268622"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268623"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268624"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268625"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268626"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268627"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268628"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268629"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268630"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268631"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268632"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268633"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268634"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268635"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268636"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268637"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268638"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268639"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268664"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268665"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268666"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268667"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268668"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268669"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268670"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268671"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268672"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268673"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268674"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268675"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268676"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268677"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268678"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268679"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268752"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268753"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268754"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268755"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268756"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268757"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268758"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268759"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268768"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268769"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268770"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268771"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268772"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268773"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268774"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268775"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268776"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268777"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268778"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268779"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268780"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268781"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268782"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268783"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268784"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268785"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268786"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268787"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268788"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268789"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268790"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268791"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268792"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268793"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268794"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268795"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268796"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268797"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268798"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268799"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F2688"] = "The object refers to an object that was not found." + self.system_fault_code["F268800"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268801"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268802"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268803"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268804"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268805"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268806"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268807"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268832"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268833"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268834"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268835"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268836"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268837"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268838"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268839"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F268840"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268841"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268842"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268843"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268844"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268845"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268846"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F268847"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2689"] = "The object refers to an object that was not found." + self.system_fault_code["F268920"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268921"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268922"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268923"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268924"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268925"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268926"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268927"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F268936"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268937"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268938"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268939"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268940"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268941"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268942"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268943"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F268944"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268945"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268946"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268947"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268948"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268949"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268950"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268951"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F268952"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268953"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268954"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268955"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268956"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268957"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268958"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268959"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F268960"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268961"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268962"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268963"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268964"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268965"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268966"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268967"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F268968"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268969"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268970"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268971"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268972"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268973"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268974"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F268975"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F2690"] = "The object refers to an object that was not found." + self.system_fault_code["F269000"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269001"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269002"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269003"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269004"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269005"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269006"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269007"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269008"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269009"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269010"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269011"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269012"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269013"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269014"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269015"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269088"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269089"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269090"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269091"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269092"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269093"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269094"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269095"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269104"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269105"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269106"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269107"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269108"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269109"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269110"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269111"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269112"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269113"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269114"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269115"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269116"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269117"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269118"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269119"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269120"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269121"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269122"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269123"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269124"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269125"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269126"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269127"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269128"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269129"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269130"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269131"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269132"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269133"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269134"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269135"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269136"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269137"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269138"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269139"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269140"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269141"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269142"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269143"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269168"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269169"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269170"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269171"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269172"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269173"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269174"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269175"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269176"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269177"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269178"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269179"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269180"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269181"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269182"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269183"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269256"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269257"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269258"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269259"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269260"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269261"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269262"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269263"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269272"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269273"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269274"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269275"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269276"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269277"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269278"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269279"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269280"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269281"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269282"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269283"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269284"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269285"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269286"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269287"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269288"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269289"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269290"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269291"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269292"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269293"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269294"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269295"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269296"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269297"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269298"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269299"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269300"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269301"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269302"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269303"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269304"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269305"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269306"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269307"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269308"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269309"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269310"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269311"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269336"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269337"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269338"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269339"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269340"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269341"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269342"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269343"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269344"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269345"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269346"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269347"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269348"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269349"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269350"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269351"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2694"] = "This fault is raised when there is an issue with respect to the end point." + self.system_fault_code["F269424"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269425"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269426"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269427"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269428"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269429"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269430"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269431"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269440"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269441"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269442"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269443"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269444"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269445"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269446"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269447"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269448"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269449"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269450"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269451"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269452"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269453"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269454"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269455"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269456"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269457"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269458"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269459"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269460"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269461"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269462"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269463"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269464"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269465"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269466"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269467"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269468"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269469"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269470"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269471"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269472"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269473"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269474"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269475"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269476"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269477"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269478"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269479"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269504"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269505"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269506"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269507"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269508"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269509"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269510"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269511"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269512"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269513"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269514"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269515"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269516"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269517"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269518"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269519"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269592"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269593"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269594"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269595"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269596"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269597"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269598"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269599"] = "This fault is caused by 'packets within the 1st bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269608"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269609"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269610"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269611"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269612"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269613"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269614"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269615"] = "This fault is caused by 'packets within the 1st bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269616"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269617"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269618"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269619"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269620"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269621"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269622"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269623"] = "This fault is caused by 'packets within the 1st bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269624"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269625"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269626"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269627"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269628"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269629"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269630"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269631"] = "This fault is caused by 'packets within the 1st bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269632"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269633"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269634"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269635"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269636"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269637"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269638"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269639"] = "This fault is caused by 'packets within the 1st bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269640"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269641"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269642"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269643"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269644"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269645"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269646"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269647"] = "This fault is caused by 'packets within the 1st bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269672"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269673"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269674"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269675"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269676"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269677"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269678"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269679"] = "This fault is caused by 'packets within the 1st bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269680"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269681"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269682"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269683"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269684"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269685"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269686"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269687"] = "This fault is caused by 'packets within the 1st bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269760"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269761"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269762"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269763"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269764"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269765"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269766"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269767"] = "This fault is caused by 'packets within the 2nd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269776"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269777"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269778"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269779"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269780"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269781"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269782"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269783"] = "This fault is caused by 'packets within the 2nd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269784"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269785"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269786"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269787"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269788"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269789"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269790"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269791"] = "This fault is caused by 'packets within the 2nd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269792"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269793"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269794"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269795"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269796"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269797"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269798"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269799"] = "This fault is caused by 'packets within the 2nd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F2698"] = "The object refers to an object that was not found." + self.system_fault_code["F269800"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269801"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269802"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269803"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269804"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269805"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269806"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269807"] = "This fault is caused by 'packets within the 2nd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269808"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269809"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269810"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269811"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269812"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269813"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269814"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269815"] = "This fault is caused by 'packets within the 2nd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269840"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269841"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269842"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269843"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269844"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269845"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269846"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269847"] = "This fault is caused by 'packets within the 2nd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F269848"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269849"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269850"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269851"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269852"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269853"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269854"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F269855"] = "This fault is caused by 'packets within the 2nd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2699"] = "This fault occurs when steady state is not reached by policy manager, with respect to policy updates, for reconciliation" + self.system_fault_code["F269928"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269929"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269930"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269931"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269932"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269933"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269934"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269935"] = "This fault is caused by 'packets within the 3rd bucket current value' statistical property crossing threshold level." + self.system_fault_code["F269944"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269945"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269946"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269947"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269948"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269949"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269950"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269951"] = "This fault is caused by 'packets within the 3rd bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F269952"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269953"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269954"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269955"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269956"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269957"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269958"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269959"] = "This fault is caused by 'packets within the 3rd bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F269960"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269961"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269962"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269963"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269964"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269965"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269966"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269967"] = "This fault is caused by 'packets within the 3rd bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F269968"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269969"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269970"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269971"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269972"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269973"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269974"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269975"] = "This fault is caused by 'packets within the 3rd bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F269976"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269977"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269978"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269979"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269980"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269981"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269982"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F269983"] = "This fault is caused by 'packets within the 3rd bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270008"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270009"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270010"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270011"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270012"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270013"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270014"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270015"] = "This fault is caused by 'packets within the 3rd bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270016"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270017"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270018"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270019"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270020"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270021"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270022"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270023"] = "This fault is caused by 'packets within the 3rd bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270096"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270097"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270098"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270099"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270100"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270101"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270102"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270103"] = "This fault is caused by 'packets within the 4th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270112"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270113"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270114"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270115"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270116"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270117"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270118"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270119"] = "This fault is caused by 'packets within the 4th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270120"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270121"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270122"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270123"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270124"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270125"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270126"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270127"] = "This fault is caused by 'packets within the 4th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270128"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270129"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270130"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270131"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270132"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270133"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270134"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270135"] = "This fault is caused by 'packets within the 4th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270136"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270137"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270138"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270139"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270140"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270141"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270142"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270143"] = "This fault is caused by 'packets within the 4th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270144"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270145"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270146"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270147"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270148"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270149"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270150"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270151"] = "This fault is caused by 'packets within the 4th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270176"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270177"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270178"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270179"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270180"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270181"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270182"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270183"] = "This fault is caused by 'packets within the 4th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270184"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270185"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270186"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270187"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270188"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270189"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270190"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270191"] = "This fault is caused by 'packets within the 4th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270264"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270265"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270266"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270267"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270268"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270269"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270270"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270271"] = "This fault is caused by 'packets within the 5th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270280"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270281"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270282"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270283"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270284"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270285"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270286"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270287"] = "This fault is caused by 'packets within the 5th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270288"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270289"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270290"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270291"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270292"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270293"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270294"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270295"] = "This fault is caused by 'packets within the 5th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270296"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270297"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270298"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270299"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270300"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270301"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270302"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270303"] = "This fault is caused by 'packets within the 5th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270304"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270305"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270306"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270307"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270308"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270309"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270310"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270311"] = "This fault is caused by 'packets within the 5th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270312"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270313"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270314"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270315"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270316"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270317"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270318"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270319"] = "This fault is caused by 'packets within the 5th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270344"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270345"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270346"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270347"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270348"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270349"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270350"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270351"] = "This fault is caused by 'packets within the 5th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270352"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270353"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270354"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270355"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270356"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270357"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270358"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270359"] = "This fault is caused by 'packets within the 5th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270432"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270433"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270434"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270435"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270436"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270437"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270438"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270439"] = "This fault is caused by 'packets within the 6th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270448"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270449"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270450"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270451"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270452"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270453"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270454"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270455"] = "This fault is caused by 'packets within the 6th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270456"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270457"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270458"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270459"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270460"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270461"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270462"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270463"] = "This fault is caused by 'packets within the 6th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270464"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270465"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270466"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270467"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270468"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270469"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270470"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270471"] = "This fault is caused by 'packets within the 6th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270472"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270473"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270474"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270475"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270476"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270477"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270478"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270479"] = "This fault is caused by 'packets within the 6th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270480"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270481"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270482"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270483"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270484"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270485"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270486"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270487"] = "This fault is caused by 'packets within the 6th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F2705"] = "This fault occurs when vpc interface goes down while peer interface is up." + self.system_fault_code["F270512"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270513"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270514"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270515"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270516"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270517"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270518"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270519"] = "This fault is caused by 'packets within the 6th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270520"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270521"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270522"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270523"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270524"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270525"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270526"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270527"] = "This fault is caused by 'packets within the 6th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270600"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270601"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270602"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270603"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270604"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270605"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270606"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270607"] = "This fault is caused by 'packets within the 7th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270616"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270617"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270618"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270619"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270620"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270621"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270622"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270623"] = "This fault is caused by 'packets within the 7th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270624"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270625"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270626"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270627"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270628"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270629"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270630"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270631"] = "This fault is caused by 'packets within the 7th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270632"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270633"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270634"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270635"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270636"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270637"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270638"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270639"] = "This fault is caused by 'packets within the 7th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270640"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270641"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270642"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270643"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270644"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270645"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270646"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270647"] = "This fault is caused by 'packets within the 7th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270648"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270649"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270650"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270651"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270652"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270653"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270654"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270655"] = "This fault is caused by 'packets within the 7th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270680"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270681"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270682"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270683"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270684"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270685"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270686"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270687"] = "This fault is caused by 'packets within the 7th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270688"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270689"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270690"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270691"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270692"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270693"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270694"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270695"] = "This fault is caused by 'packets within the 7th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270768"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270769"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270770"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270771"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270772"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270773"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270774"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270775"] = "This fault is caused by 'packets within the 8th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270784"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270785"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270786"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270787"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270788"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270789"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270790"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270791"] = "This fault is caused by 'packets within the 8th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270792"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270793"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270794"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270795"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270796"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270797"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270798"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270799"] = "This fault is caused by 'packets within the 8th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270800"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270801"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270802"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270803"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270804"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270805"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270806"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270807"] = "This fault is caused by 'packets within the 8th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270808"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270809"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270810"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270811"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270812"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270813"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270814"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270815"] = "This fault is caused by 'packets within the 8th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270816"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270817"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270818"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270819"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270820"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270821"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270822"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270823"] = "This fault is caused by 'packets within the 8th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270848"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270849"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270850"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270851"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270852"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270853"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270854"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270855"] = "This fault is caused by 'packets within the 8th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F270856"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270857"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270858"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270859"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270860"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270861"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270862"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270863"] = "This fault is caused by 'packets within the 8th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F270936"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270937"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270938"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270939"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270940"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270941"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270942"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270943"] = "This fault is caused by 'packets within the 9th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F270952"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270953"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270954"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270955"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270956"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270957"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270958"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270959"] = "This fault is caused by 'packets within the 9th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F270960"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270961"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270962"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270963"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270964"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270965"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270966"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270967"] = "This fault is caused by 'packets within the 9th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F270968"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270969"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270970"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270971"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270972"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270973"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270974"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270975"] = "This fault is caused by 'packets within the 9th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F270976"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270977"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270978"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270979"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270980"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270981"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270982"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270983"] = "This fault is caused by 'packets within the 9th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F270984"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270985"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270986"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270987"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270988"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270989"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270990"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F270991"] = "This fault is caused by 'packets within the 9th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271016"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271017"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271018"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271019"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271020"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271021"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271022"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271023"] = "This fault is caused by 'packets within the 9th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271024"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271025"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271026"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271027"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271028"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271029"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271030"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271031"] = "This fault is caused by 'packets within the 9th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271104"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271105"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271106"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271107"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271108"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271109"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271110"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271111"] = "This fault is caused by 'packets within the 10th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271120"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271121"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271122"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271123"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271124"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271125"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271126"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271127"] = "This fault is caused by 'packets within the 10th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271128"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271129"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271130"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271131"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271132"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271133"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271134"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271135"] = "This fault is caused by 'packets within the 10th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271136"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271137"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271138"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271139"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271140"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271141"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271142"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271143"] = "This fault is caused by 'packets within the 10th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271144"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271145"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271146"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271147"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271148"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271149"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271150"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271151"] = "This fault is caused by 'packets within the 10th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271152"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271153"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271154"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271155"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271156"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271157"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271158"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271159"] = "This fault is caused by 'packets within the 10th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271184"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271185"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271186"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271187"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271188"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271189"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271190"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271191"] = "This fault is caused by 'packets within the 10th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271192"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271193"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271194"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271195"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271196"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271197"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271198"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271199"] = "This fault is caused by 'packets within the 10th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271272"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271273"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271274"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271275"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271276"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271277"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271278"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271279"] = "This fault is caused by 'packets within the 11th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271288"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271289"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271290"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271291"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271292"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271293"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271294"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271295"] = "This fault is caused by 'packets within the 11th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271296"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271297"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271298"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271299"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F2713"] = "This fault occurs when a QinQ tunnel is deployed on an unsupported platform ToR" + self.system_fault_code["F271300"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271301"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271302"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271303"] = "This fault is caused by 'packets within the 11th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271304"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271305"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271306"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271307"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271308"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271309"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271310"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271311"] = "This fault is caused by 'packets within the 11th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271312"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271313"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271314"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271315"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271316"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271317"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271318"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271319"] = "This fault is caused by 'packets within the 11th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271320"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271321"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271322"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271323"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271324"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271325"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271326"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271327"] = "This fault is caused by 'packets within the 11th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271352"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271353"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271354"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271355"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271356"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271357"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271358"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271359"] = "This fault is caused by 'packets within the 11th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271360"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271361"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271362"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271363"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271364"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271365"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271366"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271367"] = "This fault is caused by 'packets within the 11th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2714"] = "This fault occurs when port mode is configured as a qinq core/edge port on an unsupported platform" + self.system_fault_code["F271440"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271441"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271442"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271443"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271444"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271445"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271446"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271447"] = "This fault is caused by 'packets within the 12th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271456"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271457"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271458"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271459"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271460"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271461"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271462"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271463"] = "This fault is caused by 'packets within the 12th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271464"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271465"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271466"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271467"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271468"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271469"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271470"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271471"] = "This fault is caused by 'packets within the 12th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271472"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271473"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271474"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271475"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271476"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271477"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271478"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271479"] = "This fault is caused by 'packets within the 12th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271480"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271481"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271482"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271483"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271484"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271485"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271486"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271487"] = "This fault is caused by 'packets within the 12th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271488"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271489"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271490"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271491"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271492"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271493"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271494"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271495"] = "This fault is caused by 'packets within the 12th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271520"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271521"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271522"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271523"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271524"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271525"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271526"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271527"] = "This fault is caused by 'packets within the 12th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271528"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271529"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271530"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271531"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271532"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271533"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271534"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271535"] = "This fault is caused by 'packets within the 12th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271608"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271609"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271610"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271611"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271612"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271613"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271614"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271615"] = "This fault is caused by 'packets within the 13th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271624"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271625"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271626"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271627"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271628"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271629"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271630"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271631"] = "This fault is caused by 'packets within the 13th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271632"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271633"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271634"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271635"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271636"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271637"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271638"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271639"] = "This fault is caused by 'packets within the 13th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271640"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271641"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271642"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271643"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271644"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271645"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271646"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271647"] = "This fault is caused by 'packets within the 13th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271648"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271649"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271650"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271651"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271652"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271653"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271654"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271655"] = "This fault is caused by 'packets within the 13th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271656"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271657"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271658"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271659"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271660"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271661"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271662"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271663"] = "This fault is caused by 'packets within the 13th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271688"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271689"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271690"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271691"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271692"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271693"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271694"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271695"] = "This fault is caused by 'packets within the 13th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271696"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271697"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271698"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271699"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271700"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271701"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271702"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271703"] = "This fault is caused by 'packets within the 13th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271776"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271777"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271778"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271779"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271780"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271781"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271782"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271783"] = "This fault is caused by 'packets within the 14th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271792"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271793"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271794"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271795"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271796"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271797"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271798"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271799"] = "This fault is caused by 'packets within the 14th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271800"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271801"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271802"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271803"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271804"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271805"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271806"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271807"] = "This fault is caused by 'packets within the 14th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271808"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271809"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271810"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271811"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271812"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271813"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271814"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271815"] = "This fault is caused by 'packets within the 14th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271816"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271817"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271818"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271819"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271820"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271821"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271822"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271823"] = "This fault is caused by 'packets within the 14th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271824"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271825"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271826"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271827"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271828"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271829"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271830"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271831"] = "This fault is caused by 'packets within the 14th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271856"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271857"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271858"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271859"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271860"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271861"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271862"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271863"] = "This fault is caused by 'packets within the 14th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F271864"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271865"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271866"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271867"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271868"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271869"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271870"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F271871"] = "This fault is caused by 'packets within the 14th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2719"] = "The object refers to an object that was not found." + self.system_fault_code["F271944"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271945"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271946"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271947"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271948"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271949"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271950"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271951"] = "This fault is caused by 'packets within the 15th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F271960"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271961"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271962"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271963"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271964"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271965"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271966"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271967"] = "This fault is caused by 'packets within the 15th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F271968"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271969"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271970"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271971"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271972"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271973"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271974"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271975"] = "This fault is caused by 'packets within the 15th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F271976"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271977"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271978"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271979"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271980"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271981"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271982"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271983"] = "This fault is caused by 'packets within the 15th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F271984"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271985"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271986"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271987"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271988"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271989"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271990"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271991"] = "This fault is caused by 'packets within the 15th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F271992"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271993"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271994"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271995"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271996"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271997"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271998"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F271999"] = "This fault is caused by 'packets within the 15th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F2720"] = "This fault occurs when translation-capable flag is set on ISIS external interface but the LC is not Sugarbowl." + self.system_fault_code["F272024"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272025"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272026"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272027"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272028"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272029"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272030"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272031"] = "This fault is caused by 'packets within the 15th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272032"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272033"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272034"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272035"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272036"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272037"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272038"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272039"] = "This fault is caused by 'packets within the 15th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2721"] = "This fault occurs when the operational state of the FHS Instance is changed due to run time resource limits exhaustion" + self.system_fault_code["F272112"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272113"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272114"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272115"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272116"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272117"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272118"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272119"] = "This fault is caused by 'packets within the 16th bucket current value' statistical property crossing threshold level." + self.system_fault_code["F272128"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272129"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272130"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272131"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272132"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272133"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272134"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272135"] = "This fault is caused by 'packets within the 16th bucket cumulative' statistical property crossing threshold level." + self.system_fault_code["F272136"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272137"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272138"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272139"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272140"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272141"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272142"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272143"] = "This fault is caused by 'packets within the 16th bucket periodic' statistical property crossing threshold level." + self.system_fault_code["F272144"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272145"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272146"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272147"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272148"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272149"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272150"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272151"] = "This fault is caused by 'packets within the 16th bucket minimum value' statistical property crossing threshold level." + self.system_fault_code["F272152"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272153"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272154"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272155"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272156"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272157"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272158"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272159"] = "This fault is caused by 'packets within the 16th bucket maximum value' statistical property crossing threshold level." + self.system_fault_code["F272160"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272161"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272162"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272163"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272164"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272165"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272166"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272167"] = "This fault is caused by 'packets within the 16th bucket average value' statistical property crossing threshold level." + self.system_fault_code["F272192"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272193"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272194"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272195"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272196"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272197"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272198"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F272199"] = "This fault is caused by 'packets within the 16th bucket trend' statistical property crossing threshold level." + self.system_fault_code["F2722"] = "This fault occurs when First Hop Security detects security violation" + self.system_fault_code["F272200"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272201"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272202"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272203"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272204"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272205"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272206"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F272207"] = "This fault is caused by 'packets within the 16th bucket rate' statistical property crossing threshold level." + self.system_fault_code["F2725"] = "This fault occurs when port security policy configuration is deployed on an unsupported platform TOR. The reason could" + self.system_fault_code["F2728"] = "This fault occurs when latency feature is inactive." + self.system_fault_code["F2730"] = "This fault occurs when the SSD media wearout indicator (life remaining) is less than 10%." + self.system_fault_code["F2731"] = "This fault occurs when the SSD media wearout indicator (life remaining) is less than 5%." + self.system_fault_code["F2732"] = "This fault occurs when the SSD media wearout indicator (life remaining) is less than 1%." + self.system_fault_code["F2734"] = "The object refers to an object that was not found." + self.system_fault_code["F2735"] = "This fault occurs when the controller out-of-band management IPV4 address a is duplicate of the inband managment IPV4 address" + self.system_fault_code["F2736"] = "This fault occurs when the controller inband management IPV4 address is a duplicate of the out-of-band managment IPV4 address" + self.system_fault_code["F2737"] = "This fault occurs when the controller out-of-band management IPV6 address a is duplicate of the inband managment IPV6 address" + self.system_fault_code["F2738"] = "This fault occurs when the controller inband management IPV6 address is a duplicate of the out-of-band managment IPV6 address" + self.system_fault_code["F2739"] = "This fault occurs when user tries to configure Reflective Relay on unsupported hardware" + self.system_fault_code["F2740"] = "This fault occurs when port speed is configured to an invalid/unsupported value" + self.system_fault_code["F2741"] = "This fault occurs when user tries to configure Vlan scope as LOCAL for DTAG ports" + self.system_fault_code["F274248"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274249"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274250"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274251"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274252"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274253"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274254"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274255"] = "This fault is caused by 'critical Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274256"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274257"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274258"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274259"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274260"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274261"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274262"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274263"] = "This fault is caused by 'critical Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274264"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274265"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274266"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274267"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274268"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274269"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274270"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274271"] = "This fault is caused by 'critical Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274272"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274273"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274274"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274275"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274276"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274277"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274278"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274279"] = "This fault is caused by 'critical Fault average value' statistical property crossing threshold level." + self.system_fault_code["F2743"] = "The object refers to an object that was not found." + self.system_fault_code["F274312"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274313"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274314"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274315"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274316"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274317"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274318"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274319"] = "This fault is caused by 'critical Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274368"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274369"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274370"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274371"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274372"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274373"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274374"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274375"] = "This fault is caused by 'major Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274376"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274377"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274378"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274379"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274380"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274381"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274382"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274383"] = "This fault is caused by 'major Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274384"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274385"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274386"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274387"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274388"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274389"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274390"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274391"] = "This fault is caused by 'major Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274392"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274393"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274394"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274395"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274396"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274397"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274398"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274399"] = "This fault is caused by 'major Fault average value' statistical property crossing threshold level." + self.system_fault_code["F2744"] = "The object refers to an object that was not found." + self.system_fault_code["F274432"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274433"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274434"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274435"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274436"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274437"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274438"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274439"] = "This fault is caused by 'major Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274488"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274489"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274490"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274491"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274492"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274493"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274494"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274495"] = "This fault is caused by 'minor Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274496"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274497"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274498"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274499"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274500"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274501"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274502"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274503"] = "This fault is caused by 'minor Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274504"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274505"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274506"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274507"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274508"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274509"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274510"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274511"] = "This fault is caused by 'minor Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274512"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274513"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274514"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274515"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274516"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274517"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274518"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274519"] = "This fault is caused by 'minor Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274552"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274553"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274554"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274555"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274556"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274557"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274558"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274559"] = "This fault is caused by 'minor Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274608"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274609"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274610"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274611"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274612"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274613"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274614"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274615"] = "This fault is caused by 'warning Fault current value' statistical property crossing threshold level." + self.system_fault_code["F274616"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274617"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274618"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274619"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274620"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274621"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274622"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274623"] = "This fault is caused by 'warning Fault minimum value' statistical property crossing threshold level." + self.system_fault_code["F274624"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274625"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274626"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274627"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274628"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274629"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274630"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274631"] = "This fault is caused by 'warning Fault maximum value' statistical property crossing threshold level." + self.system_fault_code["F274632"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274633"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274634"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274635"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274636"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274637"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274638"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274639"] = "This fault is caused by 'warning Fault average value' statistical property crossing threshold level." + self.system_fault_code["F274672"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274673"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274674"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274675"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274676"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274677"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274678"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F274679"] = "This fault is caused by 'warning Fault trend' statistical property crossing threshold level." + self.system_fault_code["F275504"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275505"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275506"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275507"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275508"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275509"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275510"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275511"] = "This fault is caused by 'Application CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F275512"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275513"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275514"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275515"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275516"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275517"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275518"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275519"] = "This fault is caused by 'Application CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275520"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275521"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275522"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275523"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275524"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275525"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275526"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275527"] = "This fault is caused by 'Application CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275528"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275529"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275530"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275531"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275532"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275533"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275534"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275535"] = "This fault is caused by 'Application CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F275568"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275569"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275570"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275571"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275572"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275573"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275574"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275575"] = "This fault is caused by 'Application CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F275624"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275625"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275626"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275627"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275628"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275629"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275630"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275631"] = "This fault is caused by 'Application memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F275632"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275633"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275634"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275635"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275636"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275637"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275638"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275639"] = "This fault is caused by 'Application memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F275640"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275641"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275642"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275643"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275644"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275645"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275646"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275647"] = "This fault is caused by 'Application memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F275648"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275649"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275650"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275651"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275652"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275653"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275654"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275655"] = "This fault is caused by 'Application memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F275688"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275689"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275690"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275691"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275692"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275693"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275694"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F275695"] = "This fault is caused by 'Application memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F2770"] = "The object refers to an object that was not found." + self.system_fault_code["F2771"] = "FEX is offline due to SDP timeout" + self.system_fault_code["F2773"] = "This fault occurs when a ntp configuration on a controller has problems" + self.system_fault_code["F2774"] = "The object refers to an object that was not found." + self.system_fault_code["F277496"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277497"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277498"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277499"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277500"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277501"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277502"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277503"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277512"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277513"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277514"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277515"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277516"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277517"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277518"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277519"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277520"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277521"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277522"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277523"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277524"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277525"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277526"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277527"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277528"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277529"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277530"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277531"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277532"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277533"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277534"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277535"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277536"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277537"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277538"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277539"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277540"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277541"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277542"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277543"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277544"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277545"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277546"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277547"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277548"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277549"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277550"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277551"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277576"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277577"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277578"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277579"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277580"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277581"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277582"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277583"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277584"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277585"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277586"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277587"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277588"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277589"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277590"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277591"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277664"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277665"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277666"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277667"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277668"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277669"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277670"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277671"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277672"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277673"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277674"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277675"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277676"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277677"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277678"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277679"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277680"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277681"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277682"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277683"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277684"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277685"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277686"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277687"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277688"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277689"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277690"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277691"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277692"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277693"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277694"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277695"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277728"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277729"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277730"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277731"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277732"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277733"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277734"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277735"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Broadcast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F277784"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277785"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277786"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277787"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277788"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277789"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277790"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277791"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic current value' statistical property crossing threshold" + self.system_fault_code["F277800"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277801"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277802"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277803"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277804"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277805"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277806"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277807"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic cumulative' statistical property crossing threshold" + self.system_fault_code["F277808"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277809"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277810"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277811"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277812"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277813"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277814"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277815"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic periodic' statistical property crossing threshold level." + self.system_fault_code["F277816"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277817"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277818"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277819"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277820"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277821"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277822"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277823"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic minimum value' statistical property crossing threshold" + self.system_fault_code["F277824"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277825"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277826"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277827"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277828"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277829"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277830"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277831"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic maximum value' statistical property crossing threshold" + self.system_fault_code["F277832"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277833"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277834"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277835"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277836"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277837"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277838"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277839"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic average value' statistical property crossing threshold" + self.system_fault_code["F277864"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277865"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277866"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277867"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277868"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277869"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277870"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277871"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic trend' statistical property crossing threshold level." + self.system_fault_code["F277872"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277873"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277874"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277875"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277876"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277877"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277878"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277879"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate' statistical property crossing threshold level." + self.system_fault_code["F277952"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277953"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277954"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277955"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277956"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277957"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277958"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277959"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate current value' statistical property crossing threshold" + self.system_fault_code["F277960"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277961"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277962"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277963"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277964"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277965"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277966"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277967"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate minimum value' statistical property crossing threshold" + self.system_fault_code["F277968"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277969"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277970"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277971"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277972"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277973"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277974"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277975"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate maximum value' statistical property crossing threshold" + self.system_fault_code["F277976"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277977"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277978"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277979"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277980"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277981"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277982"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F277983"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate average value' statistical property crossing threshold" + self.system_fault_code["F278016"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278017"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278018"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278019"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278020"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278021"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278022"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278023"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Multicast traffic rate trend' statistical property crossing threshold" + self.system_fault_code["F278072"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278073"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278074"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278075"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278076"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278077"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278078"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278079"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts current value' statistical property crossing threshold" + self.system_fault_code["F278088"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278089"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278090"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278091"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278092"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278093"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278094"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278095"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts cumulative' statistical property crossing threshold" + self.system_fault_code["F278096"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278097"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278098"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278099"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278100"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278101"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278102"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278103"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts periodic' statistical property crossing threshold" + self.system_fault_code["F278104"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278105"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278106"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278107"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278108"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278109"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278110"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278111"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts minimum value' statistical property crossing threshold" + self.system_fault_code["F278112"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278113"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278114"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278115"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278116"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278117"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278118"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278119"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts maximum value' statistical property crossing threshold" + self.system_fault_code["F278120"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278121"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278122"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278123"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278124"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278125"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278126"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278127"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts average value' statistical property crossing threshold" + self.system_fault_code["F278152"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278153"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278154"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278155"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278156"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278157"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278158"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278159"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts trend' statistical property crossing threshold level." + self.system_fault_code["F278160"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278161"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278162"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278163"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278164"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278165"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278166"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278167"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate' statistical property crossing threshold level." + self.system_fault_code["F278240"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278241"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278242"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278243"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278244"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278245"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278246"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278247"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate current value' statistical property crossing" + self.system_fault_code["F278248"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278249"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278250"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278251"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278252"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278253"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278254"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278255"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate minimum value' statistical property crossing" + self.system_fault_code["F278256"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278257"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278258"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278259"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278260"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278261"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278262"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278263"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate maximum value' statistical property crossing" + self.system_fault_code["F278264"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278265"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278266"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278267"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278268"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278269"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278270"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278271"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate average value' statistical property crossing" + self.system_fault_code["F278304"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278305"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278306"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278307"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278308"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278309"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278310"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F278311"] = "This fault is caused by 'Storm Ctrl Drop Bytes for Unknown Unicast pkts rate trend' statistical property crossing threshold" + self.system_fault_code["F2786"] = "This fault occurs when the monitor is applied on an incompatible record type" + self.system_fault_code["F2788"] = "This fault occurs when hash policy can't be configured on switch" + self.system_fault_code["F278984"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278985"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278986"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278987"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278988"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278989"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278990"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F278991"] = "This fault is caused by 'Macsec Decrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F279000"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279001"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279002"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279003"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279004"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279005"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279006"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279007"] = "This fault is caused by 'Macsec Decrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279008"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279009"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279010"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279011"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279012"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279013"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279014"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279015"] = "This fault is caused by 'Macsec Decrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279016"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279017"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279018"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279019"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279020"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279021"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279022"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279023"] = "This fault is caused by 'Macsec Decrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279024"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279025"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279026"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279027"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279028"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279029"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279030"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279031"] = "This fault is caused by 'Macsec Decrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279032"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279033"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279034"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279035"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279036"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279037"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279038"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279039"] = "This fault is caused by 'Macsec Decrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F279064"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279065"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279066"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279067"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279068"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279069"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279070"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279071"] = "This fault is caused by 'Macsec Decrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F279072"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279073"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279074"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279075"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279076"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279077"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279078"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279079"] = "This fault is caused by 'Macsec Decrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F279152"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279153"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279154"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279155"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279156"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279157"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279158"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279159"] = "This fault is caused by 'Macsec Decrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279160"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279161"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279162"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279163"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279164"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279165"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279166"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279167"] = "This fault is caused by 'Macsec Decrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279168"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279169"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279170"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279171"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279172"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279173"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279174"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279175"] = "This fault is caused by 'Macsec Decrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279176"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279177"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279178"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279179"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279180"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279181"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279182"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279183"] = "This fault is caused by 'Macsec Decrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279216"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279217"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279218"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279219"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279220"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279221"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279222"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279223"] = "This fault is caused by 'Macsec Decrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279272"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279273"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279274"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279275"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279276"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279277"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279278"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279279"] = "This fault is caused by 'Macsec Validated octets current value' statistical property crossing threshold level." + self.system_fault_code["F279288"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279289"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279290"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279291"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279292"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279293"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279294"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279295"] = "This fault is caused by 'Macsec Validated octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279296"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279297"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279298"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279299"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279300"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279301"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279302"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279303"] = "This fault is caused by 'Macsec Validated octets periodic' statistical property crossing threshold level." + self.system_fault_code["F279304"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279305"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279306"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279307"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279308"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279309"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279310"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279311"] = "This fault is caused by 'Macsec Validated octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279312"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279313"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279314"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279315"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279316"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279317"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279318"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279319"] = "This fault is caused by 'Macsec Validated octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279320"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279321"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279322"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279323"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279324"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279325"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279326"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279327"] = "This fault is caused by 'Macsec Validated octets average value' statistical property crossing threshold level." + self.system_fault_code["F279352"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279353"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279354"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279355"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279356"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279357"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279358"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279359"] = "This fault is caused by 'Macsec Validated octets trend' statistical property crossing threshold level." + self.system_fault_code["F279360"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279361"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279362"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279363"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279364"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279365"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279366"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F279367"] = "This fault is caused by 'Macsec Validated octets rate' statistical property crossing threshold level." + self.system_fault_code["F2794"] = "The object refers to an object that was not found." + self.system_fault_code["F279440"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279441"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279442"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279443"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279444"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279445"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279446"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279447"] = "This fault is caused by 'Macsec Validated octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279448"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279449"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279450"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279451"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279452"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279453"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279454"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279455"] = "This fault is caused by 'Macsec Validated octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279456"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279457"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279458"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279459"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279460"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279461"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279462"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279463"] = "This fault is caused by 'Macsec Validated octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279464"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279465"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279466"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279467"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279468"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279469"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279470"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279471"] = "This fault is caused by 'Macsec Validated octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279504"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279505"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279506"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279507"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279508"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279509"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279510"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279511"] = "This fault is caused by 'Macsec Validated octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279560"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279561"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279562"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279563"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279564"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279565"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279566"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279567"] = "This fault is caused by 'Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F279576"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279577"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279578"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279579"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279580"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279581"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279582"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279583"] = "This fault is caused by 'Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279584"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279585"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279586"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279587"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279588"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279589"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279590"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279591"] = "This fault is caused by 'Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279592"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279593"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279594"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279595"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279596"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279597"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279598"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279599"] = "This fault is caused by 'Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279600"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279601"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279602"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279603"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279604"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279605"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279606"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279607"] = "This fault is caused by 'Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279608"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279609"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279610"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279611"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279612"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279613"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279614"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279615"] = "This fault is caused by 'Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F279640"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279641"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279642"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279643"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279644"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279645"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279646"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279647"] = "This fault is caused by 'Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F279648"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279649"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279650"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279651"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279652"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279653"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279654"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279655"] = "This fault is caused by 'Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F279728"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279729"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279730"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279731"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279732"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279733"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279734"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279735"] = "This fault is caused by 'Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F279736"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279737"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279738"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279739"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279740"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279741"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279742"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279743"] = "This fault is caused by 'Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F279744"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279745"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279746"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279747"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279748"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279749"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279750"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279751"] = "This fault is caused by 'Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F279752"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279753"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279754"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279755"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279756"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279757"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279758"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279759"] = "This fault is caused by 'Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F279792"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279793"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279794"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279795"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279796"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279797"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279798"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279799"] = "This fault is caused by 'Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F279848"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279849"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279850"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279851"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279852"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279853"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279854"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279855"] = "This fault is caused by 'Macsec Validated packets current value' statistical property crossing threshold level." + self.system_fault_code["F279864"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279865"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279866"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279867"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279868"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279869"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279870"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279871"] = "This fault is caused by 'Macsec Validated packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F279872"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279873"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279874"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279875"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279876"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279877"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279878"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279879"] = "This fault is caused by 'Macsec Validated packets periodic' statistical property crossing threshold level." + self.system_fault_code["F279880"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279881"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279882"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279883"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279884"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279885"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279886"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279887"] = "This fault is caused by 'Macsec Validated packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F279888"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279889"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279890"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279891"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279892"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279893"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279894"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279895"] = "This fault is caused by 'Macsec Validated packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F279896"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279897"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279898"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279899"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F2799"] = "The object refers to an object that was not found." + self.system_fault_code["F279900"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279901"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279902"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279903"] = "This fault is caused by 'Macsec Validated packets average value' statistical property crossing threshold level." + self.system_fault_code["F279928"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279929"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279930"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279931"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279932"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279933"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279934"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279935"] = "This fault is caused by 'Macsec Validated packets trend' statistical property crossing threshold level." + self.system_fault_code["F279936"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279937"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279938"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279939"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279940"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279941"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279942"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F279943"] = "This fault is caused by 'Macsec Validated packets rate' statistical property crossing threshold level." + self.system_fault_code["F280016"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280017"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280018"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280019"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280020"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280021"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280022"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280023"] = "This fault is caused by 'Macsec Validated packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280024"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280025"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280026"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280027"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280028"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280029"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280030"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280031"] = "This fault is caused by 'Macsec Validated packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280032"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280033"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280034"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280035"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280036"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280037"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280038"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280039"] = "This fault is caused by 'Macsec Validated packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280040"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280041"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280042"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280043"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280044"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280045"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280046"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280047"] = "This fault is caused by 'Macsec Validated packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280080"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280081"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280082"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280083"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280084"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280085"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280086"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280087"] = "This fault is caused by 'Macsec Validated packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280136"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280137"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280138"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280139"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280140"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280141"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280142"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280143"] = "This fault is caused by 'Macsec Encrypted octets current value' statistical property crossing threshold level." + self.system_fault_code["F280152"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280153"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280154"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280155"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280156"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280157"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280158"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280159"] = "This fault is caused by 'Macsec Encrypted octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280160"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280161"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280162"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280163"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280164"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280165"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280166"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280167"] = "This fault is caused by 'Macsec Encrypted octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280168"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280169"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280170"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280171"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280172"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280173"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280174"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280175"] = "This fault is caused by 'Macsec Encrypted octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280176"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280177"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280178"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280179"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280180"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280181"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280182"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280183"] = "This fault is caused by 'Macsec Encrypted octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280184"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280185"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280186"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280187"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280188"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280189"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280190"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280191"] = "This fault is caused by 'Macsec Encrypted octets average value' statistical property crossing threshold level." + self.system_fault_code["F280216"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280217"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280218"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280219"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280220"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280221"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280222"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280223"] = "This fault is caused by 'Macsec Encrypted octets trend' statistical property crossing threshold level." + self.system_fault_code["F280224"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280225"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280226"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280227"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280228"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280229"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280230"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F280231"] = "This fault is caused by 'Macsec Encrypted octets rate' statistical property crossing threshold level." + self.system_fault_code["F2803"] = "The object refers to an object that was not found." + self.system_fault_code["F280304"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280305"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280306"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280307"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280308"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280309"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280310"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280311"] = "This fault is caused by 'Macsec Encrypted octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280312"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280313"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280314"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280315"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280316"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280317"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280318"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280319"] = "This fault is caused by 'Macsec Encrypted octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280320"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280321"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280322"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280323"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280324"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280325"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280326"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280327"] = "This fault is caused by 'Macsec Encrypted octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280328"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280329"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280330"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280331"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280332"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280333"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280334"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280335"] = "This fault is caused by 'Macsec Encrypted octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280368"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280369"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280370"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280371"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280372"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280373"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280374"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280375"] = "This fault is caused by 'Macsec Encrypted octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280424"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280425"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280426"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280427"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280428"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280429"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280430"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280431"] = "This fault is caused by 'Macsec Protected octets current value' statistical property crossing threshold level." + self.system_fault_code["F280440"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280441"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280442"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280443"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280444"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280445"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280446"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280447"] = "This fault is caused by 'Macsec Protected octets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280448"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280449"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280450"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280451"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280452"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280453"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280454"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280455"] = "This fault is caused by 'Macsec Protected octets periodic' statistical property crossing threshold level." + self.system_fault_code["F280456"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280457"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280458"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280459"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280460"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280461"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280462"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280463"] = "This fault is caused by 'Macsec Protected octets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280464"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280465"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280466"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280467"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280468"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280469"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280470"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280471"] = "This fault is caused by 'Macsec Protected octets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280472"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280473"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280474"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280475"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280476"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280477"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280478"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F280479"] = "This fault is caused by 'Macsec Protected octets average value' statistical property crossing threshold level." + self.system_fault_code["F2805"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F280504"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280505"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280506"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280507"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280508"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280509"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280510"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280511"] = "This fault is caused by 'Macsec Protected octets trend' statistical property crossing threshold level." + self.system_fault_code["F280512"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280513"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280514"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280515"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280516"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280517"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280518"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280519"] = "This fault is caused by 'Macsec Protected octets rate' statistical property crossing threshold level." + self.system_fault_code["F280592"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280593"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280594"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280595"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280596"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280597"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280598"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280599"] = "This fault is caused by 'Macsec Protected octets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280600"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280601"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280602"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280603"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280604"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280605"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280606"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280607"] = "This fault is caused by 'Macsec Protected octets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280608"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280609"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280610"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280611"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280612"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280613"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280614"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280615"] = "This fault is caused by 'Macsec Protected octets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280616"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280617"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280618"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280619"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280620"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280621"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280622"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280623"] = "This fault is caused by 'Macsec Protected octets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280656"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280657"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280658"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280659"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280660"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280661"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280662"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280663"] = "This fault is caused by 'Macsec Protected octets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280712"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280713"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280714"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280715"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280716"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280717"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280718"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280719"] = "This fault is caused by 'Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F280728"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280729"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280730"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280731"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280732"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280733"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280734"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280735"] = "This fault is caused by 'Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F280736"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280737"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280738"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280739"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280740"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280741"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280742"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280743"] = "This fault is caused by 'Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F280744"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280745"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280746"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280747"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280748"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280749"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280750"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280751"] = "This fault is caused by 'Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F280752"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280753"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280754"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280755"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280756"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280757"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280758"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280759"] = "This fault is caused by 'Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F280760"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280761"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280762"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280763"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280764"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280765"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280766"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280767"] = "This fault is caused by 'Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F280792"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280793"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280794"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280795"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280796"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280797"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280798"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280799"] = "This fault is caused by 'Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F280800"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280801"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280802"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280803"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280804"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280805"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280806"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280807"] = "This fault is caused by 'Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F280880"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280881"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280882"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280883"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280884"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280885"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280886"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280887"] = "This fault is caused by 'Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F280888"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280889"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280890"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280891"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280892"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280893"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280894"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280895"] = "This fault is caused by 'Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F280896"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280897"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280898"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280899"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280900"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280901"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280902"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280903"] = "This fault is caused by 'Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F280904"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280905"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280906"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280907"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280908"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280909"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280910"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280911"] = "This fault is caused by 'Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F280944"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280945"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280946"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280947"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280948"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280949"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280950"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F280951"] = "This fault is caused by 'Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281000"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281001"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281002"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281003"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281004"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281005"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281006"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281007"] = "This fault is caused by 'Macsec Protected packets current value' statistical property crossing threshold level." + self.system_fault_code["F281016"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281017"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281018"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281019"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281020"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281021"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281022"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281023"] = "This fault is caused by 'Macsec Protected packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F281024"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281025"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281026"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281027"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281028"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281029"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281030"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281031"] = "This fault is caused by 'Macsec Protected packets periodic' statistical property crossing threshold level." + self.system_fault_code["F281032"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281033"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281034"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281035"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281036"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281037"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281038"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281039"] = "This fault is caused by 'Macsec Protected packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F281040"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281041"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281042"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281043"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281044"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281045"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281046"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281047"] = "This fault is caused by 'Macsec Protected packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F281048"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281049"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281050"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281051"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281052"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281053"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281054"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281055"] = "This fault is caused by 'Macsec Protected packets average value' statistical property crossing threshold level." + self.system_fault_code["F281080"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281081"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281082"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281083"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281084"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281085"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281086"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281087"] = "This fault is caused by 'Macsec Protected packets trend' statistical property crossing threshold level." + self.system_fault_code["F281088"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281089"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281090"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281091"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281092"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281093"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281094"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281095"] = "This fault is caused by 'Macsec Protected packets rate' statistical property crossing threshold level." + self.system_fault_code["F281168"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281169"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281170"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281171"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281172"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281173"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281174"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281175"] = "This fault is caused by 'Macsec Protected packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F281176"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281177"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281178"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281179"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281180"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281181"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281182"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281183"] = "This fault is caused by 'Macsec Protected packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F281184"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281185"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281186"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281187"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281188"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281189"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281190"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281191"] = "This fault is caused by 'Macsec Protected packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F281192"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281193"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281194"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281195"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281196"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281197"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281198"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F281199"] = "This fault is caused by 'Macsec Protected packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F2812"] = "This fault occurs when the connection to DNS Server" + self.system_fault_code["F281232"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281233"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281234"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281235"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281236"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281237"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281238"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F281239"] = "This fault is caused by 'Macsec Protected packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2813"] = "This fault occurs when the connection to DNS Server doesn't read any data from zonebr/>" + self.system_fault_code["F2816"] = "The object refers to an object that was not found." + self.system_fault_code["F2817"] = "This fault occurs when either the total latency-stats rule reaches maximum programmable limit or an unsupported modification" + self.system_fault_code["F2822"] = "The object refers to an object that was not found." + self.system_fault_code["F2823"] = "The object refers to an object that was not found." + self.system_fault_code["F2824"] = "This fault occurs when more than one neighbor is learnt on an interface configured as point-to-point" + self.system_fault_code["F2827"] = "This fault occurs when Nexthop EP Reachability configuration is deployed on an unsupported platform TOR. The reason could" + self.system_fault_code["F2828"] = "This fault occurs when Nexthop EP Reachability configuration is deployed on an unsupported platform TOR. The reason could" + self.system_fault_code["F282848"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282849"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282850"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282851"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282852"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282853"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282854"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282855"] = "This fault is caused by 'ArpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F282864"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282865"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282866"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282867"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282868"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282869"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282870"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282871"] = "This fault is caused by 'ArpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F282872"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282873"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282874"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282875"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282876"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282877"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282878"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282879"] = "This fault is caused by 'ArpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F282880"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282881"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282882"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282883"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282884"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282885"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282886"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282887"] = "This fault is caused by 'ArpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F282888"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282889"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282890"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282891"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282892"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282893"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282894"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282895"] = "This fault is caused by 'ArpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F282896"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282897"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282898"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282899"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282900"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282901"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282902"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282903"] = "This fault is caused by 'ArpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F282928"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282929"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282930"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282931"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282932"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282933"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282934"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282935"] = "This fault is caused by 'ArpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F282936"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282937"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282938"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282939"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282940"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282941"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282942"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F282943"] = "This fault is caused by 'ArpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2830"] = "The object refers to an object that was not found." + self.system_fault_code["F283016"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283017"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283018"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283019"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283020"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283021"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283022"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283023"] = "This fault is caused by 'ArpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283024"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283025"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283026"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283027"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283028"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283029"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283030"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283031"] = "This fault is caused by 'ArpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283032"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283033"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283034"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283035"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283036"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283037"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283038"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283039"] = "This fault is caused by 'ArpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283040"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283041"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283042"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283043"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283044"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283045"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283046"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283047"] = "This fault is caused by 'ArpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283080"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283081"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283082"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283083"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283084"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283085"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283086"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283087"] = "This fault is caused by 'ArpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2831"] = "The object refers to an object that was not found." + self.system_fault_code["F283136"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283137"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283138"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283139"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283140"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283141"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283142"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283143"] = "This fault is caused by 'ArpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283152"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283153"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283154"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283155"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283156"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283157"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283158"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283159"] = "This fault is caused by 'ArpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283160"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283161"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283162"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283163"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283164"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283165"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283166"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283167"] = "This fault is caused by 'ArpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283168"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283169"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283170"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283171"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283172"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283173"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283174"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283175"] = "This fault is caused by 'ArpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283176"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283177"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283178"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283179"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283180"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283181"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283182"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283183"] = "This fault is caused by 'ArpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283184"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283185"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283186"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283187"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283188"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283189"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283190"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283191"] = "This fault is caused by 'ArpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283216"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283217"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283218"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283219"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283220"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283221"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283222"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283223"] = "This fault is caused by 'ArpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283224"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283225"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283226"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283227"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283228"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283229"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283230"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283231"] = "This fault is caused by 'ArpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2833"] = "This fault occurs when PBR service dest group goes to failed state due to threshold violation" + self.system_fault_code["F283304"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283305"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283306"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283307"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283308"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283309"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283310"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283311"] = "This fault is caused by 'ArpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283312"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283313"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283314"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283315"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283316"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283317"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283318"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283319"] = "This fault is caused by 'ArpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283320"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283321"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283322"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283323"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283324"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283325"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283326"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283327"] = "This fault is caused by 'ArpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283328"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283329"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283330"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283331"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283332"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283333"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283334"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283335"] = "This fault is caused by 'ArpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283368"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283369"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283370"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283371"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283372"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283373"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283374"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283375"] = "This fault is caused by 'ArpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2834"] = "This fault occurs when port mode is configured as a double encap port on an unsupported platform" + self.system_fault_code["F283424"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283425"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283426"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283427"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283428"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283429"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283430"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283431"] = "This fault is caused by 'ArpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F283440"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283441"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283442"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283443"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283444"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283445"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283446"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283447"] = "This fault is caused by 'ArpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F283448"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283449"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283450"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283451"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283452"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283453"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283454"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283455"] = "This fault is caused by 'ArpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F283456"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283457"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283458"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283459"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283460"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283461"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283462"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283463"] = "This fault is caused by 'ArpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F283464"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283465"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283466"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283467"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283468"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283469"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283470"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283471"] = "This fault is caused by 'ArpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F283472"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283473"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283474"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283475"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283476"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283477"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283478"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283479"] = "This fault is caused by 'ArpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F283504"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283505"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283506"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283507"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283508"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283509"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283510"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283511"] = "This fault is caused by 'ArpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F283512"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283513"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283514"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283515"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283516"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283517"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283518"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283519"] = "This fault is caused by 'ArpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F283592"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283593"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283594"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283595"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283596"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283597"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283598"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283599"] = "This fault is caused by 'ArpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F283600"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283601"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283602"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283603"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283604"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283605"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283606"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283607"] = "This fault is caused by 'ArpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283608"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283609"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283610"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283611"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283612"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283613"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283614"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283615"] = "This fault is caused by 'ArpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283616"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283617"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283618"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283619"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283620"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283621"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283622"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283623"] = "This fault is caused by 'ArpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F283656"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283657"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283658"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283659"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283660"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283661"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283662"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283663"] = "This fault is caused by 'ArpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F283712"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283713"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283714"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283715"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283716"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283717"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283718"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283719"] = "This fault is caused by 'ArpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F283728"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283729"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283730"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283731"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283732"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283733"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283734"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283735"] = "This fault is caused by 'ArpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F283736"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283737"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283738"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283739"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283740"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283741"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283742"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283743"] = "This fault is caused by 'ArpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F283744"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283745"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283746"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283747"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283748"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283749"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283750"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283751"] = "This fault is caused by 'ArpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F283752"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283753"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283754"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283755"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283756"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283757"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283758"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283759"] = "This fault is caused by 'ArpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F283760"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283761"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283762"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283763"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283764"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283765"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283766"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283767"] = "This fault is caused by 'ArpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F283792"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283793"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283794"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283795"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283796"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283797"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283798"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283799"] = "This fault is caused by 'ArpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F283800"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283801"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283802"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283803"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283804"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283805"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283806"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283807"] = "This fault is caused by 'ArpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F283880"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283881"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283882"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283883"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283884"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283885"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283886"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283887"] = "This fault is caused by 'ArpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F283888"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283889"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283890"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283891"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283892"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283893"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283894"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283895"] = "This fault is caused by 'ArpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F283896"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283897"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283898"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283899"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F2839"] = "This fault is raised when ACI controller failed to get the properties of a VMware Distributed Switch." + self.system_fault_code["F283900"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283901"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283902"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283903"] = "This fault is caused by 'ArpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F283904"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283905"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283906"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283907"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283908"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283909"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283910"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283911"] = "This fault is caused by 'ArpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F283944"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283945"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283946"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283947"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283948"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283949"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283950"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F283951"] = "This fault is caused by 'ArpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2840"] = "This fault is raised when ACI controller failed to update the properties of a VMware hypervisor." + self.system_fault_code["F284000"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284001"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284002"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284003"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284004"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284005"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284006"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284007"] = "This fault is caused by 'BfdAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284016"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284017"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284018"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284019"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284020"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284021"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284022"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284023"] = "This fault is caused by 'BfdAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284024"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284025"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284026"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284027"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284028"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284029"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284030"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284031"] = "This fault is caused by 'BfdAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284032"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284033"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284034"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284035"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284036"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284037"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284038"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284039"] = "This fault is caused by 'BfdAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284040"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284041"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284042"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284043"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284044"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284045"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284046"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284047"] = "This fault is caused by 'BfdAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284048"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284049"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284050"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284051"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284052"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284053"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284054"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284055"] = "This fault is caused by 'BfdAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284080"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284081"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284082"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284083"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284084"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284085"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284086"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284087"] = "This fault is caused by 'BfdAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284088"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284089"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284090"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284091"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284092"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284093"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284094"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284095"] = "This fault is caused by 'BfdAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2841"] = "This fault is raised when ACI controller failed to update the properties of a VMware virtual machine." + self.system_fault_code["F284168"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284169"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284170"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284171"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284172"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284173"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284174"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284175"] = "This fault is caused by 'BfdAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284176"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284177"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284178"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284179"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284180"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284181"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284182"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284183"] = "This fault is caused by 'BfdAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284184"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284185"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284186"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284187"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284188"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284189"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284190"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284191"] = "This fault is caused by 'BfdAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284192"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284193"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284194"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284195"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284196"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284197"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284198"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284199"] = "This fault is caused by 'BfdAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F2842"] = "This fault is raised when ACI controller failed to update the properties of a VNIC (e.g., it can not find the EPG that" + self.system_fault_code["F284232"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284233"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284234"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284235"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284236"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284237"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284238"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284239"] = "This fault is caused by 'BfdAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284288"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284289"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284290"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284291"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284292"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284293"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284294"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284295"] = "This fault is caused by 'BfdAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F2843"] = "This fault is raised when ACI controller failed to find the DVS that the Hypervisor NIC is attached to." + self.system_fault_code["F284304"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284305"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284306"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284307"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284308"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284309"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284310"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284311"] = "This fault is caused by 'BfdAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284312"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284313"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284314"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284315"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284316"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284317"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284318"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284319"] = "This fault is caused by 'BfdAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284320"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284321"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284322"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284323"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284324"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284325"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284326"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284327"] = "This fault is caused by 'BfdAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284328"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284329"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284330"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284331"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284332"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284333"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284334"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284335"] = "This fault is caused by 'BfdAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284336"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284337"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284338"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284339"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284340"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284341"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284342"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284343"] = "This fault is caused by 'BfdAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284368"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284369"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284370"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284371"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284372"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284373"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284374"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284375"] = "This fault is caused by 'BfdAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284376"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284377"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284378"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284379"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284380"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284381"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284382"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284383"] = "This fault is caused by 'BfdAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2844"] = "This fault is raised when ACI controller failed to find the DVS that the VM KNIC is attached to." + self.system_fault_code["F284456"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284457"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284458"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284459"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284460"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284461"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284462"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284463"] = "This fault is caused by 'BfdAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F284464"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284465"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284466"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284467"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284468"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284469"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284470"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284471"] = "This fault is caused by 'BfdAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284472"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284473"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284474"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284475"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284476"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284477"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284478"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284479"] = "This fault is caused by 'BfdAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284480"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284481"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284482"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284483"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284484"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284485"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284486"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284487"] = "This fault is caused by 'BfdAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F284520"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284521"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284522"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284523"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284524"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284525"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284526"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284527"] = "This fault is caused by 'BfdAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F284576"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284577"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284578"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284579"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284580"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284581"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284582"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284583"] = "This fault is caused by 'BfdDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F284592"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284593"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284594"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284595"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284596"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284597"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284598"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284599"] = "This fault is caused by 'BfdDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F284600"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284601"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284602"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284603"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284604"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284605"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284606"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284607"] = "This fault is caused by 'BfdDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F284608"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284609"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284610"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284611"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284612"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284613"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284614"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284615"] = "This fault is caused by 'BfdDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F284616"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284617"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284618"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284619"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284620"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284621"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284622"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284623"] = "This fault is caused by 'BfdDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F284624"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284625"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284626"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284627"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284628"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284629"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284630"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284631"] = "This fault is caused by 'BfdDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F284656"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284657"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284658"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284659"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284660"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284661"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284662"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284663"] = "This fault is caused by 'BfdDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F284664"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284665"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284666"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284667"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284668"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284669"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284670"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284671"] = "This fault is caused by 'BfdDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F284744"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284745"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284746"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284747"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284748"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284749"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284750"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284751"] = "This fault is caused by 'BfdDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F284752"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284753"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284754"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284755"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284756"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284757"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284758"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284759"] = "This fault is caused by 'BfdDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F284760"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284761"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284762"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284763"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284764"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284765"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284766"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284767"] = "This fault is caused by 'BfdDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F284768"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284769"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284770"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284771"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284772"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284773"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284774"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284775"] = "This fault is caused by 'BfdDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F284808"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284809"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284810"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284811"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284812"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284813"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284814"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284815"] = "This fault is caused by 'BfdDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F284864"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284865"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284866"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284867"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284868"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284869"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284870"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284871"] = "This fault is caused by 'BfdDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F284880"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284881"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284882"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284883"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284884"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284885"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284886"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284887"] = "This fault is caused by 'BfdDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F284888"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284889"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284890"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284891"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284892"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284893"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284894"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284895"] = "This fault is caused by 'BfdDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F284896"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284897"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284898"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284899"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284900"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284901"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284902"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284903"] = "This fault is caused by 'BfdDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F284904"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284905"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284906"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284907"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284908"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284909"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284910"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284911"] = "This fault is caused by 'BfdDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F284912"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284913"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284914"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284915"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284916"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284917"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284918"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284919"] = "This fault is caused by 'BfdDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F284944"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284945"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284946"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284947"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284948"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284949"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284950"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284951"] = "This fault is caused by 'BfdDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F284952"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284953"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284954"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284955"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284956"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284957"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284958"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F284959"] = "This fault is caused by 'BfdDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285032"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285033"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285034"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285035"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285036"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285037"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285038"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285039"] = "This fault is caused by 'BfdDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285040"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285041"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285042"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285043"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285044"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285045"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285046"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285047"] = "This fault is caused by 'BfdDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285048"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285049"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285050"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285051"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285052"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285053"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285054"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285055"] = "This fault is caused by 'BfdDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285056"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285057"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285058"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285059"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285060"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285061"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285062"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285063"] = "This fault is caused by 'BfdDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285096"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285097"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285098"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285099"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2851"] = "This fault occurs when the Rsa Provider is not operational." + self.system_fault_code["F285100"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285101"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285102"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285103"] = "This fault is caused by 'BfdDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285152"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285153"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285154"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285155"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285156"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285157"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285158"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285159"] = "This fault is caused by 'BgpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285168"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285169"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285170"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285171"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285172"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285173"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285174"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285175"] = "This fault is caused by 'BgpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285176"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285177"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285178"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285179"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285180"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285181"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285182"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285183"] = "This fault is caused by 'BgpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285184"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285185"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285186"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285187"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285188"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285189"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285190"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285191"] = "This fault is caused by 'BgpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285192"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285193"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285194"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285195"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285196"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285197"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285198"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285199"] = "This fault is caused by 'BgpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F2852"] = "This fault occurs when the Rsa Provider is not operational." + self.system_fault_code["F285200"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285201"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285202"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285203"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285204"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285205"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285206"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285207"] = "This fault is caused by 'BgpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285232"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285233"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285234"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285235"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285236"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285237"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285238"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285239"] = "This fault is caused by 'BgpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285240"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285241"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285242"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285243"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285244"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285245"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285246"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285247"] = "This fault is caused by 'BgpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2853"] = "This fault occurs when the operational state of MACSec Interface is unsupported" + self.system_fault_code["F285320"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285321"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285322"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285323"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285324"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285325"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285326"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285327"] = "This fault is caused by 'BgpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285328"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285329"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285330"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285331"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285332"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285333"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285334"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285335"] = "This fault is caused by 'BgpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285336"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285337"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285338"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285339"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285340"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285341"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285342"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285343"] = "This fault is caused by 'BgpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285344"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285345"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285346"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285347"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285348"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285349"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285350"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285351"] = "This fault is caused by 'BgpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285384"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285385"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285386"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285387"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285388"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285389"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285390"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285391"] = "This fault is caused by 'BgpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2854"] = "This fault occurs when the operational state of MACSec Interface is unsupported" + self.system_fault_code["F285440"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285441"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285442"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285443"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285444"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285445"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285446"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285447"] = "This fault is caused by 'BgpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F285456"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285457"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285458"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285459"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285460"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285461"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285462"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285463"] = "This fault is caused by 'BgpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F285464"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285465"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285466"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285467"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285468"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285469"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285470"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285471"] = "This fault is caused by 'BgpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F285472"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285473"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285474"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285475"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285476"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285477"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285478"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285479"] = "This fault is caused by 'BgpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F285480"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285481"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285482"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285483"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285484"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285485"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285486"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285487"] = "This fault is caused by 'BgpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F285488"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285489"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285490"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285491"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285492"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285493"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285494"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F285495"] = "This fault is caused by 'BgpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F2855"] = "The object refers to an object that was not found." + self.system_fault_code["F285520"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285521"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285522"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285523"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285524"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285525"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285526"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285527"] = "This fault is caused by 'BgpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F285528"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285529"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285530"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285531"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285532"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285533"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285534"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F285535"] = "This fault is caused by 'BgpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2856"] = "The object refers to an object that was not found." + self.system_fault_code["F285608"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285609"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285610"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285611"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285612"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285613"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285614"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285615"] = "This fault is caused by 'BgpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F285616"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285617"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285618"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285619"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285620"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285621"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285622"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285623"] = "This fault is caused by 'BgpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285624"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285625"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285626"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285627"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285628"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285629"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285630"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285631"] = "This fault is caused by 'BgpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285632"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285633"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285634"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285635"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285636"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285637"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285638"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285639"] = "This fault is caused by 'BgpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F285672"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285673"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285674"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285675"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285676"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285677"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285678"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285679"] = "This fault is caused by 'BgpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F285728"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285729"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285730"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285731"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285732"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285733"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285734"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285735"] = "This fault is caused by 'BgpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F285744"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285745"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285746"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285747"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285748"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285749"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285750"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285751"] = "This fault is caused by 'BgpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F285752"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285753"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285754"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285755"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285756"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285757"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285758"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285759"] = "This fault is caused by 'BgpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F285760"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285761"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285762"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285763"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285764"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285765"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285766"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285767"] = "This fault is caused by 'BgpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F285768"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285769"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285770"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285771"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285772"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285773"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285774"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285775"] = "This fault is caused by 'BgpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F285776"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285777"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285778"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285779"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285780"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285781"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285782"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285783"] = "This fault is caused by 'BgpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F285808"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285809"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285810"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285811"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285812"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285813"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285814"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285815"] = "This fault is caused by 'BgpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F285816"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285817"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285818"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285819"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285820"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285821"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285822"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285823"] = "This fault is caused by 'BgpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F285896"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285897"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285898"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285899"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F2859"] = "This fault occurs because Analytics Cluster information is present on a leaf but inband management VRF is missing." + self.system_fault_code["F285900"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285901"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285902"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285903"] = "This fault is caused by 'BgpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F285904"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285905"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285906"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285907"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285908"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285909"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285910"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285911"] = "This fault is caused by 'BgpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F285912"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285913"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285914"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285915"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285916"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285917"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285918"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285919"] = "This fault is caused by 'BgpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F285920"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285921"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285922"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285923"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285924"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285925"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285926"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285927"] = "This fault is caused by 'BgpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F285960"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285961"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285962"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285963"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285964"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285965"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285966"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F285967"] = "This fault is caused by 'BgpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2860"] = "This fault occurs when sending a callhome message to a slow destination." + self.system_fault_code["F286016"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286017"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286018"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286019"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286020"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286021"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286022"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286023"] = "This fault is caused by 'BgpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286032"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286033"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286034"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286035"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286036"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286037"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286038"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286039"] = "This fault is caused by 'BgpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286040"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286041"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286042"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286043"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286044"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286045"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286046"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286047"] = "This fault is caused by 'BgpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286048"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286049"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286050"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286051"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286052"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286053"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286054"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286055"] = "This fault is caused by 'BgpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286056"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286057"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286058"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286059"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286060"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286061"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286062"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286063"] = "This fault is caused by 'BgpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286064"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286065"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286066"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286067"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286068"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286069"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286070"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286071"] = "This fault is caused by 'BgpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286096"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286097"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286098"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286099"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286100"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286101"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286102"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286103"] = "This fault is caused by 'BgpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286104"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286105"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286106"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286107"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286108"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286109"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286110"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286111"] = "This fault is caused by 'BgpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286184"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286185"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286186"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286187"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286188"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286189"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286190"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286191"] = "This fault is caused by 'BgpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286192"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286193"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286194"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286195"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286196"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286197"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286198"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286199"] = "This fault is caused by 'BgpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286200"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286201"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286202"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286203"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286204"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286205"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286206"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286207"] = "This fault is caused by 'BgpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286208"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286209"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286210"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286211"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286212"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286213"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286214"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286215"] = "This fault is caused by 'BgpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286248"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286249"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286250"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286251"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286252"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286253"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286254"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286255"] = "This fault is caused by 'BgpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286304"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286305"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286306"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286307"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286308"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286309"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286310"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286311"] = "This fault is caused by 'CdpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286320"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286321"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286322"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286323"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286324"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286325"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286326"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286327"] = "This fault is caused by 'CdpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286328"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286329"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286330"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286331"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286332"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286333"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286334"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286335"] = "This fault is caused by 'CdpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286336"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286337"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286338"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286339"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286340"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286341"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286342"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286343"] = "This fault is caused by 'CdpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286344"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286345"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286346"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286347"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286348"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286349"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286350"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286351"] = "This fault is caused by 'CdpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286352"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286353"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286354"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286355"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286356"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286357"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286358"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286359"] = "This fault is caused by 'CdpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286384"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286385"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286386"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286387"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286388"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286389"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286390"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286391"] = "This fault is caused by 'CdpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286392"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286393"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286394"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286395"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286396"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286397"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286398"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286399"] = "This fault is caused by 'CdpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286472"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286473"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286474"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286475"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286476"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286477"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286478"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286479"] = "This fault is caused by 'CdpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F286480"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286481"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286482"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286483"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286484"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286485"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286486"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286487"] = "This fault is caused by 'CdpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286488"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286489"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286490"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286491"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286492"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286493"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286494"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286495"] = "This fault is caused by 'CdpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286496"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286497"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286498"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286499"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286500"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286501"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286502"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286503"] = "This fault is caused by 'CdpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F286536"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286537"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286538"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286539"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286540"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286541"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286542"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286543"] = "This fault is caused by 'CdpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F286592"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286593"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286594"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286595"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286596"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286597"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286598"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286599"] = "This fault is caused by 'CdpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F286608"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286609"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286610"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286611"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286612"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286613"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286614"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286615"] = "This fault is caused by 'CdpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F286616"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286617"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286618"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286619"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286620"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286621"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286622"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286623"] = "This fault is caused by 'CdpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F286624"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286625"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286626"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286627"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286628"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286629"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286630"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286631"] = "This fault is caused by 'CdpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F286632"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286633"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286634"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286635"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286636"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286637"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286638"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286639"] = "This fault is caused by 'CdpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F286640"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286641"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286642"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286643"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286644"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286645"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286646"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286647"] = "This fault is caused by 'CdpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F286672"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286673"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286674"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286675"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286676"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286677"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286678"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286679"] = "This fault is caused by 'CdpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F286680"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286681"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286682"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286683"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286684"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286685"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286686"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286687"] = "This fault is caused by 'CdpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F286760"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286761"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286762"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286763"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286764"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286765"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286766"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286767"] = "This fault is caused by 'CdpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F286768"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286769"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286770"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286771"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286772"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286773"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286774"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286775"] = "This fault is caused by 'CdpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F286776"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286777"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286778"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286779"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286780"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286781"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286782"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286783"] = "This fault is caused by 'CdpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F286784"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286785"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286786"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286787"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286788"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286789"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286790"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286791"] = "This fault is caused by 'CdpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F286824"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286825"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286826"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286827"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286828"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286829"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286830"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286831"] = "This fault is caused by 'CdpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F286880"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286881"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286882"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286883"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286884"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286885"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286886"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286887"] = "This fault is caused by 'CdpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F286896"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286897"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286898"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286899"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F2869"] = "This fault occurs when the SAML provider is not operational." + self.system_fault_code["F286900"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286901"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286902"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286903"] = "This fault is caused by 'CdpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F286904"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286905"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286906"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286907"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286908"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286909"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286910"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286911"] = "This fault is caused by 'CdpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F286912"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286913"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286914"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286915"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286916"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286917"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286918"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286919"] = "This fault is caused by 'CdpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F286920"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286921"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286922"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286923"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286924"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286925"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286926"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286927"] = "This fault is caused by 'CdpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F286928"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286929"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286930"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286931"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286932"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286933"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286934"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286935"] = "This fault is caused by 'CdpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F286960"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286961"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286962"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286963"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286964"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286965"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286966"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286967"] = "This fault is caused by 'CdpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F286968"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286969"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286970"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286971"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286972"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286973"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286974"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F286975"] = "This fault is caused by 'CdpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2870"] = "This fault occurs when the SAML provider is not operational." + self.system_fault_code["F287048"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287049"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287050"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287051"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287052"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287053"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287054"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287055"] = "This fault is caused by 'CdpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287056"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287057"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287058"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287059"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287060"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287061"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287062"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287063"] = "This fault is caused by 'CdpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287064"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287065"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287066"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287067"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287068"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287069"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287070"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287071"] = "This fault is caused by 'CdpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287072"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287073"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287074"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287075"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287076"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287077"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287078"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287079"] = "This fault is caused by 'CdpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F2871"] = "The object refers to an object that was not found." + self.system_fault_code["F287112"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287113"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287114"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287115"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287116"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287117"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287118"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287119"] = "This fault is caused by 'CdpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287168"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287169"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287170"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287171"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287172"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287173"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287174"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287175"] = "This fault is caused by 'CdpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287184"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287185"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287186"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287187"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287188"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287189"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287190"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287191"] = "This fault is caused by 'CdpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287192"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287193"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287194"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287195"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287196"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287197"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287198"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287199"] = "This fault is caused by 'CdpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F2872"] = "The object refers to an object that was not found." + self.system_fault_code["F287200"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287201"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287202"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287203"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287204"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287205"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287206"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287207"] = "This fault is caused by 'CdpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287208"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287209"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287210"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287211"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287212"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287213"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287214"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287215"] = "This fault is caused by 'CdpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287216"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287217"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287218"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287219"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287220"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287221"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287222"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287223"] = "This fault is caused by 'CdpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287248"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287249"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287250"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287251"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287252"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287253"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287254"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287255"] = "This fault is caused by 'CdpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287256"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287257"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287258"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287259"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287260"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287261"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287262"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287263"] = "This fault is caused by 'CdpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2873"] = "This fault occurs when deployment of policy to a leaf fails." + self.system_fault_code["F287336"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287337"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287338"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287339"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287340"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287341"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287342"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287343"] = "This fault is caused by 'CdpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287344"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287345"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287346"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287347"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287348"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287349"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287350"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287351"] = "This fault is caused by 'CdpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287352"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287353"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287354"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287355"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287356"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287357"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287358"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287359"] = "This fault is caused by 'CdpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287360"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287361"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287362"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287363"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287364"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287365"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287366"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287367"] = "This fault is caused by 'CdpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F2874"] = "This fault occurs when Analytics/Netflow is enable on unsupported platform" + self.system_fault_code["F287400"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287401"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287402"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287403"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287404"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287405"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287406"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287407"] = "This fault is caused by 'CdpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287456"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287457"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287458"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287459"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287460"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287461"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287462"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287463"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F287472"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287473"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287474"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287475"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287476"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287477"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287478"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287479"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F287480"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287481"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287482"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287483"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287484"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287485"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287486"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287487"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F287488"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287489"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287490"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287491"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287492"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287493"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287494"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287495"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F287496"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287497"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287498"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287499"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F2875"] = "This fault occurs when some interfaces are in local scope but they are receiving MST (802.1s) BPDUs. It could lead to" + self.system_fault_code["F287500"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287501"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287502"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287503"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F287504"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287505"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287506"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287507"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287508"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287509"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287510"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287511"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F287536"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287537"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287538"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287539"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287540"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287541"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287542"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287543"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F287544"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287545"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287546"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287547"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287548"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287549"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287550"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287551"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F287624"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287625"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287626"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287627"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287628"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287629"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287630"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287631"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F287632"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287633"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287634"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287635"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287636"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287637"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287638"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287639"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287640"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287641"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287642"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287643"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287644"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287645"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287646"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287647"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287648"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287649"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287650"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287651"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287652"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287653"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287654"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287655"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F287688"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287689"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287690"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287691"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287692"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287693"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287694"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287695"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F287744"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287745"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287746"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287747"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287748"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287749"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287750"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287751"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F287760"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287761"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287762"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287763"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287764"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287765"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287766"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287767"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F287768"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287769"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287770"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287771"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287772"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287773"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287774"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287775"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F287776"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287777"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287778"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287779"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287780"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287781"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287782"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287783"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F287784"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287785"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287786"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287787"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287788"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287789"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287790"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287791"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F287792"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287793"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287794"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287795"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287796"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287797"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287798"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287799"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F287824"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287825"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287826"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287827"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287828"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287829"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287830"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287831"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F287832"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287833"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287834"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287835"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287836"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287837"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287838"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287839"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F287912"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287913"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287914"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287915"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287916"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287917"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287918"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287919"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F287920"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287921"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287922"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287923"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287924"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287925"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287926"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287927"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F287928"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287929"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287930"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287931"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287932"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287933"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287934"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287935"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F287936"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287937"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287938"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287939"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287940"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287941"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287942"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287943"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F287976"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287977"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287978"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287979"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287980"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287981"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287982"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F287983"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2880"] = "This fault occurs when a PortDirecPol is failed to apply." + self.system_fault_code["F288032"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288033"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288034"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288035"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288036"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288037"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288038"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288039"] = "This fault is caused by 'IcmpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288048"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288049"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288050"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288051"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288052"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288053"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288054"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288055"] = "This fault is caused by 'IcmpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288056"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288057"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288058"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288059"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288060"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288061"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288062"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288063"] = "This fault is caused by 'IcmpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288064"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288065"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288066"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288067"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288068"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288069"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288070"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288071"] = "This fault is caused by 'IcmpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288072"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288073"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288074"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288075"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288076"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288077"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288078"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288079"] = "This fault is caused by 'IcmpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288080"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288081"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288082"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288083"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288084"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288085"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288086"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288087"] = "This fault is caused by 'IcmpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F2881"] = "This fault occurs when a PortDirecPolPol is failed to apply." + self.system_fault_code["F288112"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288113"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288114"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288115"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288116"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288117"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288118"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288119"] = "This fault is caused by 'IcmpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288120"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288121"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288122"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288123"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288124"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288125"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288126"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288127"] = "This fault is caused by 'IcmpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288200"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288201"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288202"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288203"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288204"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288205"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288206"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288207"] = "This fault is caused by 'IcmpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288208"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288209"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288210"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288211"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288212"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288213"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288214"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288215"] = "This fault is caused by 'IcmpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288216"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288217"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288218"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288219"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288220"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288221"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288222"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288223"] = "This fault is caused by 'IcmpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288224"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288225"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288226"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288227"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288228"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288229"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288230"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288231"] = "This fault is caused by 'IcmpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288264"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288265"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288266"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288267"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288268"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288269"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288270"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288271"] = "This fault is caused by 'IcmpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288320"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288321"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288322"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288323"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288324"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288325"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288326"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288327"] = "This fault is caused by 'IcmpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288336"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288337"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288338"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288339"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288340"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288341"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288342"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288343"] = "This fault is caused by 'IcmpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288344"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288345"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288346"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288347"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288348"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288349"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288350"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288351"] = "This fault is caused by 'IcmpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288352"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288353"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288354"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288355"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288356"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288357"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288358"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288359"] = "This fault is caused by 'IcmpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288360"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288361"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288362"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288363"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288364"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288365"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288366"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288367"] = "This fault is caused by 'IcmpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288368"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288369"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288370"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288371"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288372"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288373"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288374"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288375"] = "This fault is caused by 'IcmpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288400"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288401"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288402"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288403"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288404"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288405"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288406"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288407"] = "This fault is caused by 'IcmpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288408"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288409"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288410"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288411"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288412"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288413"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288414"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288415"] = "This fault is caused by 'IcmpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288488"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288489"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288490"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288491"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288492"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288493"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288494"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288495"] = "This fault is caused by 'IcmpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F288496"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288497"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288498"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288499"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288500"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288501"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288502"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288503"] = "This fault is caused by 'IcmpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288504"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288505"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288506"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288507"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288508"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288509"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288510"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288511"] = "This fault is caused by 'IcmpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288512"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288513"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288514"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288515"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288516"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288517"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288518"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288519"] = "This fault is caused by 'IcmpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F288552"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288553"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288554"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288555"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288556"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288557"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288558"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288559"] = "This fault is caused by 'IcmpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F288608"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288609"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288610"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288611"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288612"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288613"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288614"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288615"] = "This fault is caused by 'IcmpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F288624"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288625"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288626"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288627"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288628"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288629"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288630"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288631"] = "This fault is caused by 'IcmpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F288632"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288633"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288634"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288635"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288636"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288637"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288638"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288639"] = "This fault is caused by 'IcmpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F288640"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288641"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288642"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288643"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288644"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288645"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288646"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288647"] = "This fault is caused by 'IcmpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F288648"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288649"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288650"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288651"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288652"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288653"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288654"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288655"] = "This fault is caused by 'IcmpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F288656"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288657"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288658"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288659"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288660"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288661"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288662"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288663"] = "This fault is caused by 'IcmpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F288688"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288689"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288690"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288691"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288692"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288693"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288694"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288695"] = "This fault is caused by 'IcmpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F288696"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288697"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288698"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288699"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2887"] = "The object refers to an object that was not found." + self.system_fault_code["F288700"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288701"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288702"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288703"] = "This fault is caused by 'IcmpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F288776"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288777"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288778"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288779"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288780"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288781"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288782"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288783"] = "This fault is caused by 'IcmpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F288784"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288785"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288786"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288787"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288788"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288789"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288790"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288791"] = "This fault is caused by 'IcmpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F288792"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288793"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288794"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288795"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288796"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288797"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288798"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F288799"] = "This fault is caused by 'IcmpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F2888"] = "The object refers to an object that was not found." + self.system_fault_code["F288800"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288801"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288802"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288803"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288804"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288805"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288806"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288807"] = "This fault is caused by 'IcmpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F288840"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288841"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288842"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288843"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288844"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288845"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288846"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288847"] = "This fault is caused by 'IcmpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F288896"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288897"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288898"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288899"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F2889"] = "The object refers to an object that was not found." + self.system_fault_code["F288900"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288901"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288902"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288903"] = "This fault is caused by 'IcmpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F288912"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288913"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288914"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288915"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288916"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288917"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288918"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288919"] = "This fault is caused by 'IcmpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F288920"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288921"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288922"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288923"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288924"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288925"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288926"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288927"] = "This fault is caused by 'IcmpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F288928"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288929"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288930"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288931"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288932"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288933"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288934"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288935"] = "This fault is caused by 'IcmpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F288936"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288937"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288938"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288939"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288940"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288941"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288942"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288943"] = "This fault is caused by 'IcmpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F288944"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288945"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288946"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288947"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288948"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288949"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288950"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288951"] = "This fault is caused by 'IcmpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F288976"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288977"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288978"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288979"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288980"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288981"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288982"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288983"] = "This fault is caused by 'IcmpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F288984"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288985"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288986"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288987"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288988"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288989"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288990"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F288991"] = "This fault is caused by 'IcmpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2890"] = "The object refers to an object that was not found." + self.system_fault_code["F289064"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289065"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289066"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289067"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289068"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289069"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289070"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289071"] = "This fault is caused by 'IcmpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289072"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289073"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289074"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289075"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289076"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289077"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289078"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289079"] = "This fault is caused by 'IcmpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289080"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289081"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289082"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289083"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289084"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289085"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289086"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289087"] = "This fault is caused by 'IcmpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289088"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289089"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289090"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289091"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289092"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289093"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289094"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289095"] = "This fault is caused by 'IcmpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289128"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289129"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289130"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289131"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289132"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289133"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289134"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289135"] = "This fault is caused by 'IcmpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289184"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289185"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289186"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289187"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289188"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289189"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289190"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289191"] = "This fault is caused by 'LacpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289200"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289201"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289202"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289203"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289204"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289205"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289206"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289207"] = "This fault is caused by 'LacpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289208"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289209"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289210"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289211"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289212"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289213"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289214"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289215"] = "This fault is caused by 'LacpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289216"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289217"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289218"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289219"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289220"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289221"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289222"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289223"] = "This fault is caused by 'LacpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289224"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289225"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289226"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289227"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289228"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289229"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289230"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289231"] = "This fault is caused by 'LacpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289232"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289233"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289234"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289235"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289236"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289237"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289238"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289239"] = "This fault is caused by 'LacpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289264"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289265"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289266"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289267"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289268"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289269"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289270"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289271"] = "This fault is caused by 'LacpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289272"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289273"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289274"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289275"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289276"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289277"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289278"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289279"] = "This fault is caused by 'LacpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289352"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289353"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289354"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289355"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289356"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289357"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289358"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289359"] = "This fault is caused by 'LacpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289360"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289361"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289362"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289363"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289364"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289365"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289366"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289367"] = "This fault is caused by 'LacpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289368"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289369"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289370"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289371"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289372"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289373"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289374"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289375"] = "This fault is caused by 'LacpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289376"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289377"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289378"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289379"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289380"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289381"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289382"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289383"] = "This fault is caused by 'LacpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289416"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289417"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289418"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289419"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289420"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289421"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289422"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289423"] = "This fault is caused by 'LacpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289472"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289473"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289474"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289475"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289476"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289477"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289478"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289479"] = "This fault is caused by 'LacpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F289488"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289489"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289490"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289491"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289492"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289493"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289494"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289495"] = "This fault is caused by 'LacpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F289496"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289497"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289498"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289499"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289500"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289501"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289502"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289503"] = "This fault is caused by 'LacpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F289504"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289505"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289506"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289507"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289508"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289509"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289510"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289511"] = "This fault is caused by 'LacpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F289512"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289513"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289514"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289515"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289516"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289517"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289518"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289519"] = "This fault is caused by 'LacpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F289520"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289521"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289522"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289523"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289524"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289525"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289526"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289527"] = "This fault is caused by 'LacpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F289552"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289553"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289554"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289555"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289556"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289557"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289558"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289559"] = "This fault is caused by 'LacpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F289560"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289561"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289562"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289563"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289564"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289565"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289566"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F289567"] = "This fault is caused by 'LacpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2896"] = "This fault occurs when the ospfv3 protocol is not supported on the platform" + self.system_fault_code["F289640"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289641"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289642"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289643"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289644"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289645"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289646"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289647"] = "This fault is caused by 'LacpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F289648"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289649"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289650"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289651"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289652"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289653"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289654"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289655"] = "This fault is caused by 'LacpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289656"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289657"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289658"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289659"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289660"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289661"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289662"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289663"] = "This fault is caused by 'LacpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289664"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289665"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289666"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289667"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289668"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289669"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289670"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F289671"] = "This fault is caused by 'LacpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F2897"] = "This fault occurs when the ospf protocol is not supported on the platform" + self.system_fault_code["F289704"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289705"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289706"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289707"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289708"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289709"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289710"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289711"] = "This fault is caused by 'LacpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F289760"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289761"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289762"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289763"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289764"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289765"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289766"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289767"] = "This fault is caused by 'LacpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F289776"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289777"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289778"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289779"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289780"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289781"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289782"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289783"] = "This fault is caused by 'LacpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F289784"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289785"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289786"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289787"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289788"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289789"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289790"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289791"] = "This fault is caused by 'LacpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F289792"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289793"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289794"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289795"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289796"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289797"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289798"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F289799"] = "This fault is caused by 'LacpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F2898"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F289800"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289801"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289802"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289803"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289804"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289805"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289806"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289807"] = "This fault is caused by 'LacpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F289808"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289809"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289810"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289811"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289812"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289813"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289814"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289815"] = "This fault is caused by 'LacpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F289840"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289841"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289842"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289843"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289844"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289845"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289846"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289847"] = "This fault is caused by 'LacpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F289848"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289849"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289850"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289851"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289852"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289853"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289854"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F289855"] = "This fault is caused by 'LacpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2899"] = "The object refers to an object that was not found." + self.system_fault_code["F289928"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289929"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289930"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289931"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289932"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289933"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289934"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289935"] = "This fault is caused by 'LacpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F289936"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289937"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289938"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289939"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289940"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289941"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289942"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289943"] = "This fault is caused by 'LacpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F289944"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289945"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289946"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289947"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289948"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289949"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289950"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289951"] = "This fault is caused by 'LacpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F289952"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289953"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289954"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289955"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289956"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289957"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289958"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289959"] = "This fault is caused by 'LacpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F289992"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289993"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289994"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289995"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289996"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289997"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289998"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F289999"] = "This fault is caused by 'LacpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2900"] = "The object refers to an object that was not found." + self.system_fault_code["F290048"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290049"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290050"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290051"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290052"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290053"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290054"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290055"] = "This fault is caused by 'LacpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290064"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290065"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290066"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290067"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290068"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290069"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290070"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290071"] = "This fault is caused by 'LacpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290072"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290073"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290074"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290075"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290076"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290077"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290078"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290079"] = "This fault is caused by 'LacpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290080"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290081"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290082"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290083"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290084"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290085"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290086"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290087"] = "This fault is caused by 'LacpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290088"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290089"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290090"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290091"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290092"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290093"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290094"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290095"] = "This fault is caused by 'LacpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290096"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290097"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290098"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290099"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F2901"] = "The object refers to an object that was not found." + self.system_fault_code["F290100"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290101"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290102"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290103"] = "This fault is caused by 'LacpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290128"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290129"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290130"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290131"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290132"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290133"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290134"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290135"] = "This fault is caused by 'LacpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290136"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290137"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290138"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290139"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290140"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290141"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290142"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290143"] = "This fault is caused by 'LacpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290216"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290217"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290218"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290219"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290220"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290221"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290222"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290223"] = "This fault is caused by 'LacpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290224"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290225"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290226"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290227"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290228"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290229"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290230"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290231"] = "This fault is caused by 'LacpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290232"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290233"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290234"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290235"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290236"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290237"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290238"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290239"] = "This fault is caused by 'LacpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290240"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290241"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290242"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290243"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290244"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290245"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290246"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290247"] = "This fault is caused by 'LacpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290280"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290281"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290282"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290283"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290284"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290285"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290286"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290287"] = "This fault is caused by 'LacpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2903"] = "This fault occurs when a QinQ EPG is deployed on an unsupported platform TOR" + self.system_fault_code["F290336"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290337"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290338"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290339"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290340"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290341"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290342"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290343"] = "This fault is caused by 'LldpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290352"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290353"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290354"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290355"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290356"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290357"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290358"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290359"] = "This fault is caused by 'LldpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290360"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290361"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290362"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290363"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290364"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290365"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290366"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290367"] = "This fault is caused by 'LldpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290368"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290369"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290370"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290371"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290372"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290373"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290374"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290375"] = "This fault is caused by 'LldpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290376"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290377"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290378"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290379"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290380"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290381"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290382"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290383"] = "This fault is caused by 'LldpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290384"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290385"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290386"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290387"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290388"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290389"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290390"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290391"] = "This fault is caused by 'LldpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290416"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290417"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290418"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290419"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290420"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290421"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290422"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290423"] = "This fault is caused by 'LldpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290424"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290425"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290426"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290427"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290428"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290429"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290430"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290431"] = "This fault is caused by 'LldpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F290504"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290505"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290506"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290507"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290508"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290509"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290510"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290511"] = "This fault is caused by 'LldpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F290512"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290513"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290514"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290515"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290516"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290517"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290518"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290519"] = "This fault is caused by 'LldpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290520"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290521"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290522"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290523"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290524"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290525"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290526"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290527"] = "This fault is caused by 'LldpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290528"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290529"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290530"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290531"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290532"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290533"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290534"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290535"] = "This fault is caused by 'LldpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F290568"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290569"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290570"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290571"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290572"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290573"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290574"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290575"] = "This fault is caused by 'LldpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F290624"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290625"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290626"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290627"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290628"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290629"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290630"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290631"] = "This fault is caused by 'LldpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F290640"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290641"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290642"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290643"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290644"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290645"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290646"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290647"] = "This fault is caused by 'LldpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F290648"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290649"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290650"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290651"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290652"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290653"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290654"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290655"] = "This fault is caused by 'LldpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F290656"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290657"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290658"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290659"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290660"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290661"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290662"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290663"] = "This fault is caused by 'LldpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F290664"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290665"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290666"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290667"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290668"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290669"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290670"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290671"] = "This fault is caused by 'LldpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F290672"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290673"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290674"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290675"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290676"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290677"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290678"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290679"] = "This fault is caused by 'LldpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F290704"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290705"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290706"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290707"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290708"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290709"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290710"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290711"] = "This fault is caused by 'LldpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F290712"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290713"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290714"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290715"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290716"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290717"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290718"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290719"] = "This fault is caused by 'LldpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F290792"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290793"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290794"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290795"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290796"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290797"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290798"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290799"] = "This fault is caused by 'LldpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F290800"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290801"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290802"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290803"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290804"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290805"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290806"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290807"] = "This fault is caused by 'LldpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F290808"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290809"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290810"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290811"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290812"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290813"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290814"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290815"] = "This fault is caused by 'LldpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F290816"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290817"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290818"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290819"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290820"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290821"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290822"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290823"] = "This fault is caused by 'LldpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F290856"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290857"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290858"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290859"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290860"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290861"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290862"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290863"] = "This fault is caused by 'LldpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F290912"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290913"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290914"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290915"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290916"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290917"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290918"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290919"] = "This fault is caused by 'LldpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F290928"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290929"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290930"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290931"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290932"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290933"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290934"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290935"] = "This fault is caused by 'LldpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F290936"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290937"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290938"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290939"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290940"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290941"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290942"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290943"] = "This fault is caused by 'LldpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F290944"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290945"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290946"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290947"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290948"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290949"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290950"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290951"] = "This fault is caused by 'LldpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F290952"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290953"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290954"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290955"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290956"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290957"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290958"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290959"] = "This fault is caused by 'LldpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F290960"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290961"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290962"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290963"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290964"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290965"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290966"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290967"] = "This fault is caused by 'LldpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F290992"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290993"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290994"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290995"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290996"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290997"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290998"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F290999"] = "This fault is caused by 'LldpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291000"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291001"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291002"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291003"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291004"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291005"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291006"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291007"] = "This fault is caused by 'LldpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291080"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291081"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291082"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291083"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291084"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291085"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291086"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291087"] = "This fault is caused by 'LldpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291088"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291089"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291090"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291091"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291092"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291093"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291094"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291095"] = "This fault is caused by 'LldpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291096"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291097"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291098"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291099"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F2911"] = "This fault occurs when PBR health group goes down" + self.system_fault_code["F291100"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291101"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291102"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291103"] = "This fault is caused by 'LldpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291104"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291105"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291106"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291107"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291108"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291109"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291110"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291111"] = "This fault is caused by 'LldpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291144"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291145"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291146"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291147"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291148"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291149"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291150"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291151"] = "This fault is caused by 'LldpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2912"] = "This fault occurs when there is no space in the TCAM's SUP region." + self.system_fault_code["F291200"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291201"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291202"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291203"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291204"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291205"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291206"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291207"] = "This fault is caused by 'LldpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291216"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291217"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291218"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291219"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291220"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291221"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291222"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291223"] = "This fault is caused by 'LldpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291224"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291225"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291226"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291227"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291228"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291229"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291230"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291231"] = "This fault is caused by 'LldpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291232"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291233"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291234"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291235"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291236"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291237"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291238"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291239"] = "This fault is caused by 'LldpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291240"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291241"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291242"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291243"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291244"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291245"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291246"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291247"] = "This fault is caused by 'LldpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291248"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291249"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291250"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291251"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291252"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291253"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291254"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291255"] = "This fault is caused by 'LldpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291280"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291281"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291282"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291283"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291284"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291285"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291286"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291287"] = "This fault is caused by 'LldpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291288"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291289"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291290"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291291"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291292"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291293"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291294"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291295"] = "This fault is caused by 'LldpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2913"] = "This fault occurs when there is no more INTERFACE ACL LABELS." + self.system_fault_code["F291368"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291369"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291370"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291371"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291372"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291373"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291374"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291375"] = "This fault is caused by 'LldpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291376"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291377"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291378"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291379"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291380"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291381"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291382"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291383"] = "This fault is caused by 'LldpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291384"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291385"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291386"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291387"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291388"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291389"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291390"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291391"] = "This fault is caused by 'LldpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291392"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291393"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291394"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291395"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291396"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291397"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291398"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291399"] = "This fault is caused by 'LldpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F2914"] = "This fault occurs due to errors in hardware installation." + self.system_fault_code["F291432"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291433"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291434"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291435"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291436"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291437"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291438"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291439"] = "This fault is caused by 'LldpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F291488"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291489"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291490"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291491"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291492"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291493"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291494"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F291495"] = "This fault is caused by 'OspfAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F2915"] = "This fault occurs when tha values of rate/burst is incorrect." + self.system_fault_code["F291504"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291505"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291506"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291507"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291508"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291509"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291510"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291511"] = "This fault is caused by 'OspfAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F291512"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291513"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291514"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291515"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291516"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291517"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291518"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291519"] = "This fault is caused by 'OspfAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F291520"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291521"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291522"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291523"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291524"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291525"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291526"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291527"] = "This fault is caused by 'OspfAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F291528"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291529"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291530"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291531"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291532"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291533"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291534"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291535"] = "This fault is caused by 'OspfAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F291536"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291537"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291538"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291539"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291540"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291541"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291542"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291543"] = "This fault is caused by 'OspfAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F291568"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291569"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291570"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291571"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291572"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291573"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291574"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291575"] = "This fault is caused by 'OspfAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F291576"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291577"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291578"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291579"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291580"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291581"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291582"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F291583"] = "This fault is caused by 'OspfAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2916"] = "This fault occurs when there is no more Policers free." + self.system_fault_code["F291656"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291657"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291658"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291659"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291660"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291661"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291662"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291663"] = "This fault is caused by 'OspfAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F291664"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291665"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291666"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291667"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291668"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291669"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291670"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291671"] = "This fault is caused by 'OspfAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291672"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291673"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291674"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291675"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291676"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291677"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291678"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291679"] = "This fault is caused by 'OspfAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291680"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291681"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291682"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291683"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291684"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291685"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291686"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291687"] = "This fault is caused by 'OspfAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F291720"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291721"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291722"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291723"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291724"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291725"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291726"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291727"] = "This fault is caused by 'OspfAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F291776"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291777"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291778"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291779"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291780"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291781"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291782"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291783"] = "This fault is caused by 'OspfAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F291792"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291793"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291794"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291795"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291796"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291797"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291798"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291799"] = "This fault is caused by 'OspfAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F291800"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291801"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291802"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291803"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291804"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291805"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291806"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291807"] = "This fault is caused by 'OspfAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F291808"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291809"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291810"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291811"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291812"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291813"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291814"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291815"] = "This fault is caused by 'OspfAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F291816"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291817"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291818"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291819"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291820"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291821"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291822"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291823"] = "This fault is caused by 'OspfAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F291824"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291825"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291826"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291827"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291828"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291829"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291830"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291831"] = "This fault is caused by 'OspfAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F291856"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291857"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291858"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291859"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291860"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291861"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291862"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291863"] = "This fault is caused by 'OspfAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F291864"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291865"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291866"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291867"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291868"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291869"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291870"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291871"] = "This fault is caused by 'OspfAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F291944"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291945"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291946"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291947"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291948"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291949"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291950"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291951"] = "This fault is caused by 'OspfAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F291952"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291953"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291954"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291955"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291956"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291957"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291958"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291959"] = "This fault is caused by 'OspfAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F291960"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291961"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291962"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291963"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291964"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291965"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291966"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291967"] = "This fault is caused by 'OspfAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F291968"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291969"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291970"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291971"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291972"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291973"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291974"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F291975"] = "This fault is caused by 'OspfAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292008"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292009"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292010"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292011"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292012"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292013"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292014"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292015"] = "This fault is caused by 'OspfAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292064"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292065"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292066"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292067"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292068"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292069"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292070"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292071"] = "This fault is caused by 'OspfDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292080"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292081"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292082"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292083"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292084"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292085"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292086"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292087"] = "This fault is caused by 'OspfDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292088"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292089"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292090"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292091"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292092"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292093"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292094"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292095"] = "This fault is caused by 'OspfDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292096"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292097"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292098"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292099"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292100"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292101"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292102"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292103"] = "This fault is caused by 'OspfDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292104"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292105"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292106"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292107"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292108"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292109"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292110"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292111"] = "This fault is caused by 'OspfDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292112"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292113"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292114"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292115"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292116"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292117"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292118"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292119"] = "This fault is caused by 'OspfDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292144"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292145"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292146"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292147"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292148"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292149"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292150"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292151"] = "This fault is caused by 'OspfDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292152"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292153"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292154"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292155"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292156"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292157"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292158"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292159"] = "This fault is caused by 'OspfDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2922"] = "This fault occurs when Dot1x authentication fails" + self.system_fault_code["F292232"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292233"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292234"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292235"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292236"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292237"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292238"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292239"] = "This fault is caused by 'OspfDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292240"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292241"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292242"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292243"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292244"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292245"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292246"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292247"] = "This fault is caused by 'OspfDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292248"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292249"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292250"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292251"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292252"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292253"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292254"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292255"] = "This fault is caused by 'OspfDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292256"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292257"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292258"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292259"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292260"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292261"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292262"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292263"] = "This fault is caused by 'OspfDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292296"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292297"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292298"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292299"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2923"] = "This fault occurs when there is no space available in the TCAM on at least one of the modules. Note: If hw has more than" + self.system_fault_code["F292300"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292301"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292302"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292303"] = "This fault is caused by 'OspfDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292352"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292353"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292354"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292355"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292356"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292357"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292358"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292359"] = "This fault is caused by 'OspfDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292368"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292369"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292370"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292371"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292372"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292373"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292374"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292375"] = "This fault is caused by 'OspfDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292376"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292377"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292378"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292379"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292380"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292381"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292382"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292383"] = "This fault is caused by 'OspfDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292384"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292385"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292386"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292387"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292388"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292389"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292390"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292391"] = "This fault is caused by 'OspfDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292392"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292393"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292394"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292395"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292396"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292397"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292398"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292399"] = "This fault is caused by 'OspfDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F2924"] = "This fault occurs when CoPP prefilter ACL entry installation failed due to hardware programming error." + self.system_fault_code["F292400"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292401"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292402"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292403"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292404"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292405"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292406"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292407"] = "This fault is caused by 'OspfDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292432"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292433"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292434"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292435"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292436"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292437"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292438"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292439"] = "This fault is caused by 'OspfDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F292440"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292441"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292442"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292443"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292444"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292445"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292446"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F292447"] = "This fault is caused by 'OspfDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F2925"] = "This fault occurs when CoPP prefilter ACL entry installation failed due to unsupported hardware.The broadcom based platforms" + self.system_fault_code["F292520"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292521"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292522"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292523"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292524"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292525"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292526"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292527"] = "This fault is caused by 'OspfDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F292528"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292529"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292530"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292531"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292532"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292533"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292534"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292535"] = "This fault is caused by 'OspfDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292536"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292537"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292538"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292539"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292540"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292541"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292542"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292543"] = "This fault is caused by 'OspfDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292544"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292545"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292546"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292547"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292548"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292549"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292550"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292551"] = "This fault is caused by 'OspfDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F292584"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292585"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292586"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292587"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292588"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292589"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292590"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F292591"] = "This fault is caused by 'OspfDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2926"] = "This fault occurs when CoPP prefilter ACL entry config is invalid." + self.system_fault_code["F292640"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292641"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292642"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292643"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292644"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292645"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292646"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292647"] = "This fault is caused by 'StpAllowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F292656"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292657"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292658"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292659"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292660"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292661"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292662"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292663"] = "This fault is caused by 'StpAllowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F292664"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292665"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292666"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292667"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292668"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292669"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292670"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292671"] = "This fault is caused by 'StpAllowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F292672"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292673"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292674"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292675"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292676"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292677"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292678"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292679"] = "This fault is caused by 'StpAllowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F292680"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292681"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292682"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292683"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292684"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292685"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292686"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292687"] = "This fault is caused by 'StpAllowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F292688"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292689"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292690"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292691"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292692"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292693"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292694"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F292695"] = "This fault is caused by 'StpAllowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F2927"] = "This fault occurs when the custom KeyRing X.509 Certificate is going to expire in one month." + self.system_fault_code["F292720"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292721"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292722"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292723"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292724"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292725"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292726"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292727"] = "This fault is caused by 'StpAllowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F292728"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292729"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292730"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292731"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292732"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292733"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292734"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F292735"] = "This fault is caused by 'StpAllowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2928"] = "This fault occurs when the custom KeyRing X.509 Certificate has expired." + self.system_fault_code["F292808"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292809"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292810"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292811"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292812"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292813"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292814"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292815"] = "This fault is caused by 'StpAllowed Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F292816"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292817"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292818"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292819"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292820"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292821"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292822"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292823"] = "This fault is caused by 'StpAllowed Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F292824"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292825"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292826"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292827"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292828"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292829"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292830"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292831"] = "This fault is caused by 'StpAllowed Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F292832"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292833"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292834"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292835"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292836"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292837"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292838"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292839"] = "This fault is caused by 'StpAllowed Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F292872"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292873"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292874"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292875"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292876"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292877"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292878"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F292879"] = "This fault is caused by 'StpAllowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F2929"] = "This fault occurs when the TP X.509 Certificate is going to expire in one month." + self.system_fault_code["F292928"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292929"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292930"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292931"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292932"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292933"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292934"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292935"] = "This fault is caused by 'StpAllowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F292944"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292945"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292946"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292947"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292948"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292949"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292950"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292951"] = "This fault is caused by 'StpAllowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F292952"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292953"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292954"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292955"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292956"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292957"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292958"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292959"] = "This fault is caused by 'StpAllowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F292960"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292961"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292962"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292963"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292964"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292965"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292966"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292967"] = "This fault is caused by 'StpAllowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F292968"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292969"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292970"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292971"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292972"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292973"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292974"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292975"] = "This fault is caused by 'StpAllowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F292976"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292977"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292978"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292979"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292980"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292981"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292982"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F292983"] = "This fault is caused by 'StpAllowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F2930"] = "This fault occurs when the TP X.509 Certificate has expired." + self.system_fault_code["F293008"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293009"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293010"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293011"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293012"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293013"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293014"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293015"] = "This fault is caused by 'StpAllowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293016"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293017"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293018"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293019"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293020"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293021"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293022"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293023"] = "This fault is caused by 'StpAllowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293096"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293097"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293098"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293099"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F2931"] = "This fault occurs when thei User X.509 Certificate is going to expire in one month." + self.system_fault_code["F293100"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293101"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293102"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293103"] = "This fault is caused by 'StpAllowed Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293104"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293105"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293106"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293107"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293108"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293109"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293110"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293111"] = "This fault is caused by 'StpAllowed Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293112"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293113"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293114"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293115"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293116"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293117"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293118"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293119"] = "This fault is caused by 'StpAllowed Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293120"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293121"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293122"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293123"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293124"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293125"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293126"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293127"] = "This fault is caused by 'StpAllowed Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293160"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293161"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293162"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293163"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293164"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293165"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293166"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293167"] = "This fault is caused by 'StpAllowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2932"] = "This fault occurs when the User X.509 Certificate has expired." + self.system_fault_code["F293216"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293217"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293218"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293219"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293220"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293221"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293222"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293223"] = "This fault is caused by 'StpDropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F293232"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293233"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293234"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293235"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293236"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293237"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293238"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293239"] = "This fault is caused by 'StpDropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F293240"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293241"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293242"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293243"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293244"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293245"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293246"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293247"] = "This fault is caused by 'StpDropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F293248"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293249"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293250"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293251"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293252"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293253"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293254"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293255"] = "This fault is caused by 'StpDropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F293256"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293257"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293258"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293259"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293260"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293261"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293262"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293263"] = "This fault is caused by 'StpDropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F293264"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293265"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293266"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293267"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293268"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293269"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293270"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293271"] = "This fault is caused by 'StpDropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F293296"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293297"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293298"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293299"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293300"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293301"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293302"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293303"] = "This fault is caused by 'StpDropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F293304"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293305"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293306"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293307"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293308"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293309"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293310"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293311"] = "This fault is caused by 'StpDropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F293384"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293385"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293386"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293387"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293388"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293389"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293390"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293391"] = "This fault is caused by 'StpDropped Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F293392"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293393"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293394"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293395"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293396"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293397"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293398"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293399"] = "This fault is caused by 'StpDropped Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293400"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293401"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293402"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293403"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293404"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293405"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293406"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293407"] = "This fault is caused by 'StpDropped Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293408"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293409"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293410"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293411"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293412"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293413"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293414"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293415"] = "This fault is caused by 'StpDropped Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F293448"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293449"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293450"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293451"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293452"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293453"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293454"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293455"] = "This fault is caused by 'StpDropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F293504"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293505"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293506"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293507"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293508"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293509"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293510"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293511"] = "This fault is caused by 'StpDropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F293520"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293521"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293522"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293523"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293524"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293525"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293526"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293527"] = "This fault is caused by 'StpDropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F293528"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293529"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293530"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293531"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293532"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293533"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293534"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293535"] = "This fault is caused by 'StpDropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F293536"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293537"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293538"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293539"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293540"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293541"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293542"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293543"] = "This fault is caused by 'StpDropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F293544"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293545"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293546"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293547"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293548"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293549"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293550"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293551"] = "This fault is caused by 'StpDropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F293552"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293553"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293554"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293555"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293556"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293557"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293558"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293559"] = "This fault is caused by 'StpDropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F293584"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293585"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293586"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293587"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293588"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293589"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293590"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293591"] = "This fault is caused by 'StpDropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F293592"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293593"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293594"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293595"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293596"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293597"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293598"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293599"] = "This fault is caused by 'StpDropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F293672"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293673"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293674"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293675"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293676"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293677"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293678"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293679"] = "This fault is caused by 'StpDropped Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F293680"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293681"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293682"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293683"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293684"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293685"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293686"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293687"] = "This fault is caused by 'StpDropped Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F293688"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293689"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293690"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293691"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293692"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293693"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293694"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293695"] = "This fault is caused by 'StpDropped Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F293696"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293697"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293698"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293699"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293700"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293701"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293702"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293703"] = "This fault is caused by 'StpDropped Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F293736"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293737"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293738"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293739"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293740"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293741"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293742"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F293743"] = "This fault is caused by 'StpDropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2942"] = "The object refers to an object that was not found." + self.system_fault_code["F2943"] = "The object refers to an object that was not found." + self.system_fault_code["F2944"] = "The object refers to an object that was not found." + self.system_fault_code["F2948"] = "The object refers to an object that was not found." + self.system_fault_code["F2958"] = "This fault occurs when flood in encapsulation is enabled for an EPG in an unsupported platform" + self.system_fault_code["F2959"] = "This fault occurs when intra-epg isolation and flood in enacapsulation is enabled for an EPG." + self.system_fault_code["F296104"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296105"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296106"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296107"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296108"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296109"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296110"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296111"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296120"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296121"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296122"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296123"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296124"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296125"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296126"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296127"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296128"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296129"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296130"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296131"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296132"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296133"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296134"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296135"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296136"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296137"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296138"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296139"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296140"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296141"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296142"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296143"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296144"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296145"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296146"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296147"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296148"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296149"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296150"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296151"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296152"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296153"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296154"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296155"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296156"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296157"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296158"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296159"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296184"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296185"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296186"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296187"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296188"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296189"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296190"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296191"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296192"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296193"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296194"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296195"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296196"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296197"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296198"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296199"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2962"] = "The object refers to an object that was not found." + self.system_fault_code["F296272"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296273"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296274"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296275"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296276"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296277"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296278"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296279"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296280"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296281"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296282"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296283"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296284"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296285"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296286"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296287"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296288"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296289"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296290"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296291"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296292"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296293"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296294"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296295"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296296"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296297"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296298"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296299"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296300"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296301"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296302"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296303"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296336"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296337"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296338"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296339"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296340"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296341"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296342"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296343"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296392"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296393"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296394"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296395"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296396"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296397"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296398"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296399"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296408"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296409"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296410"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296411"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296412"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296413"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296414"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296415"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296416"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296417"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296418"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296419"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296420"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296421"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296422"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296423"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296424"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296425"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296426"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296427"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296428"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296429"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296430"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296431"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F296432"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296433"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296434"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296435"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296436"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296437"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296438"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296439"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F296440"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296441"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296442"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296443"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296444"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296445"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296446"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296447"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F296472"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296473"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296474"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296475"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296476"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296477"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296478"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296479"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F296480"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296481"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296482"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296483"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296484"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296485"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296486"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296487"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F296560"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296561"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296562"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296563"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296564"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296565"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296566"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296567"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F296568"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296569"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296570"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296571"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296572"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296573"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296574"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296575"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296576"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296577"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296578"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296579"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296580"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296581"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296582"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296583"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296584"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296585"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296586"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296587"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296588"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296589"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296590"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F296591"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F2966"] = "The object refers to an object that was not found." + self.system_fault_code["F296624"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296625"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296626"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296627"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296628"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296629"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296630"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296631"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F296680"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296681"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296682"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296683"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296684"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296685"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296686"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296687"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F296696"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296697"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296698"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296699"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F2967"] = "This fault occurs when Radius server host is configured with invalid VRF" + self.system_fault_code["F296700"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296701"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296702"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296703"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F296704"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296705"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296706"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296707"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296708"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296709"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296710"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296711"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F296712"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296713"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296714"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296715"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296716"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296717"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296718"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296719"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F296720"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296721"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296722"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296723"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296724"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296725"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296726"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296727"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F296728"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296729"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296730"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296731"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296732"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296733"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296734"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296735"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F296760"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296761"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296762"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296763"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296764"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296765"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296766"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296767"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F296768"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296769"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296770"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296771"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296772"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296773"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296774"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F296775"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F2968"] = "This fault occurs because MACSec policy cannot be deployed on the interface." + self.system_fault_code["F296848"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296849"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296850"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296851"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296852"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296853"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296854"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296855"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F296856"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296857"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296858"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296859"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296860"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296861"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296862"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296863"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F296864"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296865"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296866"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296867"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296868"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296869"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296870"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296871"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F296872"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296873"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296874"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296875"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296876"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296877"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296878"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296879"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F296912"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296913"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296914"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296915"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296916"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296917"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296918"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296919"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F296968"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296969"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296970"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296971"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296972"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296973"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296974"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296975"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F296984"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296985"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296986"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296987"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296988"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296989"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296990"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296991"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F296992"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296993"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296994"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296995"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296996"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296997"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296998"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F296999"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F297000"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297001"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297002"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297003"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297004"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297005"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297006"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297007"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F297008"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297009"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297010"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297011"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297012"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297013"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297014"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297015"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F297016"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297017"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297018"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297019"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297020"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297021"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297022"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297023"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F297048"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297049"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297050"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297051"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297052"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297053"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297054"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297055"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F297056"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297057"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297058"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297059"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297060"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297061"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297062"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297063"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F297136"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297137"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297138"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297139"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297140"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297141"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297142"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297143"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F297144"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297145"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297146"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297147"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297148"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297149"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297150"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297151"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F297152"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297153"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297154"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297155"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297156"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297157"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297158"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297159"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F297160"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297161"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297162"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297163"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297164"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297165"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297166"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F297167"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F2972"] = "This Fault usually occurs if some feature requested the switch reboot." + self.system_fault_code["F297200"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297201"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297202"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297203"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297204"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297205"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297206"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F297207"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F2973"] = "This fault occurs when applying portp policy on a port fails." + self.system_fault_code["F2974"] = "This fault occurs when a duplicate learn is received for a SVI IP. This packet is dropped and a fault is raised" + self.system_fault_code["F2975"] = "The object refers to an object that was not found." + self.system_fault_code["F2977"] = "The object refers to an object that was not found." + self.system_fault_code["F2978"] = "The object refers to an object that was not found." + self.system_fault_code["F2980"] = "This fault occurs when we try to configure a latency policy while precision time protocol is disabled." + self.system_fault_code["F2981"] = "This fault occurs when applying portp policy on a port exceeds the limit allowed." + self.system_fault_code["F2982"] = "This fault occurs when First Hop Security detects security violation" + self.system_fault_code["F2984"] = "The object refers to an object that was not found." + self.system_fault_code["F2985"] = "The object refers to an object that was not found." + self.system_fault_code["F2986"] = "This fault occurs when the number of MacSec keys is more than 64" + self.system_fault_code["F2987"] = "The object refers to an object that was not found." + self.system_fault_code["F2990"] = "This fault occurs when an anomaly is reported on the app." + self.system_fault_code["F2991"] = "This fault is raised when both the opflex channels are down on AVE host." + self.system_fault_code["F2992"] = "This fault occurs when corresponding PBR service destination goes to failed state" + self.system_fault_code["F2995"] = "This fault occurs when PBR health group dest goes down" + self.system_fault_code["F2996"] = "This Fault usually occurs if some feature enable was requested but failed due to mutual exclusion." + self.system_fault_code["F2998"] = "The object refers to an object that was not found." + self.system_fault_code["F2999"] = "The object refers to an object that was not found." + self.system_fault_code["F3000"] = "This fault occurs when the session is not secured" + self.system_fault_code["F3001"] = "This fault occurs when the session is not secured" + self.system_fault_code["F3007"] = "The object refers to an object that was not found." + self.system_fault_code["F3010"] = "The object refers to an object that was not found." + self.system_fault_code["F3011"] = "The object refers to an object that was not found." + self.system_fault_code["F3013"] = "This fault occurs when a IP endpoint turns rogue" + self.system_fault_code["F3014"] = "This fault occurs when a MAC endpoint turns rogue" + self.system_fault_code["F301616"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301617"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301618"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301619"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301620"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301621"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301622"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301623"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F301632"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301633"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301634"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301635"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301636"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301637"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301638"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301639"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F301640"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301641"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301642"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301643"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301644"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301645"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301646"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301647"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F301648"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301649"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301650"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301651"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301652"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301653"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301654"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301655"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F301656"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301657"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301658"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301659"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301660"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301661"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301662"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301663"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F301664"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301665"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301666"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301667"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301668"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301669"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301670"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301671"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F301696"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301697"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301698"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301699"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301700"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301701"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301702"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301703"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F301704"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301705"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301706"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301707"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301708"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301709"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301710"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301711"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F301784"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301785"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301786"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301787"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301788"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301789"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301790"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301791"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F301792"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301793"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301794"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301795"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301796"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301797"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301798"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F301799"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F3018"] = "This fault occurs when span source on a l3out interface goes to failed state" + self.system_fault_code["F301800"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301801"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301802"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301803"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301804"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301805"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301806"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301807"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F301808"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301809"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301810"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301811"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301812"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301813"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301814"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301815"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F301848"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301849"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301850"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301851"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301852"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301853"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301854"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F301855"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F3019"] = "This fault is raised when ACI controller failed to retrieve complete Tagging information." + self.system_fault_code["F301904"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301905"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301906"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301907"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301908"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301909"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301910"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301911"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F301920"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301921"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301922"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301923"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301924"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301925"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301926"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301927"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F301928"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301929"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301930"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301931"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301932"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301933"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301934"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301935"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F301936"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301937"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301938"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301939"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301940"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301941"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301942"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301943"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F301944"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301945"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301946"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301947"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301948"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301949"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301950"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301951"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F301952"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301953"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301954"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301955"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301956"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301957"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301958"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301959"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F301984"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301985"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301986"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301987"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301988"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301989"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301990"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301991"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F301992"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301993"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301994"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301995"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301996"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301997"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301998"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F301999"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F3020"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F302072"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302073"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302074"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302075"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302076"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302077"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302078"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302079"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F302080"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302081"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302082"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302083"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302084"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302085"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302086"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302087"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F302088"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302089"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302090"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302091"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302092"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302093"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302094"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302095"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F302096"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302097"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302098"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302099"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302100"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302101"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302102"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302103"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F302136"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302137"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302138"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302139"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302140"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302141"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302142"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302143"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F302256"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302257"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302258"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302259"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302260"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302261"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302262"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302263"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F302264"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302265"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302266"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302267"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302268"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302269"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302270"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302271"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F302272"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302273"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302274"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302275"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302276"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302277"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302278"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302279"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F302280"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302281"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302282"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302283"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302284"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302285"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302286"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302287"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F302320"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302321"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302322"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302323"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302324"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302325"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302326"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302327"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F302376"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302377"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302378"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302379"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302380"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302381"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302382"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302383"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F302384"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302385"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302386"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302387"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302388"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302389"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302390"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302391"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F302392"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302393"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302394"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302395"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302396"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302397"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302398"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F302399"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F3024"] = "This fault occurs because MACSec Key policy has an issue." + self.system_fault_code["F302400"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302401"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302402"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302403"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302404"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302405"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302406"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302407"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F302440"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302441"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302442"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302443"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302444"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302445"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302446"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F302447"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F3026"] = "This fault occurs when TWAMP Server on a node becomes operationally down" + self.system_fault_code["F3027"] = "This fault occurs when TWAMP Responder on a node becomes operationally down" + self.system_fault_code["F3028"] = "This fault occurs when the operational state of the nd adjacency is down" + self.system_fault_code["F3029"] = "This fault occurs when the peers are reachable but the zmq connection cannot be established between the peers. To avoid" + self.system_fault_code["F3031"] = "This fault occurs when the Device X.509 Certificate is invalid." + self.system_fault_code["F303472"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303473"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303474"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303475"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303476"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303477"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303478"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303479"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F303488"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303489"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303490"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303491"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303492"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303493"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303494"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303495"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303496"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303497"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303498"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303499"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303500"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303501"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303502"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303503"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303504"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303505"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303506"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303507"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303508"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303509"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303510"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303511"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F303512"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303513"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303514"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303515"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303516"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303517"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303518"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303519"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F303520"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303521"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303522"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303523"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303524"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303525"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303526"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303527"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F303552"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303553"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303554"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303555"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303556"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303557"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303558"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303559"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303560"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303561"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303562"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303563"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303564"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303565"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303566"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303567"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F3036"] = "This fault occurs on a specific configuration error in DNS label on a tenant mgmt VRF. Allowed use on DNS label is only" + self.system_fault_code["F303640"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303641"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303642"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303643"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303644"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303645"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303646"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303647"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F303648"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303649"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303650"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303651"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303652"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303653"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303654"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303655"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F303680"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303681"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303682"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303683"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303684"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303685"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303686"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303687"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F303688"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303689"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303690"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303691"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303692"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303693"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303694"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303695"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F303744"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303745"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303746"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303747"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303748"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303749"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303750"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303751"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F303752"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303753"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303754"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303755"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303756"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303757"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303758"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303759"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F303760"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303761"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303762"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303763"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303764"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303765"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303766"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303767"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F303768"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303769"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303770"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303771"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303772"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303773"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303774"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303775"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F303808"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303809"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303810"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303811"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303812"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303813"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303814"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303815"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F303864"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303865"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303866"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303867"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303868"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303869"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303870"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303871"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets current value' statistical property crossing threshold level." + self.system_fault_code["F303880"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303881"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303882"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303883"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303884"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303885"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303886"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303887"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F303888"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303889"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303890"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303891"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303892"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303893"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303894"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303895"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F303896"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303897"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303898"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303899"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303900"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303901"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303902"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303903"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F303904"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303905"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303906"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303907"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303908"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303909"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303910"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303911"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F303912"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303913"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303914"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303915"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303916"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303917"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303918"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303919"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets average value' statistical property crossing threshold level." + self.system_fault_code["F303944"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303945"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303946"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303947"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303948"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303949"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303950"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303951"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F303952"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303953"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303954"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303955"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303956"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303957"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303958"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F303959"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304032"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304033"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304034"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304035"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304036"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304037"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304038"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304039"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304040"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304041"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304042"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304043"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304044"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304045"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304046"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304047"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304072"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304073"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304074"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304075"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304076"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304077"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304078"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304079"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304080"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304081"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304082"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304083"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304084"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304085"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304086"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304087"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate' statistical property crossing threshold level." + self.system_fault_code["F3041"] = "This fault occurs when unified port type configuration is invalid." + self.system_fault_code["F304136"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304137"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304138"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304139"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304140"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304141"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304142"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304143"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304144"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304145"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304146"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304147"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304148"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304149"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304150"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304151"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304152"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304153"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304154"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304155"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304156"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304157"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304158"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304159"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304160"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304161"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304162"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304163"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304164"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304165"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304166"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304167"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304200"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304201"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304202"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304203"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304204"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304205"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304206"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304207"] = "This fault is caused by 'IfCkt Ingress Policer Allowed Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304256"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304257"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304258"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304259"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304260"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304261"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304262"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304263"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F304272"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304273"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304274"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304275"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304276"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304277"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304278"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304279"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304280"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304281"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304282"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304283"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304284"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304285"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304286"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304287"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304288"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304289"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304290"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304291"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304292"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304293"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304294"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304295"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F304296"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304297"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304298"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304299"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F3043"] = "The object refers to an object that was not found." + self.system_fault_code["F304300"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304301"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304302"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304303"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F304304"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304305"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304306"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304307"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304308"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304309"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304310"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304311"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F304336"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304337"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304338"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304339"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304340"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304341"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304342"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304343"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304344"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304345"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304346"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304347"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304348"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304349"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304350"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304351"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304424"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304425"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304426"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304427"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304428"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304429"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304430"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304431"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F304432"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304433"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304434"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304435"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304436"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304437"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304438"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304439"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F304464"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304465"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304466"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304467"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304468"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304469"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304470"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304471"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F304472"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304473"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304474"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304475"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304476"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304477"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304478"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F304479"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F3045"] = "The object refers to an object that was not found." + self.system_fault_code["F304528"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304529"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304530"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304531"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304532"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304533"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304534"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304535"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate current value' statistical property crossing threshold" + self.system_fault_code["F304536"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304537"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304538"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304539"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304540"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304541"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304542"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304543"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304544"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304545"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304546"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304547"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304548"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304549"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304550"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304551"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304552"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304553"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304554"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304555"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304556"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304557"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304558"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304559"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate average value' statistical property crossing threshold" + self.system_fault_code["F304592"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304593"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304594"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304595"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304596"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304597"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304598"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F304599"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F3046"] = "The object refers to an object that was not found." + self.system_fault_code["F304648"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304649"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304650"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304651"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304652"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304653"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304654"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304655"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets current value' statistical property crossing threshold level." + self.system_fault_code["F304664"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304665"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304666"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304667"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304668"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304669"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304670"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304671"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304672"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304673"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304674"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304675"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304676"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304677"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304678"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304679"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304680"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304681"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304682"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304683"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304684"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304685"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304686"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304687"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F304688"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304689"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304690"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304691"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304692"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304693"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304694"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304695"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F304696"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304697"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304698"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304699"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304700"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304701"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304702"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304703"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets average value' statistical property crossing threshold level." + self.system_fault_code["F304728"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304729"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304730"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304731"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304732"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304733"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304734"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304735"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304736"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304737"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304738"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304739"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304740"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304741"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304742"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304743"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304816"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304817"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304818"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304819"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304820"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304821"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304822"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304823"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F304824"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304825"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304826"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304827"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304828"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304829"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304830"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304831"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F304856"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304857"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304858"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304859"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304860"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304861"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304862"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304863"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets trend' statistical property crossing threshold level." + self.system_fault_code["F304864"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304865"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304866"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304867"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304868"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304869"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304870"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304871"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate' statistical property crossing threshold level." + self.system_fault_code["F304920"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304921"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304922"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304923"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304924"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304925"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304926"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304927"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate current value' statistical property crossing threshold" + self.system_fault_code["F304928"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304929"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304930"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304931"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304932"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304933"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304934"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304935"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate minimum value' statistical property crossing threshold" + self.system_fault_code["F304936"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304937"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304938"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304939"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304940"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304941"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304942"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304943"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate maximum value' statistical property crossing threshold" + self.system_fault_code["F304944"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304945"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304946"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304947"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304948"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304949"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304950"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304951"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate average value' statistical property crossing threshold" + self.system_fault_code["F304984"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304985"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304986"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304987"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304988"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304989"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304990"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F304991"] = "This fault is caused by 'IfCkt Ingress Policer Dropped Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F3053"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3054"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3055"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3056"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3057"] = "This fault is raised when APIC Controller product is not registered with Cisco Smart Software Manager (CSSM)." + self.system_fault_code["F3058"] = "This fault is raised when registering APIC Controller product is failed." + self.system_fault_code["F3059"] = "This fault is raised when APIC Controller receives license out of compliance notification from CSSM." + self.system_fault_code["F3060"] = "This fault is raised when APIC Controller receives license authorization expired notification from SA (Smart Agent), which" + self.system_fault_code["F3061"] = "This fault is raised when APIC Controller receives ID certificate expired notification from SA (Smart Agent)." + self.system_fault_code["F3062"] = "This fault is raised when product license evaluation period (90 days) is expired." + self.system_fault_code["F3068"] = "This fault occurs when a learn for anycast IP is encountered with non-anycast MAC" + self.system_fault_code["F3069"] = "This fault occurs when Anycast EP Reachability configuration is deployed on an unsupported platform TOR. The reason could" + self.system_fault_code["F3070"] = "This fault occurs when Anycast EP Reachability configuration is deployed on an unsupported platform TOR. The reason could" + self.system_fault_code["F3071"] = "This fault occurs when Anycast MAC EP Reachability configuration is deployed on an unsupported platform TOR. The reason" + self.system_fault_code["F3072"] = "This fault is raised when APIC Controller receives ID certificate expired warning notification from SA (Smart Agent), which" + self.system_fault_code["F3073"] = "This fault occurs if the flash lifetime usage has reached 90% endurance limit" + self.system_fault_code["F3074"] = "This fault occurs if the flash lifetime usage has reached 80% endurance limit" + self.system_fault_code["F3080"] = "This fault occurs when the bgp dom router-id changes" + self.system_fault_code["F3081"] = "This fault occurs when the SAML X.509 Certificate is going to expire in one month." + self.system_fault_code["F3082"] = "This fault occurs when the SAML X.509 Certificate has expired." + self.system_fault_code["F3083"] = "This fault occurs when multiple MACs have same IP address in the same VRF." + self.system_fault_code["F3086"] = "The object refers to an object that was not found." + self.system_fault_code["F3088"] = "The object refers to an object that was not found." + self.system_fault_code["F308928"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308929"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308930"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308931"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308932"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308933"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308934"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308935"] = "This fault is caused by 'Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F308944"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308945"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308946"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308947"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308948"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308949"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308950"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308951"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F308952"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308953"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308954"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308955"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308956"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308957"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308958"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308959"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F308960"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308961"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308962"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308963"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308964"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308965"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308966"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308967"] = "This fault is caused by 'Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F308968"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308969"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308970"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308971"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308972"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308973"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308974"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308975"] = "This fault is caused by 'Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F308976"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308977"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308978"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308979"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308980"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308981"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308982"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F308983"] = "This fault is caused by 'Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F309008"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309009"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309010"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309011"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309012"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309013"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309014"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309015"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309016"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309017"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309018"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309019"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309020"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309021"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309022"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309023"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309096"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309097"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309098"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309099"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309100"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309101"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309102"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309103"] = "This fault is caused by 'Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F309104"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309105"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309106"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309107"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309108"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309109"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309110"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309111"] = "This fault is caused by 'Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F309136"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309137"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309138"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309139"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309140"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309141"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309142"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309143"] = "This fault is caused by 'Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F309144"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309145"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309146"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309147"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309148"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309149"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309150"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309151"] = "This fault is caused by 'Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F309200"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309201"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309202"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309203"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309204"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309205"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309206"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309207"] = "This fault is caused by 'Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F309208"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309209"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309210"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309211"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309212"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309213"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309214"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309215"] = "This fault is caused by 'Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309216"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309217"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309218"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309219"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309220"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309221"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309222"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309223"] = "This fault is caused by 'Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309224"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309225"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309226"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309227"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309228"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309229"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309230"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309231"] = "This fault is caused by 'Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F309264"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309265"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309266"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309267"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309268"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309269"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309270"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309271"] = "This fault is caused by 'Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F309320"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309321"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309322"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309323"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309324"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309325"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309326"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309327"] = "This fault is caused by 'Packets current value' statistical property crossing threshold level." + self.system_fault_code["F309336"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309337"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309338"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309339"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309340"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309341"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309342"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309343"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309344"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309345"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309346"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309347"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309348"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309349"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309350"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309351"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309352"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309353"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309354"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309355"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309356"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309357"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309358"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309359"] = "This fault is caused by 'Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F309360"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309361"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309362"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309363"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309364"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309365"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309366"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309367"] = "This fault is caused by 'Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F309368"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309369"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309370"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309371"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309372"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309373"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309374"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309375"] = "This fault is caused by 'Packets average value' statistical property crossing threshold level." + self.system_fault_code["F309400"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309401"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309402"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309403"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309404"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309405"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309406"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309407"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309408"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309409"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309410"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309411"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309412"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309413"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309414"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309415"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309488"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309489"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309490"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309491"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309492"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309493"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309494"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309495"] = "This fault is caused by 'Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F309496"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309497"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309498"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309499"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309500"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309501"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309502"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309503"] = "This fault is caused by 'Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F309528"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309529"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309530"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309531"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309532"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309533"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309534"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309535"] = "This fault is caused by 'Packets trend' statistical property crossing threshold level." + self.system_fault_code["F309536"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309537"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309538"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309539"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309540"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309541"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309542"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309543"] = "This fault is caused by 'Packets rate' statistical property crossing threshold level." + self.system_fault_code["F309592"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309593"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309594"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309595"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309596"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309597"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309598"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309599"] = "This fault is caused by 'Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F309600"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309601"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309602"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309603"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309604"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309605"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309606"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309607"] = "This fault is caused by 'Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F309608"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309609"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309610"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309611"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309612"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309613"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309614"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309615"] = "This fault is caused by 'Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F309616"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309617"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309618"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309619"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309620"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309621"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309622"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309623"] = "This fault is caused by 'Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F309656"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309657"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309658"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309659"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309660"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309661"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309662"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F309663"] = "This fault is caused by 'Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F3103"] = "This fault occurs when Dot1x and MACSEC policies are configured on the same port" + self.system_fault_code["F3105"] = "This fault occurs when PBR service dest group goes to failed state due to number of redir dests crosses limit of 128" + self.system_fault_code["F3108"] = "The object refers to an object that was not found." + self.system_fault_code["F3109"] = "The object refers to an object that was not found." + self.system_fault_code["F3113"] = "This fault occurs when a transceiver is invalid or has hardware issues." + self.system_fault_code["F3117"] = "The object refers to an object that was not found." + self.system_fault_code["F3118"] = "This fault occurs when the Macsec policy conflicts with dot1x policy" + self.system_fault_code["F312240"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312241"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312242"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312243"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312244"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312245"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312246"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312247"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312256"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312257"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312258"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312259"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312260"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312261"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312262"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312263"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312264"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312265"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312266"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312267"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312268"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312269"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312270"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312271"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312272"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312273"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312274"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312275"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312276"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312277"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312278"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312279"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312280"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312281"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312282"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312283"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312284"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312285"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312286"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312287"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312288"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312289"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312290"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312291"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312292"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312293"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312294"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312295"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312320"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312321"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312322"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312323"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312324"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312325"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312326"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312327"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312328"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312329"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312330"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312331"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312332"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312333"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312334"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312335"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312408"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312409"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312410"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312411"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312412"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312413"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312414"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312415"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F312424"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312425"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312426"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312427"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312428"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312429"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312430"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312431"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312432"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312433"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312434"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312435"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312436"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312437"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312438"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312439"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312440"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312441"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312442"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312443"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312444"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312445"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312446"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312447"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F312448"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312449"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312450"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312451"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312452"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312453"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312454"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312455"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F312456"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312457"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312458"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312459"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312460"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312461"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312462"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312463"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F312488"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312489"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312490"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312491"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312492"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312493"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312494"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312495"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312496"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312497"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312498"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312499"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312500"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312501"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312502"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312503"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312576"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312577"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312578"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312579"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312580"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312581"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312582"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312583"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F312584"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312585"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312586"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312587"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312588"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312589"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312590"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F312591"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F3126"] = "This fault is raised when ACI controller fails to deploy vm in vcenter." + self.system_fault_code["F312616"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312617"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312618"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312619"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312620"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312621"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312622"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312623"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F312624"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312625"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312626"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312627"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312628"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312629"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312630"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312631"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F312680"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312681"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312682"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312683"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312684"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312685"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312686"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312687"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312696"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312697"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312698"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312699"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F3127"] = "This fault is raised when ACI controller fails to update the datastore information." + self.system_fault_code["F312700"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312701"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312702"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312703"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312704"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312705"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312706"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312707"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312708"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312709"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312710"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312711"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312712"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312713"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312714"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312715"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312716"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312717"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312718"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312719"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312720"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312721"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312722"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312723"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312724"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312725"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312726"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312727"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312728"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312729"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312730"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312731"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312732"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312733"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312734"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312735"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312760"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312761"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312762"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312763"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312764"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312765"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312766"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312767"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312768"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312769"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312770"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312771"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312772"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312773"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312774"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312775"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F3128"] = "This fault is raised when ACI controller fails to update the resource pool information." + self.system_fault_code["F312848"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312849"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312850"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312851"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312852"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312853"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312854"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312855"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F312864"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312865"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312866"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312867"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312868"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312869"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312870"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312871"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F312872"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312873"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312874"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312875"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312876"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312877"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312878"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312879"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F312880"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312881"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312882"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312883"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312884"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312885"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312886"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312887"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F312888"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312889"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312890"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312891"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312892"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312893"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312894"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312895"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F312896"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312897"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312898"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312899"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312900"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312901"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312902"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312903"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F312928"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312929"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312930"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312931"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312932"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312933"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312934"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312935"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F312936"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312937"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312938"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312939"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312940"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312941"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312942"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F312943"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313016"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313017"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313018"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313019"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313020"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313021"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313022"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313023"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F313024"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313025"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313026"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313027"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313028"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313029"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313030"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313031"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F313056"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313057"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313058"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313059"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313060"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313061"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313062"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313063"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F313064"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313065"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313066"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313067"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313068"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313069"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313070"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313071"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F313120"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313121"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313122"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313123"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313124"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313125"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313126"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313127"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313136"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313137"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313138"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313139"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313140"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313141"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313142"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313143"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313144"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313145"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313146"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313147"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313148"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313149"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313150"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313151"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313152"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313153"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313154"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313155"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313156"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313157"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313158"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313159"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313160"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313161"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313162"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313163"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313164"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313165"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313166"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313167"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313168"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313169"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313170"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313171"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313172"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313173"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313174"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313175"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313200"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313201"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313202"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313203"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313204"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313205"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313206"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313207"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313208"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313209"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313210"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313211"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313212"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313213"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313214"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313215"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313288"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313289"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313290"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313291"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313292"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313293"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313294"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313295"] = "This fault is caused by 'received bytes (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313304"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313305"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313306"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313307"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313308"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313309"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313310"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313311"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313312"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313313"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313314"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313315"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313316"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313317"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313318"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313319"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313320"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313321"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313322"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313323"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313324"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313325"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313326"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313327"] = "This fault is caused by 'received bytes (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313328"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313329"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313330"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313331"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313332"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313333"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313334"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313335"] = "This fault is caused by 'received bytes (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313336"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313337"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313338"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313339"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313340"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313341"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313342"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313343"] = "This fault is caused by 'received bytes (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313368"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313369"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313370"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313371"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313372"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313373"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313374"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313375"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313376"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313377"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313378"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313379"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313380"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313381"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313382"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313383"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F3134"] = "The object refers to an object that was not found." + self.system_fault_code["F313456"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313457"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313458"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313459"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313460"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313461"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313462"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313463"] = "This fault is caused by 'received bytes (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313464"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313465"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313466"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313467"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313468"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313469"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313470"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313471"] = "This fault is caused by 'received bytes (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313496"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313497"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313498"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313499"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F3135"] = "The object refers to an object that was not found." + self.system_fault_code["F313500"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313501"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313502"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313503"] = "This fault is caused by 'received bytes (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313504"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313505"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313506"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313507"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313508"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313509"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313510"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313511"] = "This fault is caused by 'received bytes (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313560"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313561"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313562"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313563"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313564"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313565"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313566"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313567"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313576"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313577"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313578"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313579"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313580"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313581"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313582"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313583"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313584"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313585"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313586"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313587"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313588"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313589"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313590"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313591"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313592"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313593"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313594"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313595"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313596"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313597"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313598"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313599"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313600"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313601"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313602"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313603"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313604"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313605"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313606"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313607"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313608"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313609"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313610"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313611"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313612"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313613"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313614"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313615"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313640"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313641"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313642"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313643"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313644"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313645"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313646"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313647"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313648"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313649"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313650"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313651"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313652"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313653"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313654"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313655"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313728"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313729"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313730"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313731"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313732"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313733"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313734"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313735"] = "This fault is caused by 'received packets (reverse) current value' statistical property crossing threshold level." + self.system_fault_code["F313744"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313745"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313746"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313747"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313748"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313749"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313750"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313751"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313752"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313753"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313754"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313755"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313756"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313757"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313758"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313759"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313760"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313761"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313762"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313763"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313764"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313765"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313766"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313767"] = "This fault is caused by 'received packets (reverse) minimum value' statistical property crossing threshold level." + self.system_fault_code["F313768"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313769"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313770"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313771"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313772"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313773"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313774"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313775"] = "This fault is caused by 'received packets (reverse) maximum value' statistical property crossing threshold level." + self.system_fault_code["F313776"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313777"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313778"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313779"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313780"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313781"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313782"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F313783"] = "This fault is caused by 'received packets (reverse) average value' statistical property crossing threshold level." + self.system_fault_code["F3138"] = "The object refers to an object that was not found." + self.system_fault_code["F313808"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313809"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313810"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313811"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313812"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313813"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313814"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313815"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313816"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313817"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313818"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313819"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313820"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313821"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313822"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313823"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313896"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313897"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313898"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313899"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313900"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313901"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313902"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313903"] = "This fault is caused by 'received packets (reverse) cumulative' statistical property crossing threshold level." + self.system_fault_code["F313904"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313905"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313906"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313907"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313908"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313909"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313910"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313911"] = "This fault is caused by 'received packets (reverse) periodic' statistical property crossing threshold level." + self.system_fault_code["F313936"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313937"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313938"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313939"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313940"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313941"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313942"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313943"] = "This fault is caused by 'received packets (reverse) trend' statistical property crossing threshold level." + self.system_fault_code["F313944"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313945"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313946"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313947"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313948"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313949"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313950"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F313951"] = "This fault is caused by 'received packets (reverse) rate' statistical property crossing threshold level." + self.system_fault_code["F314000"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314001"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314002"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314003"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314004"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314005"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314006"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314007"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314016"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314017"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314018"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314019"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314020"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314021"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314022"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314023"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314024"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314025"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314026"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314027"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314028"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314029"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314030"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314031"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314032"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314033"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314034"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314035"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314036"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314037"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314038"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314039"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314040"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314041"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314042"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314043"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314044"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314045"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314046"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314047"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314048"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314049"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314050"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314051"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314052"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314053"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314054"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314055"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314080"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314081"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314082"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314083"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314084"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314085"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314086"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314087"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314088"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314089"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314090"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314091"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314092"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314093"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314094"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314095"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F3141"] = "This fault occurs when VFC interface is created with per-port vlan config" + self.system_fault_code["F314168"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314169"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314170"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314171"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314172"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314173"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314174"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314175"] = "This fault is caused by 'received bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314184"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314185"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314186"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314187"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314188"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314189"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314190"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314191"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314192"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314193"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314194"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314195"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314196"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314197"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314198"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314199"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314200"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314201"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314202"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314203"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314204"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314205"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314206"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314207"] = "This fault is caused by 'received bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314208"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314209"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314210"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314211"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314212"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314213"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314214"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314215"] = "This fault is caused by 'received bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314216"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314217"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314218"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314219"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314220"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314221"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314222"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314223"] = "This fault is caused by 'received bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314248"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314249"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314250"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314251"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314252"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314253"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314254"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314255"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314256"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314257"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314258"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314259"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314260"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314261"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314262"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314263"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314336"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314337"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314338"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314339"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314340"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314341"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314342"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314343"] = "This fault is caused by 'received bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314344"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314345"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314346"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314347"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314348"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314349"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314350"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314351"] = "This fault is caused by 'received bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314376"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314377"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314378"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314379"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314380"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314381"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314382"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314383"] = "This fault is caused by 'received bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314384"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314385"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314386"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314387"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314388"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314389"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314390"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314391"] = "This fault is caused by 'received bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314440"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314441"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314442"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314443"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314444"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314445"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314446"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314447"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314456"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314457"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314458"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314459"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314460"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314461"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314462"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314463"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314464"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314465"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314466"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314467"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314468"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314469"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314470"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314471"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314472"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314473"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314474"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314475"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314476"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314477"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314478"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314479"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314480"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314481"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314482"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314483"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314484"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314485"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314486"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314487"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314488"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314489"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314490"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314491"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314492"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314493"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314494"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314495"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F3145"] = "This fault occurs when there is a mismatch between user config and EPM config Defaulting rogue EP hold interval to 1800" + self.system_fault_code["F314520"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314521"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314522"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314523"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314524"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314525"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314526"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314527"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314528"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314529"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314530"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314531"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314532"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314533"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314534"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314535"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F3146"] = "This fault occurs when there is a mismatch between user config and EPM config Defaulting rogue EP detect multiple to" + self.system_fault_code["F314608"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314609"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314610"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314611"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314612"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314613"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314614"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314615"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F314624"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314625"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314626"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314627"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314628"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314629"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314630"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314631"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314632"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314633"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314634"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314635"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314636"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314637"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314638"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314639"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314640"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314641"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314642"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314643"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314644"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314645"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314646"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314647"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F314648"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314649"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314650"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314651"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314652"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314653"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314654"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314655"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F314656"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314657"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314658"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314659"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314660"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314661"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314662"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314663"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F314688"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314689"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314690"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314691"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314692"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314693"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314694"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314695"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314696"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314697"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314698"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314699"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F3147"] = "This fault occurs when Dot1x was deployed on an unsupported hardware platform" + self.system_fault_code["F314700"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314701"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314702"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314703"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314776"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314777"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314778"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314779"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314780"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314781"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314782"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314783"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F314784"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314785"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314786"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314787"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314788"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314789"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314790"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F314791"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F3148"] = "This fault occurs when inband ips are not confiured on apic nodes." + self.system_fault_code["F314816"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314817"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314818"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314819"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314820"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314821"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314822"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314823"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F314824"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314825"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314826"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314827"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314828"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314829"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314830"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314831"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F314880"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314881"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314882"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314883"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314884"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314885"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314886"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314887"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F314896"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314897"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314898"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314899"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F3149"] = "This fault occurs when inband ips are not confiured on apic nodes." + self.system_fault_code["F314900"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314901"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314902"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314903"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F314904"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314905"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314906"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314907"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314908"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314909"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314910"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314911"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F314912"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314913"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314914"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314915"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314916"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314917"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314918"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314919"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F314920"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314921"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314922"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314923"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314924"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314925"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314926"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314927"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F314928"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314929"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314930"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314931"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314932"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314933"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314934"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314935"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F314960"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314961"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314962"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314963"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314964"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314965"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314966"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314967"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F314968"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314969"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314970"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314971"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314972"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314973"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314974"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F314975"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F3150"] = "This fault occurs when PTP is not enabled in the fabric and FlowCollector policy is enabled" + self.system_fault_code["F315048"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315049"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315050"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315051"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315052"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315053"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315054"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315055"] = "This fault is caused by 'transmitted bytes current value' statistical property crossing threshold level." + self.system_fault_code["F315064"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315065"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315066"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315067"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315068"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315069"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315070"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315071"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315072"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315073"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315074"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315075"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315076"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315077"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315078"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315079"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315080"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315081"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315082"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315083"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315084"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315085"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315086"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315087"] = "This fault is caused by 'transmitted bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F315088"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315089"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315090"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315091"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315092"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315093"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315094"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315095"] = "This fault is caused by 'transmitted bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F315096"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315097"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315098"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315099"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F3151"] = "This fault occurs when the operational state of the Cloudsec Interface is changed to due to deployement failures on the" + self.system_fault_code["F315100"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315101"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315102"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315103"] = "This fault is caused by 'transmitted bytes average value' statistical property crossing threshold level." + self.system_fault_code["F315128"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315129"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315130"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315131"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315132"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315133"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315134"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315135"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315136"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315137"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315138"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315139"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315140"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315141"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315142"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315143"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F3152"] = "This fault occurs when the operational state of the Cloudsec SaPeer is changed to due to deployement failures on the" + self.system_fault_code["F315216"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315217"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315218"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315219"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315220"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315221"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315222"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315223"] = "This fault is caused by 'transmitted bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F315224"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315225"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315226"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315227"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315228"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315229"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315230"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315231"] = "This fault is caused by 'transmitted bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F315256"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315257"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315258"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315259"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315260"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315261"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315262"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315263"] = "This fault is caused by 'transmitted bytes trend' statistical property crossing threshold level." + self.system_fault_code["F315264"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315265"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315266"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315267"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315268"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315269"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315270"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F315271"] = "This fault is caused by 'transmitted bytes rate' statistical property crossing threshold level." + self.system_fault_code["F3153"] = "This fault occurs when the operational state of the Cloudsec Tx Key is changed to due to deployement failures on the" + self.system_fault_code["F315320"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315321"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315322"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315323"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315324"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315325"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315326"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315327"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315336"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315337"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315338"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315339"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315340"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315341"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315342"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315343"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315344"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315345"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315346"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315347"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315348"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315349"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315350"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315351"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315352"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315353"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315354"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315355"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315356"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315357"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315358"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315359"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315360"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315361"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315362"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315363"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315364"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315365"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315366"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315367"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315368"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315369"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315370"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315371"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315372"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315373"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315374"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315375"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F3154"] = "This fault occurs when the operational state of the Cloudsec Rx Key is changed to due to deployement failures on the" + self.system_fault_code["F315400"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315401"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315402"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315403"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315404"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315405"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315406"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315407"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315408"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315409"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315410"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315411"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315412"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315413"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315414"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315415"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315488"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315489"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315490"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315491"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315492"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315493"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315494"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315495"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F315504"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315505"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315506"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315507"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315508"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315509"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315510"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315511"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315512"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315513"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315514"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315515"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315516"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315517"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315518"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315519"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315520"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315521"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315522"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315523"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315524"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315525"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315526"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315527"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F315528"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315529"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315530"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315531"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315532"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315533"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315534"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315535"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F315536"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315537"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315538"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315539"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315540"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315541"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315542"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315543"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F315568"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315569"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315570"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315571"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315572"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315573"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315574"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315575"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315576"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315577"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315578"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315579"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315580"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315581"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315582"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315583"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315656"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315657"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315658"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315659"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315660"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315661"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315662"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315663"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F315664"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315665"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315666"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315667"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315668"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315669"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315670"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315671"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F315696"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315697"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315698"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315699"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F3157"] = "The object refers to an object that was not found." + self.system_fault_code["F315700"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315701"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315702"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315703"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F315704"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315705"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315706"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315707"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315708"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315709"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315710"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F315711"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F3158"] = "This fault occurs when qos manager fails to activate a class due to exceeding max allowed strict priority classes" + self.system_fault_code["F3160"] = "This fault is raised when the APIC is unable to connect to the external Identity server. Recovery is in process." + self.system_fault_code["F316272"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316273"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316274"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316275"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316276"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316277"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316278"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316279"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage current value' statistical property crossing" + self.system_fault_code["F316280"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316281"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316282"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316283"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316284"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316285"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316286"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316287"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage minimum value' statistical property crossing" + self.system_fault_code["F316288"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316289"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316290"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316291"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316292"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316293"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316294"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316295"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage maximum value' statistical property crossing" + self.system_fault_code["F316296"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316297"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316298"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316299"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316300"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316301"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316302"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316303"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage average value' statistical property crossing" + self.system_fault_code["F316336"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316337"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316338"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316339"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316340"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316341"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316342"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316343"] = "This fault is caused by 'External Subnet v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold" + self.system_fault_code["F316392"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316393"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316394"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316395"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316396"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316397"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316398"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316399"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F316400"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316401"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316402"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316403"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316404"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316405"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316406"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316407"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F316408"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316409"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316410"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316411"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316412"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316413"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316414"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316415"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F316416"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316417"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316418"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316419"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316420"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316421"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316422"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316423"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F316456"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316457"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316458"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316459"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316460"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316461"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316462"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316463"] = "This fault is caused by 'v6 /84 to /127 prefix entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F316512"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316513"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316514"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316515"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316516"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316517"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316518"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316519"] = "This fault is caused by 'Deprecated.. current value' statistical property crossing threshold level." + self.system_fault_code["F316520"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316521"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316522"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316523"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316524"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316525"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316526"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316527"] = "This fault is caused by 'Deprecated.. minimum value' statistical property crossing threshold level." + self.system_fault_code["F316528"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316529"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316530"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316531"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316532"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316533"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316534"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316535"] = "This fault is caused by 'Deprecated.. maximum value' statistical property crossing threshold level." + self.system_fault_code["F316536"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316537"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316538"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316539"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316540"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316541"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316542"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316543"] = "This fault is caused by 'Deprecated.. average value' statistical property crossing threshold level." + self.system_fault_code["F316576"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316577"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316578"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316579"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316580"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316581"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316582"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F316583"] = "This fault is caused by 'Deprecated.. trend' statistical property crossing threshold level." + self.system_fault_code["F3180"] = "The object refers to an object that was not found." + self.system_fault_code["F3181"] = "The object refers to an object that was not found." + self.system_fault_code["F3182"] = "The object refers to an object that was not found." + self.system_fault_code["F3183"] = "The object refers to an object that was not found." + self.system_fault_code["F3189"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F3190"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F3191"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F3192"] = "This fault is raised when there is an operational issue with respect to the Opflex device" + self.system_fault_code["F3193"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F3194"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F3195"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F3196"] = "This fault is raised when there is an operational issue with respect to the OpFlex End Points." + self.system_fault_code["F3206"] = "This fault occurs when failed EPg or Vlan field is empty for l2NodeAuthPol" + self.system_fault_code["F3208"] = "This fault is raised when the APIC is unable to connect to the External Device. Recovery is in process." + self.system_fault_code["F3209"] = "This fault is raised when the APIC is unable to connect to the External Device. Recovery is in process." + self.system_fault_code["F3210"] = "This fault is raised when the NIC Profile has been configured but is not present on the External Device." + self.system_fault_code["F3211"] = "This fault is raised when the Uplink Profile has been configured but is not present on the External Device." + self.system_fault_code["F3218"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3219"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3220"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3221"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3222"] = "This fault occurs when any Vlan pool has been consumed to a limit." + self.system_fault_code["F3227"] = "This fault occurs when ACI fails processing an already accepted configuration change." + self.system_fault_code["F3232"] = "This fault occurs when a controller reports snapshot for a given service did not succeed." + self.system_fault_code["F3235"] = "This fault occurs when there service vm deployed using compute-orchestration is deleted from VCenter." + self.system_fault_code["F3236"] = "The object refers to an object that was not found." + self.system_fault_code["F3238"] = "The object refers to an object that was not found." + self.system_fault_code["F3242"] = "This fault occurs when the vlan encap for PoE policy is not present." + self.system_fault_code["F324240"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324241"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324242"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324243"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324244"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324245"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324246"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324247"] = "This fault is caused by 'Remote L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324272"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324273"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324274"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324275"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324276"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324277"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324278"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324279"] = "This fault is caused by 'Remote L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324280"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324281"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324282"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324283"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324284"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324285"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324286"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324287"] = "This fault is caused by 'Remote L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324288"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324289"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324290"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324291"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324292"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324293"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324294"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324295"] = "This fault is caused by 'Remote L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F3243"] = "The object refers to an object that was not found." + self.system_fault_code["F324320"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324321"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324322"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324323"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324324"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324325"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324326"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324327"] = "This fault is caused by 'Remote L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F3244"] = "The object refers to an object that was not found." + self.system_fault_code["F324408"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324409"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324410"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324411"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324412"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324413"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324414"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324415"] = "This fault is caused by 'Remote L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324440"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324441"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324442"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324443"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324444"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324445"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324446"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324447"] = "This fault is caused by 'Remote L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324448"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324449"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324450"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324451"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324452"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324453"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324454"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324455"] = "This fault is caused by 'Remote L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324456"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324457"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324458"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324459"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324460"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324461"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324462"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324463"] = "This fault is caused by 'Remote L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324488"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324489"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324490"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324491"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324492"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324493"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324494"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324495"] = "This fault is caused by 'Remote L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F3245"] = "The object refers to an object that was not found." + self.system_fault_code["F324576"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324577"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324578"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324579"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324580"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324581"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324582"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324583"] = "This fault is caused by 'Remote L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F324584"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324585"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324586"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324587"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324588"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324589"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324590"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324591"] = "This fault is caused by 'Remote L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F324592"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324593"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324594"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324595"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324596"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324597"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324598"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324599"] = "This fault is caused by 'Remote L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F324600"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324601"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324602"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324603"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324604"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324605"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324606"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324607"] = "This fault is caused by 'Remote L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F324640"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324641"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324642"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324643"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324644"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324645"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324646"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324647"] = "This fault is caused by 'Remote L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F324696"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324697"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324698"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324699"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F3247"] = "This fault occurs due to missing PSK in cloudsec Interface Policy." + self.system_fault_code["F324700"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324701"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324702"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324703"] = "This fault is caused by 'Total L2 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F324728"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324729"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324730"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324731"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324732"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324733"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324734"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324735"] = "This fault is caused by 'Total L2 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F324736"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324737"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324738"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324739"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324740"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324741"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324742"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324743"] = "This fault is caused by 'Total L2 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F324744"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324745"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324746"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324747"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324748"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324749"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324750"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324751"] = "This fault is caused by 'Total L2 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F324776"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324777"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324778"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324779"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324780"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324781"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324782"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F324783"] = "This fault is caused by 'Total L2 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F3248"] = "This fault occurs when user tries to configure unsupported configuration for FC ports" + self.system_fault_code["F324864"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324865"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324866"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324867"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324868"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324869"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324870"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324871"] = "This fault is caused by 'Total L2 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F324896"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324897"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324898"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324899"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324900"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324901"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324902"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324903"] = "This fault is caused by 'Total L2 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F324904"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324905"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324906"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324907"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324908"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324909"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324910"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324911"] = "This fault is caused by 'Total L2 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F324912"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324913"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324914"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324915"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324916"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324917"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324918"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324919"] = "This fault is caused by 'Total L2 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F324944"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324945"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324946"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324947"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324948"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324949"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324950"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F324951"] = "This fault is caused by 'Total L2 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F3250"] = "This fault is raised when the Claim Device Licenses operation is timeout after 5 minutes." + self.system_fault_code["F325032"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325033"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325034"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325035"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325036"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325037"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325038"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325039"] = "This fault is caused by 'Total L2 entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F325040"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325041"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325042"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325043"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325044"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325045"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325046"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325047"] = "This fault is caused by 'Total L2 entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325048"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325049"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325050"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325051"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325052"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325053"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325054"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325055"] = "This fault is caused by 'Total L2 entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325056"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325057"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325058"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325059"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325060"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325061"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325062"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325063"] = "This fault is caused by 'Total L2 entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F325096"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325097"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325098"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325099"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325100"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325101"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325102"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325103"] = "This fault is caused by 'Total L2 entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F325152"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325153"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325154"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325155"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325156"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325157"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325158"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325159"] = "This fault is caused by 'Remote v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325184"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325185"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325186"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325187"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325188"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325189"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325190"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325191"] = "This fault is caused by 'Remote v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325192"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325193"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325194"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325195"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325196"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325197"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325198"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325199"] = "This fault is caused by 'Remote v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325200"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325201"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325202"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325203"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325204"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325205"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325206"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325207"] = "This fault is caused by 'Remote v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325232"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325233"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325234"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325235"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325236"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325237"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325238"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325239"] = "This fault is caused by 'Remote v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325320"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325321"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325322"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325323"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325324"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325325"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325326"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325327"] = "This fault is caused by 'Remote v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F325352"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325353"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325354"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325355"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325356"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325357"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325358"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325359"] = "This fault is caused by 'Remote v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F325360"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325361"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325362"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325363"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325364"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325365"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325366"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325367"] = "This fault is caused by 'Remote v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F325368"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325369"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325370"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325371"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325372"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325373"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325374"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F325375"] = "This fault is caused by 'Remote v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F3254"] = "Plugin health is not OK." + self.system_fault_code["F325400"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325401"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325402"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325403"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325404"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325405"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325406"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325407"] = "This fault is caused by 'Remote v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F325488"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325489"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325490"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325491"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325492"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325493"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325494"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325495"] = "This fault is caused by 'Remote v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F3255"] = "This fault occurs when same PC Tag value is used for more than one instances of a class." + self.system_fault_code["F325520"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325521"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325522"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325523"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325524"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325525"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325526"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325527"] = "This fault is caused by 'Remote v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325528"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325529"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325530"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325531"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325532"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325533"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325534"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325535"] = "This fault is caused by 'Remote v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325536"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325537"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325538"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325539"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325540"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325541"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325542"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325543"] = "This fault is caused by 'Remote v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325568"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325569"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325570"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325571"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325572"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325573"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325574"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325575"] = "This fault is caused by 'Remote v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325656"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325657"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325658"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325659"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325660"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325661"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325662"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325663"] = "This fault is caused by 'Remote v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F325688"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325689"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325690"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325691"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325692"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325693"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325694"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325695"] = "This fault is caused by 'Remote v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F325696"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325697"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325698"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325699"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325700"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325701"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325702"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325703"] = "This fault is caused by 'Remote v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F325704"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325705"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325706"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325707"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325708"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325709"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325710"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325711"] = "This fault is caused by 'Remote v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F325736"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325737"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325738"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325739"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325740"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325741"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325742"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325743"] = "This fault is caused by 'Remote v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F325824"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325825"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325826"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325827"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325828"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325829"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325830"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325831"] = "This fault is caused by 'Remote v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325832"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325833"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325834"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325835"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325836"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325837"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325838"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325839"] = "This fault is caused by 'Remote v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325840"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325841"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325842"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325843"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325844"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325845"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325846"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325847"] = "This fault is caused by 'Remote v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325848"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325849"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325850"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325851"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325852"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325853"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325854"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325855"] = "This fault is caused by 'Remote v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325888"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325889"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325890"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325891"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325892"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325893"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325894"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325895"] = "This fault is caused by 'Remote v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F325944"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325945"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325946"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325947"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325948"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325949"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325950"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325951"] = "This fault is caused by 'Remote v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F325952"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325953"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325954"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325955"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325956"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325957"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325958"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325959"] = "This fault is caused by 'Remote v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F325960"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325961"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325962"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325963"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325964"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325965"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325966"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325967"] = "This fault is caused by 'Remote v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F325968"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325969"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325970"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325971"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325972"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325973"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325974"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F325975"] = "This fault is caused by 'Remote v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326008"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326009"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326010"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326011"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326012"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326013"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326014"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326015"] = "This fault is caused by 'Remote v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326064"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326065"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326066"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326067"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326068"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326069"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326070"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326071"] = "This fault is caused by 'Total v4 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326096"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326097"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326098"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326099"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F3261"] = "This fault occurs when the ep learning is disabled because of loop detection" + self.system_fault_code["F326100"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326101"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326102"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326103"] = "This fault is caused by 'Total v4 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326104"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326105"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326106"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326107"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326108"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326109"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326110"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326111"] = "This fault is caused by 'Total v4 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326112"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326113"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326114"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326115"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326116"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326117"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326118"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326119"] = "This fault is caused by 'Total v4 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326144"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326145"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326146"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326147"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326148"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326149"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326150"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326151"] = "This fault is caused by 'Total v4 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326232"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326233"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326234"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326235"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326236"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326237"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326238"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326239"] = "This fault is caused by 'Total v6 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F326264"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326265"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326266"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326267"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326268"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326269"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326270"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326271"] = "This fault is caused by 'Total v6 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F326272"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326273"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326274"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326275"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326276"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326277"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326278"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326279"] = "This fault is caused by 'Total v6 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F326280"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326281"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326282"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326283"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326284"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326285"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326286"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326287"] = "This fault is caused by 'Total v6 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F326312"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326313"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326314"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326315"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326316"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326317"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326318"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F326319"] = "This fault is caused by 'Total v6 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F3264"] = "This fault is raised when there are Node Identity or Secondary Subnet issues" + self.system_fault_code["F326400"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326401"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326402"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326403"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326404"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326405"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326406"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326407"] = "This fault is caused by 'Total v4 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326432"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326433"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326434"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326435"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326436"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326437"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326438"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326439"] = "This fault is caused by 'Total v4 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326440"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326441"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326442"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326443"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326444"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326445"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326446"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326447"] = "This fault is caused by 'Total v4 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326448"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326449"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326450"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326451"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326452"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326453"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326454"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326455"] = "This fault is caused by 'Total v4 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326480"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326481"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326482"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326483"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326484"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326485"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326486"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326487"] = "This fault is caused by 'Total v4 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F3265"] = "This fault is raised when the Policy Manager is not able to assign routable IP address to a node" + self.system_fault_code["F326568"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326569"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326570"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326571"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326572"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326573"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326574"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326575"] = "This fault is caused by 'Total v6 Endpoints capacity current value' statistical property crossing threshold level." + self.system_fault_code["F326600"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326601"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326602"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326603"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326604"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326605"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326606"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326607"] = "This fault is caused by 'Total v6 Endpoints capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F326608"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326609"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326610"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326611"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326612"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326613"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326614"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326615"] = "This fault is caused by 'Total v6 Endpoints capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F326616"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326617"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326618"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326619"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326620"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326621"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326622"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326623"] = "This fault is caused by 'Total v6 Endpoints capacity average value' statistical property crossing threshold level." + self.system_fault_code["F326648"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326649"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326650"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326651"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326652"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326653"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326654"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326655"] = "This fault is caused by 'Total v6 Endpoints capacity trend' statistical property crossing threshold level." + self.system_fault_code["F326736"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326737"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326738"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326739"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326740"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326741"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326742"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326743"] = "This fault is caused by 'Total v4 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326744"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326745"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326746"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326747"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326748"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326749"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326750"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326751"] = "This fault is caused by 'Total v4 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326752"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326753"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326754"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326755"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326756"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326757"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326758"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326759"] = "This fault is caused by 'Total v4 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326760"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326761"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326762"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326763"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326764"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326765"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326766"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326767"] = "This fault is caused by 'Total v4 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326800"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326801"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326802"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326803"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326804"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326805"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326806"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326807"] = "This fault is caused by 'Total v4 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326856"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326857"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326858"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326859"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326860"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326861"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326862"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326863"] = "This fault is caused by 'Total v6 L3 entries usage percentage current value' statistical property crossing threshold level." + self.system_fault_code["F326864"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326865"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326866"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326867"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326868"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326869"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326870"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326871"] = "This fault is caused by 'Total v6 L3 entries usage percentage minimum value' statistical property crossing threshold level." + self.system_fault_code["F326872"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326873"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326874"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326875"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326876"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326877"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326878"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326879"] = "This fault is caused by 'Total v6 L3 entries usage percentage maximum value' statistical property crossing threshold level." + self.system_fault_code["F326880"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326881"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326882"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326883"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326884"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326885"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326886"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326887"] = "This fault is caused by 'Total v6 L3 entries usage percentage average value' statistical property crossing threshold level." + self.system_fault_code["F326920"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326921"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326922"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326923"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326924"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326925"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326926"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F326927"] = "This fault is caused by 'Total v6 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F3272"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3273"] = "This fault is caused by a hardware programming failure" + self.system_fault_code["F3274"] = "This event occurs when there is a mismatch for the fabric-encap allocated for the EPG between vpc peers. It is a result" + self.system_fault_code["F3276"] = "This fault is raised when there is an issue with respect to the OpFlex device of type ave-ng" + self.system_fault_code["F3278"] = "This fault is raised when both the opflex channels have not received HBs for the specified AVE Timeout duration." + self.system_fault_code["F3279"] = "This fault occurs on the event of FCF-Mac-Pool exhaustion during VFC interface creation" + self.system_fault_code["F3280"] = "The object refers to an object that was not found." + self.system_fault_code["F3281"] = "The object refers to an object that was not found." + self.system_fault_code["F3282"] = "The object refers to an object that was not found." + self.system_fault_code["F3283"] = "This fault occurs when there is no space available in the TCAM on at least one of the modules. Note: If hw has more than" + self.system_fault_code["F3284"] = "This fault occurs when Remote Leaf ACL entry installation failed due to unsupported hardware." + self.system_fault_code["F3285"] = "This fault occurs when Remote Leaf ACL entry config is invalid." + self.system_fault_code["F3286"] = "This fault occurs when traffic map configuration failed" + self.system_fault_code["F3287"] = "The object refers to an object that was not found." + self.system_fault_code["F3288"] = "The object refers to an object that was not found." + self.system_fault_code["F3290"] = "This fault is raised when issues are detected with EnhancedLag policies learned from vCenter. E.g. missing Enhanced Lacp" + self.system_fault_code["F3291"] = "This fault occurs when qos manager fails to activate a dot1p rule due to hardware programming failure" + self.system_fault_code["F3292"] = "This fault occurs when qos manager fails to activate a dscp rule due to hardware programming failure" + self.system_fault_code["F3293"] = "Plugin has failed to stop." + self.system_fault_code["F3295"] = "This fault occurs when PBR service dest group goes to failed state due to both l1/l2 device being active" + self.system_fault_code["F3296"] = "This fault occurs when span filter entry creation fails due to lack of hw resources" + self.system_fault_code["F3299"] = "This fault occurs when the mld snooping local learning is disabled" + self.system_fault_code["F3300"] = "This fault occurs when the mld snooping fabric learning is disabled" + self.system_fault_code["F3301"] = "This fault occurs when the switch querier is the same as the BD SVI querier" + self.system_fault_code["F3302"] = "The object refers to an object that was not found." + self.system_fault_code["F3303"] = "This fault is raised when there are Dhcp Server issues" + self.system_fault_code["F3306"] = "This fault occurs when port has been suspended by LACP." + self.system_fault_code["F3307"] = "This fault occurs when an FC port is down" + self.system_fault_code["F3308"] = "This fault occurs because PIM IPV6 is enabled on a VRF which is deployed on a a leaf which does not support multicast configuratio" + self.system_fault_code["F3309"] = "The object refers to an object that was not found." + self.system_fault_code["F3311"] = "The object refers to an object that was not found." + self.system_fault_code["F3318"] = "This fault occurs when span sessio to fltgrp relation is created on oldgen tor" + self.system_fault_code["F3319"] = "This fault occurs when span Source to Filter group relation is created on oldgen tor" + self.system_fault_code["F3326"] = "The object refers to an object that was not found." + self.system_fault_code["F3327"] = "The object refers to an object that was not found." + self.system_fault_code["F3328"] = "The object refers to an object that was not found." + self.system_fault_code["F3329"] = "The object refers to an object that was not found." + self.system_fault_code["F3330"] = "The object refers to an object that was not found." + self.system_fault_code["F3332"] = "The object refers to an object that was not found." + self.system_fault_code["F3335"] = "Required platform not available." + self.system_fault_code["F3336"] = "This fault occurs when user tries to configure storm control action or soak instance count on unsupported hardware" + self.system_fault_code["F3337"] = "This fault occurs when a node has an anomaly" + self.system_fault_code["F3341"] = "This fault occurs when a recoverable error happens on a PoE configured port" + self.system_fault_code["F3342"] = "This fault occurs when a unrecoverable error happens on a PoE configured port" + self.system_fault_code["F3361"] = "This is a fault state which occurs when a physical interface is not reachable or has not been correctly configured." + self.system_fault_code["F3362"] = "This is a transient fault state which occurs when a tunnel interface is not reachable." + self.system_fault_code["F3363"] = "This fault occurs when an erroneous configuration is pushed for creating a Loopback." + self.system_fault_code["F3364"] = "This fault occurs when an erroneous configuration is pushed for creating a NVE." + self.system_fault_code["F3365"] = "This fault occurs when an erroneous configuration is pushed for creating a Bgp session." + self.system_fault_code["F3366"] = "This fault occurs when an erroneous configuration is pushed for creating a Loopback OSPF session ." + self.system_fault_code["F3367"] = "This fault occurs when an erroneous configuration is pushed for creating a Tunnel OSPF session." + self.system_fault_code["F3369"] = "The object refers to an object that was not found." + self.system_fault_code["F3370"] = "The object refers to an object that was not found." + self.system_fault_code["F3371"] = "The object refers to an object that was not found." + self.system_fault_code["F3372"] = "The object refers to an object that was not found." + self.system_fault_code["F3373"] = "The object refers to an object that was not found." + self.system_fault_code["F3374"] = "The object refers to an object that was not found." + self.system_fault_code["F3375"] = "The object refers to an object that was not found." + self.system_fault_code["F3377"] = "The object refers to an object that was not found." + self.system_fault_code["F3378"] = "The object refers to an object that was not found." + self.system_fault_code["F3380"] = "The object refers to an object that was not found." + self.system_fault_code["F3381"] = "The object refers to an object that was not found." + self.system_fault_code["F3382"] = "The object refers to an object that was not found." + self.system_fault_code["F3383"] = "The object refers to an object that was not found." + self.system_fault_code["F3384"] = "The object refers to an object that was not found." + self.system_fault_code["F3385"] = "The object refers to an object that was not found." + self.system_fault_code["F3387"] = "The object refers to an object that was not found." + self.system_fault_code["F3389"] = "The object refers to an object that was not found." + self.system_fault_code["F3390"] = "The object refers to an object that was not found." + self.system_fault_code["F3391"] = "The object refers to an object that was not found." + self.system_fault_code["F3392"] = "The object refers to an object that was not found." + self.system_fault_code["F3393"] = "The object refers to an object that was not found." + self.system_fault_code["F3394"] = "The object refers to an object that was not found." + self.system_fault_code["F3395"] = "The object refers to an object that was not found." + self.system_fault_code["F3396"] = "The object refers to an object that was not found." + self.system_fault_code["F3397"] = "The object refers to an object that was not found." + self.system_fault_code["F3398"] = "The object refers to an object that was not found." + self.system_fault_code["F3399"] = "The object refers to an object that was not found." + self.system_fault_code["F3400"] = "The object refers to an object that was not found." + self.system_fault_code["F3401"] = "The object refers to an object that was not found." + self.system_fault_code["F3402"] = "The object refers to an object that was not found." + self.system_fault_code["F3403"] = "The object refers to an object that was not found." + self.system_fault_code["F3404"] = "The object refers to an object that was not found." + self.system_fault_code["F3405"] = "The object refers to an object that was not found." + self.system_fault_code["F3406"] = "The object refers to an object that was not found." + self.system_fault_code["F3407"] = "The object refers to an object that was not found." + self.system_fault_code["F3408"] = "The object refers to an object that was not found." + self.system_fault_code["F3409"] = "The object refers to an object that was not found." + self.system_fault_code["F3410"] = "The object refers to an object that was not found." + self.system_fault_code["F3411"] = "The object refers to an object that was not found." + self.system_fault_code["F3412"] = "The object refers to an object that was not found." + self.system_fault_code["F3425"] = "This fault occurs when the tunnel source IP does not exist on the local switch or if the interface associated with the" + self.system_fault_code["F3426"] = "This fault is raised when the DHCP server running on vtor state changes from normal" + self.system_fault_code["F3428"] = "This fault occurs when NLB VIP configuration is deployed on an unsupported platform TOR." + self.system_fault_code["F3429"] = "This fault occurs when NLB VIP configuration is deployed on an unsupported platform TOR." + self.system_fault_code["F3430"] = "This fault occurs when there is a NLB BD configuration error: - NLB BD is in proxy mode" + self.system_fault_code["F3431"] = "This fault occurs when there is a NLB BD configuration error: - NLB BD is in proxy mode" + self.system_fault_code["F3432"] = "This fault occurs when there is a NLB BD configuration error: - PIM is enabled on NLB BD" + self.system_fault_code["F3433"] = "This fault occurs when there is a NLB BD configuration error: - PIM is enabled on NLB BD" + self.system_fault_code["F3434"] = "This fault occurs when max NLB VIP limit(128) is reached" + self.system_fault_code["F3435"] = "This fault occurs when max NLB VIP limit(128) is reached." + self.system_fault_code["F3436"] = "This fault occurs when NLB IGMP group is in use by some other NLB VIP." + self.system_fault_code["F3437"] = "This fault occurs when NLB IGMP group is in use by some other NLB VIP." + self.system_fault_code["F3438"] = "This fault occurs when an erroneous configuration is pushed for creating a CtxProfile." + self.system_fault_code["F3439"] = "This fault occurs when an erroneous configuration is pushed for creating a Cidr." + self.system_fault_code["F3440"] = "This fault occurs when an erroneous configuration is pushed for creating a Subnet." + self.system_fault_code["F3441"] = "This fault occurs when an erroneous configuration is pushed for creating a RouteTable." + self.system_fault_code["F3442"] = "This fault occurs when an erroneous configuration is pushed for creating a CloudRouter." + self.system_fault_code["F3443"] = "This fault occurs when an erroneous configuration is pushed for creating a CloudRouter interface." + self.system_fault_code["F3455"] = "The object refers to an object that was not found." + self.system_fault_code["F3456"] = "The object refers to an object that was not found." + self.system_fault_code["F3460"] = "The object refers to an object that was not found." + self.system_fault_code["F3461"] = "The object refers to an object that was not found." + self.system_fault_code["F3462"] = "The object refers to an object that was not found." + self.system_fault_code["F3464"] = "The object refers to an object that was not found." + self.system_fault_code["F3465"] = "The object refers to an object that was not found." + self.system_fault_code["F3466"] = "The object refers to an object that was not found." + self.system_fault_code["F3468"] = "This fault occurs when gtp is created on oldgen tor or any spine" + self.system_fault_code["F3471"] = "User is trying to downgrade the app to an unsupported version i.e Pre 4.0 release." + self.system_fault_code["F3474"] = "The object refers to an object that was not found." + self.system_fault_code["F3479"] = "This fault occurs when NLB VIP used is same as SVI IP." + self.system_fault_code["F3480"] = "This fault occurs when NLB VIP used is same as SVI IP." + self.system_fault_code["F3481"] = "This fault occurs when NLB VIP used is same as ep reachability VIP." + self.system_fault_code["F3482"] = "This fault occurs when NLB VIP used is same as ep reachability VIP." + self.system_fault_code["F3483"] = "This fault occurs when NLB VIP used is same as anycast VIP." + self.system_fault_code["F3484"] = "This fault occurs when NLB VIP used is same as anycast VIP." + self.system_fault_code["F3485"] = "This fault occurs when NLB MAC used is same as anycast MAC." + self.system_fault_code["F3486"] = "This fault occurs when NLB MAC used is same as anycast MAC." + self.system_fault_code["F3487"] = "The object refers to an object that was not found." + self.system_fault_code["F3488"] = "This fault occurs when router id is not used as loopback and explict loopback interface is not configured for a node and" + self.system_fault_code["F3489"] = "The object refers to an object that was not found." + self.system_fault_code["F3501"] = "The object refers to an object that was not found." + self.system_fault_code["F3503"] = "The object refers to an object that was not found." + self.system_fault_code["F3505"] = "This fault occurs when an erroneous configuration is pushed for creating a Native Load balancer." + self.system_fault_code["F3506"] = "This fault occurs when an erroneous configuration is pushed for creating a Native service Listener." + self.system_fault_code["F3507"] = "This fault occurs when an erroneous configuration is pushed for creating a Native service Listener Rule." + self.system_fault_code["F3508"] = "This fault occurs when an erroneous configuration is pushed for creating a Native service Target Group." + self.system_fault_code["F3509"] = "This fault occurs when an erroneous configuration is pushed for creating a Certificate." + self.system_fault_code["F3516"] = "This fault occurs when maximum number of IPs per MAC exceeds the threshold" + self.system_fault_code["F3519"] = "The object refers to an object that was not found." + self.system_fault_code["F3524"] = "The object refers to an object that was not found." + self.system_fault_code["F3525"] = "This warning occurs when high SSD usage is observed" + self.system_fault_code["F3526"] = "This fault occurs when cloud provider for a tenant information is not correct. For example, provider crendentials can be" + self.system_fault_code["F3527"] = "This fault occurs when the License State of a CSR is not REGISTERED." + self.system_fault_code["F3528"] = "This fault occurs when an error configuring a VPN connection." + self.system_fault_code["F3529"] = "This fault occurs when an erroneous configuration is pushed for creating a CtxPeering." + self.system_fault_code["F3530"] = "The object refers to an object that was not found." + self.system_fault_code["F3531"] = "The object refers to an object that was not found." + self.system_fault_code["F3532"] = "This fault occurs when there is a problem configuring the BDI." + self.system_fault_code["F3533"] = "This fault occurs when an erroneous configuration is pushed for creating a CloudEPg." + self.system_fault_code["F3534"] = "This fault occurs when an erroneous configuration is pushed for creating a contract." + self.system_fault_code["F3535"] = "This fault occurs when an erroneous configuration is pushed for creating a contract." + self.system_fault_code["F3536"] = "This fault occurs when an erroneous configuration is pushed for creating a contract." + self.system_fault_code["F3537"] = "This fault occurs when an erroneous configuration is pushed for creating a contract." + self.system_fault_code["F3538"] = "This fault occurs when Configuration Task encounters an error while programming cloud provider." + self.system_fault_code["F3539"] = "This fault occurs when Inventory Task encounters an error while querying cloud provider." + self.system_fault_code["F3540"] = "This fault occurs when Garbage Collector encounters an error while deleting stale resources from cloud provider." + self.system_fault_code["F3544"] = "This fault occurs when the policy manager on the affected object fails to activate a prefix entry due to either a hardware" + self.system_fault_code["F3545"] = "This fault occurs when the policy manager fails to activate a contract filter rule on the affected object due to either" + self.system_fault_code["F3546"] = "This fault is raised when a DNS Profile (dns:Profile) fails to apply due to configuration issues." + self.system_fault_code["F3549"] = "This fault occurs where there are errors encountered while performing cloudwatch events related programming on AWS" + self.system_fault_code["F3550"] = "This fault occurs where there are errors encountered while performing SQS related programming on AWS" + self.system_fault_code["F3551"] = "This fault occurs where there are errors encountered while performing S3 related programming on AWS" + self.system_fault_code["F3552"] = "This fault occurs where there are errors encountered while performing cloudtrail related programming on AWS" + self.system_fault_code["F3553"] = "This fault is raised for any event channel generic error" + self.system_fault_code["F3556"] = "The object refers to an object that was not found." + self.system_fault_code["F362792"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362793"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362794"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362795"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362796"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362797"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362798"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362799"] = "This fault is caused by 'input class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F362808"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362809"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362810"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362811"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362812"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362813"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362814"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362815"] = "This fault is caused by 'input class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F362816"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362817"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362818"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362819"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362820"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362821"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362822"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362823"] = "This fault is caused by 'input class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F362824"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362825"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362826"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362827"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362828"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362829"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362830"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362831"] = "This fault is caused by 'input class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F362832"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362833"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362834"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362835"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362836"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362837"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362838"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362839"] = "This fault is caused by 'input class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F362840"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362841"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362842"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362843"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362844"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362845"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362846"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362847"] = "This fault is caused by 'input class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F362872"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362873"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362874"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362875"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362876"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362877"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362878"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362879"] = "This fault is caused by 'input class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F362880"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362881"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362882"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362883"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362884"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362885"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362886"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362887"] = "This fault is caused by 'input class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F362960"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362961"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362962"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362963"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362964"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362965"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362966"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362967"] = "This fault is caused by 'input class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F362968"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362969"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362970"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362971"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362972"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362973"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362974"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362975"] = "This fault is caused by 'input class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F362976"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362977"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362978"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362979"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362980"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362981"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362982"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362983"] = "This fault is caused by 'input class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F362984"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362985"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362986"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362987"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362988"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362989"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362990"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F362991"] = "This fault is caused by 'input class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363024"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363025"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363026"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363027"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363028"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363029"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363030"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363031"] = "This fault is caused by 'input class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363080"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363081"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363082"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363083"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363084"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363085"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363086"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363087"] = "This fault is caused by 'input class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363096"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363097"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363098"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363099"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363100"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363101"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363102"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363103"] = "This fault is caused by 'input class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363104"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363105"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363106"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363107"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363108"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363109"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363110"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363111"] = "This fault is caused by 'input class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363112"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363113"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363114"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363115"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363116"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363117"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363118"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363119"] = "This fault is caused by 'input class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363120"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363121"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363122"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363123"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363124"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363125"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363126"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363127"] = "This fault is caused by 'input class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363128"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363129"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363130"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363131"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363132"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363133"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363134"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363135"] = "This fault is caused by 'input class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363160"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363161"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363162"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363163"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363164"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363165"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363166"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363167"] = "This fault is caused by 'input class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363168"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363169"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363170"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363171"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363172"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363173"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363174"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363175"] = "This fault is caused by 'input class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363248"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363249"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363250"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363251"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363252"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363253"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363254"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363255"] = "This fault is caused by 'input class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F363256"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363257"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363258"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363259"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363260"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363261"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363262"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363263"] = "This fault is caused by 'input class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F363264"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363265"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363266"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363267"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363268"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363269"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363270"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363271"] = "This fault is caused by 'input class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F363272"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363273"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363274"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363275"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363276"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363277"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363278"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363279"] = "This fault is caused by 'input class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F363312"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363313"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363314"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363315"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363316"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363317"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363318"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363319"] = "This fault is caused by 'input class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F363368"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363369"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363370"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363371"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363372"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363373"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363374"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363375"] = "This fault is caused by 'input classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F363384"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363385"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363386"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363387"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363388"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363389"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363390"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363391"] = "This fault is caused by 'input classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F363392"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363393"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363394"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363395"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363396"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363397"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363398"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363399"] = "This fault is caused by 'input classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F363400"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363401"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363402"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363403"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363404"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363405"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363406"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363407"] = "This fault is caused by 'input classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F363408"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363409"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363410"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363411"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363412"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363413"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363414"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363415"] = "This fault is caused by 'input classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F363416"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363417"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363418"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363419"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363420"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363421"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363422"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363423"] = "This fault is caused by 'input classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F363448"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363449"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363450"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363451"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363452"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363453"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363454"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363455"] = "This fault is caused by 'input classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F363456"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363457"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363458"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363459"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363460"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363461"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363462"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363463"] = "This fault is caused by 'input classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F363536"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363537"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363538"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363539"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363540"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363541"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363542"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363543"] = "This fault is caused by 'input crc frames current value' statistical property crossing threshold level." + self.system_fault_code["F363552"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363553"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363554"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363555"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363556"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363557"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363558"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363559"] = "This fault is caused by 'input crc frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363560"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363561"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363562"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363563"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363564"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363565"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363566"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363567"] = "This fault is caused by 'input crc frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363568"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363569"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363570"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363571"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363572"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363573"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363574"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363575"] = "This fault is caused by 'input crc frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363576"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363577"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363578"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363579"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363580"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363581"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363582"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363583"] = "This fault is caused by 'input crc frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363584"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363585"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363586"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363587"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363588"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363589"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363590"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363591"] = "This fault is caused by 'input crc frames average value' statistical property crossing threshold level." + self.system_fault_code["F363616"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363617"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363618"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363619"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363620"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363621"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363622"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363623"] = "This fault is caused by 'input crc frames trend' statistical property crossing threshold level." + self.system_fault_code["F363624"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363625"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363626"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363627"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363628"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363629"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363630"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363631"] = "This fault is caused by 'input crc frames rate' statistical property crossing threshold level." + self.system_fault_code["F363704"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363705"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363706"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363707"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363708"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363709"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363710"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363711"] = "This fault is caused by 'input discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F363720"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363721"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363722"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363723"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363724"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363725"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363726"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363727"] = "This fault is caused by 'input discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363728"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363729"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363730"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363731"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363732"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363733"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363734"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363735"] = "This fault is caused by 'input discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363736"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363737"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363738"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363739"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363740"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363741"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363742"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363743"] = "This fault is caused by 'input discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363744"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363745"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363746"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363747"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363748"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363749"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363750"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363751"] = "This fault is caused by 'input discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363752"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363753"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363754"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363755"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363756"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363757"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363758"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363759"] = "This fault is caused by 'input discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F363784"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363785"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363786"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363787"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363788"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363789"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363790"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363791"] = "This fault is caused by 'input discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F363792"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363793"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363794"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363795"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363796"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363797"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363798"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363799"] = "This fault is caused by 'input discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F363872"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363873"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363874"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363875"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363876"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363877"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363878"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363879"] = "This fault is caused by 'input errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F363888"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363889"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363890"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363891"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363892"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363893"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363894"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363895"] = "This fault is caused by 'input errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F363896"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363897"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363898"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363899"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363900"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363901"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363902"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363903"] = "This fault is caused by 'input errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F363904"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363905"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363906"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363907"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363908"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363909"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363910"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363911"] = "This fault is caused by 'input errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F363912"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363913"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363914"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363915"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363916"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363917"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363918"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363919"] = "This fault is caused by 'input errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F363920"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363921"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363922"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363923"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363924"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363925"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363926"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363927"] = "This fault is caused by 'input errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F363952"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363953"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363954"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363955"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363956"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363957"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363958"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363959"] = "This fault is caused by 'input errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F363960"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363961"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363962"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363963"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363964"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363965"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363966"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F363967"] = "This fault is caused by 'input errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F364040"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364041"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364042"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364043"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364044"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364045"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364046"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364047"] = "This fault is caused by 'input class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364056"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364057"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364058"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364059"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364060"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364061"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364062"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364063"] = "This fault is caused by 'input class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364064"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364065"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364066"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364067"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364068"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364069"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364070"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364071"] = "This fault is caused by 'input class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364072"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364073"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364074"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364075"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364076"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364077"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364078"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364079"] = "This fault is caused by 'input class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364080"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364081"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364082"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364083"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364084"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364085"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364086"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364087"] = "This fault is caused by 'input class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364088"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364089"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364090"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364091"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364092"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364093"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364094"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364095"] = "This fault is caused by 'input class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364120"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364121"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364122"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364123"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364124"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364125"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364126"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364127"] = "This fault is caused by 'input class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364128"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364129"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364130"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364131"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364132"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364133"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364134"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364135"] = "This fault is caused by 'input class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364208"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364209"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364210"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364211"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364212"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364213"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364214"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364215"] = "This fault is caused by 'input class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F364224"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364225"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364226"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364227"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364228"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364229"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364230"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364231"] = "This fault is caused by 'input class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364232"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364233"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364234"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364235"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364236"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364237"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364238"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364239"] = "This fault is caused by 'input class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364240"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364241"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364242"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364243"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364244"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364245"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364246"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364247"] = "This fault is caused by 'input class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364248"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364249"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364250"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364251"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364252"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364253"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364254"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364255"] = "This fault is caused by 'input class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364256"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364257"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364258"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364259"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364260"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364261"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364262"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364263"] = "This fault is caused by 'input class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F364288"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364289"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364290"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364291"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364292"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364293"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364294"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364295"] = "This fault is caused by 'input class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F364296"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364297"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364298"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364299"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364300"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364301"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364302"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364303"] = "This fault is caused by 'input class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F364376"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364377"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364378"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364379"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364380"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364381"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364382"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364383"] = "This fault is caused by 'input classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F364392"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364393"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364394"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364395"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364396"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364397"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364398"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364399"] = "This fault is caused by 'input classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F364400"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364401"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364402"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364403"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364404"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364405"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364406"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364407"] = "This fault is caused by 'input classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F364408"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364409"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364410"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364411"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364412"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364413"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364414"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364415"] = "This fault is caused by 'input classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F364416"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364417"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364418"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364419"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364420"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364421"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364422"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364423"] = "This fault is caused by 'input classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F364424"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364425"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364426"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364427"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364428"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364429"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364430"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364431"] = "This fault is caused by 'input classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F364456"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364457"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364458"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364459"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364460"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364461"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364462"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364463"] = "This fault is caused by 'input classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F364464"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364465"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364466"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364467"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364468"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364469"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364470"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364471"] = "This fault is caused by 'input classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F364544"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364545"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364546"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364547"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364548"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364549"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364550"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364551"] = "This fault is caused by 'input loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F364560"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364561"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364562"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364563"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364564"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364565"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364566"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364567"] = "This fault is caused by 'input loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F364568"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364569"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364570"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364571"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364572"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364573"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364574"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364575"] = "This fault is caused by 'input loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F364576"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364577"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364578"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364579"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364580"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364581"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364582"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364583"] = "This fault is caused by 'input loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F364584"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364585"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364586"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364587"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364588"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364589"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364590"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364591"] = "This fault is caused by 'input loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F364592"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364593"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364594"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364595"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364596"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364597"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364598"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364599"] = "This fault is caused by 'input loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F364624"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364625"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364626"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364627"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364628"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364629"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364630"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364631"] = "This fault is caused by 'input loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F364632"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364633"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364634"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364635"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364636"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364637"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364638"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364639"] = "This fault is caused by 'input loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F364712"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364713"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364714"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364715"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364716"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364717"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364718"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364719"] = "This fault is caused by 'input link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F364728"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364729"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364730"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364731"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364732"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364733"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364734"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364735"] = "This fault is caused by 'input link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F364736"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364737"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364738"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364739"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364740"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364741"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364742"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364743"] = "This fault is caused by 'input link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F364744"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364745"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364746"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364747"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364748"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364749"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364750"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364751"] = "This fault is caused by 'input link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F364752"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364753"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364754"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364755"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364756"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364757"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364758"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364759"] = "This fault is caused by 'input link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F364760"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364761"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364762"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364763"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364764"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364765"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364766"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364767"] = "This fault is caused by 'input link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F364792"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364793"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364794"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364795"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364796"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364797"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364798"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364799"] = "This fault is caused by 'input link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F364800"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364801"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364802"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364803"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364804"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364805"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364806"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364807"] = "This fault is caused by 'input link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F364880"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364881"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364882"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364883"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364884"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364885"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364886"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364887"] = "This fault is caused by 'input not operational current value' statistical property crossing threshold level." + self.system_fault_code["F364896"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364897"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364898"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364899"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364900"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364901"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364902"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364903"] = "This fault is caused by 'input not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F364904"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364905"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364906"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364907"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364908"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364909"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364910"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364911"] = "This fault is caused by 'input not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F364912"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364913"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364914"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364915"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364916"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364917"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364918"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364919"] = "This fault is caused by 'input not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F364920"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364921"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364922"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364923"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364924"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364925"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364926"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364927"] = "This fault is caused by 'input not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F364928"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364929"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364930"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364931"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364932"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364933"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364934"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364935"] = "This fault is caused by 'input not operational average value' statistical property crossing threshold level." + self.system_fault_code["F364960"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364961"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364962"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364963"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364964"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364965"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364966"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364967"] = "This fault is caused by 'input not operational trend' statistical property crossing threshold level." + self.system_fault_code["F364968"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364969"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364970"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364971"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364972"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364973"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364974"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F364975"] = "This fault is caused by 'input not operational rate' statistical property crossing threshold level." + self.system_fault_code["F365048"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365049"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365050"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365051"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365052"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365053"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365054"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365055"] = "This fault is caused by 'input offline current value' statistical property crossing threshold level." + self.system_fault_code["F365064"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365065"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365066"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365067"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365068"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365069"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365070"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365071"] = "This fault is caused by 'input offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F365072"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365073"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365074"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365075"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365076"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365077"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365078"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365079"] = "This fault is caused by 'input offline periodic' statistical property crossing threshold level." + self.system_fault_code["F365080"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365081"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365082"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365083"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365084"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365085"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365086"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365087"] = "This fault is caused by 'input offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F365088"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365089"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365090"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365091"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365092"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365093"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365094"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365095"] = "This fault is caused by 'input offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F365096"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365097"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365098"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365099"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365100"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365101"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365102"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365103"] = "This fault is caused by 'input offline average value' statistical property crossing threshold level." + self.system_fault_code["F365128"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365129"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365130"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365131"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365132"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365133"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365134"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365135"] = "This fault is caused by 'input offline trend' statistical property crossing threshold level." + self.system_fault_code["F365136"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365137"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365138"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365139"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365140"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365141"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365142"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365143"] = "This fault is caused by 'input offline rate' statistical property crossing threshold level." + self.system_fault_code["F365216"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365217"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365218"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365219"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365220"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365221"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365222"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365223"] = "This fault is caused by 'total input bytes current value' statistical property crossing threshold level." + self.system_fault_code["F365232"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365233"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365234"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365235"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365236"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365237"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365238"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365239"] = "This fault is caused by 'total input bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F365240"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365241"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365242"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365243"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365244"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365245"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365246"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365247"] = "This fault is caused by 'total input bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F365248"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365249"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365250"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365251"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365252"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365253"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365254"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365255"] = "This fault is caused by 'total input bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F365256"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365257"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365258"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365259"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365260"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365261"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365262"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365263"] = "This fault is caused by 'total input bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F365264"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365265"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365266"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365267"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365268"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365269"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365270"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365271"] = "This fault is caused by 'total input bytes average value' statistical property crossing threshold level." + self.system_fault_code["F365296"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365297"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365298"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365299"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365300"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365301"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365302"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365303"] = "This fault is caused by 'total input bytes trend' statistical property crossing threshold level." + self.system_fault_code["F365304"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365305"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365306"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365307"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365308"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365309"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365310"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365311"] = "This fault is caused by 'total input bytes rate' statistical property crossing threshold level." + self.system_fault_code["F365384"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365385"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365386"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365387"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365388"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365389"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365390"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365391"] = "This fault is caused by 'total input bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F365392"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365393"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365394"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365395"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365396"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365397"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365398"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365399"] = "This fault is caused by 'total input bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F365400"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365401"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365402"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365403"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365404"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365405"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365406"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365407"] = "This fault is caused by 'total input bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F365408"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365409"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365410"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365411"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365412"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365413"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365414"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365415"] = "This fault is caused by 'total input bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F365448"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365449"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365450"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365451"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365452"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365453"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365454"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365455"] = "This fault is caused by 'total input bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F365504"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365505"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365506"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365507"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365508"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365509"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365510"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365511"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F365512"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365513"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365514"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365515"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365516"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365517"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365518"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365519"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F365520"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365521"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365522"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365523"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365524"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365525"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365526"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365527"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F365528"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365529"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365530"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365531"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365532"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365533"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365534"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365535"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F365568"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365569"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365570"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365571"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365572"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365573"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365574"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365575"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F365624"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365625"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365626"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365627"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365628"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365629"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365630"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365631"] = "This fault is caused by 'input too long frames current value' statistical property crossing threshold level." + self.system_fault_code["F365640"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365641"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365642"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365643"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365644"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365645"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365646"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365647"] = "This fault is caused by 'input too long frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365648"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365649"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365650"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365651"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365652"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365653"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365654"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365655"] = "This fault is caused by 'input too long frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365656"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365657"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365658"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365659"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365660"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365661"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365662"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365663"] = "This fault is caused by 'input too long frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365664"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365665"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365666"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365667"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365668"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365669"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365670"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365671"] = "This fault is caused by 'input too long frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365672"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365673"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365674"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365675"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365676"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365677"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365678"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365679"] = "This fault is caused by 'input too long frames average value' statistical property crossing threshold level." + self.system_fault_code["F365704"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365705"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365706"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365707"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365708"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365709"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365710"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365711"] = "This fault is caused by 'input too long frames trend' statistical property crossing threshold level." + self.system_fault_code["F365712"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365713"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365714"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365715"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365716"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365717"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365718"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365719"] = "This fault is caused by 'input too long frames rate' statistical property crossing threshold level." + self.system_fault_code["F365792"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365793"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365794"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365795"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365796"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365797"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365798"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365799"] = "This fault is caused by 'input too short frames current value' statistical property crossing threshold level." + self.system_fault_code["F365808"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365809"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365810"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365811"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365812"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365813"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365814"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365815"] = "This fault is caused by 'input too short frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365816"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365817"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365818"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365819"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365820"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365821"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365822"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365823"] = "This fault is caused by 'input too short frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365824"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365825"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365826"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365827"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365828"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365829"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365830"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365831"] = "This fault is caused by 'input too short frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365832"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365833"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365834"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365835"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365836"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365837"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365838"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365839"] = "This fault is caused by 'input too short frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F365840"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365841"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365842"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365843"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365844"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365845"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365846"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365847"] = "This fault is caused by 'input too short frames average value' statistical property crossing threshold level." + self.system_fault_code["F365872"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365873"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365874"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365875"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365876"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365877"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365878"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365879"] = "This fault is caused by 'input too short frames trend' statistical property crossing threshold level." + self.system_fault_code["F365880"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365881"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365882"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365883"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365884"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365885"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365886"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365887"] = "This fault is caused by 'input too short frames rate' statistical property crossing threshold level." + self.system_fault_code["F365960"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365961"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365962"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365963"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365964"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365965"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365966"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365967"] = "This fault is caused by 'input unknown frames current value' statistical property crossing threshold level." + self.system_fault_code["F365976"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365977"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365978"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365979"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365980"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365981"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365982"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365983"] = "This fault is caused by 'input unknown frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F365984"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365985"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365986"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365987"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365988"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365989"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365990"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365991"] = "This fault is caused by 'input unknown frames periodic' statistical property crossing threshold level." + self.system_fault_code["F365992"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365993"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365994"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365995"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365996"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365997"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365998"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F365999"] = "This fault is caused by 'input unknown frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F366000"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366001"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366002"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366003"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366004"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366005"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366006"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366007"] = "This fault is caused by 'input unknown frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F366008"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366009"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366010"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366011"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366012"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366013"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366014"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366015"] = "This fault is caused by 'input unknown frames average value' statistical property crossing threshold level." + self.system_fault_code["F366040"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366041"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366042"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366043"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366044"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366045"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366046"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366047"] = "This fault is caused by 'input unknown frames trend' statistical property crossing threshold level." + self.system_fault_code["F366048"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366049"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366050"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366051"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366052"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366053"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366054"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366055"] = "This fault is caused by 'input unknown frames rate' statistical property crossing threshold level." + self.system_fault_code["F366128"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366129"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366130"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366131"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366132"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366133"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366134"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366135"] = "This fault is caused by 'link failures current value' statistical property crossing threshold level." + self.system_fault_code["F366144"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366145"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366146"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366147"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366148"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366149"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366150"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366151"] = "This fault is caused by 'link failures cumulative' statistical property crossing threshold level." + self.system_fault_code["F366152"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366153"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366154"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366155"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366156"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366157"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366158"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366159"] = "This fault is caused by 'link failures periodic' statistical property crossing threshold level." + self.system_fault_code["F366160"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366161"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366162"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366163"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366164"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366165"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366166"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366167"] = "This fault is caused by 'link failures minimum value' statistical property crossing threshold level." + self.system_fault_code["F366168"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366169"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366170"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366171"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366172"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366173"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366174"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366175"] = "This fault is caused by 'link failures maximum value' statistical property crossing threshold level." + self.system_fault_code["F366176"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366177"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366178"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366179"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366180"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366181"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366182"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366183"] = "This fault is caused by 'link failures average value' statistical property crossing threshold level." + self.system_fault_code["F366208"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366209"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366210"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366211"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366212"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366213"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366214"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366215"] = "This fault is caused by 'link failures trend' statistical property crossing threshold level." + self.system_fault_code["F366216"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366217"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366218"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366219"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366220"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366221"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366222"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366223"] = "This fault is caused by 'link failures rate' statistical property crossing threshold level." + self.system_fault_code["F366296"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366297"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366298"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366299"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366300"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366301"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366302"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366303"] = "This fault is caused by 'signal losses current value' statistical property crossing threshold level." + self.system_fault_code["F366312"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366313"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366314"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366315"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366316"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366317"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366318"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366319"] = "This fault is caused by 'signal losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366320"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366321"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366322"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366323"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366324"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366325"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366326"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366327"] = "This fault is caused by 'signal losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366328"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366329"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366330"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366331"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366332"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366333"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366334"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366335"] = "This fault is caused by 'signal losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366336"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366337"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366338"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366339"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366340"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366341"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366342"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366343"] = "This fault is caused by 'signal losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366344"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366345"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366346"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366347"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366348"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366349"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366350"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366351"] = "This fault is caused by 'signal losses average value' statistical property crossing threshold level." + self.system_fault_code["F366376"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366377"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366378"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366379"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366380"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366381"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366382"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366383"] = "This fault is caused by 'signal losses trend' statistical property crossing threshold level." + self.system_fault_code["F366384"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366385"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366386"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366387"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366388"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366389"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366390"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366391"] = "This fault is caused by 'signal losses rate' statistical property crossing threshold level." + self.system_fault_code["F366464"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366465"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366466"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366467"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366468"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366469"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366470"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366471"] = "This fault is caused by 'sync losses current value' statistical property crossing threshold level." + self.system_fault_code["F366480"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366481"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366482"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366483"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366484"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366485"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366486"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366487"] = "This fault is caused by 'sync losses cumulative' statistical property crossing threshold level." + self.system_fault_code["F366488"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366489"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366490"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366491"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366492"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366493"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366494"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366495"] = "This fault is caused by 'sync losses periodic' statistical property crossing threshold level." + self.system_fault_code["F366496"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366497"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366498"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366499"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366500"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366501"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366502"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366503"] = "This fault is caused by 'sync losses minimum value' statistical property crossing threshold level." + self.system_fault_code["F366504"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366505"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366506"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366507"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366508"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366509"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366510"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366511"] = "This fault is caused by 'sync losses maximum value' statistical property crossing threshold level." + self.system_fault_code["F366512"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366513"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366514"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366515"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366516"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366517"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366518"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366519"] = "This fault is caused by 'sync losses average value' statistical property crossing threshold level." + self.system_fault_code["F366544"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366545"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366546"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366547"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366548"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366549"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366550"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366551"] = "This fault is caused by 'sync losses trend' statistical property crossing threshold level." + self.system_fault_code["F366552"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366553"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366554"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366555"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366556"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366557"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366558"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366559"] = "This fault is caused by 'sync losses rate' statistical property crossing threshold level." + self.system_fault_code["F366632"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366633"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366634"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366635"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366636"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366637"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366638"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366639"] = "This fault is caused by 'output class2 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366648"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366649"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366650"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366651"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366652"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366653"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366654"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366655"] = "This fault is caused by 'output class2 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366656"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366657"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366658"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366659"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366660"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366661"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366662"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366663"] = "This fault is caused by 'output class2 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366664"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366665"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366666"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366667"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366668"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366669"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366670"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366671"] = "This fault is caused by 'output class2 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366672"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366673"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366674"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366675"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366676"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366677"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366678"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366679"] = "This fault is caused by 'output class2 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366680"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366681"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366682"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366683"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366684"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366685"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366686"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366687"] = "This fault is caused by 'output class2 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366712"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366713"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366714"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366715"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366716"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366717"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366718"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366719"] = "This fault is caused by 'output class2 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F366720"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366721"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366722"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366723"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366724"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366725"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366726"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366727"] = "This fault is caused by 'output class2 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F366800"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366801"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366802"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366803"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366804"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366805"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366806"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366807"] = "This fault is caused by 'output class2 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F366808"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366809"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366810"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366811"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366812"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366813"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366814"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366815"] = "This fault is caused by 'output class2 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F366816"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366817"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366818"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366819"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366820"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366821"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366822"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366823"] = "This fault is caused by 'output class2 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F366824"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366825"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366826"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366827"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366828"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366829"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366830"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366831"] = "This fault is caused by 'output class2 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F366864"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366865"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366866"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366867"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366868"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366869"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366870"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366871"] = "This fault is caused by 'output class2 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F366920"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366921"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366922"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366923"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366924"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366925"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366926"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366927"] = "This fault is caused by 'output class3 bytes current value' statistical property crossing threshold level." + self.system_fault_code["F366936"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366937"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366938"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366939"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366940"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366941"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366942"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366943"] = "This fault is caused by 'output class3 bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F366944"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366945"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366946"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366947"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366948"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366949"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366950"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366951"] = "This fault is caused by 'output class3 bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F366952"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366953"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366954"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366955"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366956"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366957"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366958"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366959"] = "This fault is caused by 'output class3 bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F366960"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366961"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366962"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366963"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366964"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366965"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366966"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366967"] = "This fault is caused by 'output class3 bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F366968"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366969"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366970"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366971"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366972"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366973"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366974"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F366975"] = "This fault is caused by 'output class3 bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367000"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367001"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367002"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367003"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367004"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367005"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367006"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367007"] = "This fault is caused by 'output class3 bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367008"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367009"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367010"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367011"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367012"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367013"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367014"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367015"] = "This fault is caused by 'output class3 bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367088"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367089"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367090"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367091"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367092"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367093"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367094"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367095"] = "This fault is caused by 'output class3 bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F367096"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367097"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367098"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367099"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367100"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367101"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367102"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367103"] = "This fault is caused by 'output class3 bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F367104"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367105"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367106"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367107"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367108"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367109"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367110"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367111"] = "This fault is caused by 'output class3 bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F367112"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367113"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367114"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367115"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367116"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367117"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367118"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367119"] = "This fault is caused by 'output class3 bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F367152"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367153"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367154"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367155"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367156"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367157"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367158"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367159"] = "This fault is caused by 'output class3 bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F367208"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367209"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367210"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367211"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367212"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367213"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367214"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367215"] = "This fault is caused by 'output classf bytes current value' statistical property crossing threshold level." + self.system_fault_code["F367224"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367225"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367226"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367227"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367228"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367229"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367230"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367231"] = "This fault is caused by 'output classf bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F367232"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367233"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367234"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367235"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367236"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367237"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367238"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367239"] = "This fault is caused by 'output classf bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F367240"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367241"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367242"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367243"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367244"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367245"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367246"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367247"] = "This fault is caused by 'output classf bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F367248"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367249"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367250"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367251"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367252"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367253"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367254"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367255"] = "This fault is caused by 'output classf bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F367256"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367257"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367258"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367259"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367260"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367261"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367262"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367263"] = "This fault is caused by 'output classf bytes average value' statistical property crossing threshold level." + self.system_fault_code["F367288"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367289"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367290"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367291"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367292"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367293"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367294"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367295"] = "This fault is caused by 'output classf bytes trend' statistical property crossing threshold level." + self.system_fault_code["F367296"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367297"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367298"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367299"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367300"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367301"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367302"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367303"] = "This fault is caused by 'output classf bytes rate' statistical property crossing threshold level." + self.system_fault_code["F367376"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367377"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367378"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367379"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367380"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367381"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367382"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367383"] = "This fault is caused by 'output discards frames current value' statistical property crossing threshold level." + self.system_fault_code["F367392"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367393"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367394"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367395"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367396"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367397"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367398"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367399"] = "This fault is caused by 'output discards frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367400"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367401"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367402"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367403"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367404"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367405"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367406"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367407"] = "This fault is caused by 'output discards frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367408"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367409"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367410"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367411"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367412"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367413"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367414"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367415"] = "This fault is caused by 'output discards frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367416"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367417"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367418"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367419"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367420"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367421"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367422"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367423"] = "This fault is caused by 'output discards frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367424"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367425"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367426"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367427"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367428"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367429"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367430"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367431"] = "This fault is caused by 'output discards frames average value' statistical property crossing threshold level." + self.system_fault_code["F367456"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367457"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367458"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367459"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367460"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367461"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367462"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367463"] = "This fault is caused by 'output discards frames trend' statistical property crossing threshold level." + self.system_fault_code["F367464"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367465"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367466"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367467"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367468"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367469"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367470"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367471"] = "This fault is caused by 'output discards frames rate' statistical property crossing threshold level." + self.system_fault_code["F367544"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367545"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367546"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367547"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367548"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367549"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367550"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367551"] = "This fault is caused by 'output errors frames current value' statistical property crossing threshold level." + self.system_fault_code["F367560"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367561"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367562"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367563"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367564"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367565"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367566"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367567"] = "This fault is caused by 'output errors frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367568"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367569"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367570"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367571"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367572"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367573"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367574"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367575"] = "This fault is caused by 'output errors frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367576"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367577"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367578"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367579"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367580"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367581"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367582"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367583"] = "This fault is caused by 'output errors frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367584"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367585"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367586"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367587"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367588"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367589"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367590"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367591"] = "This fault is caused by 'output errors frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367592"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367593"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367594"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367595"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367596"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367597"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367598"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367599"] = "This fault is caused by 'output errors frames average value' statistical property crossing threshold level." + self.system_fault_code["F367624"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367625"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367626"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367627"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367628"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367629"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367630"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367631"] = "This fault is caused by 'output errors frames trend' statistical property crossing threshold level." + self.system_fault_code["F367632"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367633"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367634"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367635"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367636"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367637"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367638"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367639"] = "This fault is caused by 'output errors frames rate' statistical property crossing threshold level." + self.system_fault_code["F367712"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367713"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367714"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367715"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367716"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367717"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367718"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367719"] = "This fault is caused by 'output class2 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367728"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367729"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367730"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367731"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367732"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367733"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367734"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367735"] = "This fault is caused by 'output class2 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367736"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367737"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367738"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367739"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367740"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367741"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367742"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367743"] = "This fault is caused by 'output class2 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367744"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367745"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367746"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367747"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367748"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367749"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367750"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367751"] = "This fault is caused by 'output class2 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367752"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367753"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367754"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367755"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367756"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367757"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367758"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367759"] = "This fault is caused by 'output class2 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367760"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367761"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367762"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367763"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367764"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367765"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367766"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367767"] = "This fault is caused by 'output class2 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367792"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367793"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367794"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367795"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367796"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367797"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367798"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367799"] = "This fault is caused by 'output class2 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367800"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367801"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367802"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367803"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367804"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367805"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367806"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367807"] = "This fault is caused by 'output class2 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367880"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367881"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367882"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367883"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367884"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367885"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367886"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367887"] = "This fault is caused by 'output class3 frames current value' statistical property crossing threshold level." + self.system_fault_code["F367896"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367897"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367898"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367899"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367900"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367901"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367902"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367903"] = "This fault is caused by 'output class3 frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F367904"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367905"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367906"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367907"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367908"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367909"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367910"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367911"] = "This fault is caused by 'output class3 frames periodic' statistical property crossing threshold level." + self.system_fault_code["F367912"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367913"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367914"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367915"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367916"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367917"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367918"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367919"] = "This fault is caused by 'output class3 frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F367920"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367921"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367922"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367923"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367924"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367925"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367926"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367927"] = "This fault is caused by 'output class3 frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F367928"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367929"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367930"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367931"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367932"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367933"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367934"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367935"] = "This fault is caused by 'output class3 frames average value' statistical property crossing threshold level." + self.system_fault_code["F367960"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367961"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367962"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367963"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367964"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367965"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367966"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367967"] = "This fault is caused by 'output class3 frames trend' statistical property crossing threshold level." + self.system_fault_code["F367968"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367969"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367970"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367971"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367972"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367973"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367974"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F367975"] = "This fault is caused by 'output class3 frames rate' statistical property crossing threshold level." + self.system_fault_code["F368048"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368049"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368050"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368051"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368052"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368053"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368054"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368055"] = "This fault is caused by 'output classf frames current value' statistical property crossing threshold level." + self.system_fault_code["F368064"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368065"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368066"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368067"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368068"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368069"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368070"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368071"] = "This fault is caused by 'output classf frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F368072"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368073"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368074"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368075"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368076"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368077"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368078"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368079"] = "This fault is caused by 'output classf frames periodic' statistical property crossing threshold level." + self.system_fault_code["F368080"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368081"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368082"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368083"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368084"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368085"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368086"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368087"] = "This fault is caused by 'output classf frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F368088"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368089"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368090"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368091"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368092"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368093"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368094"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368095"] = "This fault is caused by 'output classf frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F368096"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368097"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368098"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368099"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368100"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368101"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368102"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368103"] = "This fault is caused by 'output classf frames average value' statistical property crossing threshold level." + self.system_fault_code["F368128"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368129"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368130"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368131"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368132"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368133"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368134"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368135"] = "This fault is caused by 'output classf frames trend' statistical property crossing threshold level." + self.system_fault_code["F368136"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368137"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368138"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368139"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368140"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368141"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368142"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368143"] = "This fault is caused by 'output classf frames rate' statistical property crossing threshold level." + self.system_fault_code["F368216"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368217"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368218"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368219"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368220"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368221"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368222"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368223"] = "This fault is caused by 'output loop inits current value' statistical property crossing threshold level." + self.system_fault_code["F368232"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368233"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368234"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368235"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368236"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368237"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368238"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368239"] = "This fault is caused by 'output loop inits cumulative' statistical property crossing threshold level." + self.system_fault_code["F368240"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368241"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368242"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368243"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368244"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368245"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368246"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368247"] = "This fault is caused by 'output loop inits periodic' statistical property crossing threshold level." + self.system_fault_code["F368248"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368249"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368250"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368251"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368252"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368253"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368254"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368255"] = "This fault is caused by 'output loop inits minimum value' statistical property crossing threshold level." + self.system_fault_code["F368256"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368257"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368258"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368259"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368260"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368261"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368262"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368263"] = "This fault is caused by 'output loop inits maximum value' statistical property crossing threshold level." + self.system_fault_code["F368264"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368265"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368266"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368267"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368268"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368269"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368270"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368271"] = "This fault is caused by 'output loop inits average value' statistical property crossing threshold level." + self.system_fault_code["F368296"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368297"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368298"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368299"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368300"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368301"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368302"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368303"] = "This fault is caused by 'output loop inits trend' statistical property crossing threshold level." + self.system_fault_code["F368304"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368305"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368306"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368307"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368308"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368309"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368310"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368311"] = "This fault is caused by 'output loop inits rate' statistical property crossing threshold level." + self.system_fault_code["F368384"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368385"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368386"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368387"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368388"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368389"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368390"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368391"] = "This fault is caused by 'output link Reset Response current value' statistical property crossing threshold level." + self.system_fault_code["F368400"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368401"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368402"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368403"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368404"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368405"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368406"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368407"] = "This fault is caused by 'output link Reset Response cumulative' statistical property crossing threshold level." + self.system_fault_code["F368408"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368409"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368410"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368411"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368412"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368413"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368414"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368415"] = "This fault is caused by 'output link Reset Response periodic' statistical property crossing threshold level." + self.system_fault_code["F368416"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368417"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368418"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368419"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368420"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368421"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368422"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368423"] = "This fault is caused by 'output link Reset Response minimum value' statistical property crossing threshold level." + self.system_fault_code["F368424"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368425"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368426"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368427"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368428"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368429"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368430"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368431"] = "This fault is caused by 'output link Reset Response maximum value' statistical property crossing threshold level." + self.system_fault_code["F368432"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368433"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368434"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368435"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368436"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368437"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368438"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368439"] = "This fault is caused by 'output link Reset Response average value' statistical property crossing threshold level." + self.system_fault_code["F368464"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368465"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368466"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368467"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368468"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368469"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368470"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368471"] = "This fault is caused by 'output link Reset Response trend' statistical property crossing threshold level." + self.system_fault_code["F368472"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368473"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368474"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368475"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368476"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368477"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368478"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368479"] = "This fault is caused by 'output link Reset Response rate' statistical property crossing threshold level." + self.system_fault_code["F368552"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368553"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368554"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368555"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368556"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368557"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368558"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368559"] = "This fault is caused by 'output not operational current value' statistical property crossing threshold level." + self.system_fault_code["F368568"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368569"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368570"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368571"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368572"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368573"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368574"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368575"] = "This fault is caused by 'output not operational cumulative' statistical property crossing threshold level." + self.system_fault_code["F368576"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368577"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368578"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368579"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368580"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368581"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368582"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368583"] = "This fault is caused by 'output not operational periodic' statistical property crossing threshold level." + self.system_fault_code["F368584"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368585"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368586"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368587"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368588"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368589"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368590"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368591"] = "This fault is caused by 'output not operational minimum value' statistical property crossing threshold level." + self.system_fault_code["F368592"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368593"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368594"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368595"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368596"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368597"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368598"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368599"] = "This fault is caused by 'output not operational maximum value' statistical property crossing threshold level." + self.system_fault_code["F368600"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368601"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368602"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368603"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368604"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368605"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368606"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368607"] = "This fault is caused by 'output not operational average value' statistical property crossing threshold level." + self.system_fault_code["F368632"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368633"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368634"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368635"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368636"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368637"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368638"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368639"] = "This fault is caused by 'output not operational trend' statistical property crossing threshold level." + self.system_fault_code["F368640"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368641"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368642"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368643"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368644"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368645"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368646"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368647"] = "This fault is caused by 'output not operational rate' statistical property crossing threshold level." + self.system_fault_code["F368720"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368721"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368722"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368723"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368724"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368725"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368726"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368727"] = "This fault is caused by 'output offline current value' statistical property crossing threshold level." + self.system_fault_code["F368736"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368737"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368738"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368739"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368740"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368741"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368742"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368743"] = "This fault is caused by 'output offline cumulative' statistical property crossing threshold level." + self.system_fault_code["F368744"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368745"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368746"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368747"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368748"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368749"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368750"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368751"] = "This fault is caused by 'output offline periodic' statistical property crossing threshold level." + self.system_fault_code["F368752"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368753"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368754"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368755"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368756"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368757"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368758"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368759"] = "This fault is caused by 'output offline minimum value' statistical property crossing threshold level." + self.system_fault_code["F368760"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368761"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368762"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368763"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368764"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368765"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368766"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368767"] = "This fault is caused by 'output offline maximum value' statistical property crossing threshold level." + self.system_fault_code["F368768"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368769"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368770"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368771"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368772"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368773"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368774"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368775"] = "This fault is caused by 'output offline average value' statistical property crossing threshold level." + self.system_fault_code["F368800"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368801"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368802"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368803"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368804"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368805"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368806"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368807"] = "This fault is caused by 'output offline trend' statistical property crossing threshold level." + self.system_fault_code["F368808"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368809"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368810"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368811"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368812"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368813"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368814"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368815"] = "This fault is caused by 'output offline rate' statistical property crossing threshold level." + self.system_fault_code["F368888"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368889"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368890"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368891"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368892"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368893"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368894"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368895"] = "This fault is caused by 'total output bytes current value' statistical property crossing threshold level." + self.system_fault_code["F368904"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368905"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368906"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368907"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368908"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368909"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368910"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368911"] = "This fault is caused by 'total output bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F368912"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368913"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368914"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368915"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368916"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368917"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368918"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368919"] = "This fault is caused by 'total output bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F368920"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368921"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368922"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368923"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368924"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368925"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368926"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368927"] = "This fault is caused by 'total output bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F368928"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368929"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368930"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368931"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368932"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368933"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368934"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368935"] = "This fault is caused by 'total output bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F368936"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368937"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368938"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368939"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368940"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368941"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368942"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368943"] = "This fault is caused by 'total output bytes average value' statistical property crossing threshold level." + self.system_fault_code["F368968"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368969"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368970"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368971"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368972"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368973"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368974"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368975"] = "This fault is caused by 'total output bytes trend' statistical property crossing threshold level." + self.system_fault_code["F368976"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368977"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368978"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368979"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368980"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368981"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368982"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F368983"] = "This fault is caused by 'total output bytes rate' statistical property crossing threshold level." + self.system_fault_code["F369056"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369057"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369058"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369059"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369060"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369061"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369062"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369063"] = "This fault is caused by 'total output bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F369064"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369065"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369066"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369067"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369068"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369069"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369070"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369071"] = "This fault is caused by 'total output bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F369072"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369073"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369074"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369075"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369076"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369077"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369078"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369079"] = "This fault is caused by 'total output bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F369080"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369081"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369082"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369083"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369084"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369085"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369086"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369087"] = "This fault is caused by 'total output bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F369120"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369121"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369122"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369123"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369124"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369125"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369126"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369127"] = "This fault is caused by 'total output bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F369176"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369177"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369178"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369179"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369180"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369181"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369182"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369183"] = "This fault is caused by 'ingress link utilization current value' statistical property crossing threshold level." + self.system_fault_code["F369184"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369185"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369186"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369187"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369188"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369189"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369190"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369191"] = "This fault is caused by 'ingress link utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F369192"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369193"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369194"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369195"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369196"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369197"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369198"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369199"] = "This fault is caused by 'ingress link utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F369200"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369201"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369202"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369203"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369204"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369205"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369206"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369207"] = "This fault is caused by 'ingress link utilization average value' statistical property crossing threshold level." + self.system_fault_code["F369240"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369241"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369242"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369243"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369244"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369245"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369246"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369247"] = "This fault is caused by 'ingress link utilization trend' statistical property crossing threshold level." + self.system_fault_code["F369296"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369297"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369298"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369299"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369300"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369301"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369302"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369303"] = "This fault is caused by 'remaining B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369312"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369313"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369314"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369315"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369316"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369317"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369318"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369319"] = "This fault is caused by 'remaining B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369320"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369321"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369322"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369323"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369324"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369325"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369326"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369327"] = "This fault is caused by 'remaining B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369328"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369329"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369330"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369331"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369332"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369333"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369334"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369335"] = "This fault is caused by 'remaining B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369336"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369337"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369338"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369339"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369340"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369341"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369342"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369343"] = "This fault is caused by 'remaining B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369344"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369345"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369346"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369347"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369348"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369349"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369350"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369351"] = "This fault is caused by 'remaining B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369376"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369377"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369378"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369379"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369380"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369381"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369382"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369383"] = "This fault is caused by 'remaining B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369384"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369385"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369386"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369387"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369388"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369389"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369390"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369391"] = "This fault is caused by 'remaining B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369464"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369465"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369466"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369467"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369468"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369469"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369470"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369471"] = "This fault is caused by 'receive B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369480"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369481"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369482"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369483"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369484"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369485"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369486"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369487"] = "This fault is caused by 'receive B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369488"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369489"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369490"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369491"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369492"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369493"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369494"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369495"] = "This fault is caused by 'receive B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369496"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369497"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369498"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369499"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369500"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369501"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369502"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369503"] = "This fault is caused by 'receive B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369504"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369505"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369506"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369507"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369508"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369509"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369510"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369511"] = "This fault is caused by 'receive B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369512"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369513"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369514"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369515"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369516"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369517"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369518"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369519"] = "This fault is caused by 'receive B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369544"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369545"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369546"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369547"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369548"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369549"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369550"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369551"] = "This fault is caused by 'receive B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369552"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369553"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369554"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369555"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369556"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369557"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369558"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369559"] = "This fault is caused by 'receive B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369632"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369633"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369634"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369635"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369636"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369637"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369638"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369639"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369648"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369649"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369650"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369651"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369652"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369653"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369654"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369655"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369656"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369657"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369658"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369659"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369660"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369661"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369662"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369663"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369664"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369665"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369666"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369667"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369668"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369669"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369670"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369671"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369672"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369673"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369674"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369675"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369676"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369677"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369678"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369679"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369680"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369681"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369682"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369683"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369684"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369685"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369686"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369687"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369712"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369713"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369714"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369715"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369716"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369717"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369718"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369719"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369720"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369721"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369722"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369723"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369724"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369725"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369726"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369727"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369800"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369801"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369802"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369803"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369804"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369805"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369806"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369807"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369816"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369817"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369818"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369819"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369820"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369821"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369822"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369823"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369824"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369825"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369826"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369827"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369828"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369829"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369830"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369831"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369832"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369833"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369834"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369835"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369836"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369837"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369838"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369839"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F369840"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369841"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369842"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369843"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369844"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369845"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369846"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369847"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F369848"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369849"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369850"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369851"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369852"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369853"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369854"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369855"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F369880"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369881"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369882"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369883"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369884"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369885"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369886"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369887"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F369888"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369889"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369890"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369891"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369892"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369893"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369894"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369895"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F369968"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369969"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369970"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369971"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369972"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369973"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369974"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369975"] = "This fault is caused by 'transmit B2B credit current value' statistical property crossing threshold level." + self.system_fault_code["F369984"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369985"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369986"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369987"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369988"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369989"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369990"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369991"] = "This fault is caused by 'transmit B2B credit cumulative' statistical property crossing threshold level." + self.system_fault_code["F369992"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369993"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369994"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369995"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369996"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369997"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369998"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F369999"] = "This fault is caused by 'transmit B2B credit periodic' statistical property crossing threshold level." + self.system_fault_code["F370000"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370001"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370002"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370003"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370004"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370005"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370006"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370007"] = "This fault is caused by 'transmit B2B credit minimum value' statistical property crossing threshold level." + self.system_fault_code["F370008"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370009"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370010"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370011"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370012"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370013"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370014"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370015"] = "This fault is caused by 'transmit B2B credit maximum value' statistical property crossing threshold level." + self.system_fault_code["F370016"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370017"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370018"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370019"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370020"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370021"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370022"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370023"] = "This fault is caused by 'transmit B2B credit average value' statistical property crossing threshold level." + self.system_fault_code["F370048"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370049"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370050"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370051"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370052"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370053"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370054"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370055"] = "This fault is caused by 'transmit B2B credit trend' statistical property crossing threshold level." + self.system_fault_code["F370056"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370057"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370058"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370059"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370060"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370061"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370062"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F370063"] = "This fault is caused by 'transmit B2B credit rate' statistical property crossing threshold level." + self.system_fault_code["F373200"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373201"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373202"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373203"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373204"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373205"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373206"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373207"] = "This fault is caused by 'BV Macsec Decrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373216"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373217"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373218"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373219"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373220"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373221"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373222"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373223"] = "This fault is caused by 'BV Macsec Decrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373224"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373225"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373226"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373227"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373228"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373229"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373230"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373231"] = "This fault is caused by 'BV Macsec Decrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373232"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373233"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373234"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373235"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373236"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373237"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373238"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373239"] = "This fault is caused by 'BV Macsec Decrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373240"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373241"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373242"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373243"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373244"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373245"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373246"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373247"] = "This fault is caused by 'BV Macsec Decrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373248"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373249"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373250"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373251"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373252"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373253"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373254"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373255"] = "This fault is caused by 'BV Macsec Decrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373280"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373281"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373282"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373283"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373284"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373285"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373286"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373287"] = "This fault is caused by 'BV Macsec Decrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373288"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373289"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373290"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373291"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373292"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373293"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373294"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373295"] = "This fault is caused by 'BV Macsec Decrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373368"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373369"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373370"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373371"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373372"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373373"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373374"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373375"] = "This fault is caused by 'BV Macsec Decrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373376"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373377"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373378"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373379"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373380"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373381"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373382"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373383"] = "This fault is caused by 'BV Macsec Decrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373384"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373385"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373386"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373387"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373388"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373389"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373390"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373391"] = "This fault is caused by 'BV Macsec Decrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373392"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373393"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373394"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373395"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373396"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373397"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373398"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373399"] = "This fault is caused by 'BV Macsec Decrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373432"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373433"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373434"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373435"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373436"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373437"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373438"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373439"] = "This fault is caused by 'BV Macsec Decrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373488"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373489"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373490"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373491"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373492"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373493"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373494"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373495"] = "This fault is caused by 'BV Macsec Encrypted packets current value' statistical property crossing threshold level." + self.system_fault_code["F373504"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373505"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373506"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373507"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373508"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373509"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373510"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373511"] = "This fault is caused by 'BV Macsec Encrypted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F373512"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373513"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373514"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373515"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373516"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373517"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373518"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373519"] = "This fault is caused by 'BV Macsec Encrypted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F373520"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373521"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373522"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373523"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373524"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373525"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373526"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373527"] = "This fault is caused by 'BV Macsec Encrypted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F373528"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373529"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373530"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373531"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373532"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373533"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373534"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373535"] = "This fault is caused by 'BV Macsec Encrypted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F373536"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373537"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373538"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373539"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373540"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373541"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373542"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373543"] = "This fault is caused by 'BV Macsec Encrypted packets average value' statistical property crossing threshold level." + self.system_fault_code["F373568"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373569"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373570"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373571"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373572"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373573"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373574"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373575"] = "This fault is caused by 'BV Macsec Encrypted packets trend' statistical property crossing threshold level." + self.system_fault_code["F373576"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373577"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373578"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373579"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373580"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373581"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373582"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373583"] = "This fault is caused by 'BV Macsec Encrypted packets rate' statistical property crossing threshold level." + self.system_fault_code["F373656"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373657"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373658"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373659"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373660"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373661"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373662"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373663"] = "This fault is caused by 'BV Macsec Encrypted packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F373664"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373665"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373666"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373667"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373668"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373669"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373670"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373671"] = "This fault is caused by 'BV Macsec Encrypted packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F373672"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373673"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373674"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373675"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373676"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373677"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373678"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373679"] = "This fault is caused by 'BV Macsec Encrypted packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F373680"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373681"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373682"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373683"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373684"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373685"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373686"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373687"] = "This fault is caused by 'BV Macsec Encrypted packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F373720"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373721"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373722"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373723"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373724"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373725"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373726"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F373727"] = "This fault is caused by 'BV Macsec Encrypted packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F375424"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375425"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375426"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375427"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375428"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375429"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375430"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375431"] = "This fault is caused by 'input fbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375440"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375441"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375442"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375443"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375444"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375445"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375446"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375447"] = "This fault is caused by 'input fbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375448"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375449"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375450"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375451"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375452"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375453"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375454"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375455"] = "This fault is caused by 'input fbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375456"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375457"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375458"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375459"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375460"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375461"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375462"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375463"] = "This fault is caused by 'input fbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375464"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375465"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375466"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375467"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375468"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375469"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375470"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375471"] = "This fault is caused by 'input fbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375472"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375473"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375474"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375475"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375476"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375477"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375478"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375479"] = "This fault is caused by 'input fbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375504"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375505"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375506"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375507"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375508"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375509"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375510"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375511"] = "This fault is caused by 'input fbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375512"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375513"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375514"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375515"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375516"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375517"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375518"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375519"] = "This fault is caused by 'input fbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375592"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375593"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375594"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375595"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375596"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375597"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375598"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375599"] = "This fault is caused by 'input frjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375608"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375609"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375610"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375611"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375612"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375613"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375614"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375615"] = "This fault is caused by 'input frjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375616"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375617"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375618"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375619"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375620"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375621"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375622"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375623"] = "This fault is caused by 'input frjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375624"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375625"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375626"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375627"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375628"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375629"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375630"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375631"] = "This fault is caused by 'input frjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375632"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375633"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375634"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375635"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375636"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375637"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375638"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375639"] = "This fault is caused by 'input frjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375640"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375641"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375642"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375643"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375644"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375645"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375646"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375647"] = "This fault is caused by 'input frjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375672"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375673"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375674"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375675"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375676"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375677"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375678"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375679"] = "This fault is caused by 'input frjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F375680"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375681"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375682"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375683"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375684"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375685"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375686"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375687"] = "This fault is caused by 'input frjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F375760"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375761"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375762"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375763"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375764"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375765"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375766"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375767"] = "This fault is caused by 'input pbsy frames current value' statistical property crossing threshold level." + self.system_fault_code["F375776"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375777"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375778"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375779"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375780"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375781"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375782"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375783"] = "This fault is caused by 'input pbsy frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375784"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375785"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375786"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375787"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375788"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375789"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375790"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375791"] = "This fault is caused by 'input pbsy frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375792"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375793"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375794"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375795"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375796"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375797"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375798"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375799"] = "This fault is caused by 'input pbsy frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375800"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375801"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375802"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375803"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375804"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375805"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375806"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375807"] = "This fault is caused by 'input pbsy frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375808"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375809"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375810"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375811"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375812"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375813"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375814"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375815"] = "This fault is caused by 'input pbsy frames average value' statistical property crossing threshold level." + self.system_fault_code["F375840"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375841"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375842"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375843"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375844"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375845"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375846"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375847"] = "This fault is caused by 'input pbsy frames trend' statistical property crossing threshold level." + self.system_fault_code["F375848"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375849"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375850"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375851"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375852"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375853"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375854"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375855"] = "This fault is caused by 'input pbsy frames rate' statistical property crossing threshold level." + self.system_fault_code["F375928"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375929"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375930"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375931"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375932"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375933"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375934"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375935"] = "This fault is caused by 'input prjt frames current value' statistical property crossing threshold level." + self.system_fault_code["F375944"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375945"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375946"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375947"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375948"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375949"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375950"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375951"] = "This fault is caused by 'input prjt frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F375952"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375953"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375954"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375955"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375956"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375957"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375958"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375959"] = "This fault is caused by 'input prjt frames periodic' statistical property crossing threshold level." + self.system_fault_code["F375960"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375961"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375962"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375963"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375964"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375965"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375966"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375967"] = "This fault is caused by 'input prjt frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F375968"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375969"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375970"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375971"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375972"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375973"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375974"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375975"] = "This fault is caused by 'input prjt frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F375976"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375977"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375978"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375979"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375980"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375981"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375982"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F375983"] = "This fault is caused by 'input prjt frames average value' statistical property crossing threshold level." + self.system_fault_code["F376008"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376009"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376010"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376011"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376012"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376013"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376014"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376015"] = "This fault is caused by 'input prjt frames trend' statistical property crossing threshold level." + self.system_fault_code["F376016"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376017"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376018"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376019"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376020"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376021"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376022"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376023"] = "This fault is caused by 'input prjt frames rate' statistical property crossing threshold level." + self.system_fault_code["F376096"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376097"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376098"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376099"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376100"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376101"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376102"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376103"] = "This fault is caused by 'Input Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376112"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376113"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376114"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376115"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376116"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376117"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376118"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376119"] = "This fault is caused by 'Input Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376120"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376121"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376122"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376123"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376124"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376125"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376126"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376127"] = "This fault is caused by 'Input Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376128"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376129"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376130"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376131"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376132"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376133"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376134"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376135"] = "This fault is caused by 'Input Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376136"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376137"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376138"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376139"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376140"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376141"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376142"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376143"] = "This fault is caused by 'Input Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376144"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376145"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376146"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376147"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376148"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376149"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376150"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376151"] = "This fault is caused by 'Input Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376176"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376177"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376178"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376179"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376180"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376181"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376182"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376183"] = "This fault is caused by 'Input Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376184"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376185"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376186"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376187"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376188"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376189"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376190"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376191"] = "This fault is caused by 'Input Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376264"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376265"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376266"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376267"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376268"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376269"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376270"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376271"] = "This fault is caused by 'Input Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376280"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376281"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376282"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376283"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376284"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376285"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376286"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376287"] = "This fault is caused by 'Input Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376288"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376289"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376290"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376291"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376292"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376293"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376294"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376295"] = "This fault is caused by 'Input Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376296"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376297"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376298"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376299"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376300"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376301"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376302"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376303"] = "This fault is caused by 'Input Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376304"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376305"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376306"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376307"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376308"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376309"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376310"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376311"] = "This fault is caused by 'Input Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376312"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376313"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376314"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376315"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376316"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376317"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376318"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376319"] = "This fault is caused by 'Input Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376344"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376345"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376346"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376347"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376348"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376349"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376350"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376351"] = "This fault is caused by 'Input Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376352"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376353"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376354"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376355"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376356"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376357"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376358"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376359"] = "This fault is caused by 'Input Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376432"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376433"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376434"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376435"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376436"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376437"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376438"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376439"] = "This fault is caused by 'Input Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F376448"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376449"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376450"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376451"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376452"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376453"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376454"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376455"] = "This fault is caused by 'Input Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F376456"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376457"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376458"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376459"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376460"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376461"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376462"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376463"] = "This fault is caused by 'Input Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F376464"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376465"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376466"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376467"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376468"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376469"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376470"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376471"] = "This fault is caused by 'Input Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F376472"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376473"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376474"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376475"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376476"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376477"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376478"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376479"] = "This fault is caused by 'Input Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F376480"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376481"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376482"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376483"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376484"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376485"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376486"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376487"] = "This fault is caused by 'Input Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F376512"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376513"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376514"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376515"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376516"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376517"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376518"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376519"] = "This fault is caused by 'Input Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F376520"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376521"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376522"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376523"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376524"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376525"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376526"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376527"] = "This fault is caused by 'Input Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F376600"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376601"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376602"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376603"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376604"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376605"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376606"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376607"] = "This fault is caused by 'input class2 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376616"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376617"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376618"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376619"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376620"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376621"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376622"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376623"] = "This fault is caused by 'input class2 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376624"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376625"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376626"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376627"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376628"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376629"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376630"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376631"] = "This fault is caused by 'input class2 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376632"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376633"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376634"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376635"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376636"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376637"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376638"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376639"] = "This fault is caused by 'input class2 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376640"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376641"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376642"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376643"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376644"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376645"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376646"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376647"] = "This fault is caused by 'input class2 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376648"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376649"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376650"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376651"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376652"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376653"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376654"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376655"] = "This fault is caused by 'input class2 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376680"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376681"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376682"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376683"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376684"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376685"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376686"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376687"] = "This fault is caused by 'input class2 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376688"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376689"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376690"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376691"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376692"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376693"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376694"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376695"] = "This fault is caused by 'input class2 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376768"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376769"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376770"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376771"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376772"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376773"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376774"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376775"] = "This fault is caused by 'input class3 discards current value' statistical property crossing threshold level." + self.system_fault_code["F376784"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376785"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376786"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376787"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376788"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376789"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376790"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376791"] = "This fault is caused by 'input class3 discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376792"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376793"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376794"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376795"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376796"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376797"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376798"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376799"] = "This fault is caused by 'input class3 discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376800"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376801"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376802"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376803"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376804"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376805"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376806"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376807"] = "This fault is caused by 'input class3 discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376808"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376809"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376810"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376811"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376812"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376813"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376814"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376815"] = "This fault is caused by 'input class3 discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376816"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376817"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376818"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376819"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376820"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376821"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376822"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376823"] = "This fault is caused by 'input class3 discards average value' statistical property crossing threshold level." + self.system_fault_code["F376848"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376849"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376850"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376851"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376852"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376853"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376854"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376855"] = "This fault is caused by 'input class3 discards trend' statistical property crossing threshold level." + self.system_fault_code["F376856"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376857"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376858"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376859"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376860"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376861"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376862"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376863"] = "This fault is caused by 'input class3 discards rate' statistical property crossing threshold level." + self.system_fault_code["F376936"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376937"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376938"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376939"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376940"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376941"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376942"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376943"] = "This fault is caused by 'input classf discards current value' statistical property crossing threshold level." + self.system_fault_code["F376952"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376953"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376954"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376955"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376956"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376957"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376958"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376959"] = "This fault is caused by 'input classf discards cumulative' statistical property crossing threshold level." + self.system_fault_code["F376960"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376961"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376962"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376963"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376964"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376965"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376966"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376967"] = "This fault is caused by 'input classf discards periodic' statistical property crossing threshold level." + self.system_fault_code["F376968"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376969"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376970"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376971"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376972"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376973"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376974"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376975"] = "This fault is caused by 'input classf discards minimum value' statistical property crossing threshold level." + self.system_fault_code["F376976"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376977"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376978"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376979"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376980"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376981"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376982"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376983"] = "This fault is caused by 'input classf discards maximum value' statistical property crossing threshold level." + self.system_fault_code["F376984"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376985"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376986"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376987"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376988"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376989"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376990"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F376991"] = "This fault is caused by 'input classf discards average value' statistical property crossing threshold level." + self.system_fault_code["F377016"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377017"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377018"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377019"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377020"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377021"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377022"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377023"] = "This fault is caused by 'input classf discards trend' statistical property crossing threshold level." + self.system_fault_code["F377024"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377025"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377026"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377027"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377028"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377029"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377030"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377031"] = "This fault is caused by 'input classf discards rate' statistical property crossing threshold level." + self.system_fault_code["F377104"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377105"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377106"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377107"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377108"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377109"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377110"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377111"] = "This fault is caused by 'address identifier errors current value' statistical property crossing threshold level." + self.system_fault_code["F377120"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377121"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377122"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377123"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377124"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377125"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377126"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377127"] = "This fault is caused by 'address identifier errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377128"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377129"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377130"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377131"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377132"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377133"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377134"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377135"] = "This fault is caused by 'address identifier errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377136"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377137"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377138"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377139"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377140"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377141"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377142"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377143"] = "This fault is caused by 'address identifier errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377144"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377145"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377146"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377147"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377148"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377149"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377150"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377151"] = "This fault is caused by 'address identifier errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377152"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377153"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377154"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377155"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377156"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377157"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377158"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377159"] = "This fault is caused by 'address identifier errors average value' statistical property crossing threshold level." + self.system_fault_code["F377184"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377185"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377186"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377187"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377188"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377189"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377190"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377191"] = "This fault is caused by 'address identifier errors trend' statistical property crossing threshold level." + self.system_fault_code["F377192"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377193"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377194"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377195"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377196"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377197"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377198"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377199"] = "This fault is caused by 'address identifier errors rate' statistical property crossing threshold level." + self.system_fault_code["F377272"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377273"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377274"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377275"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377276"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377277"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377278"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377279"] = "This fault is caused by 'delimiter errors current value' statistical property crossing threshold level." + self.system_fault_code["F377288"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377289"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377290"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377291"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377292"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377293"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377294"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377295"] = "This fault is caused by 'delimiter errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377296"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377297"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377298"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377299"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377300"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377301"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377302"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377303"] = "This fault is caused by 'delimiter errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377304"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377305"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377306"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377307"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377308"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377309"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377310"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377311"] = "This fault is caused by 'delimiter errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377312"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377313"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377314"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377315"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377316"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377317"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377318"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377319"] = "This fault is caused by 'delimiter errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377320"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377321"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377322"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377323"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377324"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377325"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377326"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377327"] = "This fault is caused by 'delimiter errors average value' statistical property crossing threshold level." + self.system_fault_code["F377352"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377353"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377354"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377355"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377356"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377357"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377358"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377359"] = "This fault is caused by 'delimiter errors trend' statistical property crossing threshold level." + self.system_fault_code["F377360"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377361"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377362"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377363"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377364"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377365"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377366"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377367"] = "This fault is caused by 'delimiter errors rate' statistical property crossing threshold level." + self.system_fault_code["F377440"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377441"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377442"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377443"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377444"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377445"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377446"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377447"] = "This fault is caused by 'input link Reset Protocol current value' statistical property crossing threshold level." + self.system_fault_code["F377456"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377457"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377458"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377459"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377460"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377461"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377462"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377463"] = "This fault is caused by 'input link Reset Protocol cumulative' statistical property crossing threshold level." + self.system_fault_code["F377464"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377465"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377466"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377467"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377468"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377469"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377470"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377471"] = "This fault is caused by 'input link Reset Protocol periodic' statistical property crossing threshold level." + self.system_fault_code["F377472"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377473"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377474"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377475"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377476"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377477"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377478"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377479"] = "This fault is caused by 'input link Reset Protocol minimum value' statistical property crossing threshold level." + self.system_fault_code["F377480"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377481"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377482"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377483"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377484"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377485"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377486"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377487"] = "This fault is caused by 'input link Reset Protocol maximum value' statistical property crossing threshold level." + self.system_fault_code["F377488"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377489"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377490"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377491"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377492"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377493"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377494"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377495"] = "This fault is caused by 'input link Reset Protocol average value' statistical property crossing threshold level." + self.system_fault_code["F377520"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377521"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377522"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377523"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377524"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377525"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377526"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377527"] = "This fault is caused by 'input link Reset Protocol trend' statistical property crossing threshold level." + self.system_fault_code["F377528"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377529"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377530"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377531"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377532"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377533"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377534"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377535"] = "This fault is caused by 'input link Reset Protocol rate' statistical property crossing threshold level." + self.system_fault_code["F377608"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377609"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377610"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377611"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377612"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377613"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377614"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377615"] = "This fault is caused by 'primitive seq proto errors current value' statistical property crossing threshold level." + self.system_fault_code["F377624"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377625"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377626"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377627"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377628"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377629"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377630"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377631"] = "This fault is caused by 'primitive seq proto errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F377632"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377633"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377634"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377635"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377636"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377637"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377638"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377639"] = "This fault is caused by 'primitive seq proto errors periodic' statistical property crossing threshold level." + self.system_fault_code["F377640"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377641"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377642"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377643"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377644"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377645"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377646"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377647"] = "This fault is caused by 'primitive seq proto errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F377648"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377649"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377650"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377651"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377652"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377653"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377654"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377655"] = "This fault is caused by 'primitive seq proto errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F377656"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377657"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377658"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377659"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377660"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377661"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377662"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377663"] = "This fault is caused by 'primitive seq proto errors average value' statistical property crossing threshold level." + self.system_fault_code["F377688"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377689"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377690"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377691"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377692"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377693"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377694"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377695"] = "This fault is caused by 'primitive seq proto errors trend' statistical property crossing threshold level." + self.system_fault_code["F377696"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377697"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377698"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377699"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377700"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377701"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377702"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377703"] = "This fault is caused by 'primitive seq proto errors rate' statistical property crossing threshold level." + self.system_fault_code["F377776"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377777"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377778"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377779"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377780"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377781"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377782"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377783"] = "This fault is caused by 'input eof aborts current value' statistical property crossing threshold level." + self.system_fault_code["F377792"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377793"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377794"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377795"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377796"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377797"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377798"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377799"] = "This fault is caused by 'input eof aborts cumulative' statistical property crossing threshold level." + self.system_fault_code["F377800"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377801"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377802"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377803"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377804"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377805"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377806"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377807"] = "This fault is caused by 'input eof aborts periodic' statistical property crossing threshold level." + self.system_fault_code["F377808"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377809"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377810"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377811"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377812"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377813"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377814"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377815"] = "This fault is caused by 'input eof aborts minimum value' statistical property crossing threshold level." + self.system_fault_code["F377816"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377817"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377818"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377819"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377820"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377821"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377822"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377823"] = "This fault is caused by 'input eof aborts maximum value' statistical property crossing threshold level." + self.system_fault_code["F377824"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377825"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377826"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377827"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377828"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377829"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377830"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377831"] = "This fault is caused by 'input eof aborts average value' statistical property crossing threshold level." + self.system_fault_code["F377856"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377857"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377858"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377859"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377860"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377861"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377862"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377863"] = "This fault is caused by 'input eof aborts trend' statistical property crossing threshold level." + self.system_fault_code["F377864"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377865"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377866"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377867"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377868"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377869"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377870"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377871"] = "This fault is caused by 'input eof aborts rate' statistical property crossing threshold level." + self.system_fault_code["F377944"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377945"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377946"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377947"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377948"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377949"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377950"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377951"] = "This fault is caused by 'input f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F377960"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377961"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377962"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377963"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377964"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377965"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377966"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377967"] = "This fault is caused by 'input f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F377968"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377969"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377970"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377971"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377972"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377973"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377974"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377975"] = "This fault is caused by 'input f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F377976"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377977"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377978"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377979"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377980"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377981"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377982"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377983"] = "This fault is caused by 'input f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F377984"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377985"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377986"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377987"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377988"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377989"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377990"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377991"] = "This fault is caused by 'input f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F377992"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377993"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377994"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377995"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377996"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377997"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377998"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F377999"] = "This fault is caused by 'input f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378024"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378025"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378026"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378027"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378028"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378029"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378030"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378031"] = "This fault is caused by 'input f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378032"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378033"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378034"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378035"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378036"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378037"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378038"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378039"] = "This fault is caused by 'input f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378112"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378113"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378114"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378115"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378116"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378117"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378118"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378119"] = "This fault is caused by 'fragmented frames current value' statistical property crossing threshold level." + self.system_fault_code["F378128"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378129"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378130"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378131"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378132"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378133"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378134"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378135"] = "This fault is caused by 'fragmented frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F378136"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378137"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378138"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378139"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378140"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378141"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378142"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378143"] = "This fault is caused by 'fragmented frames periodic' statistical property crossing threshold level." + self.system_fault_code["F378144"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378145"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378146"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378147"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378148"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378149"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378150"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378151"] = "This fault is caused by 'fragmented frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F378152"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378153"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378154"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378155"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378156"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378157"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378158"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378159"] = "This fault is caused by 'fragmented frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F378160"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378161"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378162"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378163"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378164"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378165"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378166"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378167"] = "This fault is caused by 'fragmented frames average value' statistical property crossing threshold level." + self.system_fault_code["F378192"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378193"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378194"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378195"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378196"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378197"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378198"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378199"] = "This fault is caused by 'fragmented frames trend' statistical property crossing threshold level." + self.system_fault_code["F378200"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378201"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378202"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378203"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378204"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378205"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378206"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378207"] = "This fault is caused by 'fragmented frames rate' statistical property crossing threshold level." + self.system_fault_code["F378280"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378281"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378282"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378283"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378284"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378285"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378286"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378287"] = "This fault is caused by 'input non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F378296"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378297"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378298"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378299"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378300"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378301"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378302"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378303"] = "This fault is caused by 'input non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F378304"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378305"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378306"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378307"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378308"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378309"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378310"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378311"] = "This fault is caused by 'input non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F378312"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378313"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378314"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378315"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378316"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378317"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378318"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378319"] = "This fault is caused by 'input non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F378320"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378321"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378322"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378323"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378324"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378325"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378326"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378327"] = "This fault is caused by 'input non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F378328"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378329"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378330"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378331"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378332"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378333"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378334"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378335"] = "This fault is caused by 'input non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F378360"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378361"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378362"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378363"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378364"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378365"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378366"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378367"] = "This fault is caused by 'input non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F378368"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378369"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378370"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378371"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378372"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378373"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378374"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378375"] = "This fault is caused by 'input non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F378448"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378449"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378450"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378451"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378452"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378453"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378454"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378455"] = "This fault is caused by 'input 8b10b disparity current value' statistical property crossing threshold level." + self.system_fault_code["F378464"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378465"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378466"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378467"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378468"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378469"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378470"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378471"] = "This fault is caused by 'input 8b10b disparity cumulative' statistical property crossing threshold level." + self.system_fault_code["F378472"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378473"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378474"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378475"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378476"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378477"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378478"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378479"] = "This fault is caused by 'input 8b10b disparity periodic' statistical property crossing threshold level." + self.system_fault_code["F378480"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378481"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378482"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378483"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378484"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378485"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378486"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378487"] = "This fault is caused by 'input 8b10b disparity minimum value' statistical property crossing threshold level." + self.system_fault_code["F378488"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378489"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378490"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378491"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378492"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378493"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378494"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378495"] = "This fault is caused by 'input 8b10b disparity maximum value' statistical property crossing threshold level." + self.system_fault_code["F378496"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378497"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378498"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378499"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378500"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378501"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378502"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378503"] = "This fault is caused by 'input 8b10b disparity average value' statistical property crossing threshold level." + self.system_fault_code["F378528"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378529"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378530"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378531"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378532"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378533"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378534"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378535"] = "This fault is caused by 'input 8b10b disparity trend' statistical property crossing threshold level." + self.system_fault_code["F378536"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378537"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378538"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378539"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378540"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378541"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378542"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378543"] = "This fault is caused by 'input 8b10b disparity rate' statistical property crossing threshold level." + self.system_fault_code["F378616"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378617"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378618"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378619"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378620"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378621"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378622"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378623"] = "This fault is caused by 'input eisl current value' statistical property crossing threshold level." + self.system_fault_code["F378632"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378633"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378634"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378635"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378636"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378637"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378638"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378639"] = "This fault is caused by 'input eisl cumulative' statistical property crossing threshold level." + self.system_fault_code["F378640"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378641"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378642"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378643"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378644"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378645"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378646"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378647"] = "This fault is caused by 'input eisl periodic' statistical property crossing threshold level." + self.system_fault_code["F378648"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378649"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378650"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378651"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378652"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378653"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378654"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378655"] = "This fault is caused by 'input eisl minimum value' statistical property crossing threshold level." + self.system_fault_code["F378656"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378657"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378658"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378659"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378660"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378661"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378662"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378663"] = "This fault is caused by 'input eisl maximum value' statistical property crossing threshold level." + self.system_fault_code["F378664"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378665"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378666"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378667"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378668"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378669"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378670"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378671"] = "This fault is caused by 'input eisl average value' statistical property crossing threshold level." + self.system_fault_code["F378696"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378697"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378698"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378699"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378700"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378701"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378702"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378703"] = "This fault is caused by 'input eisl trend' statistical property crossing threshold level." + self.system_fault_code["F378704"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378705"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378706"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378707"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378708"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378709"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378710"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378711"] = "This fault is caused by 'input eisl rate' statistical property crossing threshold level." + self.system_fault_code["F378784"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378785"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378786"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378787"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378788"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378789"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378790"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378791"] = "This fault is caused by 'input elp current value' statistical property crossing threshold level." + self.system_fault_code["F378800"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378801"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378802"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378803"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378804"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378805"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378806"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378807"] = "This fault is caused by 'input elp cumulative' statistical property crossing threshold level." + self.system_fault_code["F378808"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378809"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378810"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378811"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378812"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378813"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378814"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378815"] = "This fault is caused by 'input elp periodic' statistical property crossing threshold level." + self.system_fault_code["F378816"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378817"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378818"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378819"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378820"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378821"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378822"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378823"] = "This fault is caused by 'input elp minimum value' statistical property crossing threshold level." + self.system_fault_code["F378824"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378825"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378826"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378827"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378828"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378829"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378830"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378831"] = "This fault is caused by 'input elp maximum value' statistical property crossing threshold level." + self.system_fault_code["F378832"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378833"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378834"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378835"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378836"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378837"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378838"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378839"] = "This fault is caused by 'input elp average value' statistical property crossing threshold level." + self.system_fault_code["F378864"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378865"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378866"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378867"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378868"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378869"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378870"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378871"] = "This fault is caused by 'input elp trend' statistical property crossing threshold level." + self.system_fault_code["F378872"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378873"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378874"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378875"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378876"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378877"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378878"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378879"] = "This fault is caused by 'input elp rate' statistical property crossing threshold level." + self.system_fault_code["F378952"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378953"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378954"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378955"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378956"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378957"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378958"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378959"] = "This fault is caused by 'input framing errors current value' statistical property crossing threshold level." + self.system_fault_code["F378968"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378969"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378970"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378971"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378972"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378973"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378974"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378975"] = "This fault is caused by 'input framing errors cumulative' statistical property crossing threshold level." + self.system_fault_code["F378976"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378977"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378978"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378979"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378980"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378981"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378982"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378983"] = "This fault is caused by 'input framing errors periodic' statistical property crossing threshold level." + self.system_fault_code["F378984"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378985"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378986"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378987"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378988"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378989"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378990"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378991"] = "This fault is caused by 'input framing errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F378992"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378993"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378994"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378995"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378996"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378997"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378998"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F378999"] = "This fault is caused by 'input framing errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F379000"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379001"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379002"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379003"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379004"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379005"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379006"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379007"] = "This fault is caused by 'input framing errors average value' statistical property crossing threshold level." + self.system_fault_code["F379032"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379033"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379034"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379035"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379036"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379037"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379038"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379039"] = "This fault is caused by 'input framing errors trend' statistical property crossing threshold level." + self.system_fault_code["F379040"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379041"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379042"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379043"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379044"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379045"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379046"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379047"] = "This fault is caused by 'input framing errors rate' statistical property crossing threshold level." + self.system_fault_code["F379120"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379121"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379122"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379123"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379124"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379125"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379126"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379127"] = "This fault is caused by 'Output Broadcast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379136"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379137"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379138"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379139"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379140"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379141"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379142"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379143"] = "This fault is caused by 'Output Broadcast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379144"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379145"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379146"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379147"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379148"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379149"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379150"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379151"] = "This fault is caused by 'Output Broadcast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379152"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379153"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379154"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379155"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379156"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379157"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379158"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379159"] = "This fault is caused by 'Output Broadcast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379160"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379161"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379162"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379163"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379164"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379165"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379166"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379167"] = "This fault is caused by 'Output Broadcast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379168"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379169"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379170"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379171"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379172"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379173"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379174"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379175"] = "This fault is caused by 'Output Broadcast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379200"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379201"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379202"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379203"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379204"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379205"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379206"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379207"] = "This fault is caused by 'Output Broadcast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379208"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379209"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379210"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379211"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379212"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379213"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379214"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379215"] = "This fault is caused by 'Output Broadcast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379288"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379289"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379290"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379291"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379292"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379293"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379294"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379295"] = "This fault is caused by 'Output Multicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379304"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379305"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379306"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379307"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379308"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379309"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379310"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379311"] = "This fault is caused by 'Output Multicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379312"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379313"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379314"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379315"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379316"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379317"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379318"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379319"] = "This fault is caused by 'Output Multicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379320"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379321"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379322"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379323"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379324"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379325"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379326"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379327"] = "This fault is caused by 'Output Multicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379328"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379329"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379330"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379331"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379332"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379333"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379334"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379335"] = "This fault is caused by 'Output Multicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379336"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379337"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379338"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379339"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379340"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379341"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379342"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379343"] = "This fault is caused by 'Output Multicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379368"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379369"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379370"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379371"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379372"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379373"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379374"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379375"] = "This fault is caused by 'Output Multicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379376"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379377"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379378"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379379"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379380"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379381"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379382"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379383"] = "This fault is caused by 'Output Multicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379456"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379457"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379458"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379459"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379460"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379461"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379462"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379463"] = "This fault is caused by 'Output Unicast Frames current value' statistical property crossing threshold level." + self.system_fault_code["F379472"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379473"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379474"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379475"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379476"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379477"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379478"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379479"] = "This fault is caused by 'Output Unicast Frames cumulative' statistical property crossing threshold level." + self.system_fault_code["F379480"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379481"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379482"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379483"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379484"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379485"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379486"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379487"] = "This fault is caused by 'Output Unicast Frames periodic' statistical property crossing threshold level." + self.system_fault_code["F379488"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379489"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379490"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379491"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379492"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379493"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379494"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379495"] = "This fault is caused by 'Output Unicast Frames minimum value' statistical property crossing threshold level." + self.system_fault_code["F379496"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379497"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379498"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379499"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379500"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379501"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379502"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379503"] = "This fault is caused by 'Output Unicast Frames maximum value' statistical property crossing threshold level." + self.system_fault_code["F379504"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379505"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379506"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379507"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379508"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379509"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379510"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379511"] = "This fault is caused by 'Output Unicast Frames average value' statistical property crossing threshold level." + self.system_fault_code["F379536"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379537"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379538"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379539"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379540"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379541"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379542"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379543"] = "This fault is caused by 'Output Unicast Frames trend' statistical property crossing threshold level." + self.system_fault_code["F379544"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379545"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379546"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379547"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379548"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379549"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379550"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379551"] = "This fault is caused by 'Output Unicast Frames rate' statistical property crossing threshold level." + self.system_fault_code["F379624"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379625"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379626"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379627"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379628"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379629"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379630"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379631"] = "This fault is caused by 'output f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379640"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379641"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379642"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379643"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379644"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379645"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379646"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379647"] = "This fault is caused by 'output f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379648"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379649"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379650"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379651"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379652"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379653"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379654"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379655"] = "This fault is caused by 'output f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379656"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379657"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379658"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379659"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379660"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379661"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379662"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379663"] = "This fault is caused by 'output f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379664"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379665"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379666"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379667"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379668"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379669"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379670"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379671"] = "This fault is caused by 'output f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379672"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379673"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379674"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379675"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379676"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379677"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379678"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379679"] = "This fault is caused by 'output f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379704"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379705"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379706"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379707"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379708"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379709"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379710"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379711"] = "This fault is caused by 'output f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379712"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379713"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379714"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379715"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379716"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379717"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379718"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379719"] = "This fault is caused by 'output f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379792"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379793"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379794"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379795"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379796"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379797"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379798"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379799"] = "This fault is caused by 'output non f8 lip error current value' statistical property crossing threshold level." + self.system_fault_code["F379808"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379809"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379810"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379811"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379812"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379813"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379814"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379815"] = "This fault is caused by 'output non f8 lip error cumulative' statistical property crossing threshold level." + self.system_fault_code["F379816"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379817"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379818"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379819"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379820"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379821"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379822"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379823"] = "This fault is caused by 'output non f8 lip error periodic' statistical property crossing threshold level." + self.system_fault_code["F379824"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379825"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379826"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379827"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379828"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379829"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379830"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379831"] = "This fault is caused by 'output non f8 lip error minimum value' statistical property crossing threshold level." + self.system_fault_code["F379832"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379833"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379834"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379835"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379836"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379837"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379838"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379839"] = "This fault is caused by 'output non f8 lip error maximum value' statistical property crossing threshold level." + self.system_fault_code["F379840"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379841"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379842"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379843"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379844"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379845"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379846"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379847"] = "This fault is caused by 'output non f8 lip error average value' statistical property crossing threshold level." + self.system_fault_code["F379872"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379873"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379874"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379875"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379876"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379877"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379878"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379879"] = "This fault is caused by 'output non f8 lip error trend' statistical property crossing threshold level." + self.system_fault_code["F379880"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379881"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379882"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379883"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379884"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379885"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379886"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F379887"] = "This fault is caused by 'output non f8 lip error rate' statistical property crossing threshold level." + self.system_fault_code["F381328"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381329"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381330"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381331"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381332"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381333"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381334"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381335"] = "This fault is caused by 'CRC Align Errors current value' statistical property crossing threshold level." + self.system_fault_code["F381360"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381361"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381362"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381363"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381364"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381365"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381366"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381367"] = "This fault is caused by 'CRC Align Errors minimum value' statistical property crossing threshold level." + self.system_fault_code["F381368"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381369"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381370"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381371"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381372"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381373"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381374"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381375"] = "This fault is caused by 'CRC Align Errors maximum value' statistical property crossing threshold level." + self.system_fault_code["F381376"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381377"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381378"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381379"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381380"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381381"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381382"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381383"] = "This fault is caused by 'CRC Align Errors average value' statistical property crossing threshold level." + self.system_fault_code["F381408"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381409"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381410"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381411"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381412"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381413"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381414"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F381415"] = "This fault is caused by 'CRC Align Errors trend' statistical property crossing threshold level." + self.system_fault_code["F384512"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384513"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384514"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384515"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384516"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384517"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384518"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384519"] = "This fault is caused by 'Total v4 32 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F384528"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384529"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384530"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384531"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384532"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384533"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384534"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384535"] = "This fault is caused by 'Total v4 32 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F384536"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384537"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384538"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384539"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384540"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384541"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384542"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384543"] = "This fault is caused by 'Total v4 32 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F384544"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384545"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384546"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384547"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384548"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384549"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384550"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384551"] = "This fault is caused by 'Total v4 32 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F384552"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384553"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384554"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384555"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384556"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384557"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384558"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384559"] = "This fault is caused by 'Total v4 32 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F384560"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384561"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384562"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384563"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384564"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384565"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384566"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384567"] = "This fault is caused by 'Total v4 32 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F384592"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384593"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384594"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384595"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384596"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384597"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384598"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384599"] = "This fault is caused by 'Total v4 32 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F384600"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384601"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384602"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384603"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384604"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384605"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384606"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384607"] = "This fault is caused by 'Total v4 32 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F384680"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384681"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384682"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384683"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384684"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384685"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384686"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384687"] = "This fault is caused by 'Total v4 32 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384696"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384697"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384698"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384699"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384700"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384701"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384702"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384703"] = "This fault is caused by 'Total v4 32 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384704"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384705"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384706"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384707"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384708"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384709"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384710"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384711"] = "This fault is caused by 'Total v4 32 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384712"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384713"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384714"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384715"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384716"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384717"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384718"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384719"] = "This fault is caused by 'Total v4 32 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384720"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384721"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384722"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384723"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384724"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384725"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384726"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384727"] = "This fault is caused by 'Total v4 32 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384728"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384729"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384730"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384731"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384732"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384733"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384734"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384735"] = "This fault is caused by 'Total v4 32 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384760"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384761"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384762"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384763"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384764"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384765"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384766"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384767"] = "This fault is caused by 'Total v4 32 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384768"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384769"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384770"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384771"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384772"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384773"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384774"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384775"] = "This fault is caused by 'Total v4 32 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384848"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384849"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384850"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384851"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384852"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384853"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384854"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384855"] = "This fault is caused by 'Total v4 32 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F384864"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384865"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384866"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384867"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384868"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384869"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384870"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384871"] = "This fault is caused by 'Total v4 32 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F384872"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384873"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384874"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384875"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384876"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384877"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384878"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384879"] = "This fault is caused by 'Total v4 32 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F384880"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384881"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384882"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384883"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384884"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384885"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384886"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384887"] = "This fault is caused by 'Total v4 32 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F384888"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384889"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384890"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384891"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384892"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384893"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384894"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384895"] = "This fault is caused by 'Total v4 32 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F384896"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384897"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384898"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384899"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384900"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384901"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384902"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384903"] = "This fault is caused by 'Total v4 32 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F384928"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384929"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384930"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384931"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384932"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384933"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384934"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384935"] = "This fault is caused by 'Total v4 32 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F384936"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384937"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384938"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384939"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384940"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384941"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384942"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F384943"] = "This fault is caused by 'Total v4 32 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385016"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385017"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385018"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385019"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385020"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385021"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385022"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385023"] = "This fault is caused by 'Total v4 32 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385032"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385033"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385034"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385035"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385036"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385037"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385038"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385039"] = "This fault is caused by 'Total v4 32 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385040"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385041"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385042"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385043"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385044"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385045"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385046"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385047"] = "This fault is caused by 'Total v4 32 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385048"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385049"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385050"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385051"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385052"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385053"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385054"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385055"] = "This fault is caused by 'Total v4 32 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385056"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385057"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385058"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385059"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385060"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385061"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385062"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385063"] = "This fault is caused by 'Total v4 32 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385064"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385065"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385066"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385067"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385068"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385069"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385070"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385071"] = "This fault is caused by 'Total v4 32 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385096"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385097"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385098"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385099"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385100"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385101"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385102"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385103"] = "This fault is caused by 'Total v4 32 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385104"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385105"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385106"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385107"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385108"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385109"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385110"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385111"] = "This fault is caused by 'Total v4 32 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385184"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385185"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385186"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385187"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385188"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385189"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385190"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385191"] = "This fault is caused by 'Total v4 32 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F385200"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385201"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385202"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385203"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385204"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385205"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385206"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385207"] = "This fault is caused by 'Total v4 32 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F385208"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385209"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385210"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385211"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385212"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385213"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385214"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385215"] = "This fault is caused by 'Total v4 32 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F385216"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385217"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385218"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385219"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385220"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385221"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385222"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385223"] = "This fault is caused by 'Total v4 32 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F385224"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385225"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385226"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385227"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385228"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385229"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385230"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385231"] = "This fault is caused by 'Total v4 32 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F385232"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385233"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385234"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385235"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385236"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385237"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385238"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385239"] = "This fault is caused by 'Total v4 32 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F385264"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385265"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385266"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385267"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385268"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385269"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385270"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385271"] = "This fault is caused by 'Total v4 32 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F385272"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385273"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385274"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385275"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385276"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385277"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385278"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385279"] = "This fault is caused by 'Total v4 32 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F385352"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385353"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385354"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385355"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385356"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385357"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385358"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385359"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F385360"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385361"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385362"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385363"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385364"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385365"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385366"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385367"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F385368"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385369"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385370"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385371"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385372"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385373"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385374"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385375"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F385376"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385377"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385378"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385379"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385380"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385381"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385382"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385383"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F385416"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385417"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385418"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385419"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385420"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385421"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385422"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385423"] = "This fault is caused by 'Total v4 32 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F385472"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385473"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385474"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385475"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385476"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385477"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385478"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385479"] = "This fault is caused by 'Total v6 128 Endpoints current value' statistical property crossing threshold level." + self.system_fault_code["F385488"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385489"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385490"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385491"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385492"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385493"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385494"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385495"] = "This fault is caused by 'Total v6 128 Endpoints cumulative' statistical property crossing threshold level." + self.system_fault_code["F385496"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385497"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385498"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385499"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385500"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385501"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385502"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385503"] = "This fault is caused by 'Total v6 128 Endpoints periodic' statistical property crossing threshold level." + self.system_fault_code["F385504"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385505"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385506"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385507"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385508"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385509"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385510"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385511"] = "This fault is caused by 'Total v6 128 Endpoints minimum value' statistical property crossing threshold level." + self.system_fault_code["F385512"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385513"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385514"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385515"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385516"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385517"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385518"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385519"] = "This fault is caused by 'Total v6 128 Endpoints maximum value' statistical property crossing threshold level." + self.system_fault_code["F385520"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385521"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385522"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385523"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385524"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385525"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385526"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385527"] = "This fault is caused by 'Total v6 128 Endpoints average value' statistical property crossing threshold level." + self.system_fault_code["F385552"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385553"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385554"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385555"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385556"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385557"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385558"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385559"] = "This fault is caused by 'Total v6 128 Endpoints trend' statistical property crossing threshold level." + self.system_fault_code["F385560"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385561"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385562"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385563"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385564"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385565"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385566"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385567"] = "This fault is caused by 'Total v6 128 Endpoints rate' statistical property crossing threshold level." + self.system_fault_code["F385640"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385641"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385642"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385643"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385644"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385645"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385646"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385647"] = "This fault is caused by 'Total v6 128 MC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385656"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385657"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385658"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385659"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385660"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385661"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385662"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385663"] = "This fault is caused by 'Total v6 128 MC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385664"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385665"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385666"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385667"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385668"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385669"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385670"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385671"] = "This fault is caused by 'Total v6 128 MC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385672"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385673"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385674"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385675"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385676"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385677"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385678"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385679"] = "This fault is caused by 'Total v6 128 MC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385680"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385681"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385682"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385683"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385684"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385685"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385686"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385687"] = "This fault is caused by 'Total v6 128 MC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385688"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385689"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385690"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385691"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385692"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385693"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385694"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385695"] = "This fault is caused by 'Total v6 128 MC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385720"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385721"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385722"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385723"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385724"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385725"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385726"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385727"] = "This fault is caused by 'Total v6 128 MC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385728"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385729"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385730"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385731"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385732"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385733"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385734"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385735"] = "This fault is caused by 'Total v6 128 MC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385808"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385809"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385810"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385811"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385812"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385813"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385814"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385815"] = "This fault is caused by 'Total v6 128 Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385824"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385825"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385826"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385827"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385828"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385829"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385830"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385831"] = "This fault is caused by 'Total v6 128 Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385832"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385833"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385834"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385835"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385836"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385837"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385838"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385839"] = "This fault is caused by 'Total v6 128 Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F385840"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385841"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385842"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385843"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385844"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385845"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385846"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385847"] = "This fault is caused by 'Total v6 128 Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F385848"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385849"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385850"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385851"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385852"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385853"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385854"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385855"] = "This fault is caused by 'Total v6 128 Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F385856"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385857"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385858"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385859"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385860"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385861"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385862"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385863"] = "This fault is caused by 'Total v6 128 Routes average value' statistical property crossing threshold level." + self.system_fault_code["F385888"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385889"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385890"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385891"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385892"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385893"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385894"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385895"] = "This fault is caused by 'Total v6 128 Routes trend' statistical property crossing threshold level." + self.system_fault_code["F385896"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385897"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385898"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385899"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385900"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385901"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385902"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385903"] = "This fault is caused by 'Total v6 128 Routes rate' statistical property crossing threshold level." + self.system_fault_code["F385976"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385977"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385978"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385979"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385980"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385981"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385982"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385983"] = "This fault is caused by 'Total v6 128 UC Routes current value' statistical property crossing threshold level." + self.system_fault_code["F385992"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385993"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385994"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385995"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385996"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385997"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385998"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F385999"] = "This fault is caused by 'Total v6 128 UC Routes cumulative' statistical property crossing threshold level." + self.system_fault_code["F386000"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386001"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386002"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386003"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386004"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386005"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386006"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386007"] = "This fault is caused by 'Total v6 128 UC Routes periodic' statistical property crossing threshold level." + self.system_fault_code["F386008"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386009"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386010"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386011"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386012"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386013"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386014"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386015"] = "This fault is caused by 'Total v6 128 UC Routes minimum value' statistical property crossing threshold level." + self.system_fault_code["F386016"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386017"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386018"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386019"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386020"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386021"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386022"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386023"] = "This fault is caused by 'Total v6 128 UC Routes maximum value' statistical property crossing threshold level." + self.system_fault_code["F386024"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386025"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386026"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386027"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386028"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386029"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386030"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386031"] = "This fault is caused by 'Total v6 128 UC Routes average value' statistical property crossing threshold level." + self.system_fault_code["F386056"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386057"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386058"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386059"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386060"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386061"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386062"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386063"] = "This fault is caused by 'Total v6 128 UC Routes trend' statistical property crossing threshold level." + self.system_fault_code["F386064"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386065"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386066"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386067"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386068"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386069"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386070"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386071"] = "This fault is caused by 'Total v6 128 UC Routes rate' statistical property crossing threshold level." + self.system_fault_code["F386144"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386145"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386146"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386147"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386148"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386149"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386150"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386151"] = "This fault is caused by 'Total v6 128 Routes capacity current value' statistical property crossing threshold level." + self.system_fault_code["F386160"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386161"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386162"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386163"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386164"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386165"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386166"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386167"] = "This fault is caused by 'Total v6 128 Routes capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F386168"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386169"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386170"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386171"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386172"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386173"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386174"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386175"] = "This fault is caused by 'Total v6 128 Routes capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F386176"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386177"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386178"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386179"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386180"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386181"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386182"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386183"] = "This fault is caused by 'Total v6 128 Routes capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F386184"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386185"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386186"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386187"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386188"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386189"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386190"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386191"] = "This fault is caused by 'Total v6 128 Routes capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F386192"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386193"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386194"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386195"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386196"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386197"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386198"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386199"] = "This fault is caused by 'Total v6 128 Routes capacity average value' statistical property crossing threshold level." + self.system_fault_code["F386224"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386225"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386226"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386227"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386228"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386229"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386230"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386231"] = "This fault is caused by 'Total v6 128 Routes capacity trend' statistical property crossing threshold level." + self.system_fault_code["F386232"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386233"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386234"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386235"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386236"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386237"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386238"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386239"] = "This fault is caused by 'Total v6 128 Routes capacity rate' statistical property crossing threshold level." + self.system_fault_code["F386312"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386313"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386314"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386315"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386316"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386317"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386318"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386319"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage current value' statistical property crossing threshold" + self.system_fault_code["F386320"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386321"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386322"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386323"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386324"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386325"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386326"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386327"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage minimum value' statistical property crossing threshold" + self.system_fault_code["F386328"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386329"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386330"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386331"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386332"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386333"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386334"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386335"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage maximum value' statistical property crossing threshold" + self.system_fault_code["F386336"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386337"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386338"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386339"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386340"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386341"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386342"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386343"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage average value' statistical property crossing threshold" + self.system_fault_code["F386376"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386377"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386378"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386379"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386380"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386381"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386382"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386383"] = "This fault is caused by 'Total v6 128 L3 entries usage percentage trend' statistical property crossing threshold level." + self.system_fault_code["F386728"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386729"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386730"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386731"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386732"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386733"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386734"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386735"] = "This fault is caused by 'tcam LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386744"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386745"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386746"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386747"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386748"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386749"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386750"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386751"] = "This fault is caused by 'tcam LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386752"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386753"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386754"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386755"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386756"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386757"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386758"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386759"] = "This fault is caused by 'tcam LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386760"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386761"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386762"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386763"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386764"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386765"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386766"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386767"] = "This fault is caused by 'tcam LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386768"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386769"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386770"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386771"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386772"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386773"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386774"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386775"] = "This fault is caused by 'tcam LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386776"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386777"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386778"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386779"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386780"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386781"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386782"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386783"] = "This fault is caused by 'tcam LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386808"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386809"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386810"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386811"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386812"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386813"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386814"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386815"] = "This fault is caused by 'tcam LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386816"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386817"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386818"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386819"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386820"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386821"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386822"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386823"] = "This fault is caused by 'tcam LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386896"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386897"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386898"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386899"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386900"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386901"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386902"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386903"] = "This fault is caused by 'Total L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F386912"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386913"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386914"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386915"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386916"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386917"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386918"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386919"] = "This fault is caused by 'Total L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F386920"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386921"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386922"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386923"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386924"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386925"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386926"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386927"] = "This fault is caused by 'Total L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F386928"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386929"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386930"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386931"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386932"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386933"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386934"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386935"] = "This fault is caused by 'Total L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F386936"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386937"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386938"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386939"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386940"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386941"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386942"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386943"] = "This fault is caused by 'Total L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F386944"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386945"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386946"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386947"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386948"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386949"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386950"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386951"] = "This fault is caused by 'Total L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F386976"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386977"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386978"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386979"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386980"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386981"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386982"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386983"] = "This fault is caused by 'Total L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F386984"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386985"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386986"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386987"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386988"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386989"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386990"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F386991"] = "This fault is caused by 'Total L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387064"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387065"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387066"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387067"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387068"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387069"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387070"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387071"] = "This fault is caused by 'v4 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387080"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387081"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387082"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387083"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387084"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387085"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387086"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387087"] = "This fault is caused by 'v4 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387088"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387089"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387090"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387091"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387092"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387093"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387094"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387095"] = "This fault is caused by 'v4 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387096"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387097"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387098"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387099"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387100"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387101"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387102"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387103"] = "This fault is caused by 'v4 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387104"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387105"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387106"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387107"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387108"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387109"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387110"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387111"] = "This fault is caused by 'v4 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387112"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387113"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387114"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387115"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387116"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387117"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387118"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387119"] = "This fault is caused by 'v4 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387144"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387145"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387146"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387147"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387148"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387149"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387150"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387151"] = "This fault is caused by 'v4 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387152"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387153"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387154"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387155"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387156"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387157"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387158"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387159"] = "This fault is caused by 'v4 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387232"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387233"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387234"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387235"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387236"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387237"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387238"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387239"] = "This fault is caused by 'v6 L3 LPM current value' statistical property crossing threshold level." + self.system_fault_code["F387248"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387249"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387250"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387251"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387252"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387253"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387254"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387255"] = "This fault is caused by 'v6 L3 LPM cumulative' statistical property crossing threshold level." + self.system_fault_code["F387256"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387257"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387258"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387259"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387260"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387261"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387262"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387263"] = "This fault is caused by 'v6 L3 LPM periodic' statistical property crossing threshold level." + self.system_fault_code["F387264"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387265"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387266"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387267"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387268"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387269"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387270"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387271"] = "This fault is caused by 'v6 L3 LPM minimum value' statistical property crossing threshold level." + self.system_fault_code["F387272"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387273"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387274"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387275"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387276"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387277"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387278"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387279"] = "This fault is caused by 'v6 L3 LPM maximum value' statistical property crossing threshold level." + self.system_fault_code["F387280"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387281"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387282"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387283"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387284"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387285"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387286"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387287"] = "This fault is caused by 'v6 L3 LPM average value' statistical property crossing threshold level." + self.system_fault_code["F387312"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387313"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387314"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387315"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387316"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387317"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387318"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387319"] = "This fault is caused by 'v6 L3 LPM trend' statistical property crossing threshold level." + self.system_fault_code["F387320"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387321"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387322"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387323"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387324"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387325"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387326"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387327"] = "This fault is caused by 'v6 L3 LPM rate' statistical property crossing threshold level." + self.system_fault_code["F387400"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387401"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387402"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387403"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387404"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387405"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387406"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387407"] = "This fault is caused by 'L3 lpm capacity current value' statistical property crossing threshold level." + self.system_fault_code["F387416"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387417"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387418"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387419"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387420"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387421"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387422"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387423"] = "This fault is caused by 'L3 lpm capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F387424"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387425"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387426"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387427"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387428"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387429"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387430"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387431"] = "This fault is caused by 'L3 lpm capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F387432"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387433"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387434"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387435"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387436"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387437"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387438"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387439"] = "This fault is caused by 'L3 lpm capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F387440"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387441"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387442"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387443"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387444"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387445"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387446"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387447"] = "This fault is caused by 'L3 lpm capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F387448"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387449"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387450"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387451"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387452"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387453"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387454"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387455"] = "This fault is caused by 'L3 lpm capacity average value' statistical property crossing threshold level." + self.system_fault_code["F387480"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387481"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387482"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387483"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387484"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387485"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387486"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387487"] = "This fault is caused by 'L3 lpm capacity trend' statistical property crossing threshold level." + self.system_fault_code["F387488"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387489"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387490"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387491"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387492"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387493"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387494"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387495"] = "This fault is caused by 'L3 lpm capacity rate' statistical property crossing threshold level." + self.system_fault_code["F387952"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387953"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387954"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387955"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387956"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387957"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387958"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387959"] = "This fault is caused by 'PG label entries usage current value' statistical property crossing threshold level." + self.system_fault_code["F387960"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387961"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387962"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387963"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387964"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387965"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387966"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387967"] = "This fault is caused by 'PG label entries usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F387968"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387969"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387970"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387971"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387972"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387973"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387974"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387975"] = "This fault is caused by 'PG label entries usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F387976"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387977"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387978"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387979"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387980"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387981"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387982"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F387983"] = "This fault is caused by 'PG label entries usage average value' statistical property crossing threshold level." + self.system_fault_code["F388016"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388017"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388018"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388019"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388020"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388021"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388022"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388023"] = "This fault is caused by 'PG label entries usage trend' statistical property crossing threshold level." + self.system_fault_code["F388072"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388073"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388074"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388075"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388076"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388077"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388078"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388079"] = "This fault is caused by 'PG label Usage capacity current value' statistical property crossing threshold level." + self.system_fault_code["F388088"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388089"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388090"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388091"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388092"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388093"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388094"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388095"] = "This fault is caused by 'PG label Usage capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F388096"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388097"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388098"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388099"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388100"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388101"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388102"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388103"] = "This fault is caused by 'PG label Usage capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F388104"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388105"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388106"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388107"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388108"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388109"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388110"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388111"] = "This fault is caused by 'PG label Usage capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F388112"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388113"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388114"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388115"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388116"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388117"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388118"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388119"] = "This fault is caused by 'PG label Usage capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F388120"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388121"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388122"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388123"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388124"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388125"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388126"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388127"] = "This fault is caused by 'PG label Usage capacity average value' statistical property crossing threshold level." + self.system_fault_code["F388152"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388153"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388154"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388155"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388156"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388157"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388158"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388159"] = "This fault is caused by 'PG label Usage capacity trend' statistical property crossing threshold level." + self.system_fault_code["F388160"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388161"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388162"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388163"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388164"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388165"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388166"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388167"] = "This fault is caused by 'PG label Usage capacity rate' statistical property crossing threshold level." + self.system_fault_code["F388240"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388241"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388242"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388243"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388244"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388245"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388246"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388247"] = "This fault is caused by 'PG label Usage current value' statistical property crossing threshold level." + self.system_fault_code["F388256"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388257"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388258"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388259"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388260"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388261"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388262"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388263"] = "This fault is caused by 'PG label Usage cumulative' statistical property crossing threshold level." + self.system_fault_code["F388264"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388265"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388266"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388267"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388268"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388269"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388270"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388271"] = "This fault is caused by 'PG label Usage periodic' statistical property crossing threshold level." + self.system_fault_code["F388272"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388273"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388274"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388275"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388276"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388277"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388278"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388279"] = "This fault is caused by 'PG label Usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F388280"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388281"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388282"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388283"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388284"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388285"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388286"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388287"] = "This fault is caused by 'PG label Usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F388288"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388289"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388290"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388291"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388292"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388293"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388294"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388295"] = "This fault is caused by 'PG label Usage average value' statistical property crossing threshold level." + self.system_fault_code["F388320"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388321"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388322"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388323"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388324"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388325"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388326"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388327"] = "This fault is caused by 'PG label Usage trend' statistical property crossing threshold level." + self.system_fault_code["F388328"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388329"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388330"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388331"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388332"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388333"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388334"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F388335"] = "This fault is caused by 'PG label Usage rate' statistical property crossing threshold level." + self.system_fault_code["F392544"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392545"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392546"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392547"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392548"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392549"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392550"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392551"] = "This fault is caused by 'Number of flaps current value' statistical property crossing threshold level." + self.system_fault_code["F392560"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392561"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392562"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392563"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392564"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392565"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392566"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392567"] = "This fault is caused by 'Number of flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F392568"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392569"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392570"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392571"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392572"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392573"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392574"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392575"] = "This fault is caused by 'Number of flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F392576"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392577"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392578"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392579"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392580"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392581"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392582"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392583"] = "This fault is caused by 'Number of flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F392584"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392585"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392586"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392587"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392588"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392589"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392590"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392591"] = "This fault is caused by 'Number of flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F392592"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392593"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392594"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392595"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392596"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392597"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392598"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392599"] = "This fault is caused by 'Number of flaps average value' statistical property crossing threshold level." + self.system_fault_code["F392624"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392625"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392626"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392627"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392628"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392629"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392630"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392631"] = "This fault is caused by 'Number of flaps trend' statistical property crossing threshold level." + self.system_fault_code["F392632"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392633"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392634"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392635"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392636"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392637"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392638"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392639"] = "This fault is caused by 'Number of flaps rate' statistical property crossing threshold level." + self.system_fault_code["F392712"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392713"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392714"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392715"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392716"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392717"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392718"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392719"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F392728"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392729"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392730"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392731"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392732"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392733"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392734"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392735"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F392736"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392737"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392738"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392739"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392740"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392741"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392742"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392743"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F392744"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392745"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392746"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392747"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392748"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392749"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392750"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392751"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F392752"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392753"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392754"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392755"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392756"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392757"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392758"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392759"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F392760"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392761"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392762"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392763"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392764"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392765"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392766"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392767"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F392792"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392793"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392794"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392795"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392796"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392797"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392798"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392799"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F392800"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392801"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392802"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392803"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392804"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392805"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392806"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392807"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F392880"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392881"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392882"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392883"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392884"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392885"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392886"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392887"] = "This fault is caused by 'Number of Partner PDU timeout events rate current value' statistical property crossing threshold" + self.system_fault_code["F392888"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392889"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392890"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392891"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392892"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392893"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392894"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392895"] = "This fault is caused by 'Number of Partner PDU timeout events rate minimum value' statistical property crossing threshold" + self.system_fault_code["F392896"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392897"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392898"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392899"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392900"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392901"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392902"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392903"] = "This fault is caused by 'Number of Partner PDU timeout events rate maximum value' statistical property crossing threshold" + self.system_fault_code["F392904"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392905"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392906"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392907"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392908"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392909"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392910"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392911"] = "This fault is caused by 'Number of Partner PDU timeout events rate average value' statistical property crossing threshold" + self.system_fault_code["F392944"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392945"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392946"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392947"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392948"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392949"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392950"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F392951"] = "This fault is caused by 'Number of Partner PDU timeout events rate trend' statistical property crossing threshold level." + self.system_fault_code["F393000"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393001"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393002"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393003"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393004"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393005"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393006"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393007"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393016"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393017"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393018"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393019"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393020"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393021"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393022"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393023"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393024"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393025"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393026"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393027"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393028"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393029"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393030"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393031"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393032"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393033"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393034"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393035"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393036"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393037"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393038"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393039"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393040"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393041"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393042"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393043"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393044"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393045"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393046"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393047"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393048"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393049"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393050"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393051"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393052"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393053"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393054"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393055"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393080"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393081"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393082"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393083"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393084"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393085"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393086"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393087"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393088"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393089"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393090"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393091"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393092"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393093"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393094"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393095"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393168"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393169"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393170"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393171"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393172"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393173"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393174"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393175"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393176"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393177"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393178"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393179"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393180"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393181"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393182"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393183"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393184"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393185"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393186"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393187"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393188"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393189"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393190"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393191"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393192"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393193"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393194"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393195"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393196"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393197"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393198"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393199"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393232"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393233"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393234"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393235"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393236"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393237"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393238"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393239"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393288"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393289"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393290"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393291"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393292"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393293"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393294"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393295"] = "This fault is caused by 'Number of Partner PDU timeout events current value' statistical property crossing threshold level." + self.system_fault_code["F393304"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393305"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393306"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393307"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393308"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393309"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393310"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393311"] = "This fault is caused by 'Number of Partner PDU timeout events cumulative' statistical property crossing threshold level." + self.system_fault_code["F393312"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393313"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393314"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393315"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393316"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393317"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393318"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393319"] = "This fault is caused by 'Number of Partner PDU timeout events periodic' statistical property crossing threshold level." + self.system_fault_code["F393320"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393321"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393322"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393323"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393324"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393325"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393326"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393327"] = "This fault is caused by 'Number of Partner PDU timeout events minimum value' statistical property crossing threshold level." + self.system_fault_code["F393328"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393329"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393330"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393331"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393332"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393333"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393334"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393335"] = "This fault is caused by 'Number of Partner PDU timeout events maximum value' statistical property crossing threshold level." + self.system_fault_code["F393336"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393337"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393338"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393339"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393340"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393341"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393342"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393343"] = "This fault is caused by 'Number of Partner PDU timeout events average value' statistical property crossing threshold level." + self.system_fault_code["F393368"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393369"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393370"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393371"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393372"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393373"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393374"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393375"] = "This fault is caused by 'Number of Partner PDU timeout events trend' statistical property crossing threshold level." + self.system_fault_code["F393376"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393377"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393378"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393379"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393380"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393381"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393382"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393383"] = "This fault is caused by 'Number of Partner PDU timeout events rate' statistical property crossing threshold level." + self.system_fault_code["F393456"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393457"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393458"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393459"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393460"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393461"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393462"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393463"] = "This fault is caused by 'Number of lldp PDU packets received current value' statistical property crossing threshold level." + self.system_fault_code["F393472"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393473"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393474"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393475"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393476"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393477"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393478"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393479"] = "This fault is caused by 'Number of lldp PDU packets received cumulative' statistical property crossing threshold level." + self.system_fault_code["F393480"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393481"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393482"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393483"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393484"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393485"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393486"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393487"] = "This fault is caused by 'Number of lldp PDU packets received periodic' statistical property crossing threshold level." + self.system_fault_code["F393488"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393489"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393490"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393491"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393492"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393493"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393494"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393495"] = "This fault is caused by 'Number of lldp PDU packets received minimum value' statistical property crossing threshold level." + self.system_fault_code["F393496"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393497"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393498"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393499"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393500"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393501"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393502"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393503"] = "This fault is caused by 'Number of lldp PDU packets received maximum value' statistical property crossing threshold level." + self.system_fault_code["F393504"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393505"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393506"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393507"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393508"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393509"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393510"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393511"] = "This fault is caused by 'Number of lldp PDU packets received average value' statistical property crossing threshold level." + self.system_fault_code["F393536"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393537"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393538"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393539"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393540"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393541"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393542"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393543"] = "This fault is caused by 'Number of lldp PDU packets received trend' statistical property crossing threshold level." + self.system_fault_code["F393544"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393545"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393546"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393547"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393548"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393549"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393550"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393551"] = "This fault is caused by 'Number of lldp PDU packets received rate' statistical property crossing threshold level." + self.system_fault_code["F393624"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393625"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393626"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393627"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393628"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393629"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393630"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393631"] = "This fault is caused by 'Number of lldp PDU packets received rate current value' statistical property crossing threshold" + self.system_fault_code["F393632"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393633"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393634"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393635"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393636"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393637"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393638"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393639"] = "This fault is caused by 'Number of lldp PDU packets received rate minimum value' statistical property crossing threshold" + self.system_fault_code["F393640"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393641"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393642"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393643"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393644"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393645"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393646"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393647"] = "This fault is caused by 'Number of lldp PDU packets received rate maximum value' statistical property crossing threshold" + self.system_fault_code["F393648"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393649"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393650"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393651"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393652"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393653"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393654"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393655"] = "This fault is caused by 'Number of lldp PDU packets received rate average value' statistical property crossing threshold" + self.system_fault_code["F393688"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393689"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393690"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393691"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393692"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393693"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393694"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393695"] = "This fault is caused by 'Number of lldp PDU packets received rate trend' statistical property crossing threshold level." + self.system_fault_code["F393744"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393745"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393746"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393747"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393748"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393749"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393750"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393751"] = "This fault is caused by 'Number of lldp PDU packets sent current value' statistical property crossing threshold level." + self.system_fault_code["F393760"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393761"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393762"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393763"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393764"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393765"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393766"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393767"] = "This fault is caused by 'Number of lldp PDU packets sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F393768"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393769"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393770"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393771"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393772"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393773"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393774"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393775"] = "This fault is caused by 'Number of lldp PDU packets sent periodic' statistical property crossing threshold level." + self.system_fault_code["F393776"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393777"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393778"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393779"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393780"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393781"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393782"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393783"] = "This fault is caused by 'Number of lldp PDU packets sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F393784"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393785"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393786"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393787"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393788"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393789"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393790"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393791"] = "This fault is caused by 'Number of lldp PDU packets sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F393792"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393793"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393794"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393795"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393796"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393797"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393798"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393799"] = "This fault is caused by 'Number of lldp PDU packets sent average value' statistical property crossing threshold level." + self.system_fault_code["F393824"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393825"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393826"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393827"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393828"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393829"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393830"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393831"] = "This fault is caused by 'Number of lldp PDU packets sent trend' statistical property crossing threshold level." + self.system_fault_code["F393832"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393833"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393834"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393835"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393836"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393837"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393838"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393839"] = "This fault is caused by 'Number of lldp PDU packets sent rate' statistical property crossing threshold level." + self.system_fault_code["F393912"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393913"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393914"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393915"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393916"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393917"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393918"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393919"] = "This fault is caused by 'Number of lldp PDU packets sent rate current value' statistical property crossing threshold level." + self.system_fault_code["F393920"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393921"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393922"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393923"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393924"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393925"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393926"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393927"] = "This fault is caused by 'Number of lldp PDU packets sent rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F393928"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393929"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393930"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393931"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393932"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393933"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393934"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393935"] = "This fault is caused by 'Number of lldp PDU packets sent rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F393936"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393937"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393938"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393939"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393940"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393941"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393942"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393943"] = "This fault is caused by 'Number of lldp PDU packets sent rate average value' statistical property crossing threshold level." + self.system_fault_code["F393976"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393977"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393978"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393979"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393980"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393981"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393982"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F393983"] = "This fault is caused by 'Number of lldp PDU packets sent rate trend' statistical property crossing threshold level." + self.system_fault_code["F394096"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394097"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394098"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394099"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394100"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394101"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394102"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394103"] = "This fault is caused by 'Corrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394112"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394113"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394114"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394115"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394116"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394117"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394118"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394119"] = "This fault is caused by 'Corrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394120"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394121"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394122"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394123"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394124"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394125"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394126"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394127"] = "This fault is caused by 'Corrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394128"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394129"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394130"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394131"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394132"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394133"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394134"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394135"] = "This fault is caused by 'Corrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394136"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394137"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394138"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394139"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394140"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394141"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394142"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394143"] = "This fault is caused by 'Corrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394144"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394145"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394146"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394147"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394148"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394149"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394150"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394151"] = "This fault is caused by 'Corrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394176"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394177"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394178"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394179"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394180"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394181"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394182"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394183"] = "This fault is caused by 'Corrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394184"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394185"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394186"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394187"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394188"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394189"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394190"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394191"] = "This fault is caused by 'Corrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394264"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394265"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394266"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394267"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394268"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394269"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394270"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394271"] = "This fault is caused by 'Uncorrected counters current value' statistical property crossing threshold level." + self.system_fault_code["F394280"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394281"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394282"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394283"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394284"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394285"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394286"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394287"] = "This fault is caused by 'Uncorrected counters cumulative' statistical property crossing threshold level." + self.system_fault_code["F394288"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394289"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394290"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394291"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394292"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394293"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394294"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394295"] = "This fault is caused by 'Uncorrected counters periodic' statistical property crossing threshold level." + self.system_fault_code["F394296"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394297"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394298"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394299"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394300"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394301"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394302"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394303"] = "This fault is caused by 'Uncorrected counters minimum value' statistical property crossing threshold level." + self.system_fault_code["F394304"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394305"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394306"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394307"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394308"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394309"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394310"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394311"] = "This fault is caused by 'Uncorrected counters maximum value' statistical property crossing threshold level." + self.system_fault_code["F394312"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394313"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394314"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394315"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394316"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394317"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394318"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394319"] = "This fault is caused by 'Uncorrected counters average value' statistical property crossing threshold level." + self.system_fault_code["F394344"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394345"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394346"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394347"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394348"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394349"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394350"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394351"] = "This fault is caused by 'Uncorrected counters trend' statistical property crossing threshold level." + self.system_fault_code["F394352"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394353"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394354"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394355"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394356"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394357"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394358"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394359"] = "This fault is caused by 'Uncorrected counters rate' statistical property crossing threshold level." + self.system_fault_code["F394480"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394481"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394482"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394483"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394484"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394485"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394486"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394487"] = "This fault is caused by 'CRC Align Errored Packets current value' statistical property crossing threshold level." + self.system_fault_code["F394496"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394497"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394498"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394499"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394500"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394501"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394502"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394503"] = "This fault is caused by 'CRC Align Errored Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F394504"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394505"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394506"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394507"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394508"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394509"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394510"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394511"] = "This fault is caused by 'CRC Align Errored Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F394512"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394513"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394514"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394515"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394516"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394517"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394518"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394519"] = "This fault is caused by 'CRC Align Errored Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F394520"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394521"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394522"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394523"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394524"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394525"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394526"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394527"] = "This fault is caused by 'CRC Align Errored Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F394528"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394529"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394530"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394531"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394532"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394533"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394534"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394535"] = "This fault is caused by 'CRC Align Errored Packets average value' statistical property crossing threshold level." + self.system_fault_code["F394560"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394561"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394562"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394563"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394564"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394565"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394566"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394567"] = "This fault is caused by 'CRC Align Errored Packets trend' statistical property crossing threshold level." + self.system_fault_code["F394568"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394569"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394570"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394571"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394572"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394573"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394574"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394575"] = "This fault is caused by 'CRC Align Errored Packets rate' statistical property crossing threshold level." + self.system_fault_code["F394648"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394649"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394650"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394651"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394652"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394653"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394654"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394655"] = "This fault is caused by 'CRC Align Errored Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F394656"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394657"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394658"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394659"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394660"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394661"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394662"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394663"] = "This fault is caused by 'CRC Align Errored Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F394664"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394665"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394666"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394667"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394668"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394669"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394670"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394671"] = "This fault is caused by 'CRC Align Errored Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F394672"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394673"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394674"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394675"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394676"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394677"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394678"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394679"] = "This fault is caused by 'CRC Align Errored Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F394712"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394713"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394714"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394715"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394716"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394717"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394718"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F394719"] = "This fault is caused by 'CRC Align Errored Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F401296"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401297"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401298"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401299"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401300"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401301"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401302"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401303"] = "This fault is caused by 'CSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F401312"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401313"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401314"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401315"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401316"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401317"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401318"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401319"] = "This fault is caused by 'CSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401320"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401321"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401322"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401323"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401324"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401325"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401326"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401327"] = "This fault is caused by 'CSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401328"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401329"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401330"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401331"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401332"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401333"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401334"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401335"] = "This fault is caused by 'CSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401336"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401337"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401338"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401339"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401340"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401341"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401342"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401343"] = "This fault is caused by 'CSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401344"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401345"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401346"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401347"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401348"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401349"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401350"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401351"] = "This fault is caused by 'CSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F401376"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401377"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401378"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401379"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401380"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401381"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401382"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401383"] = "This fault is caused by 'CSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F401384"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401385"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401386"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401387"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401388"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401389"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401390"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401391"] = "This fault is caused by 'CSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F401464"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401465"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401466"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401467"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401468"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401469"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401470"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401471"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F401480"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401481"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401482"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401483"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401484"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401485"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401486"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401487"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F401488"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401489"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401490"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401491"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401492"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401493"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401494"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401495"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F401496"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401497"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401498"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401499"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401500"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401501"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401502"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401503"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F401504"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401505"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401506"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401507"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401508"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401509"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401510"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401511"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F401512"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401513"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401514"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401515"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401516"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401517"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401518"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401519"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F401544"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401545"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401546"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401547"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401548"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401549"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401550"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401551"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F401552"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401553"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401554"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401555"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401556"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401557"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401558"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401559"] = "This fault is caused by 'CSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F401632"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401633"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401634"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401635"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401636"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401637"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401638"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401639"] = "This fault is caused by 'CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401648"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401649"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401650"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401651"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401652"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401653"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401654"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401655"] = "This fault is caused by 'CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401656"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401657"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401658"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401659"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401660"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401661"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401662"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401663"] = "This fault is caused by 'CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401664"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401665"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401666"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401667"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401668"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401669"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401670"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401671"] = "This fault is caused by 'CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F401672"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401673"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401674"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401675"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401676"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401677"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401678"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401679"] = "This fault is caused by 'CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F401680"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401681"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401682"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401683"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401684"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401685"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401686"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401687"] = "This fault is caused by 'CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F401712"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401713"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401714"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401715"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401716"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401717"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401718"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401719"] = "This fault is caused by 'CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F401720"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401721"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401722"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401723"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401724"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401725"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401726"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401727"] = "This fault is caused by 'CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F401800"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401801"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401802"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401803"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401804"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401805"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401806"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401807"] = "This fault is caused by 'CSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F401816"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401817"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401818"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401819"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401820"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401821"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401822"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401823"] = "This fault is caused by 'CSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F401824"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401825"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401826"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401827"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401828"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401829"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401830"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401831"] = "This fault is caused by 'CSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F401832"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401833"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401834"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401835"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401836"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401837"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401838"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401839"] = "This fault is caused by 'CSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F401840"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401841"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401842"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401843"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401844"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401845"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401846"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401847"] = "This fault is caused by 'CSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F401848"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401849"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401850"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401851"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401852"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401853"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401854"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401855"] = "This fault is caused by 'CSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F401880"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401881"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401882"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401883"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401884"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401885"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401886"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401887"] = "This fault is caused by 'CSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F401888"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401889"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401890"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401891"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401892"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401893"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401894"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401895"] = "This fault is caused by 'CSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F401968"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401969"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401970"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401971"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401972"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401973"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401974"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401975"] = "This fault is caused by 'Fast CSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F401984"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401985"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401986"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401987"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401988"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401989"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401990"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401991"] = "This fault is caused by 'Fast CSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F401992"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401993"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401994"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401995"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401996"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401997"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401998"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F401999"] = "This fault is caused by 'Fast CSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402000"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402001"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402002"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402003"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402004"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402005"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402006"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402007"] = "This fault is caused by 'Fast CSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402008"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402009"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402010"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402011"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402012"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402013"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402014"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402015"] = "This fault is caused by 'Fast CSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402016"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402017"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402018"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402019"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402020"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402021"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402022"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402023"] = "This fault is caused by 'Fast CSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402048"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402049"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402050"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402051"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402052"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402053"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402054"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402055"] = "This fault is caused by 'Fast CSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402056"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402057"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402058"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402059"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402060"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402061"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402062"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402063"] = "This fault is caused by 'Fast CSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402136"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402137"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402138"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402139"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402140"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402141"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402142"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402143"] = "This fault is caused by 'LAN IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F402152"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402153"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402154"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402155"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402156"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402157"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402158"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402159"] = "This fault is caused by 'LAN IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402160"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402161"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402162"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402163"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402164"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402165"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402166"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402167"] = "This fault is caused by 'LAN IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402168"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402169"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402170"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402171"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402172"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402173"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402174"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402175"] = "This fault is caused by 'LAN IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402176"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402177"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402178"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402179"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402180"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402181"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402182"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402183"] = "This fault is caused by 'LAN IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402184"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402185"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402186"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402187"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402188"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402189"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402190"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402191"] = "This fault is caused by 'LAN IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F402216"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402217"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402218"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402219"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402220"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402221"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402222"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402223"] = "This fault is caused by 'LAN IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402224"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402225"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402226"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402227"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402228"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402229"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402230"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402231"] = "This fault is caused by 'LAN IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402304"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402305"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402306"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402307"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402308"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402309"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402310"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402311"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F402320"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402321"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402322"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402323"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402324"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402325"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402326"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402327"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402328"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402329"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402330"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402331"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402332"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402333"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402334"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402335"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402336"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402337"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402338"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402339"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402340"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402341"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402342"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402343"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F402344"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402345"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402346"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402347"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402348"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402349"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402350"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402351"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F402352"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402353"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402354"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402355"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402356"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402357"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402358"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402359"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F402384"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402385"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402386"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402387"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402388"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402389"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402390"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402391"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F402392"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402393"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402394"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402395"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402396"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402397"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402398"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402399"] = "This fault is caused by 'LAN IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F402472"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402473"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402474"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402475"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402476"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402477"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402478"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402479"] = "This fault is caused by 'LAN IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F402488"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402489"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402490"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402491"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402492"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402493"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402494"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402495"] = "This fault is caused by 'LAN IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F402496"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402497"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402498"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402499"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402500"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402501"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402502"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402503"] = "This fault is caused by 'LAN IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F402504"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402505"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402506"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402507"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402508"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402509"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402510"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402511"] = "This fault is caused by 'LAN IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F402512"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402513"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402514"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402515"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402516"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402517"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402518"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402519"] = "This fault is caused by 'LAN IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F402520"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402521"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402522"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402523"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402524"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402525"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402526"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402527"] = "This fault is caused by 'LAN IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F402552"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402553"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402554"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402555"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402556"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402557"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402558"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402559"] = "This fault is caused by 'LAN IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F402560"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402561"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402562"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402563"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402564"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402565"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402566"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402567"] = "This fault is caused by 'LAN IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F402640"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402641"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402642"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402643"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402644"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402645"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402646"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402647"] = "This fault is caused by 'LAN IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F402656"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402657"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402658"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402659"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402660"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402661"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402662"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402663"] = "This fault is caused by 'LAN IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F402664"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402665"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402666"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402667"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402668"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402669"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402670"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402671"] = "This fault is caused by 'LAN IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F402672"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402673"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402674"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402675"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402676"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402677"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402678"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402679"] = "This fault is caused by 'LAN IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F402680"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402681"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402682"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402683"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402684"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402685"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402686"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402687"] = "This fault is caused by 'LAN IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F402688"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402689"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402690"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402691"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402692"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402693"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402694"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402695"] = "This fault is caused by 'LAN IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F402720"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402721"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402722"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402723"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402724"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402725"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402726"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402727"] = "This fault is caused by 'LAN IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F402728"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402729"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402730"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402731"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402732"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402733"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402734"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402735"] = "This fault is caused by 'LAN IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F402808"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402809"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402810"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402811"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402812"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402813"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402814"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402815"] = "This fault is caused by 'LSP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F402824"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402825"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402826"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402827"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402828"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402829"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402830"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402831"] = "This fault is caused by 'LSP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402832"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402833"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402834"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402835"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402836"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402837"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402838"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402839"] = "This fault is caused by 'LSP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F402840"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402841"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402842"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402843"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402844"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402845"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402846"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402847"] = "This fault is caused by 'LSP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F402848"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402849"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402850"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402851"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402852"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402853"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402854"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402855"] = "This fault is caused by 'LSP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F402856"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402857"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402858"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402859"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402860"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402861"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402862"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402863"] = "This fault is caused by 'LSP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F402888"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402889"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402890"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402891"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402892"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402893"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402894"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402895"] = "This fault is caused by 'LSP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F402896"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402897"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402898"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402899"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402900"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402901"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402902"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402903"] = "This fault is caused by 'LSP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F402976"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402977"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402978"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402979"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402980"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402981"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402982"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402983"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F402992"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402993"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402994"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402995"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402996"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402997"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402998"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F402999"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403000"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403001"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403002"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403003"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403004"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403005"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403006"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403007"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403008"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403009"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403010"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403011"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403012"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403013"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403014"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403015"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F403016"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403017"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403018"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403019"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403020"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403021"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403022"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403023"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F403024"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403025"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403026"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403027"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403028"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403029"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403030"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403031"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F403056"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403057"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403058"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403059"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403060"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403061"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403062"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403063"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F403064"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403065"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403066"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403067"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403068"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403069"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403070"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403071"] = "This fault is caused by 'LSP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F403144"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403145"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403146"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403147"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403148"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403149"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403150"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403151"] = "This fault is caused by 'Fast LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403160"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403161"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403162"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403163"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403164"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403165"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403166"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403167"] = "This fault is caused by 'Fast LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403168"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403169"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403170"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403171"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403172"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403173"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403174"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403175"] = "This fault is caused by 'Fast LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403176"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403177"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403178"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403179"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403180"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403181"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403182"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403183"] = "This fault is caused by 'Fast LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403184"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403185"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403186"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403187"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403188"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403189"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403190"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403191"] = "This fault is caused by 'Fast LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403192"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403193"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403194"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403195"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403196"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403197"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403198"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403199"] = "This fault is caused by 'Fast LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403224"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403225"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403226"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403227"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403228"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403229"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403230"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403231"] = "This fault is caused by 'Fast LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403232"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403233"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403234"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403235"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403236"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403237"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403238"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403239"] = "This fault is caused by 'Fast LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403312"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403313"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403314"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403315"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403316"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403317"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403318"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403319"] = "This fault is caused by 'LSP Packets Retransmitted current value' statistical property crossing threshold level." + self.system_fault_code["F403328"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403329"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403330"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403331"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403332"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403333"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403334"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403335"] = "This fault is caused by 'LSP Packets Retransmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F403336"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403337"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403338"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403339"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403340"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403341"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403342"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403343"] = "This fault is caused by 'LSP Packets Retransmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F403344"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403345"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403346"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403347"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403348"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403349"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403350"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403351"] = "This fault is caused by 'LSP Packets Retransmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F403352"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403353"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403354"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403355"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403356"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403357"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403358"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403359"] = "This fault is caused by 'LSP Packets Retransmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F403360"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403361"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403362"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403363"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403364"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403365"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403366"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403367"] = "This fault is caused by 'LSP Packets Retransmitted average value' statistical property crossing threshold level." + self.system_fault_code["F403392"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403393"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403394"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403395"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403396"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403397"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403398"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403399"] = "This fault is caused by 'LSP Packets Retransmitted trend' statistical property crossing threshold level." + self.system_fault_code["F403400"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403401"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403402"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403403"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403404"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403405"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403406"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403407"] = "This fault is caused by 'LSP Packets Retransmitted rate' statistical property crossing threshold level." + self.system_fault_code["F403480"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403481"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403482"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403483"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403484"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403485"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403486"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403487"] = "This fault is caused by 'LSP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F403496"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403497"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403498"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403499"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403500"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403501"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403502"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403503"] = "This fault is caused by 'LSP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F403504"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403505"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403506"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403507"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403508"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403509"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403510"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403511"] = "This fault is caused by 'LSP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F403512"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403513"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403514"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403515"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403516"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403517"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403518"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403519"] = "This fault is caused by 'LSP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F403520"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403521"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403522"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403523"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403524"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403525"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403526"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403527"] = "This fault is caused by 'LSP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F403528"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403529"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403530"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403531"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403532"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403533"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403534"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403535"] = "This fault is caused by 'LSP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F403560"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403561"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403562"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403563"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403564"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403565"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403566"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403567"] = "This fault is caused by 'LSP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F403568"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403569"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403570"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403571"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403572"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403573"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403574"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403575"] = "This fault is caused by 'LSP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F403648"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403649"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403650"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403651"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403652"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403653"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403654"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403655"] = "This fault is caused by 'LSP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F403664"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403665"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403666"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403667"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403668"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403669"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403670"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403671"] = "This fault is caused by 'LSP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F403672"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403673"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403674"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403675"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403676"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403677"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403678"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403679"] = "This fault is caused by 'LSP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F403680"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403681"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403682"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403683"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403684"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403685"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403686"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403687"] = "This fault is caused by 'LSP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F403688"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403689"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403690"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403691"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403692"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403693"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403694"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403695"] = "This fault is caused by 'LSP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F403696"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403697"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403698"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403699"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403700"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403701"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403702"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403703"] = "This fault is caused by 'LSP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F403728"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403729"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403730"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403731"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403732"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403733"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403734"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403735"] = "This fault is caused by 'LSP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F403736"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403737"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403738"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403739"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403740"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403741"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403742"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403743"] = "This fault is caused by 'LSP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F403816"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403817"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403818"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403819"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403820"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403821"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403822"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403823"] = "This fault is caused by 'P2P IIH Packets with Authentication Error current value' statistical property crossing threshold" + self.system_fault_code["F403832"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403833"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403834"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403835"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403836"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403837"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403838"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403839"] = "This fault is caused by 'P2P IIH Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F403840"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403841"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403842"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403843"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403844"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403845"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403846"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403847"] = "This fault is caused by 'P2P IIH Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F403848"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403849"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403850"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403851"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403852"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403853"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403854"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403855"] = "This fault is caused by 'P2P IIH Packets with Authentication Error minimum value' statistical property crossing threshold" + self.system_fault_code["F403856"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403857"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403858"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403859"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403860"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403861"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403862"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403863"] = "This fault is caused by 'P2P IIH Packets with Authentication Error maximum value' statistical property crossing threshold" + self.system_fault_code["F403864"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403865"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403866"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403867"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403868"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403869"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403870"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403871"] = "This fault is caused by 'P2P IIH Packets with Authentication Error average value' statistical property crossing threshold" + self.system_fault_code["F403896"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403897"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403898"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403899"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403900"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403901"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403902"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403903"] = "This fault is caused by 'P2P IIH Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F403904"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403905"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403906"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403907"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403908"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403909"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403910"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403911"] = "This fault is caused by 'P2P IIH Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F403984"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403985"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403986"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403987"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403988"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403989"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403990"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F403991"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error current value' statistical property crossing threshold" + self.system_fault_code["F404000"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404001"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404002"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404003"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404004"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404005"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404006"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404007"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404008"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404009"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404010"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404011"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404012"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404013"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404014"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404015"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404016"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404017"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404018"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404019"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404020"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404021"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404022"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404023"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error minimum value' statistical property crossing threshold" + self.system_fault_code["F404024"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404025"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404026"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404027"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404028"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404029"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404030"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404031"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error maximum value' statistical property crossing threshold" + self.system_fault_code["F404032"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404033"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404034"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404035"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404036"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404037"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404038"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404039"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error average value' statistical property crossing threshold" + self.system_fault_code["F404064"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404065"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404066"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404067"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404068"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404069"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404070"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404071"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404072"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404073"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404074"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404075"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404076"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404077"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404078"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404079"] = "This fault is caused by 'P2P IIH Packets with Miscellaneous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404152"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404153"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404154"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404155"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404156"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404157"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404158"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404159"] = "This fault is caused by 'P2P IIH Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404168"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404169"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404170"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404171"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404172"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404173"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404174"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404175"] = "This fault is caused by 'P2P IIH Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404176"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404177"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404178"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404179"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404180"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404181"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404182"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404183"] = "This fault is caused by 'P2P IIH Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404184"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404185"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404186"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404187"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404188"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404189"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404190"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404191"] = "This fault is caused by 'P2P IIH Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404192"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404193"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404194"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404195"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404196"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404197"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404198"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404199"] = "This fault is caused by 'P2P IIH Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404200"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404201"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404202"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404203"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404204"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404205"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404206"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404207"] = "This fault is caused by 'P2P IIH Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404232"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404233"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404234"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404235"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404236"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404237"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404238"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404239"] = "This fault is caused by 'P2P IIH Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404240"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404241"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404242"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404243"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404244"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404245"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404246"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404247"] = "This fault is caused by 'P2P IIH Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404320"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404321"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404322"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404323"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404324"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404325"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404326"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404327"] = "This fault is caused by 'P2P IIH Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404336"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404337"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404338"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404339"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404340"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404341"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404342"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404343"] = "This fault is caused by 'P2P IIH Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F404344"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404345"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404346"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404347"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404348"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404349"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404350"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404351"] = "This fault is caused by 'P2P IIH Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F404352"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404353"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404354"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404355"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404356"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404357"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404358"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404359"] = "This fault is caused by 'P2P IIH Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F404360"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404361"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404362"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404363"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404364"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404365"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404366"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404367"] = "This fault is caused by 'P2P IIH Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F404368"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404369"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404370"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404371"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404372"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404373"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404374"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404375"] = "This fault is caused by 'P2P IIH Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F404400"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404401"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404402"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404403"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404404"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404405"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404406"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404407"] = "This fault is caused by 'P2P IIH Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F404408"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404409"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404410"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404411"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404412"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404413"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404414"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404415"] = "This fault is caused by 'P2P IIH Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F404488"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404489"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404490"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404491"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404492"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404493"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404494"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404495"] = "This fault is caused by 'PSNP Packets with Authentication Error current value' statistical property crossing threshold level." + self.system_fault_code["F404504"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404505"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404506"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404507"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404508"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404509"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404510"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404511"] = "This fault is caused by 'PSNP Packets with Authentication Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404512"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404513"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404514"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404515"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404516"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404517"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404518"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404519"] = "This fault is caused by 'PSNP Packets with Authentication Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404520"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404521"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404522"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404523"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404524"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404525"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404526"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404527"] = "This fault is caused by 'PSNP Packets with Authentication Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404528"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404529"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404530"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404531"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404532"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404533"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404534"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404535"] = "This fault is caused by 'PSNP Packets with Authentication Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404536"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404537"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404538"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404539"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404540"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404541"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404542"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404543"] = "This fault is caused by 'PSNP Packets with Authentication Error average value' statistical property crossing threshold level." + self.system_fault_code["F404568"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404569"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404570"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404571"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404572"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404573"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404574"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404575"] = "This fault is caused by 'PSNP Packets with Authentication Error trend' statistical property crossing threshold level." + self.system_fault_code["F404576"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404577"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404578"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404579"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404580"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404581"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404582"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404583"] = "This fault is caused by 'PSNP Packets with Authentication Error rate' statistical property crossing threshold level." + self.system_fault_code["F404656"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404657"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404658"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404659"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404660"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404661"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404662"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404663"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error current value' statistical property crossing threshold level." + self.system_fault_code["F404672"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404673"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404674"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404675"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404676"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404677"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404678"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404679"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error cumulative' statistical property crossing threshold level." + self.system_fault_code["F404680"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404681"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404682"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404683"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404684"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404685"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404686"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404687"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error periodic' statistical property crossing threshold level." + self.system_fault_code["F404688"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404689"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404690"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404691"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404692"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404693"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404694"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404695"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error minimum value' statistical property crossing threshold level." + self.system_fault_code["F404696"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404697"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404698"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404699"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404700"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404701"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404702"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404703"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error maximum value' statistical property crossing threshold level." + self.system_fault_code["F404704"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404705"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404706"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404707"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404708"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404709"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404710"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404711"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error average value' statistical property crossing threshold level." + self.system_fault_code["F404736"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404737"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404738"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404739"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404740"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404741"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404742"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404743"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error trend' statistical property crossing threshold level." + self.system_fault_code["F404744"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404745"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404746"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404747"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404748"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404749"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404750"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404751"] = "This fault is caused by 'PSNP Packets with Miscelcsnpeous Error rate' statistical property crossing threshold level." + self.system_fault_code["F404824"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404825"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404826"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404827"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404828"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404829"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404830"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404831"] = "This fault is caused by 'PSNP Packets Recevied current value' statistical property crossing threshold level." + self.system_fault_code["F404840"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404841"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404842"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404843"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404844"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404845"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404846"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404847"] = "This fault is caused by 'PSNP Packets Recevied cumulative' statistical property crossing threshold level." + self.system_fault_code["F404848"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404849"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404850"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404851"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404852"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404853"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404854"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404855"] = "This fault is caused by 'PSNP Packets Recevied periodic' statistical property crossing threshold level." + self.system_fault_code["F404856"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404857"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404858"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404859"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404860"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404861"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404862"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404863"] = "This fault is caused by 'PSNP Packets Recevied minimum value' statistical property crossing threshold level." + self.system_fault_code["F404864"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404865"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404866"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404867"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404868"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404869"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404870"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404871"] = "This fault is caused by 'PSNP Packets Recevied maximum value' statistical property crossing threshold level." + self.system_fault_code["F404872"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404873"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404874"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404875"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404876"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404877"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404878"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404879"] = "This fault is caused by 'PSNP Packets Recevied average value' statistical property crossing threshold level." + self.system_fault_code["F404904"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404905"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404906"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404907"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404908"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404909"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404910"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404911"] = "This fault is caused by 'PSNP Packets Recevied trend' statistical property crossing threshold level." + self.system_fault_code["F404912"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404913"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404914"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404915"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404916"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404917"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404918"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404919"] = "This fault is caused by 'PSNP Packets Recevied rate' statistical property crossing threshold level." + self.system_fault_code["F404992"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404993"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404994"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404995"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404996"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404997"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404998"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F404999"] = "This fault is caused by 'PSNP Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F405008"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405009"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405010"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405011"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405012"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405013"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405014"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405015"] = "This fault is caused by 'PSNP Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F405016"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405017"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405018"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405019"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405020"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405021"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405022"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405023"] = "This fault is caused by 'PSNP Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F405024"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405025"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405026"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405027"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405028"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405029"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405030"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405031"] = "This fault is caused by 'PSNP Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F405032"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405033"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405034"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405035"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405036"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405037"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405038"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405039"] = "This fault is caused by 'PSNP Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F405040"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405041"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405042"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405043"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405044"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405045"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405046"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405047"] = "This fault is caused by 'PSNP Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F405072"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405073"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405074"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405075"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405076"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405077"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405078"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405079"] = "This fault is caused by 'PSNP Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F405080"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405081"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405082"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405083"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405084"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405085"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405086"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F405087"] = "This fault is caused by 'PSNP Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F409864"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409865"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409866"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409867"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409868"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409869"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409870"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409871"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F409880"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409881"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409882"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409883"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409884"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409885"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409886"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409887"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F409888"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409889"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409890"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409891"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409892"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409893"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409894"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409895"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F409896"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409897"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409898"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409899"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409900"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409901"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409902"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409903"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F409904"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409905"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409906"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409907"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409908"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409909"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409910"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409911"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F409912"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409913"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409914"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409915"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409916"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409917"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409918"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409919"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F409944"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409945"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409946"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409947"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409948"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409949"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409950"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409951"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F409952"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409953"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409954"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409955"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409956"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409957"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409958"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F409959"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410032"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410033"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410034"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410035"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410036"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410037"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410038"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410039"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410048"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410049"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410050"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410051"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410052"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410053"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410054"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410055"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410056"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410057"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410058"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410059"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410060"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410061"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410062"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410063"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410064"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410065"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410066"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410067"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410068"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410069"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410070"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410071"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410072"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410073"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410074"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410075"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410076"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410077"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410078"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410079"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410080"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410081"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410082"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410083"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410084"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410085"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410086"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410087"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410112"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410113"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410114"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410115"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410116"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410117"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410118"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410119"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410120"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410121"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410122"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410123"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410124"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410125"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410126"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410127"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410200"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410201"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410202"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410203"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410204"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410205"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410206"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410207"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410216"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410217"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410218"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410219"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410220"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410221"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410222"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410223"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410224"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410225"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410226"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410227"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410228"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410229"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410230"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410231"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410232"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410233"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410234"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410235"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410236"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410237"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410238"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410239"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410240"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410241"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410242"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410243"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410244"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410245"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410246"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410247"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410248"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410249"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410250"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410251"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410252"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410253"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410254"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410255"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410280"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410281"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410282"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410283"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410284"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410285"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410286"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410287"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410288"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410289"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410290"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410291"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410292"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410293"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410294"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410295"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410368"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410369"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410370"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410371"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410372"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410373"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410374"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410375"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410384"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410385"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410386"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410387"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410388"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410389"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410390"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410391"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410392"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410393"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410394"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410395"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410396"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410397"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410398"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410399"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410400"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410401"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410402"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410403"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410404"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410405"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410406"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410407"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410408"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410409"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410410"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410411"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410412"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410413"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410414"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410415"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410416"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410417"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410418"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410419"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410420"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410421"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410422"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410423"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410448"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410449"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410450"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410451"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410452"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410453"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410454"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410455"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410456"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410457"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410458"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410459"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410460"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410461"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410462"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410463"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410536"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410537"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410538"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410539"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410540"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410541"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410542"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410543"] = "This fault is caused by 'Drop Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410552"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410553"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410554"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410555"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410556"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410557"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410558"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410559"] = "This fault is caused by 'Drop Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410560"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410561"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410562"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410563"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410564"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410565"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410566"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410567"] = "This fault is caused by 'Drop Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410568"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410569"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410570"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410571"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410572"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410573"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410574"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410575"] = "This fault is caused by 'Drop Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410576"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410577"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410578"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410579"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410580"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410581"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410582"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410583"] = "This fault is caused by 'Drop Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410584"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410585"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410586"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410587"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410588"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410589"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410590"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410591"] = "This fault is caused by 'Drop Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410616"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410617"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410618"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410619"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410620"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410621"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410622"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410623"] = "This fault is caused by 'Drop Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410624"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410625"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410626"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410627"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410628"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410629"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410630"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410631"] = "This fault is caused by 'Drop Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410704"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410705"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410706"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410707"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410708"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410709"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410710"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410711"] = "This fault is caused by 'Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F410720"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410721"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410722"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410723"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410724"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410725"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410726"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410727"] = "This fault is caused by 'Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F410728"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410729"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410730"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410731"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410732"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410733"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410734"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410735"] = "This fault is caused by 'Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F410736"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410737"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410738"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410739"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410740"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410741"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410742"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410743"] = "This fault is caused by 'Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F410744"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410745"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410746"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410747"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410748"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410749"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410750"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410751"] = "This fault is caused by 'Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F410752"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410753"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410754"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410755"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410756"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410757"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410758"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410759"] = "This fault is caused by 'Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F410784"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410785"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410786"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410787"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410788"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410789"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410790"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410791"] = "This fault is caused by 'Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F410792"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410793"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410794"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410795"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410796"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410797"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410798"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410799"] = "This fault is caused by 'Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F410872"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410873"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410874"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410875"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410876"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410877"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410878"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410879"] = "This fault is caused by 'Forwarded Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F410888"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410889"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410890"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410891"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410892"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410893"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410894"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410895"] = "This fault is caused by 'Forwarded Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F410896"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410897"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410898"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410899"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410900"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410901"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410902"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410903"] = "This fault is caused by 'Forwarded Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F410904"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410905"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410906"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410907"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410908"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410909"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410910"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410911"] = "This fault is caused by 'Forwarded Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F410912"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410913"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410914"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410915"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410916"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410917"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410918"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410919"] = "This fault is caused by 'Forwarded Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F410920"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410921"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410922"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410923"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410924"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410925"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410926"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410927"] = "This fault is caused by 'Forwarded Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F410952"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410953"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410954"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410955"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410956"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410957"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410958"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410959"] = "This fault is caused by 'Forwarded Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F410960"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410961"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410962"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410963"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410964"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410965"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410966"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F410967"] = "This fault is caused by 'Forwarded Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F411040"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411041"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411042"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411043"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411044"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411045"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411046"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411047"] = "This fault is caused by 'Forwarded Packets current value' statistical property crossing threshold level." + self.system_fault_code["F411056"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411057"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411058"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411059"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411060"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411061"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411062"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411063"] = "This fault is caused by 'Forwarded Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F411064"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411065"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411066"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411067"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411068"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411069"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411070"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411071"] = "This fault is caused by 'Forwarded Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F411072"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411073"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411074"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411075"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411076"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411077"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411078"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411079"] = "This fault is caused by 'Forwarded Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F411080"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411081"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411082"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411083"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411084"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411085"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411086"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411087"] = "This fault is caused by 'Forwarded Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F411088"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411089"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411090"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411091"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411092"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411093"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411094"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411095"] = "This fault is caused by 'Forwarded Packets average value' statistical property crossing threshold level." + self.system_fault_code["F411120"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411121"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411122"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411123"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411124"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411125"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411126"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411127"] = "This fault is caused by 'Forwarded Packets trend' statistical property crossing threshold level." + self.system_fault_code["F411128"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411129"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411130"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411131"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411132"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411133"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411134"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411135"] = "This fault is caused by 'Forwarded Packets rate' statistical property crossing threshold level." + self.system_fault_code["F411208"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411209"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411210"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411211"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411212"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411213"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411214"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411215"] = "This fault is caused by 'Number of Tunnel Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F411224"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411225"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411226"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411227"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411228"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411229"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411230"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411231"] = "This fault is caused by 'Number of Tunnel Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F411232"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411233"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411234"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411235"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411236"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411237"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411238"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411239"] = "This fault is caused by 'Number of Tunnel Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F411240"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411241"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411242"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411243"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411244"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411245"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411246"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411247"] = "This fault is caused by 'Number of Tunnel Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F411248"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411249"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411250"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411251"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411252"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411253"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411254"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411255"] = "This fault is caused by 'Number of Tunnel Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F411256"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411257"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411258"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411259"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411260"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411261"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411262"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411263"] = "This fault is caused by 'Number of Tunnel Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F411288"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411289"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411290"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411291"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411292"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411293"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411294"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411295"] = "This fault is caused by 'Number of Tunnel Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F411296"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411297"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411298"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411299"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411300"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411301"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411302"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F411303"] = "This fault is caused by 'Number of Tunnel Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F412632"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412633"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412634"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412635"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412636"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412637"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412638"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412639"] = "This fault is caused by 'Bridge domain entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412648"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412649"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412650"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412651"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412652"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412653"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412654"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412655"] = "This fault is caused by 'Bridge domain entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412656"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412657"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412658"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412659"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412660"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412661"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412662"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412663"] = "This fault is caused by 'Bridge domain entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412664"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412665"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412666"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412667"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412668"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412669"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412670"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412671"] = "This fault is caused by 'Bridge domain entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F412672"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412673"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412674"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412675"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412676"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412677"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412678"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412679"] = "This fault is caused by 'Bridge domain entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F412680"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412681"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412682"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412683"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412684"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412685"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412686"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412687"] = "This fault is caused by 'Bridge domain entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F412712"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412713"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412714"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412715"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412716"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412717"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412718"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412719"] = "This fault is caused by 'Bridge domain entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F412720"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412721"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412722"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412723"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412724"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412725"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412726"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412727"] = "This fault is caused by 'Bridge domain entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F412800"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412801"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412802"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412803"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412804"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412805"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412806"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412807"] = "This fault is caused by 'Total Bridge domain entries current value' statistical property crossing threshold level." + self.system_fault_code["F412816"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412817"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412818"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412819"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412820"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412821"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412822"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412823"] = "This fault is caused by 'Total Bridge domain entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F412824"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412825"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412826"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412827"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412828"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412829"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412830"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412831"] = "This fault is caused by 'Total Bridge domain entries periodic' statistical property crossing threshold level." + self.system_fault_code["F412832"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412833"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412834"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412835"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412836"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412837"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412838"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412839"] = "This fault is caused by 'Total Bridge domain entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F412840"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412841"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412842"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412843"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412844"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412845"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412846"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412847"] = "This fault is caused by 'Total Bridge domain entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F412848"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412849"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412850"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412851"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412852"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412853"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412854"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412855"] = "This fault is caused by 'Total Bridge domain entries average value' statistical property crossing threshold level." + self.system_fault_code["F412880"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412881"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412882"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412883"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412884"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412885"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412886"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412887"] = "This fault is caused by 'Total Bridge domain entries trend' statistical property crossing threshold level." + self.system_fault_code["F412888"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412889"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412890"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412891"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412892"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412893"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412894"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412895"] = "This fault is caused by 'Total Bridge domain entries rate' statistical property crossing threshold level." + self.system_fault_code["F412968"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412969"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412970"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412971"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412972"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412973"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412974"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412975"] = "This fault is caused by 'Endpoint groups capacity current value' statistical property crossing threshold level." + self.system_fault_code["F412984"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412985"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412986"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412987"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412988"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412989"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412990"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412991"] = "This fault is caused by 'Endpoint groups capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F412992"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412993"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412994"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412995"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412996"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412997"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412998"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F412999"] = "This fault is caused by 'Endpoint groups capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413000"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413001"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413002"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413003"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413004"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413005"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413006"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413007"] = "This fault is caused by 'Endpoint groups capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413008"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413009"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413010"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413011"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413012"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413013"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413014"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413015"] = "This fault is caused by 'Endpoint groups capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413016"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413017"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413018"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413019"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413020"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413021"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413022"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413023"] = "This fault is caused by 'Endpoint groups capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413048"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413049"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413050"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413051"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413052"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413053"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413054"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413055"] = "This fault is caused by 'Endpoint groups capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413056"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413057"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413058"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413059"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413060"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413061"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413062"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413063"] = "This fault is caused by 'Endpoint groups capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413136"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413137"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413138"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413139"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413140"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413141"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413142"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413143"] = "This fault is caused by 'Total Endpoint groups current value' statistical property crossing threshold level." + self.system_fault_code["F413152"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413153"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413154"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413155"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413156"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413157"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413158"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413159"] = "This fault is caused by 'Total Endpoint groups cumulative' statistical property crossing threshold level." + self.system_fault_code["F413160"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413161"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413162"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413163"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413164"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413165"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413166"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413167"] = "This fault is caused by 'Total Endpoint groups periodic' statistical property crossing threshold level." + self.system_fault_code["F413168"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413169"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413170"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413171"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413172"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413173"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413174"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413175"] = "This fault is caused by 'Total Endpoint groups minimum value' statistical property crossing threshold level." + self.system_fault_code["F413176"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413177"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413178"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413179"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413180"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413181"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413182"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413183"] = "This fault is caused by 'Total Endpoint groups maximum value' statistical property crossing threshold level." + self.system_fault_code["F413184"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413185"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413186"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413187"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413188"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413189"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413190"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413191"] = "This fault is caused by 'Total Endpoint groups average value' statistical property crossing threshold level." + self.system_fault_code["F413216"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413217"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413218"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413219"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413220"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413221"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413222"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413223"] = "This fault is caused by 'Total Endpoint groups trend' statistical property crossing threshold level." + self.system_fault_code["F413224"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413225"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413226"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413227"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413228"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413229"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413230"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413231"] = "This fault is caused by 'Total Endpoint groups rate' statistical property crossing threshold level." + self.system_fault_code["F413304"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413305"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413306"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413307"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413308"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413309"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413310"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413311"] = "This fault is caused by 'Physical ports capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413320"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413321"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413322"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413323"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413324"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413325"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413326"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413327"] = "This fault is caused by 'Physical ports capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413328"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413329"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413330"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413331"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413332"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413333"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413334"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413335"] = "This fault is caused by 'Physical ports capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413336"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413337"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413338"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413339"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413340"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413341"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413342"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413343"] = "This fault is caused by 'Physical ports capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413344"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413345"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413346"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413347"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413348"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413349"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413350"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413351"] = "This fault is caused by 'Physical ports capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413352"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413353"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413354"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413355"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413356"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413357"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413358"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413359"] = "This fault is caused by 'Physical ports capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413384"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413385"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413386"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413387"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413388"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413389"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413390"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413391"] = "This fault is caused by 'Physical ports capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413392"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413393"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413394"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413395"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413396"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413397"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413398"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413399"] = "This fault is caused by 'Physical ports capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413472"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413473"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413474"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413475"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413476"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413477"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413478"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413479"] = "This fault is caused by 'Total physical ports used current value' statistical property crossing threshold level." + self.system_fault_code["F413488"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413489"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413490"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413491"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413492"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413493"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413494"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413495"] = "This fault is caused by 'Total physical ports used cumulative' statistical property crossing threshold level." + self.system_fault_code["F413496"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413497"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413498"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413499"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413500"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413501"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413502"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413503"] = "This fault is caused by 'Total physical ports used periodic' statistical property crossing threshold level." + self.system_fault_code["F413504"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413505"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413506"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413507"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413508"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413509"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413510"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413511"] = "This fault is caused by 'Total physical ports used minimum value' statistical property crossing threshold level." + self.system_fault_code["F413512"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413513"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413514"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413515"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413516"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413517"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413518"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413519"] = "This fault is caused by 'Total physical ports used maximum value' statistical property crossing threshold level." + self.system_fault_code["F413520"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413521"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413522"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413523"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413524"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413525"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413526"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413527"] = "This fault is caused by 'Total physical ports used average value' statistical property crossing threshold level." + self.system_fault_code["F413552"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413553"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413554"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413555"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413556"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413557"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413558"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413559"] = "This fault is caused by 'Total physical ports used trend' statistical property crossing threshold level." + self.system_fault_code["F413560"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413561"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413562"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413563"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413564"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413565"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413566"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413567"] = "This fault is caused by 'Total physical ports used rate' statistical property crossing threshold level." + self.system_fault_code["F413640"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413641"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413642"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413643"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413644"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413645"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413646"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413647"] = "This fault is caused by 'VRF entries capacity current value' statistical property crossing threshold level." + self.system_fault_code["F413656"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413657"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413658"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413659"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413660"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413661"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413662"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413663"] = "This fault is caused by 'VRF entries capacity cumulative' statistical property crossing threshold level." + self.system_fault_code["F413664"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413665"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413666"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413667"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413668"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413669"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413670"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413671"] = "This fault is caused by 'VRF entries capacity periodic' statistical property crossing threshold level." + self.system_fault_code["F413672"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413673"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413674"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413675"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413676"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413677"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413678"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413679"] = "This fault is caused by 'VRF entries capacity minimum value' statistical property crossing threshold level." + self.system_fault_code["F413680"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413681"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413682"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413683"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413684"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413685"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413686"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413687"] = "This fault is caused by 'VRF entries capacity maximum value' statistical property crossing threshold level." + self.system_fault_code["F413688"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413689"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413690"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413691"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413692"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413693"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413694"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413695"] = "This fault is caused by 'VRF entries capacity average value' statistical property crossing threshold level." + self.system_fault_code["F413720"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413721"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413722"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413723"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413724"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413725"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413726"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413727"] = "This fault is caused by 'VRF entries capacity trend' statistical property crossing threshold level." + self.system_fault_code["F413728"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413729"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413730"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413731"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413732"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413733"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413734"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413735"] = "This fault is caused by 'VRF entries capacity rate' statistical property crossing threshold level." + self.system_fault_code["F413808"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413809"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413810"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413811"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413812"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413813"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413814"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413815"] = "This fault is caused by 'Total VRF entries current value' statistical property crossing threshold level." + self.system_fault_code["F413824"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413825"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413826"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413827"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413828"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413829"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413830"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413831"] = "This fault is caused by 'Total VRF entries cumulative' statistical property crossing threshold level." + self.system_fault_code["F413832"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413833"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413834"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413835"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413836"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413837"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413838"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413839"] = "This fault is caused by 'Total VRF entries periodic' statistical property crossing threshold level." + self.system_fault_code["F413840"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413841"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413842"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413843"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413844"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413845"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413846"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413847"] = "This fault is caused by 'Total VRF entries minimum value' statistical property crossing threshold level." + self.system_fault_code["F413848"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413849"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413850"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413851"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413852"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413853"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413854"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413855"] = "This fault is caused by 'Total VRF entries maximum value' statistical property crossing threshold level." + self.system_fault_code["F413856"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413857"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413858"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413859"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413860"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413861"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413862"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413863"] = "This fault is caused by 'Total VRF entries average value' statistical property crossing threshold level." + self.system_fault_code["F413888"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413889"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413890"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413891"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413892"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413893"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413894"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413895"] = "This fault is caused by 'Total VRF entries trend' statistical property crossing threshold level." + self.system_fault_code["F413896"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413897"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413898"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413899"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413900"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413901"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413902"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F413903"] = "This fault is caused by 'Total VRF entries rate' statistical property crossing threshold level." + self.system_fault_code["F415944"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415945"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415946"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415947"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415948"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415949"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415950"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415951"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F415960"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415961"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415962"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415963"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415964"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415965"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415966"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415967"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F415968"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415969"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415970"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415971"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415972"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415973"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415974"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415975"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F415976"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415977"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415978"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415979"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415980"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415981"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415982"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415983"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F415984"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415985"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415986"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415987"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415988"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415989"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415990"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415991"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F415992"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415993"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415994"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415995"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415996"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415997"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415998"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F415999"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416024"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416025"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416026"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416027"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416028"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416029"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416030"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416031"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416032"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416033"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416034"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416035"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416036"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416037"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416038"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416039"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416112"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416113"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416114"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416115"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416116"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416117"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416118"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416119"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F416128"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416129"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416130"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416131"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416132"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416133"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416134"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416135"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F416136"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416137"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416138"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416139"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416140"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416141"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416142"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416143"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F416144"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416145"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416146"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416147"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416148"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416149"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416150"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416151"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F416152"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416153"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416154"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416155"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416156"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416157"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416158"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416159"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F416160"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416161"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416162"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416163"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416164"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416165"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416166"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416167"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F416192"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416193"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416194"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416195"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416196"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416197"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416198"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416199"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F416200"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416201"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416202"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416203"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416204"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416205"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416206"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416207"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F416280"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416281"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416282"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416283"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416284"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416285"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416286"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416287"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F416296"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416297"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416298"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416299"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416300"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416301"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416302"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416303"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416304"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416305"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416306"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416307"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416308"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416309"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416310"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416311"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416312"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416313"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416314"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416315"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416316"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416317"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416318"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416319"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416320"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416321"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416322"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416323"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416324"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416325"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416326"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416327"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416328"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416329"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416330"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416331"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416332"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416333"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416334"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416335"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F416360"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416361"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416362"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416363"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416364"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416365"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416366"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416367"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F416368"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416369"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416370"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416371"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416372"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416373"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416374"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416375"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F416448"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416449"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416450"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416451"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416452"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416453"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416454"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416455"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416464"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416465"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416466"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416467"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416468"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416469"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416470"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416471"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416472"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416473"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416474"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416475"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416476"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416477"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416478"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416479"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416480"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416481"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416482"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416483"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416484"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416485"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416486"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416487"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416488"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416489"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416490"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416491"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416492"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416493"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416494"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416495"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416496"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416497"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416498"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416499"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416500"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416501"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416502"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416503"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416528"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416529"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416530"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416531"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416532"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416533"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416534"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416535"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416536"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416537"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416538"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416539"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416540"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416541"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416542"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416543"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416616"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416617"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416618"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416619"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416620"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416621"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416622"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416623"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416632"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416633"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416634"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416635"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416636"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416637"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416638"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416639"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416640"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416641"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416642"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416643"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416644"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416645"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416646"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416647"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416648"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416649"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416650"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416651"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416652"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416653"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416654"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416655"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416656"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416657"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416658"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416659"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416660"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416661"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416662"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416663"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416664"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416665"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416666"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416667"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416668"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416669"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416670"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416671"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F416696"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416697"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416698"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416699"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416700"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416701"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416702"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416703"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F416704"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416705"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416706"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416707"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416708"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416709"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416710"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416711"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F416784"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416785"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416786"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416787"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416788"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416789"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416790"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416791"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F416800"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416801"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416802"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416803"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416804"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416805"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416806"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416807"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F416808"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416809"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416810"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416811"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416812"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416813"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416814"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416815"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F416816"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416817"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416818"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416819"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416820"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416821"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416822"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416823"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F416824"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416825"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416826"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416827"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416828"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416829"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416830"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416831"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F416832"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416833"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416834"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416835"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416836"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416837"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416838"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416839"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F416864"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416865"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416866"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416867"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416868"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416869"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416870"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416871"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F416872"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416873"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416874"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416875"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416876"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416877"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416878"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416879"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F416952"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416953"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416954"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416955"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416956"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416957"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416958"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416959"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F416968"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416969"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416970"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416971"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416972"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416973"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416974"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416975"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F416976"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416977"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416978"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416979"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416980"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416981"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416982"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416983"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F416984"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416985"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416986"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416987"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416988"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416989"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416990"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416991"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F416992"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416993"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416994"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416995"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416996"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416997"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416998"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F416999"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417000"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417001"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417002"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417003"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417004"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417005"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417006"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417007"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417032"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417033"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417034"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417035"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417036"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417037"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417038"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417039"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417040"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417041"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417042"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417043"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417044"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417045"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417046"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417047"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417120"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417121"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417122"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417123"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417124"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417125"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417126"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417127"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417136"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417137"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417138"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417139"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417140"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417141"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417142"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417143"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417144"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417145"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417146"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417147"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417148"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417149"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417150"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417151"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417152"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417153"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417154"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417155"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417156"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417157"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417158"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417159"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417160"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417161"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417162"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417163"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417164"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417165"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417166"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417167"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417168"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417169"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417170"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417171"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417172"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417173"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417174"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417175"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417200"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417201"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417202"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417203"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417204"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417205"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417206"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417207"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417208"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417209"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417210"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417211"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417212"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417213"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417214"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417215"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417288"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417289"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417290"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417291"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417292"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417293"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417294"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417295"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F417304"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417305"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417306"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417307"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417308"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417309"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417310"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417311"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417312"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417313"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417314"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417315"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417316"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417317"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417318"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417319"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417320"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417321"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417322"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417323"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417324"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417325"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417326"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417327"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F417328"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417329"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417330"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417331"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417332"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417333"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417334"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417335"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F417336"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417337"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417338"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417339"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417340"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417341"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417342"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417343"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F417368"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417369"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417370"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417371"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417372"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417373"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417374"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417375"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417376"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417377"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417378"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417379"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417380"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417381"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417382"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417383"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417456"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417457"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417458"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417459"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417460"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417461"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417462"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417463"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417472"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417473"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417474"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417475"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417476"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417477"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417478"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417479"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417480"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417481"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417482"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417483"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417484"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417485"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417486"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417487"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417488"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417489"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417490"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417491"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417492"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417493"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417494"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417495"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417496"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417497"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417498"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417499"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417500"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417501"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417502"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417503"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417504"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417505"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417506"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417507"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417508"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417509"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417510"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417511"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417536"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417537"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417538"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417539"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417540"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417541"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417542"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417543"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417544"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417545"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417546"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417547"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417548"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417549"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417550"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417551"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417624"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417625"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417626"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417627"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417628"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417629"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417630"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417631"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417640"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417641"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417642"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417643"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417644"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417645"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417646"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417647"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417648"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417649"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417650"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417651"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417652"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417653"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417654"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417655"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417656"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417657"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417658"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417659"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417660"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417661"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417662"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417663"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417664"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417665"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417666"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417667"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417668"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417669"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417670"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417671"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F417672"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417673"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417674"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417675"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417676"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417677"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417678"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417679"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F417704"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417705"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417706"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417707"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417708"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417709"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417710"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417711"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F417712"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417713"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417714"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417715"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417716"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417717"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417718"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417719"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F417792"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417793"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417794"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417795"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417796"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417797"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417798"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417799"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F417808"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417809"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417810"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417811"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417812"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417813"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417814"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417815"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F417816"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417817"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417818"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417819"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417820"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417821"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417822"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417823"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F417824"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417825"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417826"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417827"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417828"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417829"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417830"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417831"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F417832"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417833"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417834"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417835"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417836"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417837"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417838"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417839"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F417840"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417841"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417842"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417843"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417844"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417845"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417846"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417847"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F417872"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417873"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417874"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417875"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417876"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417877"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417878"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417879"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F417880"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417881"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417882"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417883"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417884"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417885"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417886"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417887"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F417960"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417961"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417962"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417963"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417964"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417965"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417966"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417967"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F417976"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417977"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417978"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417979"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417980"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417981"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417982"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417983"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F417984"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417985"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417986"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417987"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417988"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417989"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417990"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417991"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F417992"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417993"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417994"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417995"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417996"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417997"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417998"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F417999"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418000"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418001"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418002"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418003"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418004"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418005"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418006"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418007"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418008"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418009"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418010"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418011"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418012"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418013"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418014"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418015"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418040"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418041"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418042"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418043"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418044"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418045"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418046"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418047"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418048"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418049"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418050"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418051"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418052"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418053"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418054"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418055"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418128"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418129"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418130"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418131"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418132"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418133"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418134"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418135"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418144"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418145"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418146"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418147"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418148"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418149"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418150"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418151"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418152"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418153"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418154"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418155"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418156"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418157"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418158"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418159"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418160"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418161"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418162"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418163"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418164"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418165"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418166"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418167"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418168"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418169"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418170"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418171"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418172"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418173"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418174"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418175"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418176"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418177"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418178"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418179"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418180"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418181"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418182"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418183"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418208"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418209"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418210"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418211"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418212"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418213"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418214"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418215"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418216"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418217"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418218"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418219"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418220"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418221"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418222"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418223"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418296"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418297"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418298"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418299"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418300"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418301"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418302"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418303"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F418312"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418313"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418314"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418315"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418316"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418317"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418318"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418319"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418320"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418321"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418322"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418323"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418324"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418325"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418326"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418327"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418328"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418329"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418330"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418331"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418332"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418333"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418334"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418335"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F418336"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418337"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418338"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418339"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418340"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418341"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418342"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418343"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F418344"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418345"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418346"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418347"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418348"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418349"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418350"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418351"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F418376"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418377"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418378"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418379"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418380"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418381"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418382"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418383"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418384"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418385"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418386"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418387"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418388"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418389"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418390"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418391"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418464"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418465"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418466"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418467"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418468"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418469"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418470"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418471"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418480"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418481"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418482"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418483"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418484"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418485"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418486"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418487"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418488"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418489"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418490"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418491"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418492"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418493"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418494"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418495"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418496"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418497"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418498"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418499"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418500"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418501"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418502"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418503"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418504"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418505"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418506"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418507"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418508"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418509"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418510"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418511"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418512"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418513"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418514"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418515"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418516"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418517"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418518"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418519"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418544"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418545"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418546"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418547"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418548"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418549"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418550"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418551"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418552"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418553"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418554"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418555"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418556"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418557"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418558"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418559"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418632"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418633"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418634"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418635"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418636"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418637"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418638"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418639"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F418648"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418649"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418650"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418651"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418652"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418653"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418654"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418655"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418656"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418657"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418658"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418659"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418660"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418661"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418662"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418663"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418664"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418665"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418666"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418667"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418668"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418669"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418670"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418671"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F418672"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418673"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418674"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418675"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418676"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418677"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418678"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418679"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F418680"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418681"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418682"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418683"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418684"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418685"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418686"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418687"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F418712"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418713"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418714"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418715"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418716"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418717"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418718"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418719"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F418720"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418721"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418722"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418723"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418724"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418725"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418726"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418727"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F418800"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418801"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418802"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418803"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418804"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418805"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418806"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418807"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F418816"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418817"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418818"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418819"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418820"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418821"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418822"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418823"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F418824"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418825"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418826"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418827"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418828"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418829"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418830"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418831"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F418832"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418833"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418834"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418835"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418836"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418837"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418838"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418839"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F418840"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418841"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418842"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418843"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418844"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418845"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418846"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418847"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F418848"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418849"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418850"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418851"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418852"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418853"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418854"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418855"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F418880"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418881"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418882"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418883"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418884"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418885"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418886"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418887"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F418888"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418889"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418890"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418891"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418892"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418893"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418894"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418895"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F418968"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418969"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418970"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418971"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418972"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418973"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418974"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418975"] = "This fault is caused by 'Bad Authentication Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F418984"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418985"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418986"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418987"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418988"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418989"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418990"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418991"] = "This fault is caused by 'Bad Authentication Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F418992"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418993"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418994"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418995"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418996"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418997"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418998"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F418999"] = "This fault is caused by 'Bad Authentication Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419000"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419001"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419002"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419003"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419004"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419005"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419006"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419007"] = "This fault is caused by 'Bad Authentication Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419008"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419009"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419010"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419011"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419012"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419013"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419014"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419015"] = "This fault is caused by 'Bad Authentication Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419016"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419017"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419018"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419019"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419020"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419021"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419022"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419023"] = "This fault is caused by 'Bad Authentication Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419048"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419049"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419050"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419051"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419052"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419053"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419054"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419055"] = "This fault is caused by 'Bad Authentication Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419056"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419057"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419058"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419059"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419060"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419061"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419062"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419063"] = "This fault is caused by 'Bad Authentication Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419136"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419137"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419138"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419139"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419140"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419141"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419142"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419143"] = "This fault is caused by 'Bad CRC Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419152"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419153"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419154"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419155"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419156"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419157"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419158"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419159"] = "This fault is caused by 'Bad CRC Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419160"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419161"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419162"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419163"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419164"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419165"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419166"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419167"] = "This fault is caused by 'Bad CRC Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419168"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419169"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419170"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419171"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419172"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419173"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419174"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419175"] = "This fault is caused by 'Bad CRC Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419176"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419177"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419178"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419179"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419180"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419181"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419182"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419183"] = "This fault is caused by 'Bad CRC Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419184"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419185"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419186"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419187"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419188"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419189"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419190"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419191"] = "This fault is caused by 'Bad CRC Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419216"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419217"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419218"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419219"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419220"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419221"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419222"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419223"] = "This fault is caused by 'Bad CRC Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419224"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419225"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419226"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419227"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419228"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419229"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419230"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419231"] = "This fault is caused by 'Bad CRC Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419304"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419305"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419306"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419307"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419308"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419309"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419310"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419311"] = "This fault is caused by 'Bad Length Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419320"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419321"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419322"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419323"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419324"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419325"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419326"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419327"] = "This fault is caused by 'Bad Length Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419328"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419329"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419330"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419331"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419332"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419333"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419334"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419335"] = "This fault is caused by 'Bad Length Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419336"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419337"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419338"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419339"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419340"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419341"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419342"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419343"] = "This fault is caused by 'Bad Length Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419344"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419345"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419346"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419347"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419348"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419349"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419350"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419351"] = "This fault is caused by 'Bad Length Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419352"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419353"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419354"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419355"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419356"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419357"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419358"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419359"] = "This fault is caused by 'Bad Length Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419384"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419385"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419386"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419387"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419388"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419389"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419390"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419391"] = "This fault is caused by 'Bad Length Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419392"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419393"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419394"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419395"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419396"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419397"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419398"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419399"] = "This fault is caused by 'Bad Length Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419472"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419473"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419474"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419475"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419476"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419477"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419478"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419479"] = "This fault is caused by 'Bad Reserved Field Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419488"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419489"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419490"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419491"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419492"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419493"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419494"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419495"] = "This fault is caused by 'Bad Reserved Field Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419496"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419497"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419498"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419499"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419500"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419501"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419502"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419503"] = "This fault is caused by 'Bad Reserved Field Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419504"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419505"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419506"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419507"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419508"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419509"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419510"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419511"] = "This fault is caused by 'Bad Reserved Field Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419512"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419513"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419514"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419515"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419516"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419517"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419518"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419519"] = "This fault is caused by 'Bad Reserved Field Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419520"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419521"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419522"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419523"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419524"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419525"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419526"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419527"] = "This fault is caused by 'Bad Reserved Field Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419552"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419553"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419554"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419555"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419556"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419557"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419558"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419559"] = "This fault is caused by 'Bad Reserved Field Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419560"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419561"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419562"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419563"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419564"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419565"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419566"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419567"] = "This fault is caused by 'Bad Reserved Field Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419640"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419641"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419642"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419643"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419644"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419645"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419646"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419647"] = "This fault is caused by 'Bad Version Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419656"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419657"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419658"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419659"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419660"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419661"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419662"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419663"] = "This fault is caused by 'Bad Version Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419664"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419665"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419666"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419667"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419668"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419669"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419670"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419671"] = "This fault is caused by 'Bad Version Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F419672"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419673"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419674"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419675"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419676"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419677"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419678"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419679"] = "This fault is caused by 'Bad Version Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F419680"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419681"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419682"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419683"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419684"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419685"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419686"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419687"] = "This fault is caused by 'Bad Version Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F419688"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419689"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419690"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419691"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419692"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419693"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419694"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419695"] = "This fault is caused by 'Bad Version Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F419720"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419721"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419722"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419723"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419724"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419725"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419726"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419727"] = "This fault is caused by 'Bad Version Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F419728"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419729"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419730"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419731"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419732"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419733"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419734"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419735"] = "This fault is caused by 'Bad Version Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F419808"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419809"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419810"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419811"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419812"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419813"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419814"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419815"] = "This fault is caused by 'Received Packets Dropped current value' statistical property crossing threshold level." + self.system_fault_code["F419824"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419825"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419826"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419827"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419828"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419829"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419830"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419831"] = "This fault is caused by 'Received Packets Dropped cumulative' statistical property crossing threshold level." + self.system_fault_code["F419832"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419833"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419834"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419835"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419836"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419837"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419838"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419839"] = "This fault is caused by 'Received Packets Dropped periodic' statistical property crossing threshold level." + self.system_fault_code["F419840"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419841"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419842"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419843"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419844"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419845"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419846"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419847"] = "This fault is caused by 'Received Packets Dropped minimum value' statistical property crossing threshold level." + self.system_fault_code["F419848"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419849"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419850"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419851"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419852"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419853"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419854"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419855"] = "This fault is caused by 'Received Packets Dropped maximum value' statistical property crossing threshold level." + self.system_fault_code["F419856"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419857"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419858"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419859"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419860"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419861"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419862"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419863"] = "This fault is caused by 'Received Packets Dropped average value' statistical property crossing threshold level." + self.system_fault_code["F419888"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419889"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419890"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419891"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419892"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419893"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419894"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419895"] = "This fault is caused by 'Received Packets Dropped trend' statistical property crossing threshold level." + self.system_fault_code["F419896"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419897"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419898"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419899"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419900"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419901"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419902"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419903"] = "This fault is caused by 'Received Packets Dropped rate' statistical property crossing threshold level." + self.system_fault_code["F419976"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419977"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419978"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419979"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419980"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419981"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419982"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419983"] = "This fault is caused by 'Unknown Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F419992"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419993"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419994"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419995"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419996"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419997"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419998"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F419999"] = "This fault is caused by 'Unknown Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420000"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420001"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420002"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420003"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420004"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420005"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420006"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420007"] = "This fault is caused by 'Unknown Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420008"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420009"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420010"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420011"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420012"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420013"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420014"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420015"] = "This fault is caused by 'Unknown Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420016"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420017"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420018"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420019"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420020"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420021"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420022"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420023"] = "This fault is caused by 'Unknown Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420024"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420025"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420026"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420027"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420028"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420029"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420030"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420031"] = "This fault is caused by 'Unknown Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420056"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420057"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420058"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420059"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420060"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420061"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420062"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420063"] = "This fault is caused by 'Unknown Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420064"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420065"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420066"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420067"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420068"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420069"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420070"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420071"] = "This fault is caused by 'Unknown Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420144"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420145"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420146"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420147"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420148"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420149"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420150"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420151"] = "This fault is caused by 'Duplicate RouterId Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420160"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420161"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420162"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420163"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420164"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420165"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420166"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420167"] = "This fault is caused by 'Duplicate RouterId Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420168"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420169"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420170"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420171"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420172"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420173"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420174"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420175"] = "This fault is caused by 'Duplicate RouterId Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420176"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420177"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420178"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420179"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420180"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420181"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420182"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420183"] = "This fault is caused by 'Duplicate RouterId Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420184"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420185"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420186"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420187"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420188"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420189"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420190"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420191"] = "This fault is caused by 'Duplicate RouterId Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420192"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420193"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420194"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420195"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420196"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420197"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420198"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420199"] = "This fault is caused by 'Duplicate RouterId Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420224"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420225"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420226"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420227"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420228"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420229"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420230"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420231"] = "This fault is caused by 'Duplicate RouterId Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420232"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420233"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420234"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420235"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420236"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420237"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420238"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420239"] = "This fault is caused by 'Duplicate RouterId Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420312"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420313"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420314"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420315"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420316"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420317"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420318"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420319"] = "This fault is caused by 'Duplicate Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420328"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420329"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420330"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420331"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420332"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420333"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420334"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420335"] = "This fault is caused by 'Duplicate Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420336"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420337"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420338"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420339"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420340"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420341"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420342"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420343"] = "This fault is caused by 'Duplicate Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420344"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420345"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420346"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420347"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420348"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420349"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420350"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420351"] = "This fault is caused by 'Duplicate Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420352"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420353"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420354"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420355"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420356"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420357"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420358"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420359"] = "This fault is caused by 'Duplicate Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420360"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420361"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420362"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420363"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420364"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420365"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420366"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420367"] = "This fault is caused by 'Duplicate Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420392"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420393"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420394"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420395"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420396"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420397"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420398"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420399"] = "This fault is caused by 'Duplicate Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420400"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420401"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420402"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420403"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420404"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420405"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420406"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420407"] = "This fault is caused by 'Duplicate Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420480"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420481"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420482"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420483"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420484"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420485"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420486"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420487"] = "This fault is caused by 'Error DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420496"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420497"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420498"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420499"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420500"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420501"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420502"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420503"] = "This fault is caused by 'Error DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420504"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420505"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420506"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420507"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420508"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420509"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420510"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420511"] = "This fault is caused by 'Error DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420512"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420513"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420514"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420515"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420516"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420517"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420518"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420519"] = "This fault is caused by 'Error DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420520"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420521"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420522"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420523"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420524"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420525"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420526"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420527"] = "This fault is caused by 'Error DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420528"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420529"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420530"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420531"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420532"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420533"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420534"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420535"] = "This fault is caused by 'Error DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420560"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420561"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420562"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420563"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420564"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420565"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420566"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420567"] = "This fault is caused by 'Error DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420568"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420569"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420570"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420571"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420572"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420573"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420574"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420575"] = "This fault is caused by 'Error DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420648"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420649"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420650"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420651"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420652"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420653"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420654"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420655"] = "This fault is caused by 'Error Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420664"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420665"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420666"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420667"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420668"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420669"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420670"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420671"] = "This fault is caused by 'Error Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420672"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420673"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420674"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420675"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420676"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420677"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420678"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420679"] = "This fault is caused by 'Error Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420680"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420681"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420682"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420683"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420684"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420685"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420686"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420687"] = "This fault is caused by 'Error Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420688"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420689"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420690"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420691"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420692"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420693"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420694"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420695"] = "This fault is caused by 'Error Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420696"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420697"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420698"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420699"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420700"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420701"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420702"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420703"] = "This fault is caused by 'Error Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420728"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420729"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420730"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420731"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420732"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420733"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420734"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420735"] = "This fault is caused by 'Error Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420736"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420737"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420738"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420739"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420740"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420741"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420742"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420743"] = "This fault is caused by 'Error Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420816"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420817"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420818"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420819"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420820"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420821"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420822"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420823"] = "This fault is caused by 'Error Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420832"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420833"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420834"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420835"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420836"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420837"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420838"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420839"] = "This fault is caused by 'Error Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F420840"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420841"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420842"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420843"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420844"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420845"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420846"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420847"] = "This fault is caused by 'Error Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F420848"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420849"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420850"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420851"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420852"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420853"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420854"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420855"] = "This fault is caused by 'Error Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F420856"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420857"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420858"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420859"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420860"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420861"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420862"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420863"] = "This fault is caused by 'Error Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F420864"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420865"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420866"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420867"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420868"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420869"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420870"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420871"] = "This fault is caused by 'Error Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F420896"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420897"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420898"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420899"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420900"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420901"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420902"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420903"] = "This fault is caused by 'Error Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F420904"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420905"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420906"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420907"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420908"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420909"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420910"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420911"] = "This fault is caused by 'Error Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F420984"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420985"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420986"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420987"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420988"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420989"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420990"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F420991"] = "This fault is caused by 'No OSPF Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421000"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421001"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421002"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421003"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421004"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421005"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421006"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421007"] = "This fault is caused by 'No OSPF Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421008"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421009"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421010"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421011"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421012"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421013"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421014"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421015"] = "This fault is caused by 'No OSPF Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421016"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421017"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421018"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421019"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421020"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421021"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421022"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421023"] = "This fault is caused by 'No OSPF Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421024"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421025"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421026"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421027"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421028"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421029"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421030"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421031"] = "This fault is caused by 'No OSPF Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421032"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421033"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421034"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421035"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421036"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421037"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421038"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421039"] = "This fault is caused by 'No OSPF Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421064"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421065"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421066"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421067"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421068"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421069"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421070"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421071"] = "This fault is caused by 'No OSPF Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421072"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421073"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421074"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421075"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421076"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421077"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421078"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421079"] = "This fault is caused by 'No OSPF Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421152"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421153"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421154"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421155"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421156"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421157"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421158"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421159"] = "This fault is caused by 'Passive Interface Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421168"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421169"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421170"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421171"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421172"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421173"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421174"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421175"] = "This fault is caused by 'Passive Interface Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421176"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421177"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421178"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421179"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421180"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421181"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421182"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421183"] = "This fault is caused by 'Passive Interface Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421184"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421185"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421186"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421187"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421188"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421189"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421190"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421191"] = "This fault is caused by 'Passive Interface Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421192"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421193"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421194"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421195"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421196"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421197"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421198"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421199"] = "This fault is caused by 'Passive Interface Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421200"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421201"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421202"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421203"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421204"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421205"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421206"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421207"] = "This fault is caused by 'Passive Interface Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421232"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421233"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421234"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421235"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421236"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421237"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421238"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421239"] = "This fault is caused by 'Passive Interface Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421240"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421241"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421242"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421243"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421244"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421245"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421246"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421247"] = "This fault is caused by 'Passive Interface Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421320"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421321"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421322"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421323"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421324"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421325"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421326"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421327"] = "This fault is caused by 'Invalid Destination Addr Packets Received current value' statistical property crossing threshold" + self.system_fault_code["F421336"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421337"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421338"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421339"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421340"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421341"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421342"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421343"] = "This fault is caused by 'Invalid Destination Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421344"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421345"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421346"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421347"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421348"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421349"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421350"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421351"] = "This fault is caused by 'Invalid Destination Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421352"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421353"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421354"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421355"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421356"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421357"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421358"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421359"] = "This fault is caused by 'Invalid Destination Addr Packets Received minimum value' statistical property crossing threshold" + self.system_fault_code["F421360"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421361"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421362"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421363"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421364"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421365"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421366"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421367"] = "This fault is caused by 'Invalid Destination Addr Packets Received maximum value' statistical property crossing threshold" + self.system_fault_code["F421368"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421369"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421370"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421371"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421372"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421373"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421374"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421375"] = "This fault is caused by 'Invalid Destination Addr Packets Received average value' statistical property crossing threshold" + self.system_fault_code["F421400"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421401"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421402"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421403"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421404"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421405"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421406"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421407"] = "This fault is caused by 'Invalid Destination Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421408"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421409"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421410"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421411"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421412"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421413"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421414"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421415"] = "This fault is caused by 'Invalid Destination Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421488"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421489"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421490"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421491"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421492"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421493"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421494"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421495"] = "This fault is caused by 'Invalid Source Addr Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421504"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421505"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421506"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421507"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421508"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421509"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421510"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421511"] = "This fault is caused by 'Invalid Source Addr Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421512"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421513"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421514"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421515"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421516"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421517"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421518"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421519"] = "This fault is caused by 'Invalid Source Addr Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421520"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421521"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421522"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421523"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421524"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421525"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421526"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421527"] = "This fault is caused by 'Invalid Source Addr Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421528"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421529"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421530"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421531"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421532"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421533"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421534"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421535"] = "This fault is caused by 'Invalid Source Addr Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421536"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421537"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421538"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421539"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421540"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421541"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421542"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421543"] = "This fault is caused by 'Invalid Source Addr Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421568"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421569"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421570"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421571"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421572"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421573"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421574"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421575"] = "This fault is caused by 'Invalid Source Addr Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421576"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421577"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421578"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421579"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421580"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421581"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421582"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421583"] = "This fault is caused by 'Invalid Source Addr Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421656"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421657"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421658"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421659"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421660"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421661"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421662"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421663"] = "This fault is caused by 'Wrong Area Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421672"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421673"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421674"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421675"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421676"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421677"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421678"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421679"] = "This fault is caused by 'Wrong Area Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421680"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421681"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421682"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421683"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421684"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421685"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421686"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421687"] = "This fault is caused by 'Wrong Area Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421688"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421689"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421690"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421691"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421692"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421693"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421694"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421695"] = "This fault is caused by 'Wrong Area Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421696"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421697"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421698"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421699"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421700"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421701"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421702"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421703"] = "This fault is caused by 'Wrong Area Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421704"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421705"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421706"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421707"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421708"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421709"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421710"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421711"] = "This fault is caused by 'Wrong Area Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421736"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421737"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421738"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421739"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421740"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421741"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421742"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421743"] = "This fault is caused by 'Wrong Area Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421744"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421745"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421746"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421747"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421748"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421749"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421750"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421751"] = "This fault is caused by 'Wrong Area Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421824"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421825"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421826"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421827"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421828"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421829"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421830"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421831"] = "This fault is caused by 'Error LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421840"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421841"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421842"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421843"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421844"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421845"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421846"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421847"] = "This fault is caused by 'Error LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F421848"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421849"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421850"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421851"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421852"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421853"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421854"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421855"] = "This fault is caused by 'Error LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F421856"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421857"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421858"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421859"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421860"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421861"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421862"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421863"] = "This fault is caused by 'Error LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F421864"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421865"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421866"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421867"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421868"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421869"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421870"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421871"] = "This fault is caused by 'Error LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F421872"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421873"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421874"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421875"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421876"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421877"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421878"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421879"] = "This fault is caused by 'Error LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F421904"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421905"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421906"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421907"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421908"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421909"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421910"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421911"] = "This fault is caused by 'Error LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F421912"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421913"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421914"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421915"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421916"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421917"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421918"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421919"] = "This fault is caused by 'Error LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F421992"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421993"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421994"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421995"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421996"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421997"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421998"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F421999"] = "This fault is caused by 'Error LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422008"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422009"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422010"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422011"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422012"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422013"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422014"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422015"] = "This fault is caused by 'Error LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422016"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422017"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422018"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422019"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422020"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422021"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422022"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422023"] = "This fault is caused by 'Error LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422024"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422025"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422026"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422027"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422028"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422029"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422030"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422031"] = "This fault is caused by 'Error LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422032"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422033"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422034"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422035"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422036"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422037"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422038"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422039"] = "This fault is caused by 'Error LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422040"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422041"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422042"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422043"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422044"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422045"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422046"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422047"] = "This fault is caused by 'Error LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422072"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422073"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422074"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422075"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422076"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422077"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422078"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422079"] = "This fault is caused by 'Error LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422080"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422081"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422082"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422083"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422084"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422085"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422086"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422087"] = "This fault is caused by 'Error LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422160"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422161"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422162"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422163"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422164"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422165"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422166"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422167"] = "This fault is caused by 'Error LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422176"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422177"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422178"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422179"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422180"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422181"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422182"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422183"] = "This fault is caused by 'Error LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422184"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422185"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422186"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422187"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422188"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422189"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422190"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422191"] = "This fault is caused by 'Error LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422192"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422193"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422194"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422195"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422196"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422197"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422198"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422199"] = "This fault is caused by 'Error LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422200"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422201"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422202"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422203"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422204"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422205"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422206"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422207"] = "This fault is caused by 'Error LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422208"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422209"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422210"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422211"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422212"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422213"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422214"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422215"] = "This fault is caused by 'Error LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422240"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422241"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422242"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422243"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422244"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422245"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422246"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422247"] = "This fault is caused by 'Error LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422248"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422249"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422250"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422251"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422252"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422253"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422254"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422255"] = "This fault is caused by 'Error LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422328"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422329"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422330"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422331"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422332"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422333"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422334"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422335"] = "This fault is caused by 'LSACK Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422344"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422345"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422346"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422347"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422348"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422349"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422350"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422351"] = "This fault is caused by 'LSACK Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422352"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422353"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422354"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422355"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422356"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422357"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422358"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422359"] = "This fault is caused by 'LSACK Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422360"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422361"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422362"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422363"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422364"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422365"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422366"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422367"] = "This fault is caused by 'LSACK Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422368"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422369"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422370"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422371"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422372"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422373"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422374"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422375"] = "This fault is caused by 'LSACK Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422376"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422377"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422378"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422379"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422380"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422381"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422382"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422383"] = "This fault is caused by 'LSACK Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422408"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422409"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422410"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422411"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422412"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422413"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422414"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422415"] = "This fault is caused by 'LSACK Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422416"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422417"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422418"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422419"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422420"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422421"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422422"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422423"] = "This fault is caused by 'LSACK Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422496"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422497"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422498"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422499"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422500"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422501"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422502"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422503"] = "This fault is caused by 'LSREQ Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422512"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422513"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422514"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422515"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422516"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422517"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422518"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422519"] = "This fault is caused by 'LSREQ Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422520"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422521"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422522"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422523"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422524"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422525"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422526"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422527"] = "This fault is caused by 'LSREQ Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422528"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422529"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422530"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422531"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422532"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422533"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422534"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422535"] = "This fault is caused by 'LSREQ Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422536"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422537"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422538"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422539"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422540"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422541"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422542"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422543"] = "This fault is caused by 'LSREQ Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422544"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422545"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422546"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422547"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422548"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422549"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422550"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422551"] = "This fault is caused by 'LSREQ Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422576"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422577"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422578"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422579"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422580"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422581"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422582"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422583"] = "This fault is caused by 'LSREQ Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422584"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422585"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422586"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422587"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422588"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422589"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422590"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422591"] = "This fault is caused by 'LSREQ Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422664"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422665"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422666"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422667"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422668"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422669"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422670"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422671"] = "This fault is caused by 'LSU Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F422680"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422681"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422682"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422683"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422684"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422685"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422686"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422687"] = "This fault is caused by 'LSU Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F422688"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422689"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422690"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422691"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422692"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422693"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422694"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422695"] = "This fault is caused by 'LSU Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F422696"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422697"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422698"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422699"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422700"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422701"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422702"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422703"] = "This fault is caused by 'LSU Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F422704"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422705"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422706"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422707"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422708"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422709"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422710"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422711"] = "This fault is caused by 'LSU Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F422712"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422713"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422714"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422715"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422716"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422717"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422718"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422719"] = "This fault is caused by 'LSU Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F422744"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422745"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422746"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422747"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422748"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422749"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422750"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422751"] = "This fault is caused by 'LSU Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F422752"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422753"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422754"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422755"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422756"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422757"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422758"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422759"] = "This fault is caused by 'LSU Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F422832"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422833"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422834"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422835"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422836"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422837"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422838"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422839"] = "This fault is caused by 'LSACK Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F422848"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422849"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422850"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422851"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422852"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422853"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422854"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422855"] = "This fault is caused by 'LSACK Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F422856"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422857"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422858"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422859"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422860"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422861"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422862"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422863"] = "This fault is caused by 'LSACK Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F422864"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422865"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422866"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422867"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422868"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422869"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422870"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422871"] = "This fault is caused by 'LSACK Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F422872"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422873"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422874"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422875"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422876"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422877"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422878"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422879"] = "This fault is caused by 'LSACK Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F422880"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422881"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422882"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422883"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422884"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422885"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422886"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422887"] = "This fault is caused by 'LSACK Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F422912"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422913"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422914"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422915"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422916"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422917"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422918"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422919"] = "This fault is caused by 'LSACK Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F422920"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422921"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422922"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422923"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422924"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422925"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422926"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F422927"] = "This fault is caused by 'LSACK Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423000"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423001"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423002"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423003"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423004"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423005"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423006"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423007"] = "This fault is caused by 'LSREQ Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423016"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423017"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423018"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423019"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423020"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423021"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423022"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423023"] = "This fault is caused by 'LSREQ Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423024"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423025"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423026"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423027"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423028"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423029"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423030"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423031"] = "This fault is caused by 'LSREQ Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423032"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423033"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423034"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423035"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423036"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423037"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423038"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423039"] = "This fault is caused by 'LSREQ Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423040"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423041"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423042"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423043"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423044"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423045"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423046"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423047"] = "This fault is caused by 'LSREQ Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423048"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423049"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423050"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423051"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423052"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423053"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423054"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423055"] = "This fault is caused by 'LSREQ Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423080"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423081"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423082"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423083"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423084"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423085"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423086"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423087"] = "This fault is caused by 'LSREQ Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423088"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423089"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423090"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423091"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423092"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423093"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423094"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423095"] = "This fault is caused by 'LSREQ Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423168"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423169"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423170"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423171"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423172"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423173"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423174"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423175"] = "This fault is caused by 'LSU Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F423184"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423185"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423186"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423187"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423188"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423189"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423190"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423191"] = "This fault is caused by 'LSU Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F423192"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423193"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423194"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423195"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423196"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423197"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423198"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423199"] = "This fault is caused by 'LSU Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F423200"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423201"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423202"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423203"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423204"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423205"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423206"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423207"] = "This fault is caused by 'LSU Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F423208"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423209"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423210"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423211"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423212"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423213"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423214"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423215"] = "This fault is caused by 'LSU Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F423216"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423217"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423218"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423219"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423220"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423221"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423222"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423223"] = "This fault is caused by 'LSU Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F423248"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423249"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423250"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423251"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423252"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423253"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423254"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423255"] = "This fault is caused by 'LSU Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F423256"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423257"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423258"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423259"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423260"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423261"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423262"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423263"] = "This fault is caused by 'LSU Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F423336"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423337"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423338"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423339"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423340"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423341"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423342"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423343"] = "This fault is caused by 'LSA Packets Dropped During GR current value' statistical property crossing threshold level." + self.system_fault_code["F423352"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423353"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423354"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423355"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423356"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423357"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423358"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423359"] = "This fault is caused by 'LSA Packets Dropped During GR cumulative' statistical property crossing threshold level." + self.system_fault_code["F423360"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423361"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423362"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423363"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423364"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423365"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423366"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423367"] = "This fault is caused by 'LSA Packets Dropped During GR periodic' statistical property crossing threshold level." + self.system_fault_code["F423368"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423369"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423370"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423371"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423372"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423373"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423374"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423375"] = "This fault is caused by 'LSA Packets Dropped During GR minimum value' statistical property crossing threshold level." + self.system_fault_code["F423376"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423377"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423378"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423379"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423380"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423381"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423382"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423383"] = "This fault is caused by 'LSA Packets Dropped During GR maximum value' statistical property crossing threshold level." + self.system_fault_code["F423384"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423385"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423386"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423387"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423388"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423389"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423390"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423391"] = "This fault is caused by 'LSA Packets Dropped During GR average value' statistical property crossing threshold level." + self.system_fault_code["F423416"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423417"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423418"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423419"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423420"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423421"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423422"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423423"] = "This fault is caused by 'LSA Packets Dropped During GR trend' statistical property crossing threshold level." + self.system_fault_code["F423424"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423425"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423426"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423427"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423428"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423429"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423430"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423431"] = "This fault is caused by 'LSA Packets Dropped During GR rate' statistical property crossing threshold level." + self.system_fault_code["F423504"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423505"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423506"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423507"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423508"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423509"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423510"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423511"] = "This fault is caused by 'LSA Packets Dropped During SPF current value' statistical property crossing threshold level." + self.system_fault_code["F423520"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423521"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423522"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423523"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423524"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423525"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423526"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423527"] = "This fault is caused by 'LSA Packets Dropped During SPF cumulative' statistical property crossing threshold level." + self.system_fault_code["F423528"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423529"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423530"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423531"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423532"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423533"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423534"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423535"] = "This fault is caused by 'LSA Packets Dropped During SPF periodic' statistical property crossing threshold level." + self.system_fault_code["F423536"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423537"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423538"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423539"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423540"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423541"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423542"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423543"] = "This fault is caused by 'LSA Packets Dropped During SPF minimum value' statistical property crossing threshold level." + self.system_fault_code["F423544"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423545"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423546"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423547"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423548"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423549"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423550"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423551"] = "This fault is caused by 'LSA Packets Dropped During SPF maximum value' statistical property crossing threshold level." + self.system_fault_code["F423552"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423553"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423554"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423555"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423556"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423557"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423558"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423559"] = "This fault is caused by 'LSA Packets Dropped During SPF average value' statistical property crossing threshold level." + self.system_fault_code["F423584"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423585"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423586"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423587"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423588"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423589"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423590"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423591"] = "This fault is caused by 'LSA Packets Dropped During SPF trend' statistical property crossing threshold level." + self.system_fault_code["F423592"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423593"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423594"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423595"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423596"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423597"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423598"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423599"] = "This fault is caused by 'LSA Packets Dropped During SPF rate' statistical property crossing threshold level." + self.system_fault_code["F423672"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423673"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423674"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423675"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423676"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423677"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423678"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423679"] = "This fault is caused by 'Received LSA Packets Ignored current value' statistical property crossing threshold level." + self.system_fault_code["F423688"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423689"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423690"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423691"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423692"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423693"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423694"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423695"] = "This fault is caused by 'Received LSA Packets Ignored cumulative' statistical property crossing threshold level." + self.system_fault_code["F423696"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423697"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423698"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423699"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423700"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423701"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423702"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423703"] = "This fault is caused by 'Received LSA Packets Ignored periodic' statistical property crossing threshold level." + self.system_fault_code["F423704"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423705"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423706"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423707"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423708"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423709"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423710"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423711"] = "This fault is caused by 'Received LSA Packets Ignored minimum value' statistical property crossing threshold level." + self.system_fault_code["F423712"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423713"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423714"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423715"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423716"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423717"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423718"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423719"] = "This fault is caused by 'Received LSA Packets Ignored maximum value' statistical property crossing threshold level." + self.system_fault_code["F423720"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423721"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423722"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423723"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423724"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423725"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423726"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423727"] = "This fault is caused by 'Received LSA Packets Ignored average value' statistical property crossing threshold level." + self.system_fault_code["F423752"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423753"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423754"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423755"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423756"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423757"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423758"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423759"] = "This fault is caused by 'Received LSA Packets Ignored trend' statistical property crossing threshold level." + self.system_fault_code["F423760"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423761"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423762"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423763"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423764"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423765"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423766"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423767"] = "This fault is caused by 'Received LSA Packets Ignored rate' statistical property crossing threshold level." + self.system_fault_code["F423840"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423841"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423842"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423843"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423844"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423845"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423846"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423847"] = "This fault is caused by 'LSU First Tx Packets current value' statistical property crossing threshold level." + self.system_fault_code["F423856"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423857"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423858"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423859"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423860"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423861"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423862"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423863"] = "This fault is caused by 'LSU First Tx Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F423864"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423865"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423866"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423867"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423868"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423869"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423870"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423871"] = "This fault is caused by 'LSU First Tx Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F423872"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423873"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423874"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423875"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423876"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423877"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423878"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423879"] = "This fault is caused by 'LSU First Tx Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F423880"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423881"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423882"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423883"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423884"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423885"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423886"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423887"] = "This fault is caused by 'LSU First Tx Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F423888"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423889"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423890"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423891"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423892"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423893"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423894"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423895"] = "This fault is caused by 'LSU First Tx Packets average value' statistical property crossing threshold level." + self.system_fault_code["F423920"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423921"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423922"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423923"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423924"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423925"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423926"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423927"] = "This fault is caused by 'LSU First Tx Packets trend' statistical property crossing threshold level." + self.system_fault_code["F423928"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423929"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423930"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423931"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423932"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423933"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423934"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F423935"] = "This fault is caused by 'LSU First Tx Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424008"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424009"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424010"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424011"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424012"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424013"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424014"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424015"] = "This fault is caused by 'LSU Packets For LSREQ Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424024"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424025"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424026"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424027"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424028"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424029"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424030"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424031"] = "This fault is caused by 'LSU Packets For LSREQ Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424032"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424033"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424034"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424035"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424036"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424037"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424038"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424039"] = "This fault is caused by 'LSU Packets For LSREQ Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424040"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424041"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424042"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424043"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424044"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424045"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424046"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424047"] = "This fault is caused by 'LSU Packets For LSREQ Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424048"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424049"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424050"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424051"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424052"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424053"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424054"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424055"] = "This fault is caused by 'LSU Packets For LSREQ Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424056"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424057"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424058"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424059"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424060"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424061"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424062"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424063"] = "This fault is caused by 'LSU Packets For LSREQ Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424088"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424089"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424090"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424091"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424092"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424093"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424094"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424095"] = "This fault is caused by 'LSU Packets For LSREQ Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424096"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424097"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424098"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424099"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424100"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424101"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424102"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424103"] = "This fault is caused by 'LSU Packets For LSREQ Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424176"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424177"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424178"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424179"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424180"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424181"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424182"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424183"] = "This fault is caused by 'LSU Packets To Peer current value' statistical property crossing threshold level." + self.system_fault_code["F424192"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424193"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424194"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424195"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424196"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424197"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424198"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424199"] = "This fault is caused by 'LSU Packets To Peer cumulative' statistical property crossing threshold level." + self.system_fault_code["F424200"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424201"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424202"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424203"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424204"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424205"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424206"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424207"] = "This fault is caused by 'LSU Packets To Peer periodic' statistical property crossing threshold level." + self.system_fault_code["F424208"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424209"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424210"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424211"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424212"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424213"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424214"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424215"] = "This fault is caused by 'LSU Packets To Peer minimum value' statistical property crossing threshold level." + self.system_fault_code["F424216"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424217"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424218"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424219"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424220"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424221"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424222"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424223"] = "This fault is caused by 'LSU Packets To Peer maximum value' statistical property crossing threshold level." + self.system_fault_code["F424224"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424225"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424226"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424227"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424228"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424229"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424230"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424231"] = "This fault is caused by 'LSU Packets To Peer average value' statistical property crossing threshold level." + self.system_fault_code["F424256"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424257"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424258"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424259"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424260"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424261"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424262"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424263"] = "This fault is caused by 'LSU Packets To Peer trend' statistical property crossing threshold level." + self.system_fault_code["F424264"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424265"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424266"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424267"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424268"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424269"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424270"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424271"] = "This fault is caused by 'LSU Packets To Peer rate' statistical property crossing threshold level." + self.system_fault_code["F424344"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424345"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424346"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424347"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424348"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424349"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424350"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424351"] = "This fault is caused by 'LSU Retransmission Packets current value' statistical property crossing threshold level." + self.system_fault_code["F424360"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424361"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424362"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424363"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424364"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424365"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424366"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424367"] = "This fault is caused by 'LSU Retransmission Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F424368"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424369"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424370"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424371"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424372"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424373"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424374"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424375"] = "This fault is caused by 'LSU Retransmission Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F424376"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424377"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424378"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424379"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424380"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424381"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424382"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424383"] = "This fault is caused by 'LSU Retransmission Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F424384"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424385"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424386"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424387"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424388"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424389"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424390"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424391"] = "This fault is caused by 'LSU Retransmission Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F424392"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424393"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424394"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424395"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424396"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424397"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424398"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424399"] = "This fault is caused by 'LSU Retransmission Packets average value' statistical property crossing threshold level." + self.system_fault_code["F424424"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424425"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424426"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424427"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424428"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424429"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424430"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424431"] = "This fault is caused by 'LSU Retransmission Packets trend' statistical property crossing threshold level." + self.system_fault_code["F424432"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424433"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424434"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424435"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424436"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424437"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424438"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424439"] = "This fault is caused by 'LSU Retransmission Packets rate' statistical property crossing threshold level." + self.system_fault_code["F424512"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424513"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424514"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424515"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424516"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424517"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424518"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424519"] = "This fault is caused by 'Peer Not Found Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424528"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424529"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424530"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424531"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424532"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424533"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424534"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424535"] = "This fault is caused by 'Peer Not Found Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424536"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424537"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424538"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424539"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424540"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424541"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424542"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424543"] = "This fault is caused by 'Peer Not Found Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424544"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424545"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424546"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424547"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424548"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424549"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424550"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424551"] = "This fault is caused by 'Peer Not Found Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424552"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424553"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424554"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424555"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424556"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424557"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424558"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424559"] = "This fault is caused by 'Peer Not Found Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424560"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424561"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424562"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424563"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424564"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424565"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424566"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424567"] = "This fault is caused by 'Peer Not Found Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424592"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424593"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424594"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424595"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424596"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424597"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424598"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424599"] = "This fault is caused by 'Peer Not Found Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424600"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424601"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424602"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424603"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424604"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424605"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424606"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424607"] = "This fault is caused by 'Peer Not Found Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424680"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424681"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424682"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424683"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424684"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424685"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424686"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424687"] = "This fault is caused by 'Peer RouterId Changed Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F424696"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424697"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424698"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424699"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424700"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424701"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424702"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424703"] = "This fault is caused by 'Peer RouterId Changed Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F424704"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424705"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424706"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424707"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424708"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424709"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424710"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424711"] = "This fault is caused by 'Peer RouterId Changed Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F424712"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424713"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424714"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424715"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424716"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424717"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424718"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424719"] = "This fault is caused by 'Peer RouterId Changed Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F424720"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424721"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424722"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424723"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424724"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424725"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424726"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424727"] = "This fault is caused by 'Peer RouterId Changed Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F424728"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424729"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424730"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424731"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424732"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424733"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424734"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424735"] = "This fault is caused by 'Peer RouterId Changed Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F424760"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424761"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424762"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424763"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424764"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424765"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424766"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424767"] = "This fault is caused by 'Peer RouterId Changed Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F424768"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424769"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424770"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424771"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424772"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424773"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424774"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424775"] = "This fault is caused by 'Peer RouterId Changed Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F424848"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424849"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424850"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424851"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424852"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424853"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424854"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424855"] = "This fault is caused by 'Adjacency Count current value' statistical property crossing threshold level." + self.system_fault_code["F424864"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424865"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424866"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424867"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424868"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424869"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424870"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424871"] = "This fault is caused by 'Adjacency Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F424872"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424873"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424874"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424875"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424876"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424877"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424878"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424879"] = "This fault is caused by 'Adjacency Count periodic' statistical property crossing threshold level." + self.system_fault_code["F424880"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424881"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424882"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424883"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424884"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424885"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424886"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424887"] = "This fault is caused by 'Adjacency Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F424888"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424889"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424890"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424891"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424892"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424893"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424894"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424895"] = "This fault is caused by 'Adjacency Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F424896"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424897"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424898"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424899"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424900"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424901"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424902"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424903"] = "This fault is caused by 'Adjacency Count average value' statistical property crossing threshold level." + self.system_fault_code["F424928"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424929"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424930"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424931"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424932"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424933"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424934"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424935"] = "This fault is caused by 'Adjacency Count trend' statistical property crossing threshold level." + self.system_fault_code["F424936"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424937"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424938"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424939"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424940"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424941"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424942"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F424943"] = "This fault is caused by 'Adjacency Count rate' statistical property crossing threshold level." + self.system_fault_code["F425016"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425017"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425018"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425019"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425020"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425021"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425022"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425023"] = "This fault is caused by 'Flood To Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425032"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425033"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425034"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425035"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425036"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425037"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425038"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425039"] = "This fault is caused by 'Flood To Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425040"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425041"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425042"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425043"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425044"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425045"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425046"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425047"] = "This fault is caused by 'Flood To Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425048"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425049"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425050"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425051"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425052"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425053"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425054"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425055"] = "This fault is caused by 'Flood To Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425056"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425057"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425058"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425059"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425060"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425061"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425062"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425063"] = "This fault is caused by 'Flood To Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425064"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425065"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425066"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425067"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425068"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425069"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425070"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425071"] = "This fault is caused by 'Flood To Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425096"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425097"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425098"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425099"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425100"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425101"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425102"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425103"] = "This fault is caused by 'Flood To Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425104"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425105"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425106"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425107"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425108"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425109"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425110"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425111"] = "This fault is caused by 'Flood To Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425184"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425185"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425186"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425187"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425188"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425189"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425190"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425191"] = "This fault is caused by 'GR Helper Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425200"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425201"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425202"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425203"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425204"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425205"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425206"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425207"] = "This fault is caused by 'GR Helper Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425208"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425209"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425210"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425211"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425212"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425213"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425214"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425215"] = "This fault is caused by 'GR Helper Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425216"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425217"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425218"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425219"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425220"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425221"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425222"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425223"] = "This fault is caused by 'GR Helper Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425224"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425225"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425226"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425227"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425228"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425229"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425230"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425231"] = "This fault is caused by 'GR Helper Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425232"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425233"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425234"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425235"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425236"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425237"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425238"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425239"] = "This fault is caused by 'GR Helper Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425264"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425265"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425266"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425267"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425268"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425269"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425270"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425271"] = "This fault is caused by 'GR Helper Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425272"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425273"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425274"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425275"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425276"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425277"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425278"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425279"] = "This fault is caused by 'GR Helper Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425352"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425353"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425354"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425355"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425356"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425357"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425358"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425359"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F425368"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425369"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425370"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425371"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425372"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425373"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425374"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425375"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F425376"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425377"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425378"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425379"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425380"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425381"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425382"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425383"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F425384"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425385"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425386"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425387"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425388"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425389"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425390"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425391"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F425392"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425393"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425394"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425395"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425396"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425397"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425398"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425399"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F425400"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425401"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425402"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425403"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425404"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425405"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425406"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425407"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F425432"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425433"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425434"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425435"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425436"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425437"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425438"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425439"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F425440"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425441"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425442"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425443"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425444"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425445"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425446"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425447"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F425520"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425521"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425522"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425523"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425524"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425525"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425526"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425527"] = "This fault is caused by 'DBD Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425536"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425537"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425538"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425539"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425540"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425541"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425542"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425543"] = "This fault is caused by 'DBD Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425544"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425545"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425546"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425547"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425548"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425549"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425550"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425551"] = "This fault is caused by 'DBD Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425552"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425553"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425554"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425555"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425556"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425557"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425558"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425559"] = "This fault is caused by 'DBD Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425560"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425561"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425562"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425563"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425564"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425565"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425566"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425567"] = "This fault is caused by 'DBD Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425568"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425569"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425570"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425571"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425572"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425573"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425574"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425575"] = "This fault is caused by 'DBD Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425600"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425601"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425602"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425603"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425604"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425605"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425606"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425607"] = "This fault is caused by 'DBD Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425608"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425609"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425610"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425611"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425612"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425613"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425614"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425615"] = "This fault is caused by 'DBD Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425688"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425689"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425690"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425691"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425692"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425693"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425694"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425695"] = "This fault is caused by 'Hello Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425704"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425705"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425706"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425707"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425708"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425709"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425710"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425711"] = "This fault is caused by 'Hello Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425712"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425713"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425714"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425715"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425716"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425717"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425718"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425719"] = "This fault is caused by 'Hello Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425720"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425721"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425722"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425723"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425724"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425725"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425726"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425727"] = "This fault is caused by 'Hello Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425728"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425729"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425730"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425731"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425732"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425733"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425734"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425735"] = "This fault is caused by 'Hello Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425736"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425737"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425738"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425739"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425740"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425741"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425742"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425743"] = "This fault is caused by 'Hello Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425768"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425769"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425770"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425771"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425772"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425773"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425774"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425775"] = "This fault is caused by 'Hello Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425776"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425777"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425778"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425779"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425780"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425781"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425782"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425783"] = "This fault is caused by 'Hello Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425856"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425857"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425858"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425859"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425860"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425861"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425862"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425863"] = "This fault is caused by 'Total Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F425872"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425873"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425874"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425875"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425876"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425877"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425878"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425879"] = "This fault is caused by 'Total Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F425880"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425881"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425882"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425883"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425884"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425885"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425886"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425887"] = "This fault is caused by 'Total Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F425888"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425889"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425890"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425891"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425892"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425893"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425894"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425895"] = "This fault is caused by 'Total Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F425896"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425897"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425898"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425899"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425900"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425901"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425902"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425903"] = "This fault is caused by 'Total Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F425904"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425905"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425906"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425907"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425908"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425909"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425910"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425911"] = "This fault is caused by 'Total Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F425936"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425937"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425938"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425939"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425940"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425941"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425942"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425943"] = "This fault is caused by 'Total Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F425944"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425945"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425946"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425947"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425948"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425949"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425950"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F425951"] = "This fault is caused by 'Total Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F426024"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426025"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426026"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426027"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426028"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426029"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426030"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426031"] = "This fault is caused by 'If Events Count current value' statistical property crossing threshold level." + self.system_fault_code["F426040"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426041"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426042"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426043"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426044"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426045"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426046"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426047"] = "This fault is caused by 'If Events Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426048"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426049"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426050"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426051"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426052"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426053"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426054"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426055"] = "This fault is caused by 'If Events Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426056"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426057"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426058"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426059"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426060"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426061"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426062"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426063"] = "This fault is caused by 'If Events Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426064"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426065"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426066"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426067"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426068"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426069"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426070"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426071"] = "This fault is caused by 'If Events Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426072"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426073"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426074"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426075"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426076"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426077"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426078"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426079"] = "This fault is caused by 'If Events Count average value' statistical property crossing threshold level." + self.system_fault_code["F426104"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426105"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426106"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426107"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426108"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426109"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426110"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426111"] = "This fault is caused by 'If Events Count trend' statistical property crossing threshold level." + self.system_fault_code["F426112"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426113"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426114"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426115"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426116"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426117"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426118"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426119"] = "This fault is caused by 'If Events Count rate' statistical property crossing threshold level." + self.system_fault_code["F426192"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426193"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426194"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426195"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426196"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426197"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426198"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426199"] = "This fault is caused by 'LSA Count current value' statistical property crossing threshold level." + self.system_fault_code["F426208"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426209"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426210"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426211"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426212"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426213"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426214"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426215"] = "This fault is caused by 'LSA Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426216"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426217"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426218"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426219"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426220"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426221"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426222"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426223"] = "This fault is caused by 'LSA Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426224"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426225"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426226"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426227"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426228"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426229"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426230"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426231"] = "This fault is caused by 'LSA Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426232"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426233"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426234"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426235"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426236"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426237"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426238"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426239"] = "This fault is caused by 'LSA Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426240"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426241"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426242"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426243"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426244"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426245"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426246"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426247"] = "This fault is caused by 'LSA Count average value' statistical property crossing threshold level." + self.system_fault_code["F426272"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426273"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426274"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426275"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426276"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426277"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426278"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426279"] = "This fault is caused by 'LSA Count trend' statistical property crossing threshold level." + self.system_fault_code["F426280"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426281"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426282"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426283"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426284"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426285"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426286"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426287"] = "This fault is caused by 'LSA Count rate' statistical property crossing threshold level." + self.system_fault_code["F426360"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426361"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426362"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426363"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426364"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426365"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426366"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426367"] = "This fault is caused by 'Peer Count current value' statistical property crossing threshold level." + self.system_fault_code["F426376"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426377"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426378"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426379"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426380"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426381"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426382"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426383"] = "This fault is caused by 'Peer Count cumulative' statistical property crossing threshold level." + self.system_fault_code["F426384"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426385"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426386"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426387"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426388"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426389"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426390"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426391"] = "This fault is caused by 'Peer Count periodic' statistical property crossing threshold level." + self.system_fault_code["F426392"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426393"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426394"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426395"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426396"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426397"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426398"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426399"] = "This fault is caused by 'Peer Count minimum value' statistical property crossing threshold level." + self.system_fault_code["F426400"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426401"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426402"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426403"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426404"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426405"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426406"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426407"] = "This fault is caused by 'Peer Count maximum value' statistical property crossing threshold level." + self.system_fault_code["F426408"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426409"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426410"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426411"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426412"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426413"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426414"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426415"] = "This fault is caused by 'Peer Count average value' statistical property crossing threshold level." + self.system_fault_code["F426440"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426441"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426442"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426443"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426444"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426445"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426446"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426447"] = "This fault is caused by 'Peer Count trend' statistical property crossing threshold level." + self.system_fault_code["F426448"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426449"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426450"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426451"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426452"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426453"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426454"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426455"] = "This fault is caused by 'Peer Count rate' statistical property crossing threshold level." + self.system_fault_code["F426528"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426529"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426530"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426531"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426532"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426533"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426534"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426535"] = "This fault is caused by 'Dropped Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426544"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426545"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426546"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426547"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426548"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426549"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426550"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426551"] = "This fault is caused by 'Dropped Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426552"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426553"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426554"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426555"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426556"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426557"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426558"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426559"] = "This fault is caused by 'Dropped Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426560"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426561"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426562"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426563"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426564"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426565"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426566"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426567"] = "This fault is caused by 'Dropped Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426568"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426569"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426570"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426571"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426572"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426573"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426574"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426575"] = "This fault is caused by 'Dropped Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426576"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426577"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426578"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426579"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426580"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426581"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426582"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426583"] = "This fault is caused by 'Dropped Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426608"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426609"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426610"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426611"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426612"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426613"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426614"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426615"] = "This fault is caused by 'Dropped Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426616"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426617"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426618"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426619"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426620"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426621"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426622"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426623"] = "This fault is caused by 'Dropped Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426696"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426697"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426698"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426699"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426700"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426701"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426702"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426703"] = "This fault is caused by 'Error Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426712"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426713"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426714"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426715"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426716"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426717"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426718"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426719"] = "This fault is caused by 'Error Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426720"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426721"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426722"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426723"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426724"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426725"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426726"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426727"] = "This fault is caused by 'Error Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426728"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426729"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426730"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426731"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426732"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426733"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426734"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426735"] = "This fault is caused by 'Error Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426736"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426737"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426738"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426739"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426740"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426741"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426742"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426743"] = "This fault is caused by 'Error Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426744"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426745"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426746"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426747"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426748"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426749"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426750"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426751"] = "This fault is caused by 'Error Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426776"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426777"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426778"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426779"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426780"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426781"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426782"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426783"] = "This fault is caused by 'Error Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426784"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426785"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426786"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426787"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426788"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426789"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426790"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426791"] = "This fault is caused by 'Error Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426864"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426865"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426866"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426867"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426868"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426869"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426870"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426871"] = "This fault is caused by 'Unknown Send Packets current value' statistical property crossing threshold level." + self.system_fault_code["F426880"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426881"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426882"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426883"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426884"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426885"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426886"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426887"] = "This fault is caused by 'Unknown Send Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F426888"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426889"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426890"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426891"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426892"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426893"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426894"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426895"] = "This fault is caused by 'Unknown Send Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F426896"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426897"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426898"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426899"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426900"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426901"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426902"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426903"] = "This fault is caused by 'Unknown Send Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F426904"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426905"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426906"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426907"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426908"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426909"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426910"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426911"] = "This fault is caused by 'Unknown Send Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F426912"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426913"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426914"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426915"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426916"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426917"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426918"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426919"] = "This fault is caused by 'Unknown Send Packets average value' statistical property crossing threshold level." + self.system_fault_code["F426944"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426945"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426946"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426947"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426948"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426949"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426950"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426951"] = "This fault is caused by 'Unknown Send Packets trend' statistical property crossing threshold level." + self.system_fault_code["F426952"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426953"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426954"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426955"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426956"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426957"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426958"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F426959"] = "This fault is caused by 'Unknown Send Packets rate' statistical property crossing threshold level." + self.system_fault_code["F427032"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427033"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427034"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427035"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427036"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427037"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427038"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427039"] = "This fault is caused by 'DBD Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427048"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427049"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427050"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427051"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427052"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427053"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427054"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427055"] = "This fault is caused by 'DBD Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427056"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427057"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427058"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427059"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427060"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427061"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427062"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427063"] = "This fault is caused by 'DBD Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427064"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427065"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427066"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427067"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427068"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427069"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427070"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427071"] = "This fault is caused by 'DBD Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427072"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427073"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427074"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427075"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427076"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427077"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427078"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427079"] = "This fault is caused by 'DBD Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427080"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427081"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427082"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427083"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427084"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427085"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427086"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427087"] = "This fault is caused by 'DBD Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427112"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427113"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427114"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427115"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427116"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427117"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427118"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427119"] = "This fault is caused by 'DBD Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427120"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427121"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427122"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427123"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427124"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427125"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427126"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427127"] = "This fault is caused by 'DBD Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427200"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427201"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427202"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427203"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427204"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427205"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427206"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427207"] = "This fault is caused by 'Hello Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427216"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427217"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427218"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427219"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427220"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427221"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427222"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427223"] = "This fault is caused by 'Hello Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427224"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427225"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427226"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427227"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427228"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427229"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427230"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427231"] = "This fault is caused by 'Hello Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427232"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427233"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427234"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427235"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427236"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427237"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427238"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427239"] = "This fault is caused by 'Hello Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427240"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427241"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427242"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427243"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427244"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427245"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427246"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427247"] = "This fault is caused by 'Hello Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427248"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427249"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427250"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427251"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427252"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427253"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427254"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427255"] = "This fault is caused by 'Hello Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427280"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427281"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427282"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427283"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427284"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427285"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427286"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427287"] = "This fault is caused by 'Hello Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427288"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427289"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427290"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427291"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427292"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427293"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427294"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427295"] = "This fault is caused by 'Hello Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427368"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427369"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427370"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427371"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427372"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427373"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427374"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427375"] = "This fault is caused by 'Total Packets Sent current value' statistical property crossing threshold level." + self.system_fault_code["F427384"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427385"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427386"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427387"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427388"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427389"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427390"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427391"] = "This fault is caused by 'Total Packets Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F427392"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427393"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427394"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427395"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427396"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427397"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427398"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427399"] = "This fault is caused by 'Total Packets Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F427400"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427401"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427402"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427403"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427404"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427405"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427406"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427407"] = "This fault is caused by 'Total Packets Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F427408"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427409"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427410"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427411"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427412"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427413"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427414"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427415"] = "This fault is caused by 'Total Packets Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F427416"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427417"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427418"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427419"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427420"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427421"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427422"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427423"] = "This fault is caused by 'Total Packets Sent average value' statistical property crossing threshold level." + self.system_fault_code["F427448"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427449"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427450"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427451"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427452"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427453"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427454"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427455"] = "This fault is caused by 'Total Packets Sent trend' statistical property crossing threshold level." + self.system_fault_code["F427456"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427457"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427458"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427459"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427460"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427461"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427462"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427463"] = "This fault is caused by 'Total Packets Sent rate' statistical property crossing threshold level." + self.system_fault_code["F427536"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427537"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427538"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427539"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427540"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427541"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427542"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427543"] = "This fault is caused by 'Flood Packet Send IP Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427552"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427553"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427554"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427555"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427556"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427557"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427558"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427559"] = "This fault is caused by 'Flood Packet Send IP Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427560"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427561"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427562"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427563"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427564"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427565"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427566"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427567"] = "This fault is caused by 'Flood Packet Send IP Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427568"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427569"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427570"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427571"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427572"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427573"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427574"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427575"] = "This fault is caused by 'Flood Packet Send IP Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427576"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427577"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427578"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427579"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427580"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427581"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427582"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427583"] = "This fault is caused by 'Flood Packet Send IP Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427584"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427585"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427586"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427587"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427588"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427589"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427590"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427591"] = "This fault is caused by 'Flood Packet Send IP Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427616"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427617"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427618"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427619"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427620"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427621"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427622"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427623"] = "This fault is caused by 'Flood Packet Send IP Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427624"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427625"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427626"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427627"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427628"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427629"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427630"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427631"] = "This fault is caused by 'Flood Packet Send IP Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427704"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427705"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427706"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427707"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427708"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427709"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427710"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427711"] = "This fault is caused by 'Flood Packet Send Token Throttle current value' statistical property crossing threshold level." + self.system_fault_code["F427720"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427721"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427722"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427723"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427724"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427725"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427726"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427727"] = "This fault is caused by 'Flood Packet Send Token Throttle cumulative' statistical property crossing threshold level." + self.system_fault_code["F427728"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427729"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427730"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427731"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427732"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427733"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427734"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427735"] = "This fault is caused by 'Flood Packet Send Token Throttle periodic' statistical property crossing threshold level." + self.system_fault_code["F427736"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427737"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427738"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427739"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427740"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427741"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427742"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427743"] = "This fault is caused by 'Flood Packet Send Token Throttle minimum value' statistical property crossing threshold level." + self.system_fault_code["F427744"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427745"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427746"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427747"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427748"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427749"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427750"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427751"] = "This fault is caused by 'Flood Packet Send Token Throttle maximum value' statistical property crossing threshold level." + self.system_fault_code["F427752"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427753"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427754"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427755"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427756"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427757"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427758"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427759"] = "This fault is caused by 'Flood Packet Send Token Throttle average value' statistical property crossing threshold level." + self.system_fault_code["F427784"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427785"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427786"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427787"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427788"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427789"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427790"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427791"] = "This fault is caused by 'Flood Packet Send Token Throttle trend' statistical property crossing threshold level." + self.system_fault_code["F427792"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427793"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427794"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427795"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427796"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427797"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427798"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F427799"] = "This fault is caused by 'Flood Packet Send Token Throttle rate' statistical property crossing threshold level." + self.system_fault_code["F428576"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428577"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428578"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428579"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428580"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428581"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428582"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428583"] = "This fault is caused by 'number of failed ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428592"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428593"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428594"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428595"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428596"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428597"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428598"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428599"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428600"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428601"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428602"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428603"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428604"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428605"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428606"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428607"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428608"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428609"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428610"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428611"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428612"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428613"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428614"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428615"] = "This fault is caused by 'number of failed ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428616"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428617"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428618"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428619"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428620"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428621"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428622"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428623"] = "This fault is caused by 'number of failed ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428624"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428625"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428626"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428627"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428628"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428629"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428630"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428631"] = "This fault is caused by 'number of failed ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428656"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428657"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428658"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428659"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428660"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428661"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428662"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428663"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428664"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428665"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428666"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428667"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428668"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428669"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428670"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428671"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428744"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428745"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428746"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428747"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428748"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428749"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428750"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428751"] = "This fault is caused by 'ICMP Echo Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F428752"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428753"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428754"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428755"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428756"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428757"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428758"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428759"] = "This fault is caused by 'ICMP Echo Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F428760"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428761"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428762"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428763"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428764"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428765"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428766"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428767"] = "This fault is caused by 'ICMP Echo Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F428768"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428769"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428770"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428771"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428772"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428773"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428774"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428775"] = "This fault is caused by 'ICMP Echo Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F428808"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428809"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428810"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428811"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428812"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428813"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428814"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428815"] = "This fault is caused by 'ICMP Echo Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F428864"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428865"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428866"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428867"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428868"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428869"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428870"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428871"] = "This fault is caused by 'number of successful ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F428880"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428881"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428882"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428883"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428884"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428885"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428886"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428887"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F428888"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428889"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428890"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428891"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428892"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428893"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428894"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428895"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F428896"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428897"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428898"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428899"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428900"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428901"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428902"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428903"] = "This fault is caused by 'number of successful ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F428904"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428905"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428906"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428907"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428908"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428909"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428910"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428911"] = "This fault is caused by 'number of successful ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F428912"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428913"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428914"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428915"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428916"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428917"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428918"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428919"] = "This fault is caused by 'number of successful ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F428944"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428945"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428946"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428947"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428948"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428949"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428950"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428951"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F428952"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428953"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428954"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428955"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428956"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428957"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428958"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F428959"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429032"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429033"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429034"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429035"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429036"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429037"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429038"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429039"] = "This fault is caused by 'number of transmitted ICMP Echo probes current value' statistical property crossing threshold level." + self.system_fault_code["F429048"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429049"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429050"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429051"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429052"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429053"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429054"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429055"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429056"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429057"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429058"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429059"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429060"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429061"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429062"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429063"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429064"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429065"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429066"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429067"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429068"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429069"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429070"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429071"] = "This fault is caused by 'number of transmitted ICMP Echo probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429072"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429073"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429074"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429075"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429076"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429077"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429078"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429079"] = "This fault is caused by 'number of transmitted ICMP Echo probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429080"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429081"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429082"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429083"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429084"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429085"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429086"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429087"] = "This fault is caused by 'number of transmitted ICMP Echo probes average value' statistical property crossing threshold level." + self.system_fault_code["F429112"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429113"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429114"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429115"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429116"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429117"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429118"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429119"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F429120"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429121"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429122"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429123"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429124"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429125"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429126"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429127"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F429200"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429201"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429202"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429203"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429204"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429205"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429206"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429207"] = "This fault is caused by 'number of failed TCP Connect probes current value' statistical property crossing threshold level." + self.system_fault_code["F429216"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429217"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429218"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429219"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429220"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429221"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429222"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429223"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429224"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429225"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429226"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429227"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429228"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429229"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429230"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429231"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429232"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429233"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429234"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429235"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429236"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429237"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429238"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429239"] = "This fault is caused by 'number of failed TCP Connect probes minimum value' statistical property crossing threshold level." + self.system_fault_code["F429240"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429241"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429242"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429243"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429244"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429245"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429246"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429247"] = "This fault is caused by 'number of failed TCP Connect probes maximum value' statistical property crossing threshold level." + self.system_fault_code["F429248"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429249"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429250"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429251"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429252"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429253"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429254"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429255"] = "This fault is caused by 'number of failed TCP Connect probes average value' statistical property crossing threshold level." + self.system_fault_code["F429280"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429281"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429282"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429283"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429284"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429285"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429286"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429287"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429288"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429289"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429290"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429291"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429292"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429293"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429294"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429295"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429368"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429369"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429370"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429371"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429372"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429373"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429374"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429375"] = "This fault is caused by 'TCP Connect Round Trip Time current value' statistical property crossing threshold level." + self.system_fault_code["F429376"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429377"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429378"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429379"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429380"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429381"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429382"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429383"] = "This fault is caused by 'TCP Connect Round Trip Time minimum value' statistical property crossing threshold level." + self.system_fault_code["F429384"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429385"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429386"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429387"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429388"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429389"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429390"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429391"] = "This fault is caused by 'TCP Connect Round Trip Time maximum value' statistical property crossing threshold level." + self.system_fault_code["F429392"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429393"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429394"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429395"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429396"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429397"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429398"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429399"] = "This fault is caused by 'TCP Connect Round Trip Time average value' statistical property crossing threshold level." + self.system_fault_code["F429432"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429433"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429434"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429435"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429436"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429437"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429438"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429439"] = "This fault is caused by 'TCP Connect Round Trip Time trend' statistical property crossing threshold level." + self.system_fault_code["F429488"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429489"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429490"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429491"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429492"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429493"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429494"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429495"] = "This fault is caused by 'number of successful TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429504"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429505"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429506"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429507"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429508"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429509"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429510"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429511"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429512"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429513"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429514"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429515"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429516"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429517"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429518"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429519"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429520"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429521"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429522"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429523"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429524"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429525"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429526"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429527"] = "This fault is caused by 'number of successful TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429528"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429529"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429530"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429531"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429532"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429533"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429534"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429535"] = "This fault is caused by 'number of successful TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429536"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429537"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429538"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429539"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429540"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429541"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429542"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429543"] = "This fault is caused by 'number of successful TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429568"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429569"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429570"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429571"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429572"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429573"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429574"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429575"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429576"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429577"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429578"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429579"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429580"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429581"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429582"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429583"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429656"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429657"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429658"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429659"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429660"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429661"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429662"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429663"] = "This fault is caused by 'number of transmitted TCP Connect probes current value' statistical property crossing threshold" + self.system_fault_code["F429672"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429673"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429674"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429675"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429676"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429677"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429678"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429679"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F429680"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429681"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429682"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429683"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429684"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429685"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429686"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429687"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F429688"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429689"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429690"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429691"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429692"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429693"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429694"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429695"] = "This fault is caused by 'number of transmitted TCP Connect probes minimum value' statistical property crossing threshold" + self.system_fault_code["F429696"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429697"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429698"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429699"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429700"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429701"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429702"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429703"] = "This fault is caused by 'number of transmitted TCP Connect probes maximum value' statistical property crossing threshold" + self.system_fault_code["F429704"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429705"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429706"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429707"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429708"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429709"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429710"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429711"] = "This fault is caused by 'number of transmitted TCP Connect probes average value' statistical property crossing threshold" + self.system_fault_code["F429736"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429737"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429738"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429739"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429740"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429741"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429742"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429743"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F429744"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429745"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429746"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429747"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429748"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429749"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429750"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429751"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F429960"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429961"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429962"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429963"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429964"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429965"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429966"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429967"] = "This fault is caused by 'Number of BFD Session Flaps current value' statistical property crossing threshold level." + self.system_fault_code["F429976"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429977"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429978"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429979"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429980"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429981"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429982"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429983"] = "This fault is caused by 'Number of BFD Session Flaps cumulative' statistical property crossing threshold level." + self.system_fault_code["F429984"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429985"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429986"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429987"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429988"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429989"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429990"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429991"] = "This fault is caused by 'Number of BFD Session Flaps periodic' statistical property crossing threshold level." + self.system_fault_code["F429992"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429993"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429994"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429995"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429996"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429997"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429998"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F429999"] = "This fault is caused by 'Number of BFD Session Flaps minimum value' statistical property crossing threshold level." + self.system_fault_code["F430000"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430001"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430002"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430003"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430004"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430005"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430006"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430007"] = "This fault is caused by 'Number of BFD Session Flaps maximum value' statistical property crossing threshold level." + self.system_fault_code["F430008"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430009"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430010"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430011"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430012"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430013"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430014"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430015"] = "This fault is caused by 'Number of BFD Session Flaps average value' statistical property crossing threshold level." + self.system_fault_code["F430040"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430041"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430042"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430043"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430044"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430045"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430046"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430047"] = "This fault is caused by 'Number of BFD Session Flaps trend' statistical property crossing threshold level." + self.system_fault_code["F430048"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430049"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430050"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430051"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430052"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430053"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430054"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430055"] = "This fault is caused by 'Number of BFD Session Flaps rate' statistical property crossing threshold level." + self.system_fault_code["F430128"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430129"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430130"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430131"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430132"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430133"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430134"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430135"] = "This fault is caused by 'Packets Received current value' statistical property crossing threshold level." + self.system_fault_code["F430144"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430145"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430146"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430147"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430148"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430149"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430150"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430151"] = "This fault is caused by 'Packets Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F430152"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430153"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430154"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430155"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430156"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430157"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430158"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430159"] = "This fault is caused by 'Packets Received periodic' statistical property crossing threshold level." + self.system_fault_code["F430160"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430161"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430162"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430163"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430164"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430165"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430166"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430167"] = "This fault is caused by 'Packets Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F430168"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430169"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430170"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430171"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430172"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430173"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430174"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430175"] = "This fault is caused by 'Packets Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F430176"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430177"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430178"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430179"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430180"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430181"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430182"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430183"] = "This fault is caused by 'Packets Received average value' statistical property crossing threshold level." + self.system_fault_code["F430208"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430209"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430210"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430211"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430212"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430213"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430214"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430215"] = "This fault is caused by 'Packets Received trend' statistical property crossing threshold level." + self.system_fault_code["F430216"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430217"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430218"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430219"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430220"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430221"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430222"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430223"] = "This fault is caused by 'Packets Received rate' statistical property crossing threshold level." + self.system_fault_code["F430296"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430297"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430298"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430299"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430300"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430301"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430302"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430303"] = "This fault is caused by 'Packets Transmitted current value' statistical property crossing threshold level." + self.system_fault_code["F430312"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430313"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430314"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430315"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430316"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430317"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430318"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430319"] = "This fault is caused by 'Packets Transmitted cumulative' statistical property crossing threshold level." + self.system_fault_code["F430320"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430321"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430322"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430323"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430324"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430325"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430326"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430327"] = "This fault is caused by 'Packets Transmitted periodic' statistical property crossing threshold level." + self.system_fault_code["F430328"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430329"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430330"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430331"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430332"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430333"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430334"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430335"] = "This fault is caused by 'Packets Transmitted minimum value' statistical property crossing threshold level." + self.system_fault_code["F430336"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430337"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430338"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430339"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430340"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430341"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430342"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430343"] = "This fault is caused by 'Packets Transmitted maximum value' statistical property crossing threshold level." + self.system_fault_code["F430344"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430345"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430346"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430347"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430348"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430349"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430350"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430351"] = "This fault is caused by 'Packets Transmitted average value' statistical property crossing threshold level." + self.system_fault_code["F430376"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430377"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430378"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430379"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430380"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430381"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430382"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430383"] = "This fault is caused by 'Packets Transmitted trend' statistical property crossing threshold level." + self.system_fault_code["F430384"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430385"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430386"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430387"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430388"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430389"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430390"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F430391"] = "This fault is caused by 'Packets Transmitted rate' statistical property crossing threshold level." + self.system_fault_code["F432528"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432529"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432530"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432531"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432532"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432533"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432534"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432535"] = "This fault is caused by 'number of failed ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432536"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432537"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432538"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432539"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432540"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432541"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432542"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432543"] = "This fault is caused by 'number of failed ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432568"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432569"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432570"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432571"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432572"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432573"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432574"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432575"] = "This fault is caused by 'number of failed ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432576"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432577"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432578"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432579"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432580"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432581"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432582"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432583"] = "This fault is caused by 'number of failed ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432632"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432633"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432634"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432635"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432636"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432637"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432638"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432639"] = "This fault is caused by 'number of successful ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432640"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432641"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432642"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432643"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432644"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432645"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432646"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432647"] = "This fault is caused by 'number of successful ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432672"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432673"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432674"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432675"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432676"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432677"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432678"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432679"] = "This fault is caused by 'number of successful ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432680"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432681"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432682"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432683"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432684"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432685"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432686"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432687"] = "This fault is caused by 'number of successful ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432736"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432737"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432738"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432739"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432740"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432741"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432742"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432743"] = "This fault is caused by 'number of transmitted ICMP Echo probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432744"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432745"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432746"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432747"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432748"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432749"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432750"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432751"] = "This fault is caused by 'number of transmitted ICMP Echo probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432776"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432777"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432778"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432779"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432780"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432781"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432782"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432783"] = "This fault is caused by 'number of transmitted ICMP Echo probes trend' statistical property crossing threshold level." + self.system_fault_code["F432784"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432785"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432786"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432787"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432788"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432789"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432790"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432791"] = "This fault is caused by 'number of transmitted ICMP Echo probes rate' statistical property crossing threshold level." + self.system_fault_code["F432840"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432841"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432842"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432843"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432844"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432845"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432846"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432847"] = "This fault is caused by 'number of failed TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432848"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432849"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432850"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432851"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432852"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432853"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432854"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432855"] = "This fault is caused by 'number of failed TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432880"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432881"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432882"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432883"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432884"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432885"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432886"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432887"] = "This fault is caused by 'number of failed TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432888"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432889"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432890"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432891"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432892"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432893"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432894"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432895"] = "This fault is caused by 'number of failed TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432944"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432945"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432946"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432947"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432948"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432949"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432950"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432951"] = "This fault is caused by 'number of successful TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F432952"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432953"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432954"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432955"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432956"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432957"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432958"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432959"] = "This fault is caused by 'number of successful TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F432984"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432985"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432986"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432987"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432988"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432989"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432990"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432991"] = "This fault is caused by 'number of successful TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F432992"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432993"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432994"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432995"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432996"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432997"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432998"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F432999"] = "This fault is caused by 'number of successful TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433048"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433049"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433050"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433051"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433052"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433053"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433054"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433055"] = "This fault is caused by 'number of transmitted TCP Connect probes cumulative' statistical property crossing threshold level." + self.system_fault_code["F433056"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433057"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433058"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433059"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433060"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433061"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433062"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433063"] = "This fault is caused by 'number of transmitted TCP Connect probes periodic' statistical property crossing threshold level." + self.system_fault_code["F433088"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433089"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433090"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433091"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433092"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433093"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433094"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433095"] = "This fault is caused by 'number of transmitted TCP Connect probes trend' statistical property crossing threshold level." + self.system_fault_code["F433096"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433097"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433098"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433099"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433100"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433101"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433102"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F433103"] = "This fault is caused by 'number of transmitted TCP Connect probes rate' statistical property crossing threshold level." + self.system_fault_code["F440192"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440193"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440194"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440195"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440196"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440197"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440198"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440199"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440208"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440209"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440210"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440211"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440212"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440213"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440214"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440215"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440216"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440217"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440218"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440219"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440220"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440221"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440222"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440223"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440224"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440225"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440226"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440227"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440228"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440229"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440230"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440231"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440232"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440233"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440234"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440235"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440236"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440237"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440238"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440239"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440240"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440241"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440242"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440243"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440244"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440245"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440246"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440247"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440272"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440273"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440274"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440275"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440276"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440277"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440278"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440279"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440280"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440281"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440282"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440283"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440284"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440285"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440286"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440287"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440360"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440361"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440362"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440363"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440364"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440365"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440366"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440367"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440368"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440369"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440370"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440371"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440372"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440373"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440374"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440375"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440400"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440401"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440402"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440403"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440404"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440405"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440406"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440407"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440408"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440409"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440410"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440411"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440412"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440413"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440414"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440415"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440464"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440465"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440466"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440467"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440468"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440469"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440470"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440471"] = "This fault is caused by 'egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F440480"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440481"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440482"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440483"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440484"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440485"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440486"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440487"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440488"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440489"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440490"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440491"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440492"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440493"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440494"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440495"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440496"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440497"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440498"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440499"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440500"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440501"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440502"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440503"] = "This fault is caused by 'egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F440504"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440505"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440506"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440507"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440508"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440509"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440510"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440511"] = "This fault is caused by 'egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F440512"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440513"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440514"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440515"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440516"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440517"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440518"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440519"] = "This fault is caused by 'egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F440544"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440545"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440546"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440547"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440548"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440549"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440550"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440551"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440552"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440553"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440554"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440555"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440556"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440557"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440558"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440559"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440632"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440633"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440634"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440635"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440636"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440637"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440638"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440639"] = "This fault is caused by 'egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F440640"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440641"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440642"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440643"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440644"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440645"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440646"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440647"] = "This fault is caused by 'egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F440672"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440673"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440674"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440675"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440676"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440677"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440678"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440679"] = "This fault is caused by 'egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F440680"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440681"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440682"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440683"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440684"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440685"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440686"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440687"] = "This fault is caused by 'egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F440736"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440737"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440738"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440739"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440740"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440741"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440742"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440743"] = "This fault is caused by 'egress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F440752"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440753"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440754"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440755"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440756"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440757"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440758"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440759"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440760"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440761"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440762"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440763"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440764"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440765"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440766"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440767"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440768"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440769"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440770"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440771"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440772"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440773"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440774"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440775"] = "This fault is caused by 'egress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F440776"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440777"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440778"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440779"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440780"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440781"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440782"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440783"] = "This fault is caused by 'egress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F440784"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440785"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440786"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440787"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440788"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440789"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440790"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440791"] = "This fault is caused by 'egress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F440816"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440817"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440818"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440819"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440820"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440821"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440822"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440823"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440824"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440825"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440826"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440827"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440828"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440829"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440830"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440831"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440904"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440905"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440906"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440907"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440908"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440909"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440910"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440911"] = "This fault is caused by 'egress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F440912"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440913"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440914"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440915"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440916"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440917"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440918"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440919"] = "This fault is caused by 'egress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F440944"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440945"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440946"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440947"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440948"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440949"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440950"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440951"] = "This fault is caused by 'egress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F440952"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440953"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440954"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440955"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440956"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440957"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440958"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F440959"] = "This fault is caused by 'egress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441008"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441009"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441010"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441011"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441012"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441013"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441014"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441015"] = "This fault is caused by 'egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F441024"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441025"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441026"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441027"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441028"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441029"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441030"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441031"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441032"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441033"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441034"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441035"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441036"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441037"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441038"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441039"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441040"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441041"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441042"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441043"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441044"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441045"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441046"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441047"] = "This fault is caused by 'egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441048"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441049"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441050"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441051"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441052"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441053"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441054"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441055"] = "This fault is caused by 'egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441056"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441057"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441058"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441059"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441060"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441061"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441062"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441063"] = "This fault is caused by 'egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F441088"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441089"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441090"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441091"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441092"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441093"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441094"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441095"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441096"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441097"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441098"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441099"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441100"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441101"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441102"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441103"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441176"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441177"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441178"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441179"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441180"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441181"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441182"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441183"] = "This fault is caused by 'egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441184"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441185"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441186"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441187"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441188"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441189"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441190"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441191"] = "This fault is caused by 'egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441216"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441217"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441218"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441219"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441220"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441221"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441222"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441223"] = "This fault is caused by 'egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F441224"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441225"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441226"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441227"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441228"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441229"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441230"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441231"] = "This fault is caused by 'egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F441280"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441281"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441282"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441283"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441284"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441285"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441286"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441287"] = "This fault is caused by 'ingress drop bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441296"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441297"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441298"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441299"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441300"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441301"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441302"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441303"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441304"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441305"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441306"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441307"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441308"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441309"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441310"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441311"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441312"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441313"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441314"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441315"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441316"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441317"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441318"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441319"] = "This fault is caused by 'ingress drop bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441320"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441321"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441322"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441323"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441324"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441325"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441326"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441327"] = "This fault is caused by 'ingress drop bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441328"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441329"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441330"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441331"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441332"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441333"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441334"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441335"] = "This fault is caused by 'ingress drop bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441360"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441361"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441362"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441363"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441364"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441365"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441366"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441367"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441368"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441369"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441370"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441371"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441372"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441373"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441374"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441375"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441448"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441449"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441450"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441451"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441452"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441453"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441454"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441455"] = "This fault is caused by 'ingress drop bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441456"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441457"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441458"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441459"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441460"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441461"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441462"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441463"] = "This fault is caused by 'ingress drop bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441488"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441489"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441490"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441491"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441492"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441493"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441494"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441495"] = "This fault is caused by 'ingress drop bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441496"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441497"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441498"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441499"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441500"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441501"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441502"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441503"] = "This fault is caused by 'ingress drop bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441552"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441553"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441554"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441555"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441556"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441557"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441558"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441559"] = "This fault is caused by 'ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F441568"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441569"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441570"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441571"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441572"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441573"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441574"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441575"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441576"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441577"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441578"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441579"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441580"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441581"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441582"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441583"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441584"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441585"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441586"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441587"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441588"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441589"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441590"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441591"] = "This fault is caused by 'ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F441592"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441593"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441594"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441595"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441596"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441597"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441598"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441599"] = "This fault is caused by 'ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F441600"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441601"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441602"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441603"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441604"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441605"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441606"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441607"] = "This fault is caused by 'ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F441632"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441633"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441634"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441635"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441636"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441637"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441638"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441639"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441640"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441641"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441642"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441643"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441644"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441645"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441646"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441647"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441720"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441721"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441722"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441723"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441724"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441725"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441726"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441727"] = "This fault is caused by 'ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F441728"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441729"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441730"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441731"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441732"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441733"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441734"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441735"] = "This fault is caused by 'ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F441760"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441761"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441762"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441763"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441764"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441765"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441766"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441767"] = "This fault is caused by 'ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F441768"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441769"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441770"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441771"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441772"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441773"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441774"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441775"] = "This fault is caused by 'ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F441824"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441825"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441826"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441827"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441828"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441829"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441830"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441831"] = "This fault is caused by 'ingress drop packets current value' statistical property crossing threshold level." + self.system_fault_code["F441840"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441841"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441842"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441843"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441844"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441845"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441846"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441847"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441848"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441849"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441850"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441851"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441852"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441853"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441854"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441855"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F441856"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441857"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441858"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441859"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441860"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441861"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441862"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441863"] = "This fault is caused by 'ingress drop packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F441864"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441865"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441866"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441867"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441868"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441869"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441870"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441871"] = "This fault is caused by 'ingress drop packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F441872"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441873"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441874"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441875"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441876"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441877"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441878"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441879"] = "This fault is caused by 'ingress drop packets average value' statistical property crossing threshold level." + self.system_fault_code["F441904"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441905"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441906"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441907"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441908"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441909"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441910"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441911"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F441912"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441913"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441914"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441915"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441916"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441917"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441918"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441919"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F441992"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441993"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441994"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441995"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441996"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441997"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441998"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F441999"] = "This fault is caused by 'ingress drop packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442000"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442001"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442002"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442003"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442004"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442005"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442006"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442007"] = "This fault is caused by 'ingress drop packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442032"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442033"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442034"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442035"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442036"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442037"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442038"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442039"] = "This fault is caused by 'ingress drop packets trend' statistical property crossing threshold level." + self.system_fault_code["F442040"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442041"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442042"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442043"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442044"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442045"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442046"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442047"] = "This fault is caused by 'ingress drop packets rate' statistical property crossing threshold level." + self.system_fault_code["F442096"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442097"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442098"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442099"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442100"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442101"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442102"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442103"] = "This fault is caused by 'ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F442112"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442113"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442114"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442115"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442116"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442117"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442118"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442119"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442120"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442121"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442122"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442123"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442124"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442125"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442126"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442127"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442128"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442129"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442130"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442131"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442132"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442133"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442134"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442135"] = "This fault is caused by 'ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F442136"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442137"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442138"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442139"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442140"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442141"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442142"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442143"] = "This fault is caused by 'ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F442144"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442145"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442146"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442147"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442148"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442149"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442150"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442151"] = "This fault is caused by 'ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F442176"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442177"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442178"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442179"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442180"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442181"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442182"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442183"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442184"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442185"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442186"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442187"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442188"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442189"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442190"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442191"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442264"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442265"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442266"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442267"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442268"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442269"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442270"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442271"] = "This fault is caused by 'ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F442272"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442273"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442274"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442275"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442276"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442277"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442278"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442279"] = "This fault is caused by 'ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F442304"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442305"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442306"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442307"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442308"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442309"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442310"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442311"] = "This fault is caused by 'ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F442312"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442313"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442314"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442315"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442316"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442317"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442318"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F442319"] = "This fault is caused by 'ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F450296"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450297"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450298"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450299"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450300"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450301"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450302"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450303"] = "This fault is caused by 'Multicast usage current value' statistical property crossing threshold level." + self.system_fault_code["F450304"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450305"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450306"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450307"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450308"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450309"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450310"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450311"] = "This fault is caused by 'Multicast usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F450312"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450313"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450314"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450315"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450316"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450317"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450318"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450319"] = "This fault is caused by 'Multicast usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F450320"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450321"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450322"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450323"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450324"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450325"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450326"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450327"] = "This fault is caused by 'Multicast usage average value' statistical property crossing threshold level." + self.system_fault_code["F450360"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450361"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450362"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450363"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450364"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450365"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450366"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F450367"] = "This fault is caused by 'Multicast usage trend' statistical property crossing threshold level." + self.system_fault_code["F452424"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452425"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452426"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452427"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452428"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452429"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452430"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452431"] = "This fault is caused by 'Native LB HTPP 5XX error count current value' statistical property crossing threshold level." + self.system_fault_code["F452440"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452441"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452442"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452443"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452444"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452445"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452446"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452447"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452448"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452449"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452450"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452451"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452452"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452453"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452454"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452455"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452456"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452457"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452458"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452459"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452460"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452461"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452462"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452463"] = "This fault is caused by 'Native LB HTPP 5XX error count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452464"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452465"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452466"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452467"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452468"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452469"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452470"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452471"] = "This fault is caused by 'Native LB HTPP 5XX error count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452472"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452473"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452474"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452475"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452476"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452477"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452478"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452479"] = "This fault is caused by 'Native LB HTPP 5XX error count average value' statistical property crossing threshold level." + self.system_fault_code["F452504"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452505"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452506"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452507"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452508"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452509"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452510"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452511"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452512"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452513"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452514"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452515"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452516"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452517"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452518"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452519"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452592"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452593"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452594"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452595"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452596"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452597"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452598"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452599"] = "This fault is caused by 'Native LB HTPP 5XX error count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452600"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452601"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452602"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452603"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452604"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452605"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452606"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452607"] = "This fault is caused by 'Native LB HTPP 5XX error count periodic' statistical property crossing threshold level." + self.system_fault_code["F452632"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452633"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452634"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452635"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452636"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452637"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452638"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452639"] = "This fault is caused by 'Native LB HTPP 5XX error count trend' statistical property crossing threshold level." + self.system_fault_code["F452640"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452641"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452642"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452643"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452644"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452645"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452646"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452647"] = "This fault is caused by 'Native LB HTPP 5XX error count rate' statistical property crossing threshold level." + self.system_fault_code["F452696"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452697"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452698"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452699"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452700"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452701"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452702"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452703"] = "This fault is caused by 'Nantive LB rejected requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452712"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452713"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452714"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452715"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452716"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452717"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452718"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452719"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452720"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452721"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452722"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452723"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452724"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452725"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452726"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452727"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452728"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452729"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452730"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452731"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452732"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452733"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452734"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452735"] = "This fault is caused by 'Nantive LB rejected requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F452736"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452737"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452738"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452739"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452740"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452741"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452742"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452743"] = "This fault is caused by 'Nantive LB rejected requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F452744"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452745"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452746"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452747"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452748"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452749"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452750"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452751"] = "This fault is caused by 'Nantive LB rejected requests count average value' statistical property crossing threshold level." + self.system_fault_code["F452776"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452777"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452778"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452779"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452780"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452781"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452782"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452783"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452784"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452785"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452786"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452787"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452788"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452789"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452790"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452791"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452864"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452865"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452866"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452867"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452868"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452869"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452870"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452871"] = "This fault is caused by 'Nantive LB rejected requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452872"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452873"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452874"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452875"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452876"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452877"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452878"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452879"] = "This fault is caused by 'Nantive LB rejected requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452904"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452905"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452906"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452907"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452908"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452909"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452910"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452911"] = "This fault is caused by 'Nantive LB rejected requests count trend' statistical property crossing threshold level." + self.system_fault_code["F452912"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452913"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452914"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452915"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452916"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452917"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452918"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452919"] = "This fault is caused by 'Nantive LB rejected requests count rate' statistical property crossing threshold level." + self.system_fault_code["F452968"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452969"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452970"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452971"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452972"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452973"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452974"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452975"] = "This fault is caused by 'Native LB requests count current value' statistical property crossing threshold level." + self.system_fault_code["F452984"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452985"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452986"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452987"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452988"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452989"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452990"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452991"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F452992"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452993"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452994"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452995"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452996"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452997"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452998"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F452999"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453000"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453001"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453002"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453003"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453004"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453005"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453006"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453007"] = "This fault is caused by 'Native LB requests count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453008"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453009"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453010"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453011"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453012"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453013"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453014"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453015"] = "This fault is caused by 'Native LB requests count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453016"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453017"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453018"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453019"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453020"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453021"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453022"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453023"] = "This fault is caused by 'Native LB requests count average value' statistical property crossing threshold level." + self.system_fault_code["F453048"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453049"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453050"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453051"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453052"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453053"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453054"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453055"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453056"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453057"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453058"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453059"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453060"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453061"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453062"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453063"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453136"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453137"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453138"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453139"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453140"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453141"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453142"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453143"] = "This fault is caused by 'Native LB requests count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453144"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453145"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453146"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453147"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453148"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453149"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453150"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453151"] = "This fault is caused by 'Native LB requests count periodic' statistical property crossing threshold level." + self.system_fault_code["F453176"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453177"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453178"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453179"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453180"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453181"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453182"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453183"] = "This fault is caused by 'Native LB requests count trend' statistical property crossing threshold level." + self.system_fault_code["F453184"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453185"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453186"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453187"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453188"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453189"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453190"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453191"] = "This fault is caused by 'Native LB requests count rate' statistical property crossing threshold level." + self.system_fault_code["F453240"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453241"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453242"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453243"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453244"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453245"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453246"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453247"] = "This fault is caused by 'Pool healthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453256"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453257"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453258"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453259"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453260"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453261"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453262"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453263"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453264"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453265"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453266"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453267"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453268"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453269"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453270"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453271"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453272"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453273"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453274"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453275"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453276"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453277"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453278"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453279"] = "This fault is caused by 'Pool healthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453280"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453281"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453282"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453283"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453284"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453285"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453286"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453287"] = "This fault is caused by 'Pool healthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453288"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453289"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453290"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453291"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453292"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453293"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453294"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453295"] = "This fault is caused by 'Pool healthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453320"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453321"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453322"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453323"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453324"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453325"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453326"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453327"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453328"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453329"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453330"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453331"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453332"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453333"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453334"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453335"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453408"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453409"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453410"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453411"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453412"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453413"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453414"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453415"] = "This fault is caused by 'Pool healthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453416"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453417"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453418"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453419"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453420"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453421"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453422"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453423"] = "This fault is caused by 'Pool healthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453448"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453449"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453450"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453451"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453452"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453453"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453454"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453455"] = "This fault is caused by 'Pool healthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453456"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453457"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453458"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453459"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453460"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453461"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453462"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453463"] = "This fault is caused by 'Pool healthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453512"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453513"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453514"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453515"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453516"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453517"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453518"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453519"] = "This fault is caused by 'Pool unhealthy hosts count current value' statistical property crossing threshold level." + self.system_fault_code["F453528"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453529"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453530"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453531"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453532"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453533"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453534"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453535"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453536"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453537"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453538"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453539"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453540"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453541"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453542"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453543"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453544"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453545"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453546"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453547"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453548"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453549"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453550"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453551"] = "This fault is caused by 'Pool unhealthy hosts count minimum value' statistical property crossing threshold level." + self.system_fault_code["F453552"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453553"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453554"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453555"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453556"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453557"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453558"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453559"] = "This fault is caused by 'Pool unhealthy hosts count maximum value' statistical property crossing threshold level." + self.system_fault_code["F453560"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453561"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453562"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453563"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453564"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453565"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453566"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453567"] = "This fault is caused by 'Pool unhealthy hosts count average value' statistical property crossing threshold level." + self.system_fault_code["F453592"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453593"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453594"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453595"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453596"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453597"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453598"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453599"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453600"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453601"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453602"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453603"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453604"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453605"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453606"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453607"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453680"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453681"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453682"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453683"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453684"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453685"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453686"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453687"] = "This fault is caused by 'Pool unhealthy hosts count cumulative' statistical property crossing threshold level." + self.system_fault_code["F453688"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453689"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453690"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453691"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453692"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453693"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453694"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453695"] = "This fault is caused by 'Pool unhealthy hosts count periodic' statistical property crossing threshold level." + self.system_fault_code["F453720"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453721"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453722"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453723"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453724"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453725"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453726"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453727"] = "This fault is caused by 'Pool unhealthy hosts count trend' statistical property crossing threshold level." + self.system_fault_code["F453728"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453729"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453730"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453731"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453732"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453733"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453734"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453735"] = "This fault is caused by 'Pool unhealthy hosts count rate' statistical property crossing threshold level." + self.system_fault_code["F453784"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453785"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453786"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453787"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453788"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453789"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453790"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453791"] = "This fault is caused by 'Pool response time current value' statistical property crossing threshold level." + self.system_fault_code["F453800"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453801"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453802"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453803"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453804"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453805"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453806"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453807"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453808"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453809"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453810"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453811"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453812"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453813"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453814"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453815"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453816"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453817"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453818"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453819"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453820"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453821"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453822"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453823"] = "This fault is caused by 'Pool response time minimum value' statistical property crossing threshold level." + self.system_fault_code["F453824"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453825"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453826"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453827"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453828"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453829"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453830"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453831"] = "This fault is caused by 'Pool response time maximum value' statistical property crossing threshold level." + self.system_fault_code["F453832"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453833"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453834"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453835"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453836"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453837"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453838"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453839"] = "This fault is caused by 'Pool response time average value' statistical property crossing threshold level." + self.system_fault_code["F453864"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453865"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453866"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453867"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453868"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453869"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453870"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453871"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453872"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453873"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453874"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453875"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453876"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453877"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453878"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453879"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F453952"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453953"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453954"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453955"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453956"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453957"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453958"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453959"] = "This fault is caused by 'Pool response time cumulative' statistical property crossing threshold level." + self.system_fault_code["F453960"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453961"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453962"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453963"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453964"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453965"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453966"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453967"] = "This fault is caused by 'Pool response time periodic' statistical property crossing threshold level." + self.system_fault_code["F453992"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453993"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453994"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453995"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453996"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453997"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453998"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F453999"] = "This fault is caused by 'Pool response time trend' statistical property crossing threshold level." + self.system_fault_code["F454000"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454001"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454002"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454003"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454004"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454005"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454006"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F454007"] = "This fault is caused by 'Pool response time rate' statistical property crossing threshold level." + self.system_fault_code["F456176"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456177"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456178"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456179"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456180"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456181"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456182"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456183"] = "This fault is caused by 'Native LB rules evaluated current value' statistical property crossing threshold level." + self.system_fault_code["F456192"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456193"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456194"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456195"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456196"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456197"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456198"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456199"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456200"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456201"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456202"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456203"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456204"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456205"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456206"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456207"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456208"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456209"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456210"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456211"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456212"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456213"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456214"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456215"] = "This fault is caused by 'Native LB rules evaluated minimum value' statistical property crossing threshold level." + self.system_fault_code["F456216"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456217"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456218"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456219"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456220"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456221"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456222"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456223"] = "This fault is caused by 'Native LB rules evaluated maximum value' statistical property crossing threshold level." + self.system_fault_code["F456224"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456225"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456226"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456227"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456228"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456229"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456230"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456231"] = "This fault is caused by 'Native LB rules evaluated average value' statistical property crossing threshold level." + self.system_fault_code["F456256"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456257"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456258"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456259"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456260"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456261"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456262"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456263"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456264"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456265"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456266"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456267"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456268"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456269"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456270"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456271"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456344"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456345"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456346"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456347"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456348"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456349"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456350"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456351"] = "This fault is caused by 'Native LB rules evaluated cumulative' statistical property crossing threshold level." + self.system_fault_code["F456352"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456353"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456354"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456355"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456356"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456357"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456358"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456359"] = "This fault is caused by 'Native LB rules evaluated periodic' statistical property crossing threshold level." + self.system_fault_code["F456384"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456385"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456386"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456387"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456388"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456389"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456390"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456391"] = "This fault is caused by 'Native LB rules evaluated trend' statistical property crossing threshold level." + self.system_fault_code["F456392"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456393"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456394"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456395"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456396"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456397"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456398"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456399"] = "This fault is caused by 'Native LB rules evaluated rate' statistical property crossing threshold level." + self.system_fault_code["F456920"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456921"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456922"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456923"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456924"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456925"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456926"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456927"] = "This fault is caused by 'adjacency updates counts current value' statistical property crossing threshold level." + self.system_fault_code["F456936"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456937"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456938"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456939"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456940"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456941"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456942"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456943"] = "This fault is caused by 'adjacency updates counts cumulative' statistical property crossing threshold level." + self.system_fault_code["F456944"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456945"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456946"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456947"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456948"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456949"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456950"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456951"] = "This fault is caused by 'adjacency updates counts periodic' statistical property crossing threshold level." + self.system_fault_code["F456952"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456953"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456954"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456955"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456956"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456957"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456958"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456959"] = "This fault is caused by 'adjacency updates counts minimum value' statistical property crossing threshold level." + self.system_fault_code["F456960"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456961"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456962"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456963"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456964"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456965"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456966"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456967"] = "This fault is caused by 'adjacency updates counts maximum value' statistical property crossing threshold level." + self.system_fault_code["F456968"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456969"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456970"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456971"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456972"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456973"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456974"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F456975"] = "This fault is caused by 'adjacency updates counts average value' statistical property crossing threshold level." + self.system_fault_code["F457000"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457001"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457002"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457003"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457004"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457005"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457006"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457007"] = "This fault is caused by 'adjacency updates counts trend' statistical property crossing threshold level." + self.system_fault_code["F457008"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457009"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457010"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457011"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457012"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457013"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457014"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457015"] = "This fault is caused by 'adjacency updates counts rate' statistical property crossing threshold level." + self.system_fault_code["F457672"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457673"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457674"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457675"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457676"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457677"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457678"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457679"] = "This fault is caused by 'Egress error current value' statistical property crossing threshold level." + self.system_fault_code["F457688"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457689"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457690"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457691"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457692"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457693"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457694"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457695"] = "This fault is caused by 'Egress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F457696"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457697"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457698"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457699"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457700"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457701"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457702"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457703"] = "This fault is caused by 'Egress error periodic' statistical property crossing threshold level." + self.system_fault_code["F457704"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457705"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457706"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457707"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457708"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457709"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457710"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457711"] = "This fault is caused by 'Egress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F457712"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457713"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457714"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457715"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457716"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457717"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457718"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457719"] = "This fault is caused by 'Egress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F457720"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457721"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457722"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457723"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457724"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457725"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457726"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457727"] = "This fault is caused by 'Egress error average value' statistical property crossing threshold level." + self.system_fault_code["F457752"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457753"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457754"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457755"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457756"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457757"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457758"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457759"] = "This fault is caused by 'Egress error trend' statistical property crossing threshold level." + self.system_fault_code["F457760"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457761"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457762"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457763"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457764"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457765"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457766"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457767"] = "This fault is caused by 'Egress error rate' statistical property crossing threshold level." + self.system_fault_code["F457840"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457841"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457842"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457843"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457844"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457845"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457846"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457847"] = "This fault is caused by 'Egress discard current value' statistical property crossing threshold level." + self.system_fault_code["F457856"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457857"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457858"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457859"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457860"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457861"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457862"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457863"] = "This fault is caused by 'Egress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F457864"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457865"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457866"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457867"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457868"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457869"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457870"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457871"] = "This fault is caused by 'Egress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F457872"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457873"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457874"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457875"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457876"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457877"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457878"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457879"] = "This fault is caused by 'Egress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F457880"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457881"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457882"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457883"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457884"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457885"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457886"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457887"] = "This fault is caused by 'Egress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F457888"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457889"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457890"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457891"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457892"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457893"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457894"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457895"] = "This fault is caused by 'Egress discard average value' statistical property crossing threshold level." + self.system_fault_code["F457920"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457921"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457922"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457923"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457924"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457925"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457926"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457927"] = "This fault is caused by 'Egress discard trend' statistical property crossing threshold level." + self.system_fault_code["F457928"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457929"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457930"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457931"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457932"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457933"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457934"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F457935"] = "This fault is caused by 'Egress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458008"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458009"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458010"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458011"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458012"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458013"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458014"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458015"] = "This fault is caused by 'Ingress error current value' statistical property crossing threshold level." + self.system_fault_code["F458024"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458025"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458026"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458027"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458028"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458029"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458030"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458031"] = "This fault is caused by 'Ingress error cumulative' statistical property crossing threshold level." + self.system_fault_code["F458032"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458033"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458034"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458035"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458036"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458037"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458038"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458039"] = "This fault is caused by 'Ingress error periodic' statistical property crossing threshold level." + self.system_fault_code["F458040"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458041"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458042"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458043"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458044"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458045"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458046"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458047"] = "This fault is caused by 'Ingress error minimum value' statistical property crossing threshold level." + self.system_fault_code["F458048"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458049"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458050"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458051"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458052"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458053"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458054"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458055"] = "This fault is caused by 'Ingress error maximum value' statistical property crossing threshold level." + self.system_fault_code["F458056"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458057"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458058"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458059"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458060"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458061"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458062"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458063"] = "This fault is caused by 'Ingress error average value' statistical property crossing threshold level." + self.system_fault_code["F458088"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458089"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458090"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458091"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458092"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458093"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458094"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458095"] = "This fault is caused by 'Ingress error trend' statistical property crossing threshold level." + self.system_fault_code["F458096"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458097"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458098"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458099"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458100"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458101"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458102"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458103"] = "This fault is caused by 'Ingress error rate' statistical property crossing threshold level." + self.system_fault_code["F458176"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458177"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458178"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458179"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458180"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458181"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458182"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458183"] = "This fault is caused by 'Ingress discard current value' statistical property crossing threshold level." + self.system_fault_code["F458192"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458193"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458194"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458195"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458196"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458197"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458198"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458199"] = "This fault is caused by 'Ingress discard cumulative' statistical property crossing threshold level." + self.system_fault_code["F458200"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458201"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458202"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458203"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458204"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458205"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458206"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458207"] = "This fault is caused by 'Ingress discard periodic' statistical property crossing threshold level." + self.system_fault_code["F458208"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458209"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458210"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458211"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458212"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458213"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458214"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458215"] = "This fault is caused by 'Ingress discard minimum value' statistical property crossing threshold level." + self.system_fault_code["F458216"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458217"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458218"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458219"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458220"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458221"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458222"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458223"] = "This fault is caused by 'Ingress discard maximum value' statistical property crossing threshold level." + self.system_fault_code["F458224"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458225"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458226"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458227"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458228"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458229"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458230"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458231"] = "This fault is caused by 'Ingress discard average value' statistical property crossing threshold level." + self.system_fault_code["F458256"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458257"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458258"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458259"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458260"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458261"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458262"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458263"] = "This fault is caused by 'Ingress discard trend' statistical property crossing threshold level." + self.system_fault_code["F458264"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458265"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458266"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458267"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458268"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458269"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458270"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F458271"] = "This fault is caused by 'Ingress discard rate' statistical property crossing threshold level." + self.system_fault_code["F460192"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460193"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460194"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460195"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460196"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460197"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460198"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460199"] = "This fault is caused by 'Bytes in Receive Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460208"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460209"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460210"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460211"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460212"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460213"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460214"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460215"] = "This fault is caused by 'Bytes in Receive Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460216"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460217"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460218"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460219"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460220"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460221"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460222"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460223"] = "This fault is caused by 'Bytes in Receive Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460224"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460225"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460226"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460227"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460228"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460229"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460230"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460231"] = "This fault is caused by 'Bytes in Receive Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460232"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460233"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460234"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460235"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460236"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460237"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460238"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460239"] = "This fault is caused by 'Bytes in Receive Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460240"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460241"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460242"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460243"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460244"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460245"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460246"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460247"] = "This fault is caused by 'Bytes in Receive Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460272"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460273"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460274"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460275"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460276"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460277"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460278"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460279"] = "This fault is caused by 'Bytes in Receive Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460280"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460281"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460282"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460283"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460284"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460285"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460286"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460287"] = "This fault is caused by 'Bytes in Receive Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460360"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460361"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460362"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460363"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460364"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460365"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460366"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460367"] = "This fault is caused by 'Bytes in Send Queue current value' statistical property crossing threshold level." + self.system_fault_code["F460376"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460377"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460378"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460379"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460380"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460381"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460382"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460383"] = "This fault is caused by 'Bytes in Send Queue cumulative' statistical property crossing threshold level." + self.system_fault_code["F460384"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460385"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460386"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460387"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460388"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460389"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460390"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460391"] = "This fault is caused by 'Bytes in Send Queue periodic' statistical property crossing threshold level." + self.system_fault_code["F460392"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460393"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460394"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460395"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460396"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460397"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460398"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460399"] = "This fault is caused by 'Bytes in Send Queue minimum value' statistical property crossing threshold level." + self.system_fault_code["F460400"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460401"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460402"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460403"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460404"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460405"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460406"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460407"] = "This fault is caused by 'Bytes in Send Queue maximum value' statistical property crossing threshold level." + self.system_fault_code["F460408"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460409"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460410"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460411"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460412"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460413"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460414"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460415"] = "This fault is caused by 'Bytes in Send Queue average value' statistical property crossing threshold level." + self.system_fault_code["F460440"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460441"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460442"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460443"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460444"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460445"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460446"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460447"] = "This fault is caused by 'Bytes in Send Queue trend' statistical property crossing threshold level." + self.system_fault_code["F460448"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460449"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460450"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460451"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460452"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460453"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460454"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460455"] = "This fault is caused by 'Bytes in Send Queue rate' statistical property crossing threshold level." + self.system_fault_code["F460528"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460529"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460530"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460531"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460532"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460533"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460534"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460535"] = "This fault is caused by 'Number of Bytes Received current value' statistical property crossing threshold level." + self.system_fault_code["F460544"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460545"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460546"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460547"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460548"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460549"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460550"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460551"] = "This fault is caused by 'Number of Bytes Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460552"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460553"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460554"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460555"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460556"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460557"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460558"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460559"] = "This fault is caused by 'Number of Bytes Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460560"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460561"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460562"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460563"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460564"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460565"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460566"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460567"] = "This fault is caused by 'Number of Bytes Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460568"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460569"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460570"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460571"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460572"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460573"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460574"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460575"] = "This fault is caused by 'Number of Bytes Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460576"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460577"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460578"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460579"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460580"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460581"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460582"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460583"] = "This fault is caused by 'Number of Bytes Received average value' statistical property crossing threshold level." + self.system_fault_code["F460608"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460609"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460610"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460611"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460612"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460613"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460614"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460615"] = "This fault is caused by 'Number of Bytes Received trend' statistical property crossing threshold level." + self.system_fault_code["F460616"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460617"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460618"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460619"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460620"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460621"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460622"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460623"] = "This fault is caused by 'Number of Bytes Received rate' statistical property crossing threshold level." + self.system_fault_code["F460696"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460697"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460698"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460699"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460700"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460701"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460702"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460703"] = "This fault is caused by 'Number of Bytes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F460712"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460713"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460714"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460715"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460716"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460717"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460718"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460719"] = "This fault is caused by 'Number of Bytes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F460720"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460721"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460722"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460723"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460724"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460725"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460726"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460727"] = "This fault is caused by 'Number of Bytes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F460728"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460729"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460730"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460731"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460732"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460733"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460734"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460735"] = "This fault is caused by 'Number of Bytes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F460736"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460737"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460738"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460739"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460740"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460741"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460742"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460743"] = "This fault is caused by 'Number of Bytes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F460744"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460745"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460746"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460747"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460748"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460749"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460750"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460751"] = "This fault is caused by 'Number of Bytes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F460776"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460777"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460778"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460779"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460780"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460781"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460782"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460783"] = "This fault is caused by 'Number of Bytes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F460784"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460785"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460786"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460787"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460788"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460789"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460790"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460791"] = "This fault is caused by 'Number of Bytes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F460864"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460865"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460866"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460867"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460868"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460869"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460870"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460871"] = "This fault is caused by 'Number of Keepalive Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F460880"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460881"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460882"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460883"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460884"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460885"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460886"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460887"] = "This fault is caused by 'Number of Keepalive Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F460888"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460889"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460890"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460891"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460892"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460893"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460894"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460895"] = "This fault is caused by 'Number of Keepalive Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F460896"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460897"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460898"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460899"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460900"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460901"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460902"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460903"] = "This fault is caused by 'Number of Keepalive Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F460904"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460905"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460906"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460907"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460908"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460909"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460910"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460911"] = "This fault is caused by 'Number of Keepalive Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F460912"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460913"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460914"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460915"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460916"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460917"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460918"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460919"] = "This fault is caused by 'Number of Keepalive Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F460944"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460945"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460946"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460947"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460948"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460949"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460950"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460951"] = "This fault is caused by 'Number of Keepalive Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F460952"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460953"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460954"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460955"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460956"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460957"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460958"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F460959"] = "This fault is caused by 'Number of Keepalive Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461032"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461033"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461034"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461035"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461036"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461037"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461038"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461039"] = "This fault is caused by 'Number of Keepalive Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461048"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461049"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461050"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461051"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461052"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461053"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461054"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461055"] = "This fault is caused by 'Number of Keepalive Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461056"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461057"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461058"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461059"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461060"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461061"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461062"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461063"] = "This fault is caused by 'Number of Keepalive Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461064"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461065"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461066"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461067"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461068"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461069"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461070"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461071"] = "This fault is caused by 'Number of Keepalive Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461072"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461073"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461074"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461075"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461076"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461077"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461078"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461079"] = "This fault is caused by 'Number of Keepalive Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461080"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461081"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461082"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461083"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461084"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461085"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461086"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461087"] = "This fault is caused by 'Number of Keepalive Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461112"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461113"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461114"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461115"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461116"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461117"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461118"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461119"] = "This fault is caused by 'Number of Keepalive Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461120"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461121"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461122"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461123"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461124"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461125"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461126"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461127"] = "This fault is caused by 'Number of Keepalive Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461200"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461201"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461202"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461203"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461204"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461205"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461206"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461207"] = "This fault is caused by 'Number of Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461216"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461217"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461218"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461219"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461220"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461221"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461222"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461223"] = "This fault is caused by 'Number of Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461224"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461225"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461226"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461227"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461228"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461229"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461230"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461231"] = "This fault is caused by 'Number of Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461232"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461233"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461234"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461235"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461236"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461237"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461238"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461239"] = "This fault is caused by 'Number of Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461240"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461241"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461242"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461243"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461244"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461245"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461246"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461247"] = "This fault is caused by 'Number of Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461248"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461249"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461250"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461251"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461252"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461253"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461254"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461255"] = "This fault is caused by 'Number of Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461280"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461281"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461282"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461283"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461284"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461285"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461286"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461287"] = "This fault is caused by 'Number of Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461288"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461289"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461290"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461291"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461292"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461293"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461294"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461295"] = "This fault is caused by 'Number of Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461368"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461369"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461370"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461371"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461372"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461373"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461374"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461375"] = "This fault is caused by 'Number of Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461384"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461385"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461386"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461387"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461388"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461389"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461390"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461391"] = "This fault is caused by 'Number of Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461392"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461393"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461394"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461395"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461396"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461397"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461398"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461399"] = "This fault is caused by 'Number of Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461400"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461401"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461402"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461403"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461404"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461405"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461406"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461407"] = "This fault is caused by 'Number of Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461408"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461409"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461410"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461411"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461412"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461413"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461414"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461415"] = "This fault is caused by 'Number of Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461416"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461417"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461418"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461419"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461420"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461421"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461422"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461423"] = "This fault is caused by 'Number of Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461448"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461449"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461450"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461451"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461452"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461453"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461454"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461455"] = "This fault is caused by 'Number of Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461456"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461457"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461458"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461459"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461460"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461461"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461462"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461463"] = "This fault is caused by 'Number of Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461536"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461537"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461538"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461539"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461540"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461541"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461542"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461543"] = "This fault is caused by 'Number of Notification Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F461552"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461553"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461554"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461555"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461556"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461557"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461558"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461559"] = "This fault is caused by 'Number of Notification Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461560"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461561"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461562"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461563"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461564"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461565"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461566"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461567"] = "This fault is caused by 'Number of Notification Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461568"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461569"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461570"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461571"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461572"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461573"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461574"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461575"] = "This fault is caused by 'Number of Notification Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F461576"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461577"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461578"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461579"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461580"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461581"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461582"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461583"] = "This fault is caused by 'Number of Notification Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F461584"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461585"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461586"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461587"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461588"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461589"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461590"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461591"] = "This fault is caused by 'Number of Notification Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F461616"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461617"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461618"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461619"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461620"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461621"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461622"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461623"] = "This fault is caused by 'Number of Notification Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461624"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461625"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461626"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461627"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461628"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461629"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461630"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461631"] = "This fault is caused by 'Number of Notification Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461704"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461705"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461706"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461707"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461708"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461709"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461710"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461711"] = "This fault is caused by 'Number of Notification Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F461720"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461721"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461722"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461723"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461724"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461725"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461726"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461727"] = "This fault is caused by 'Number of Notification Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F461728"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461729"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461730"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461731"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461732"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461733"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461734"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461735"] = "This fault is caused by 'Number of Notification Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F461736"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461737"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461738"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461739"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461740"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461741"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461742"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461743"] = "This fault is caused by 'Number of Notification Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F461744"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461745"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461746"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461747"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461748"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461749"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461750"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461751"] = "This fault is caused by 'Number of Notification Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F461752"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461753"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461754"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461755"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461756"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461757"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461758"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461759"] = "This fault is caused by 'Number of Notification Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F461784"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461785"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461786"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461787"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461788"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461789"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461790"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461791"] = "This fault is caused by 'Number of Notification Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F461792"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461793"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461794"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461795"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461796"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461797"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461798"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461799"] = "This fault is caused by 'Number of Notification Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F461872"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461873"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461874"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461875"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461876"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461877"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461878"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461879"] = "This fault is caused by 'Number of Open Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F461888"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461889"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461890"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461891"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461892"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461893"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461894"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461895"] = "This fault is caused by 'Number of Open Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F461896"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461897"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461898"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461899"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461900"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461901"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461902"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461903"] = "This fault is caused by 'Number of Open Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F461904"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461905"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461906"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461907"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461908"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461909"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461910"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461911"] = "This fault is caused by 'Number of Open Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F461912"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461913"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461914"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461915"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461916"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461917"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461918"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461919"] = "This fault is caused by 'Number of Open Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F461920"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461921"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461922"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461923"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461924"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461925"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461926"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461927"] = "This fault is caused by 'Number of Open Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F461952"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461953"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461954"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461955"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461956"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461957"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461958"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461959"] = "This fault is caused by 'Number of Open Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F461960"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461961"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461962"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461963"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461964"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461965"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461966"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F461967"] = "This fault is caused by 'Number of Open Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462040"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462041"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462042"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462043"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462044"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462045"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462046"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462047"] = "This fault is caused by 'Number of Open Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462056"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462057"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462058"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462059"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462060"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462061"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462062"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462063"] = "This fault is caused by 'Number of Open Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462064"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462065"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462066"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462067"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462068"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462069"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462070"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462071"] = "This fault is caused by 'Number of Open Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462072"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462073"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462074"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462075"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462076"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462077"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462078"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462079"] = "This fault is caused by 'Number of Open Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462080"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462081"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462082"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462083"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462084"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462085"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462086"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462087"] = "This fault is caused by 'Number of Open Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462088"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462089"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462090"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462091"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462092"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462093"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462094"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462095"] = "This fault is caused by 'Number of Open Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462120"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462121"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462122"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462123"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462124"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462125"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462126"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462127"] = "This fault is caused by 'Number of Open Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462128"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462129"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462130"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462131"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462132"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462133"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462134"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462135"] = "This fault is caused by 'Number of Open Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462208"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462209"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462210"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462211"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462212"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462213"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462214"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462215"] = "This fault is caused by 'Number of Update Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462224"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462225"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462226"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462227"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462228"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462229"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462230"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462231"] = "This fault is caused by 'Number of Update Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462232"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462233"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462234"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462235"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462236"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462237"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462238"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462239"] = "This fault is caused by 'Number of Update Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462240"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462241"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462242"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462243"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462244"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462245"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462246"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462247"] = "This fault is caused by 'Number of Update Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462248"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462249"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462250"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462251"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462252"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462253"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462254"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462255"] = "This fault is caused by 'Number of Update Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462256"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462257"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462258"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462259"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462260"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462261"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462262"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462263"] = "This fault is caused by 'Number of Update Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462288"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462289"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462290"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462291"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462292"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462293"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462294"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462295"] = "This fault is caused by 'Number of Update Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462296"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462297"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462298"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462299"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462300"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462301"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462302"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462303"] = "This fault is caused by 'Number of Update Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462376"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462377"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462378"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462379"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462380"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462381"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462382"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462383"] = "This fault is caused by 'Number of Update Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462392"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462393"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462394"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462395"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462396"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462397"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462398"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462399"] = "This fault is caused by 'Number of Update Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462400"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462401"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462402"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462403"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462404"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462405"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462406"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462407"] = "This fault is caused by 'Number of Update Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462408"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462409"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462410"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462411"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462412"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462413"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462414"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462415"] = "This fault is caused by 'Number of Update Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462416"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462417"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462418"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462419"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462420"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462421"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462422"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462423"] = "This fault is caused by 'Number of Update Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462424"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462425"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462426"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462427"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462428"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462429"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462430"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462431"] = "This fault is caused by 'Number of Update Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462456"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462457"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462458"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462459"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462460"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462461"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462462"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462463"] = "This fault is caused by 'Number of Update Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462464"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462465"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462466"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462467"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462468"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462469"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462470"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462471"] = "This fault is caused by 'Number of Update Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462544"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462545"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462546"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462547"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462548"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462549"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462550"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462551"] = "This fault is caused by 'Number of Capability Messages Received current value' statistical property crossing threshold level." + self.system_fault_code["F462560"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462561"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462562"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462563"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462564"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462565"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462566"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462567"] = "This fault is caused by 'Number of Capability Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462568"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462569"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462570"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462571"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462572"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462573"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462574"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462575"] = "This fault is caused by 'Number of Capability Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462576"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462577"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462578"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462579"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462580"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462581"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462582"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462583"] = "This fault is caused by 'Number of Capability Messages Received minimum value' statistical property crossing threshold level." + self.system_fault_code["F462584"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462585"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462586"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462587"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462588"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462589"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462590"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462591"] = "This fault is caused by 'Number of Capability Messages Received maximum value' statistical property crossing threshold level." + self.system_fault_code["F462592"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462593"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462594"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462595"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462596"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462597"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462598"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462599"] = "This fault is caused by 'Number of Capability Messages Received average value' statistical property crossing threshold level." + self.system_fault_code["F462624"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462625"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462626"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462627"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462628"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462629"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462630"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462631"] = "This fault is caused by 'Number of Capability Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462632"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462633"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462634"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462635"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462636"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462637"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462638"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462639"] = "This fault is caused by 'Number of Capability Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462712"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462713"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462714"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462715"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462716"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462717"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462718"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462719"] = "This fault is caused by 'Number of Capability Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F462728"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462729"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462730"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462731"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462732"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462733"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462734"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462735"] = "This fault is caused by 'Number of Capability Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F462736"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462737"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462738"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462739"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462740"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462741"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462742"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462743"] = "This fault is caused by 'Number of Capability Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F462744"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462745"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462746"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462747"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462748"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462749"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462750"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462751"] = "This fault is caused by 'Number of Capability Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F462752"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462753"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462754"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462755"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462756"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462757"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462758"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462759"] = "This fault is caused by 'Number of Capability Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F462760"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462761"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462762"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462763"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462764"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462765"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462766"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462767"] = "This fault is caused by 'Number of Capability Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F462792"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462793"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462794"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462795"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462796"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462797"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462798"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462799"] = "This fault is caused by 'Number of Capability Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F462800"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462801"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462802"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462803"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462804"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462805"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462806"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462807"] = "This fault is caused by 'Number of Capability Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F462880"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462881"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462882"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462883"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462884"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462885"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462886"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462887"] = "This fault is caused by 'Number of Route Refresh Messages Received current value' statistical property crossing threshold" + self.system_fault_code["F462896"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462897"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462898"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462899"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462900"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462901"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462902"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462903"] = "This fault is caused by 'Number of Route Refresh Messages Received cumulative' statistical property crossing threshold level." + self.system_fault_code["F462904"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462905"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462906"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462907"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462908"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462909"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462910"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462911"] = "This fault is caused by 'Number of Route Refresh Messages Received periodic' statistical property crossing threshold level." + self.system_fault_code["F462912"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462913"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462914"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462915"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462916"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462917"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462918"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462919"] = "This fault is caused by 'Number of Route Refresh Messages Received minimum value' statistical property crossing threshold" + self.system_fault_code["F462920"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462921"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462922"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462923"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462924"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462925"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462926"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462927"] = "This fault is caused by 'Number of Route Refresh Messages Received maximum value' statistical property crossing threshold" + self.system_fault_code["F462928"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462929"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462930"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462931"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462932"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462933"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462934"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462935"] = "This fault is caused by 'Number of Route Refresh Messages Received average value' statistical property crossing threshold" + self.system_fault_code["F462960"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462961"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462962"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462963"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462964"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462965"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462966"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462967"] = "This fault is caused by 'Number of Route Refresh Messages Received trend' statistical property crossing threshold level." + self.system_fault_code["F462968"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462969"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462970"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462971"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462972"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462973"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462974"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F462975"] = "This fault is caused by 'Number of Route Refresh Messages Received rate' statistical property crossing threshold level." + self.system_fault_code["F463048"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463049"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463050"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463051"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463052"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463053"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463054"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463055"] = "This fault is caused by 'Number of Route Refresh Messages Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463064"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463065"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463066"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463067"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463068"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463069"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463070"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463071"] = "This fault is caused by 'Number of Route Refresh Messages Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463072"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463073"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463074"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463075"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463076"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463077"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463078"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463079"] = "This fault is caused by 'Number of Route Refresh Messages Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463080"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463081"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463082"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463083"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463084"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463085"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463086"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463087"] = "This fault is caused by 'Number of Route Refresh Messages Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463088"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463089"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463090"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463091"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463092"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463093"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463094"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463095"] = "This fault is caused by 'Number of Route Refresh Messages Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463096"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463097"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463098"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463099"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463100"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463101"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463102"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463103"] = "This fault is caused by 'Number of Route Refresh Messages Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463128"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463129"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463130"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463131"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463132"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463133"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463134"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463135"] = "This fault is caused by 'Number of Route Refresh Messages Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463136"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463137"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463138"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463139"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463140"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463141"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463142"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463143"] = "This fault is caused by 'Number of Route Refresh Messages Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463216"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463217"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463218"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463219"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463220"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463221"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463222"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463223"] = "This fault is caused by 'Accepted Paths current value' statistical property crossing threshold level." + self.system_fault_code["F463232"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463233"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463234"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463235"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463236"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463237"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463238"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463239"] = "This fault is caused by 'Accepted Paths cumulative' statistical property crossing threshold level." + self.system_fault_code["F463240"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463241"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463242"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463243"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463244"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463245"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463246"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463247"] = "This fault is caused by 'Accepted Paths periodic' statistical property crossing threshold level." + self.system_fault_code["F463248"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463249"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463250"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463251"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463252"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463253"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463254"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463255"] = "This fault is caused by 'Accepted Paths minimum value' statistical property crossing threshold level." + self.system_fault_code["F463256"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463257"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463258"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463259"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463260"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463261"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463262"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463263"] = "This fault is caused by 'Accepted Paths maximum value' statistical property crossing threshold level." + self.system_fault_code["F463264"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463265"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463266"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463267"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463268"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463269"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463270"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463271"] = "This fault is caused by 'Accepted Paths average value' statistical property crossing threshold level." + self.system_fault_code["F463296"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463297"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463298"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463299"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463300"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463301"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463302"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463303"] = "This fault is caused by 'Accepted Paths trend' statistical property crossing threshold level." + self.system_fault_code["F463304"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463305"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463306"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463307"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463308"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463309"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463310"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463311"] = "This fault is caused by 'Accepted Paths rate' statistical property crossing threshold level." + self.system_fault_code["F463384"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463385"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463386"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463387"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463388"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463389"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463390"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463391"] = "This fault is caused by 'Prefixes Saved current value' statistical property crossing threshold level." + self.system_fault_code["F463400"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463401"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463402"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463403"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463404"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463405"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463406"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463407"] = "This fault is caused by 'Prefixes Saved cumulative' statistical property crossing threshold level." + self.system_fault_code["F463408"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463409"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463410"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463411"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463412"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463413"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463414"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463415"] = "This fault is caused by 'Prefixes Saved periodic' statistical property crossing threshold level." + self.system_fault_code["F463416"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463417"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463418"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463419"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463420"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463421"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463422"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463423"] = "This fault is caused by 'Prefixes Saved minimum value' statistical property crossing threshold level." + self.system_fault_code["F463424"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463425"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463426"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463427"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463428"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463429"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463430"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463431"] = "This fault is caused by 'Prefixes Saved maximum value' statistical property crossing threshold level." + self.system_fault_code["F463432"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463433"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463434"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463435"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463436"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463437"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463438"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463439"] = "This fault is caused by 'Prefixes Saved average value' statistical property crossing threshold level." + self.system_fault_code["F463464"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463465"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463466"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463467"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463468"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463469"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463470"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463471"] = "This fault is caused by 'Prefixes Saved trend' statistical property crossing threshold level." + self.system_fault_code["F463472"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463473"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463474"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463475"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463476"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463477"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463478"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463479"] = "This fault is caused by 'Prefixes Saved rate' statistical property crossing threshold level." + self.system_fault_code["F463552"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463553"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463554"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463555"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463556"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463557"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463558"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463559"] = "This fault is caused by 'Prefixes Sent current value' statistical property crossing threshold level." + self.system_fault_code["F463568"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463569"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463570"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463571"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463572"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463573"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463574"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463575"] = "This fault is caused by 'Prefixes Sent cumulative' statistical property crossing threshold level." + self.system_fault_code["F463576"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463577"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463578"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463579"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463580"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463581"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463582"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463583"] = "This fault is caused by 'Prefixes Sent periodic' statistical property crossing threshold level." + self.system_fault_code["F463584"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463585"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463586"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463587"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463588"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463589"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463590"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463591"] = "This fault is caused by 'Prefixes Sent minimum value' statistical property crossing threshold level." + self.system_fault_code["F463592"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463593"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463594"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463595"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463596"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463597"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463598"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463599"] = "This fault is caused by 'Prefixes Sent maximum value' statistical property crossing threshold level." + self.system_fault_code["F463600"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463601"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463602"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463603"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463604"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463605"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463606"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463607"] = "This fault is caused by 'Prefixes Sent average value' statistical property crossing threshold level." + self.system_fault_code["F463632"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463633"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463634"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463635"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463636"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463637"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463638"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463639"] = "This fault is caused by 'Prefixes Sent trend' statistical property crossing threshold level." + self.system_fault_code["F463640"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463641"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463642"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463643"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463644"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463645"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463646"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F463647"] = "This fault is caused by 'Prefixes Sent rate' statistical property crossing threshold level." + self.system_fault_code["F466272"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466273"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466274"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466275"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466276"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466277"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466278"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466279"] = "This fault is caused by 'host router egress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466288"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466289"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466290"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466291"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466292"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466293"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466294"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466295"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466296"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466297"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466298"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466299"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466300"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466301"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466302"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466303"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466304"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466305"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466306"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466307"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466308"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466309"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466310"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466311"] = "This fault is caused by 'host router egress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466312"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466313"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466314"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466315"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466316"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466317"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466318"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466319"] = "This fault is caused by 'host router egress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466320"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466321"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466322"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466323"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466324"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466325"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466326"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466327"] = "This fault is caused by 'host router egress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466352"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466353"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466354"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466355"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466356"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466357"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466358"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466359"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466360"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466361"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466362"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466363"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466364"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466365"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466366"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466367"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466440"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466441"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466442"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466443"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466444"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466445"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466446"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466447"] = "This fault is caused by 'host router egress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466448"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466449"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466450"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466451"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466452"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466453"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466454"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466455"] = "This fault is caused by 'host router egress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466480"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466481"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466482"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466483"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466484"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466485"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466486"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466487"] = "This fault is caused by 'host router egress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466488"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466489"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466490"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466491"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466492"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466493"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466494"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466495"] = "This fault is caused by 'host router egress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466544"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466545"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466546"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466547"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466548"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466549"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466550"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466551"] = "This fault is caused by 'host router egress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F466560"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466561"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466562"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466563"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466564"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466565"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466566"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466567"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466568"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466569"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466570"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466571"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466572"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466573"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466574"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466575"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466576"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466577"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466578"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466579"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466580"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466581"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466582"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466583"] = "This fault is caused by 'host router egress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F466584"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466585"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466586"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466587"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466588"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466589"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466590"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466591"] = "This fault is caused by 'host router egress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F466592"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466593"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466594"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466595"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466596"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466597"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466598"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466599"] = "This fault is caused by 'host router egress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F466624"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466625"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466626"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466627"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466628"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466629"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466630"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466631"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466632"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466633"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466634"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466635"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466636"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466637"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466638"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466639"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466712"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466713"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466714"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466715"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466716"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466717"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466718"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466719"] = "This fault is caused by 'host router egress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F466720"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466721"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466722"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466723"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466724"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466725"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466726"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466727"] = "This fault is caused by 'host router egress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F466752"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466753"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466754"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466755"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466756"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466757"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466758"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466759"] = "This fault is caused by 'host router egress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F466760"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466761"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466762"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466763"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466764"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466765"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466766"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466767"] = "This fault is caused by 'host router egress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F466816"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466817"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466818"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466819"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466820"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466821"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466822"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466823"] = "This fault is caused by 'host router ingress unicast bytes current value' statistical property crossing threshold level." + self.system_fault_code["F466832"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466833"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466834"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466835"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466836"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466837"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466838"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466839"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466840"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466841"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466842"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466843"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466844"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466845"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466846"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466847"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466848"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466849"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466850"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466851"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466852"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466853"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466854"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466855"] = "This fault is caused by 'host router ingress unicast bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F466856"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466857"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466858"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466859"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466860"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466861"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466862"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466863"] = "This fault is caused by 'host router ingress unicast bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F466864"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466865"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466866"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466867"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466868"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466869"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466870"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466871"] = "This fault is caused by 'host router ingress unicast bytes average value' statistical property crossing threshold level." + self.system_fault_code["F466896"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466897"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466898"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466899"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466900"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466901"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466902"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466903"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F466904"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466905"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466906"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466907"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466908"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466909"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466910"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466911"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F466984"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466985"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466986"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466987"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466988"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466989"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466990"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466991"] = "This fault is caused by 'host router ingress unicast bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F466992"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466993"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466994"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466995"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466996"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466997"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466998"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F466999"] = "This fault is caused by 'host router ingress unicast bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F467024"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467025"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467026"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467027"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467028"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467029"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467030"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467031"] = "This fault is caused by 'host router ingress unicast bytes trend' statistical property crossing threshold level." + self.system_fault_code["F467032"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467033"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467034"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467035"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467036"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467037"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467038"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467039"] = "This fault is caused by 'host router ingress unicast bytes rate' statistical property crossing threshold level." + self.system_fault_code["F467088"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467089"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467090"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467091"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467092"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467093"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467094"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467095"] = "This fault is caused by 'host router ingress unicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F467104"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467105"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467106"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467107"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467108"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467109"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467110"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467111"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467112"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467113"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467114"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467115"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467116"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467117"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467118"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467119"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467120"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467121"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467122"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467123"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467124"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467125"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467126"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467127"] = "This fault is caused by 'host router ingress unicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F467128"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467129"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467130"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467131"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467132"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467133"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467134"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467135"] = "This fault is caused by 'host router ingress unicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F467136"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467137"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467138"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467139"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467140"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467141"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467142"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467143"] = "This fault is caused by 'host router ingress unicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F467168"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467169"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467170"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467171"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467172"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467173"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467174"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467175"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467176"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467177"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467178"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467179"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467180"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467181"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467182"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467183"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467256"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467257"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467258"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467259"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467260"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467261"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467262"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467263"] = "This fault is caused by 'host router ingress unicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F467264"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467265"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467266"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467267"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467268"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467269"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467270"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467271"] = "This fault is caused by 'host router ingress unicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F467296"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467297"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467298"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467299"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467300"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467301"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467302"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467303"] = "This fault is caused by 'host router ingress unicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F467304"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467305"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467306"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467307"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467308"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467309"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467310"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F467311"] = "This fault is caused by 'host router ingress unicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F540726"] = "None set." + self.system_fault_code["F543888"] = "None set." + self.system_fault_code["F606210"] = "This fault occurs when resource consumer registration (used for ID / resource tracking) fails" + self.system_fault_code["F606211"] = "This fault occurs when resource consumer unregistration (used for ID / resource tracking) fails" + self.system_fault_code["F606212"] = "This fault occurs when a tag reference configuration fails" + self.system_fault_code["F606213"] = "This fault occurs when an alias reference configuration fails" + self.system_fault_code["F606214"] = "This fault occurs when alias reference fails to be deleted" + self.system_fault_code["F606220"] = "This fault occurs when an internal identifier fails to be released." + self.system_fault_code["F606233"] = "This fault is raised when sending export file name to correct APIC to remote it, fails" + self.system_fault_code["F606234"] = "This fault is raised when task to report core info from node to APIC fails" + self.system_fault_code["F606236"] = "None set." + self.system_fault_code["F606242"] = "This fault occurs upon failure to update information about a downloaded image" + self.system_fault_code["F606243"] = "This fault occurs upon failure to update information about download" + self.system_fault_code["F606245"] = "This fault is raised when task to report export status from node to APIC fails" + self.system_fault_code["F606253"] = "This fault is raised when the node (leaf/spine) fails to send the message to controller to resolve all its policies." + self.system_fault_code["F606262"] = "This fault is raised when FSM for Controller Add operation fails." + self.system_fault_code["F606274"] = "This fault is raised when sending top System changes to Topology Manager fails" + self.system_fault_code["F606277"] = "This fault is raised when sending controller firmwareCtrlrRunning object to firmwareFwStatusCont fails" + self.system_fault_code["F606278"] = "This fault is raised when Appliance Element fails to send upgrade request to scheduler" + self.system_fault_code["F606279"] = "This fault occurs when loading compatibility catalog for the firmware fails" + self.system_fault_code["F606347"] = "This fault is raised when adding/deleting Portgroupsfor a VMM Controller fails." + self.system_fault_code["F606348"] = "This fault is raised when updating a vNIC profile definition fails. This typically happens if fhe Physical-NICs of the" + self.system_fault_code["F606349"] = "This fault is raised when sending the external policy information from vShield controller to vCenter controller fails" + self.system_fault_code["F606350"] = "This fault is raised when updating the LACP Lag Policy at the DVS fails." + self.system_fault_code["F606351"] = "This fault is raised when updating the Controller policy container at the DVS fails." + self.system_fault_code["F606352"] = "This fault is raised when updating the statistics monitoring policy for the Controller fails." + self.system_fault_code["F606353"] = "This fault is raised when adding/deleting a VXLAN Pool definiton for the Controller fails." + self.system_fault_code["F606354"] = "This fault is raised when adding/deleting a Multicast Address Pool definition for the VMM Controller fails." + self.system_fault_code["F606359"] = "This fault is raised when adding/deleting an uplink Porgroup for the Controller fails" + self.system_fault_code["F606360"] = "This fault is raised when adding/deleting a VTEP Porgroup for the Controller fails" + self.system_fault_code["F606361"] = "This fault is raised when adding/deleting a VTEP NIC fails" + self.system_fault_code["F606365"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F606367"] = "This fault is raised when updating host vendor configuration fails" + self.system_fault_code["F606369"] = "This fault is raised when setting external policy information for the Controller fails" + self.system_fault_code["F606371"] = "This fault is raised when Endpoint Attach/Detach update to Policy Manager fails. This is an internal task." + self.system_fault_code["F606379"] = "This fault is raised when Cluster update to VMM Controller fails." + self.system_fault_code["F606386"] = "This fault is raised when sending cluster add message to VMM Controller fails." + self.system_fault_code["F606389"] = "This fault is raised when DVS preparation operation for vShield Controller fails." + self.system_fault_code["F606391"] = "This fault is raised when LLDP/CDP Adjacency information is not found for the physical adapters on the host." + self.system_fault_code["F606392"] = "This fault is raised when the IP address for the interface on the host cannot be found." + self.system_fault_code["F606395"] = "This fault is raised when an error is encountered when obtaining vCenter hyperlink reference from vCloud Director." + self.system_fault_code["F606430"] = "This fault is raised when CanIUpgrade handshake fails fails" + self.system_fault_code["F606434"] = "This fault is raised when update Adrelay on LLDP discovery fails" + self.system_fault_code["F606435"] = "This fault is raised when wait for endpoing profile download fails" + self.system_fault_code["F606436"] = "This fault is raised when LooseNode Report Update to TopoManager fails." + self.system_fault_code["F606483"] = "None set." + self.system_fault_code["F606484"] = "None set." + self.system_fault_code["F606486"] = "None set." + self.system_fault_code["F606487"] = "None set." + self.system_fault_code["F606565"] = "This fault is raised when send decommission message to switch fails" + self.system_fault_code["F606566"] = "This fault is raised when remove node request fails" + self.system_fault_code["F606567"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F606597"] = "This fault is raised when notification about a DHCP discovered node fails" + self.system_fault_code["F606615"] = "This fault occurs when filter profile fails to be updated" + self.system_fault_code["F606616"] = "This fault occurs when filter profile fails to be configured for aggregated filters" + self.system_fault_code["F606617"] = "This fault occurs when endpoint profile remote EPG contract fails to be updated" + self.system_fault_code["F606640"] = "This fault occurs when EPG collection for context configuration fails to be delivered to contract collection" + self.system_fault_code["F606643"] = "This fault occurs when a taboo entry fails to be delivered to a remote EPG" + self.system_fault_code["F606644"] = "This fault occurs when a dependent L4-L7 service graph template fails to be updated" + self.system_fault_code["F606655"] = "This fault is raised when update DHCP provider address fails" + self.system_fault_code["F606664"] = "This fault is raised when virtual port channel ID assignment fails" + self.system_fault_code["F606666"] = "This fault is raised when virtual IP address assignment fails" + self.system_fault_code["F606667"] = "This fault is raised when protection chain IP address assignment fails" + self.system_fault_code["F606668"] = "This fault is raised when send controller and node list fails" + self.system_fault_code["F606669"] = "This fault is raised when delete controller tracker list for techsupport collection fails" + self.system_fault_code["F606670"] = "This fault is raised when delete controller tracker list for on-demand collection fails" + self.system_fault_code["F606671"] = "This fault is raised when notification of an endpoint attach or detach fails" + self.system_fault_code["F606674"] = "This fault is raised when delete tag reference target fails" + self.system_fault_code["F606725"] = "This fault is raised when notfication of virtual port channel interface info fails" + self.system_fault_code["F606755"] = "This fault is raised when configuration of endpoint profile definition (EpP) fails" + self.system_fault_code["F606757"] = "This fault is raised when attempt to update inband management epg with device cluster interface fails" + self.system_fault_code["F606758"] = "This fault is raised when update DHCP provider with relation to current bridge domain fails" + self.system_fault_code["F606761"] = "This fault is raised when notify endpoint update fails" + self.system_fault_code["F606764"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F606766"] = "This fault is raised when a configuration update to EPP failed." + self.system_fault_code["F606833"] = "This fault is raised when send node information from infra to management EPG fails" + self.system_fault_code["F606834"] = "This fault is raised when send node information from infra to out-of-band management EPGfails" + self.system_fault_code["F606835"] = "This fault is raised when send out-of-band endpoint profile update fails" + self.system_fault_code["F606836"] = "This fault is raised when send out-of-band provider information to contract fails" + self.system_fault_code["F606837"] = "This fault is raised when send EPG consumer information to contract fails" + self.system_fault_code["F606840"] = "This fault is raised when handle replication for resolver fails" + self.system_fault_code["F606842"] = "This fault is raised when notification about a Span source fails" + self.system_fault_code["F606843"] = "This fault is raised when notification about a Span source group fails" + self.system_fault_code["F606844"] = "This fault is raised when notification about a Span source group fails" + self.system_fault_code["F606845"] = "This fault is raised when notification about a on-demand atomic counter policy fails" + self.system_fault_code["F606871"] = "This fault is raised when system change notification to Topology Manager fails" + self.system_fault_code["F606872"] = "This fault is raised when sending system information to Topology Manager fails" + self.system_fault_code["F606875"] = "This fault is raised when update remote port info to debugger-element fails" + self.system_fault_code["F606897"] = "None set." + self.system_fault_code["F606899"] = "None set." + self.system_fault_code["F606900"] = "None set." + self.system_fault_code["F606901"] = "None set." + self.system_fault_code["F606902"] = "None set." + self.system_fault_code["F606910"] = "This fault is raised when deploy of EPG on ports associated with Attached Entity Profile fails" + self.system_fault_code["F606911"] = "This fault is raised when sending policies associated with attached entity profile to domain fails" + self.system_fault_code["F607041"] = "This fault is raised if endpoint profile update for service graph internal EPG fails." + self.system_fault_code["F607045"] = "This fault is raised when L4-L7 service graph related information could not be deleted from leafs." + self.system_fault_code["F607048"] = "This fault is raised when updating virtual device configuration to script handler failed." + self.system_fault_code["F607050"] = "This fault is raised when rendering associated service graphs failed." + self.system_fault_code["F607450"] = "This fault is raised when sending top System changes for Chassis to Topology Manager fails" + self.system_fault_code["F607451"] = "This fault is raised when chassis change notification to Topology Manager fails" + self.system_fault_code["F607479"] = "This fault occurs when forced policy resolution fails" + self.system_fault_code["F607480"] = "This fault is raised when task to update execution status of callhome inventory policy fails" + self.system_fault_code["F607481"] = "This fault is raised when updating device configuration on script handler failed." + self.system_fault_code["F607493"] = "This fault is raised when send endpoint profile update for management EPG fails" + self.system_fault_code["F607496"] = "This fault is raised when sending Fabric Node subscription removal to Policy Manager fails" + self.system_fault_code["F607514"] = "This fault is raised when notification for a on-demand atomic counter policy fails" + self.system_fault_code["F607560"] = "This fault is raised when sending root Fabric Node changes to Appliance Element fails" + self.system_fault_code["F607563"] = "This fault is raised when updating runtime info under service script failed." + self.system_fault_code["F607564"] = "This fault is raised when running software version fails to be updated" + self.system_fault_code["F607571"] = "This fault is raised when configuration distribution of RbacRules fails" + self.system_fault_code["F607574"] = "This fault is raised when ports cannot be brought in service after incomplete policy registration" + self.system_fault_code["F607575"] = "This fault is raised when the message to notify leaf/spine about policy deployment completion fails" + self.system_fault_code["F607588"] = "This fault occurs when loading firmware compatibility catalog fails." + self.system_fault_code["F607589"] = "This fault is raised when bringing ports in service after bootstrap completion fails" + self.system_fault_code["F607590"] = "This fault is raised when update bridge domain with static route fails" + self.system_fault_code["F607591"] = "This fault is raised when update private network with taboo configuration fails" + self.system_fault_code["F607592"] = "This fault is raised when update private network with EPG summary information fails" + self.system_fault_code["F607603"] = "This fault occurs when updating the fabric node vector fails." + self.system_fault_code["F607610"] = "None set." + self.system_fault_code["F607620"] = "This fault is raised when sending message to contract shard failed and graph instance could not be re-rendered." + self.system_fault_code["F607623"] = "This fault is raised when update bridge domain container fails" + self.system_fault_code["F607628"] = "This fault occurs when contract or bundle interface configuration fails to be delivered to contract or bundle" + self.system_fault_code["F607632"] = "This fault is raised when sending Fabric Node subscription to the Policy Manager via Appliance Element fails" + self.system_fault_code["F607660"] = "This fault is raised when register for node notification fails" + self.system_fault_code["F607661"] = "This fault occurs when an alias instance update fails" + self.system_fault_code["F607664"] = "This fault is raised when NAT entry creation for concrete device management interface failed." + self.system_fault_code["F607666"] = "This fault is raised when reporting fabric path group on an external connected node fails" + self.system_fault_code["F607667"] = "This fault is raised when send callhome inventory fails" + self.system_fault_code["F607670"] = "This fault is raised when notify spine proxy create fails" + self.system_fault_code["F607684"] = "This fault occurs when private network configuration fails to be updated with remote contract collection" + self.system_fault_code["F607689"] = "This fault is raised when security filters required to allow traffic from EPgs to L4-L7 service graph traffic could not" + self.system_fault_code["F607690"] = "This fault is raised when the update of security domain configuration to PolicyMgr fails. This is an internal task used" + self.system_fault_code["F607725"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F607726"] = "This fault is raised when L4-L7 service graph related information could not be configured on leafs." + self.system_fault_code["F607727"] = "None set." + self.system_fault_code["F607728"] = "None set." + self.system_fault_code["F607729"] = "None set." + self.system_fault_code["F607730"] = "None set." + self.system_fault_code["F607746"] = "None set." + self.system_fault_code["F607750"] = "None set." + self.system_fault_code["F607783"] = "This fault is raised when virtual IP address assignment fails" + self.system_fault_code["F607846"] = "This fault is raised when sending Fabric Node removal to Topology Manager fails" + self.system_fault_code["F607861"] = "This fault is raised when a configuration update to EPP failed." + self.system_fault_code["F607874"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F607875"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F607876"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F607891"] = "This fault is raised when update of critirion information under the container fails" + self.system_fault_code["F607897"] = "This fault is raised when adding/deleting a Black Hole Porgroup for the Controller fails" + self.system_fault_code["F607905"] = "This fault is raised when system cannot validate vlan encap of this object." + self.system_fault_code["F607928"] = "This fault is raised when updating private network context with the virtual IP fails" + self.system_fault_code["F607940"] = "None set." + self.system_fault_code["F607941"] = "None set." + self.system_fault_code["F607942"] = "None set." + self.system_fault_code["F607943"] = "This fault is raised when configuration distribution of RbacRules fails" + self.system_fault_code["F607945"] = "This fault is raised when updating private network context with the virtual IP fails" + self.system_fault_code["F608054"] = "None set." + self.system_fault_code["F608059"] = "This fault is raised when task fails which is due to one shard being particularly busy." + self.system_fault_code["F608065"] = "This fault is raised when cleanup of path end-points fails." + self.system_fault_code["F608066"] = "This fault is raised when remove path end-points request fails" + self.system_fault_code["F608076"] = "This fault occurs when EPG policy enforcement tag fails to be reallocated from shared service pool" + self.system_fault_code["F608078"] = "None set." + self.system_fault_code["F608102"] = "None set." + self.system_fault_code["F608103"] = "This fault is raised when the node (leaf/spine) fails to send the message to controller to resolve all its policies." + self.system_fault_code["F608104"] = "None set." + self.system_fault_code["F608107"] = "This fault is raised when the message to notify leaf/spine about policy reconcilation fails" + self.system_fault_code["F608128"] = "This fault is raised when notification of the detach fails" + self.system_fault_code["F608132"] = "This fault is raised when notification of a policy demand message fails" + self.system_fault_code["F608149"] = "None set." + self.system_fault_code["F608154"] = "None set." + self.system_fault_code["F608155"] = "None set." + self.system_fault_code["F608161"] = "None set." + self.system_fault_code["F608162"] = "None set." + self.system_fault_code["F608163"] = "This fault is raised when handshake between PE and AD fails" + self.system_fault_code["F608167"] = "This fault is raised when delete controller tracker list for AVS techsupport collection fails" + self.system_fault_code["F608215"] = "This fault is raised when the message fails to be sent the destination shard." + self.system_fault_code["F608218"] = "None set." + self.system_fault_code["F608240"] = "None set." + self.system_fault_code["F608267"] = "This fault is raised when configuration distribution of RbacRules fails" + self.system_fault_code["F608269"] = "This fault is raised when task to reset policy status on policy deletion fails." + self.system_fault_code["F608274"] = "None set." + self.system_fault_code["F608297"] = "This fault is raised when adding or deleting microsegmentation IP set fails." + self.system_fault_code["F608298"] = "This fault is raised when adding or deleting microsegmentation MAC set fails." + self.system_fault_code["F608301"] = "This fault is raised when mac/ip address reporting to Policy Manager fails. This is an internal task." + self.system_fault_code["F608320"] = "None set." + self.system_fault_code["F608321"] = "None set." + self.system_fault_code["F608322"] = "This fault is raised when requesting an AREpP fails" + self.system_fault_code["F608332"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608333"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608334"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608335"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608336"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608337"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608342"] = "This fault is raised when adding/deleting microsegmentation firewall rules fail." + self.system_fault_code["F608343"] = "This fault is raised when adding/deleting microsegmentation filter profiles fail." + self.system_fault_code["F608344"] = "This fault is raised when adding or deleting microsegmentation end point criteria fails." + self.system_fault_code["F608345"] = "This fault is raised when microsegmentation member MAC update to Policy Manager fails." + self.system_fault_code["F608395"] = "This fault is raised when adding or deleting PVLAN configuration at the vCenter fails or when clean up of stale PVLAN" + self.system_fault_code["F608396"] = "None set." + self.system_fault_code["F608397"] = "None set." + self.system_fault_code["F608445"] = "None set." + self.system_fault_code["F608463"] = "None set." + self.system_fault_code["F608474"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608475"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F608608"] = "None set." + self.system_fault_code["F608621"] = "None set." + self.system_fault_code["F608624"] = "None set." + self.system_fault_code["F608625"] = "None set." + self.system_fault_code["F608626"] = "None set." + self.system_fault_code["F608630"] = "None set." + self.system_fault_code["F608635"] = "This fault is raised when both the opflex channels for compHv are down." + self.system_fault_code["F608754"] = "None set." + self.system_fault_code["F608764"] = "None set." + self.system_fault_code["F608786"] = "This fault occurs when multisite mappings fails to be updated" + self.system_fault_code["F608795"] = "None set." + self.system_fault_code["F608815"] = "None set." + self.system_fault_code["F608861"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F608863"] = "None set." + self.system_fault_code["F608889"] = "None set." + self.system_fault_code["F608890"] = "None set." + self.system_fault_code["F608904"] = "This fault occurs when contract or bundle interface configuration fails to be delivered to contract or bundle" + self.system_fault_code["F608908"] = "None set." + self.system_fault_code["F608912"] = "None set." + self.system_fault_code["F608924"] = "None set." + self.system_fault_code["F608937"] = "This fault is raised when update between PE and PE fails" + self.system_fault_code["F608976"] = "This fault is raised when NAT entry creation for controller appliance failed." + self.system_fault_code["F608980"] = "This fault is raised when notification of an endpoint attach or detach fails" + self.system_fault_code["F608989"] = "None set." + self.system_fault_code["F609016"] = "This fault occurs when gipo allocation fails" + self.system_fault_code["F609017"] = "This fault occurs when syncing locally allocated gipo fails" + self.system_fault_code["F609018"] = "This fault occurs when gipo reallocation fails" + self.system_fault_code["F609026"] = "None set." + self.system_fault_code["F609053"] = "None set." + self.system_fault_code["F609071"] = "None set." + self.system_fault_code["F609086"] = "None set." + self.system_fault_code["F609093"] = "None set." + self.system_fault_code["F609100"] = "This fault is raised when cleanup of path end-points fails." + self.system_fault_code["F609101"] = "This fault is raised when sending the SVM information from vCenter controller to SVM container" + self.system_fault_code["F609128"] = "None set." + self.system_fault_code["F609141"] = "This fault occurs when updating the dhcp pool fails." + self.system_fault_code["F609159"] = "None set." + self.system_fault_code["F609160"] = "None set." + self.system_fault_code["F609161"] = "None set." + self.system_fault_code["F609191"] = "This fault is raised when send decommission message to vmmmgr fails" + self.system_fault_code["F609231"] = "None set." + self.system_fault_code["F609287"] = "None set." + self.system_fault_code["F609301"] = "None set." + self.system_fault_code["F609319"] = "This fault is raised when notification of an endpoint attach or detach fails" + self.system_fault_code["F609324"] = "This fault is raised if endpoint profile update for service graph service EPG fails." + self.system_fault_code["F609328"] = "None set." + self.system_fault_code["F609331"] = "This fault is raised when updating a VM Configuration fails. This typically happens if fhe Physical-NICs of the Hosts" + self.system_fault_code["F609332"] = "None set." + self.system_fault_code["F609333"] = "None set." + self.system_fault_code["F609337"] = "None set." + self.system_fault_code["F609338"] = "None set." + self.system_fault_code["F609351"] = "None set." + self.system_fault_code["F609352"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F609367"] = "None set." + self.system_fault_code["F609379"] = "This fault is raised when a configuration update to the VMM Controller fails." + self.system_fault_code["F609380"] = "None set." + self.system_fault_code["F609382"] = "None set." + self.system_fault_code["F609384"] = "None set." + self.system_fault_code["F609385"] = "None set." + self.system_fault_code["F609386"] = "None set." + self.system_fault_code["F609393"] = "This fault is raised when updating the Enhanced LACP Lag Policy at the DVS fails." + self.system_fault_code["F609407"] = "This fault is raised when sending the SVM information from vCenter controller to SVM container" + self.system_fault_code["F609408"] = "This fault is raised when adding/deleting a Black Hole Porgroup for the Controller fails" + self.system_fault_code["F609409"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F609410"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F609411"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F609412"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F609423"] = "None set." + self.system_fault_code["F609424"] = "This fault is raised when FSM for Controller Remove operation fails." + self.system_fault_code["F609436"] = "None set." + self.system_fault_code["F609437"] = "None set." + self.system_fault_code["F609438"] = "None set." + self.system_fault_code["F609439"] = "None set." + self.system_fault_code["F609442"] = "None set." + self.system_fault_code["F609445"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F609475"] = "None set." + self.system_fault_code["F609478"] = "This fault is raised when fabric:SetupPol provisioning fails" + self.system_fault_code["F609485"] = "This fault is raised when reporting AVE timeout fails" + self.system_fault_code["F609502"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F609505"] = "None set." + self.system_fault_code["F609512"] = "None set." + self.system_fault_code["F609513"] = "None set." + self.system_fault_code["F609528"] = "None set." + self.system_fault_code["F609530"] = "None set." + self.system_fault_code["F609531"] = "This fault is raised when sending the updated set of managed Nics from vmmmgr to edmgr" + self.system_fault_code["F609532"] = "None set." + self.system_fault_code["F609547"] = "None set." + self.system_fault_code["F609548"] = "None set." + self.system_fault_code["F609551"] = "None set." + self.system_fault_code["F609553"] = "This fault is raised when the node (leaf/spine) fails to send the message to controller to resolve all its policies." + self.system_fault_code["F609558"] = "This fault is raised when task to sync cloudEpP fails" + self.system_fault_code["F609576"] = "None set." + self.system_fault_code["F609635"] = "None set." + self.system_fault_code["F609652"] = "None set." + self.system_fault_code["F609677"] = "None set." + self.system_fault_code["F609678"] = "None set." + self.system_fault_code["F609680"] = "This fault is raised when sending Fabric Node add to VMM Manager fails" + self.system_fault_code["F609684"] = "None set." + self.system_fault_code["F609707"] = "This fault is raised when an update for L4-L7 service policy fails" + self.system_fault_code["F609712"] = "None set." + self.system_fault_code["F609731"] = "None set." + self.system_fault_code["F609763"] = "None set." + self.system_fault_code["F671746"] = "This fault occurs when resource consumer registration (used for ID / resource tracking) fails" + self.system_fault_code["F671747"] = "This fault occurs when resource consumer unregistration (used for ID / resource tracking) fails" + self.system_fault_code["F671748"] = "This fault occurs when a tag reference configuration fails" + self.system_fault_code["F671749"] = "This fault occurs when an alias reference configuration fails" + self.system_fault_code["F671750"] = "This fault occurs when alias reference fails to be deleted" + self.system_fault_code["F671756"] = "This fault occurs when an internal identifier fails to be released." + self.system_fault_code["F671769"] = "This fault is raised when sending export file name to correct APIC to remote it, fails" + self.system_fault_code["F671770"] = "This fault is raised when task to report core info from node to APIC fails" + self.system_fault_code["F671772"] = "None set." + self.system_fault_code["F671778"] = "This fault occurs upon failure to update information about a downloaded image" + self.system_fault_code["F671779"] = "This fault occurs upon failure to update information about download" + self.system_fault_code["F671781"] = "This fault is raised when task to report export status from node to APIC fails" + self.system_fault_code["F671789"] = "This fault is raised when the node (leaf/spine) fails to send the message to controller to resolve all its policies." + self.system_fault_code["F671798"] = "This fault is raised when FSM for Controller Add operation fails." + self.system_fault_code["F671810"] = "This fault is raised when sending top System changes to Topology Manager fails" + self.system_fault_code["F671813"] = "This fault is raised when sending controller firmwareCtrlrRunning object to firmwareFwStatusCont fails" + self.system_fault_code["F671814"] = "This fault is raised when Appliance Element fails to send upgrade request to scheduler" + self.system_fault_code["F671815"] = "This fault occurs when loading compatibility catalog for the firmware fails" + self.system_fault_code["F671883"] = "This fault is raised when adding/deleting Portgroupsfor a VMM Controller fails." + self.system_fault_code["F671884"] = "This fault is raised when updating a vNIC profile definition fails. This typically happens if fhe Physical-NICs of the" + self.system_fault_code["F671885"] = "This fault is raised when sending the external policy information from vShield controller to vCenter controller fails" + self.system_fault_code["F671886"] = "This fault is raised when updating the LACP Lag Policy at the DVS fails." + self.system_fault_code["F671887"] = "This fault is raised when updating the Controller policy container at the DVS fails." + self.system_fault_code["F671888"] = "This fault is raised when updating the statistics monitoring policy for the Controller fails." + self.system_fault_code["F671889"] = "This fault is raised when adding/deleting a VXLAN Pool definiton for the Controller fails." + self.system_fault_code["F671890"] = "This fault is raised when adding/deleting a Multicast Address Pool definition for the VMM Controller fails." + self.system_fault_code["F671895"] = "This fault is raised when adding/deleting an uplink Porgroup for the Controller fails" + self.system_fault_code["F671896"] = "This fault is raised when adding/deleting a VTEP Porgroup for the Controller fails" + self.system_fault_code["F671897"] = "This fault is raised when adding/deleting a VTEP NIC fails" + self.system_fault_code["F671901"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F671903"] = "This fault is raised when updating host vendor configuration fails" + self.system_fault_code["F671905"] = "This fault is raised when setting external policy information for the Controller fails" + self.system_fault_code["F671907"] = "This fault is raised when Endpoint Attach/Detach update to Policy Manager fails. This is an internal task." + self.system_fault_code["F671915"] = "This fault is raised when Cluster update to VMM Controller fails." + self.system_fault_code["F671922"] = "This fault is raised when sending cluster add message to VMM Controller fails." + self.system_fault_code["F671925"] = "This fault is raised when DVS preparation operation for vShield Controller fails." + self.system_fault_code["F671927"] = "This fault is raised when LLDP/CDP Adjacency information is not found for the physical adapters on the host." + self.system_fault_code["F671928"] = "This fault is raised when the IP address for the interface on the host cannot be found." + self.system_fault_code["F671931"] = "This fault is raised when an error is encountered when obtaining vCenter hyperlink reference from vCloud Director." + self.system_fault_code["F671966"] = "This fault is raised when CanIUpgrade handshake fails fails" + self.system_fault_code["F671970"] = "This fault is raised when update Adrelay on LLDP discovery fails" + self.system_fault_code["F671971"] = "This fault is raised when wait for endpoing profile download fails" + self.system_fault_code["F671972"] = "This fault is raised when LooseNode Report Update to TopoManager fails." + self.system_fault_code["F672019"] = "None set." + self.system_fault_code["F672020"] = "None set." + self.system_fault_code["F672022"] = "None set." + self.system_fault_code["F672023"] = "None set." + self.system_fault_code["F672101"] = "This fault is raised when send decommission message to switch fails" + self.system_fault_code["F672102"] = "This fault is raised when remove node request fails" + self.system_fault_code["F672103"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F672133"] = "This fault is raised when notification about a DHCP discovered node fails" + self.system_fault_code["F672151"] = "This fault occurs when filter profile fails to be updated" + self.system_fault_code["F672152"] = "This fault occurs when filter profile fails to be configured for aggregated filters" + self.system_fault_code["F672153"] = "This fault occurs when endpoint profile remote EPG contract fails to be updated" + self.system_fault_code["F672176"] = "This fault occurs when EPG configuration fails to be delivered to contract collection" + self.system_fault_code["F672179"] = "This fault occurs when a taboo entry fails to be delivered to a remote EPG" + self.system_fault_code["F672180"] = "This fault occurs when a dependent L4-L7 service graph template fails to be updated" + self.system_fault_code["F672191"] = "This fault is raised when update DHCP provider address fails" + self.system_fault_code["F672200"] = "This fault is raised when virtual port channel ID assignment fails" + self.system_fault_code["F672202"] = "This fault is raised when virtual IP address assignment fails" + self.system_fault_code["F672203"] = "This fault is raised when protection chain IP address assignment fails" + self.system_fault_code["F672204"] = "This fault is raised when send controller and node list fails" + self.system_fault_code["F672205"] = "This fault is raised when delete controller tracker list for techsupport collection fails" + self.system_fault_code["F672206"] = "This fault is raised when delete controller tracker list for on-demand collection fails" + self.system_fault_code["F672207"] = "This fault is raised when notification of an endpoint attach or detach fails" + self.system_fault_code["F672210"] = "This fault is raised when delete tag reference target fails" + self.system_fault_code["F672261"] = "This fault is raised when notfication of virtual port channel interface info fails" + self.system_fault_code["F672291"] = "This fault is raised when configuration of endpoint profile definition (EpP) fails" + self.system_fault_code["F672293"] = "This fault is raised when attempt to update inband management epg with device cluster interface fails" + self.system_fault_code["F672294"] = "This fault is raised when update DHCP provider with relation to current bridge domain fails" + self.system_fault_code["F672297"] = "This fault is raised when notify endpoint update fails" + self.system_fault_code["F672300"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F672302"] = "This fault is raised when a configuration update to EPP failed." + self.system_fault_code["F672369"] = "This fault is raised when send node information from infra to management EPG fails" + self.system_fault_code["F672370"] = "This fault is raised when send node information from infra to out-of-band management EPGfails" + self.system_fault_code["F672371"] = "This fault is raised when send out-of-band endpoint profile update fails" + self.system_fault_code["F672372"] = "This fault is raised when send out-of-band provider information to contract fails" + self.system_fault_code["F672373"] = "This fault is raised when send EPG consumer information to contract fails" + self.system_fault_code["F672376"] = "This fault is raised when handle replication for resolver fails" + self.system_fault_code["F672378"] = "This fault is raised when notification about a Span source fails" + self.system_fault_code["F672379"] = "This fault is raised when notification about a Span source group fails" + self.system_fault_code["F672380"] = "This fault is raised when notification about a Span source group fails" + self.system_fault_code["F672381"] = "This fault is raised when notification about a on-demand atomic counter policy fails" + self.system_fault_code["F672407"] = "This fault is raised when system change notification to Topology Manager fails" + self.system_fault_code["F672408"] = "This fault is raised when sending system information to Topology Manager fails" + self.system_fault_code["F672411"] = "This fault is raised when update remote port info to debugger-element fails" + self.system_fault_code["F672433"] = "None set." + self.system_fault_code["F672435"] = "None set." + self.system_fault_code["F672436"] = "None set." + self.system_fault_code["F672437"] = "None set." + self.system_fault_code["F672438"] = "None set." + self.system_fault_code["F672446"] = "This fault is raised when deploy of EPG on ports associated with Attached Entity Profile fails" + self.system_fault_code["F672447"] = "This fault is raised when sending policies associated with attached entity profile to domain fails" + self.system_fault_code["F672577"] = "This fault is raised if endpoint profile update for service graph internal EPG fails." + self.system_fault_code["F672581"] = "This fault is raised when L4-L7 service graph related information could not be deleted from leafs." + self.system_fault_code["F672584"] = "This fault is raised when updating virtual device configuration to script handler failed." + self.system_fault_code["F672586"] = "This fault is raised when rendering associated service graphs failed." + self.system_fault_code["F672986"] = "This fault is raised when sending top System changes for Chassis to Topology Manager fails" + self.system_fault_code["F672987"] = "This fault is raised when chassis change notification to Topology Manager fails" + self.system_fault_code["F673015"] = "This fault occurs when forced policy resolution fails" + self.system_fault_code["F673016"] = "This fault is raised when task to update execution status of callhome inventory policy fails" + self.system_fault_code["F673017"] = "This fault is raised when updating device configuration on script handler failed." + self.system_fault_code["F673029"] = "This fault is raised when send endpoint profile update for management EPG fails" + self.system_fault_code["F673032"] = "This fault is raised when sending Fabric Node subscription removal to Policy Manager fails" + self.system_fault_code["F673050"] = "This fault is raised when notification for a on-demand atomic counter policy fails" + self.system_fault_code["F673096"] = "This fault is raised when sending root Fabric Node changes to Appliance Element fails" + self.system_fault_code["F673099"] = "This fault is raised when updating runtime info under service script failed." + self.system_fault_code["F673100"] = "This fault is raised when running software version fails to be updated" + self.system_fault_code["F673107"] = "This fault is raised when configuration distribution of RbacRules fails" + self.system_fault_code["F673110"] = "This fault is raised when ports cannot be brought in service after incomplete policy registration" + self.system_fault_code["F673111"] = "This fault is raised when the message to notify leaf/spine about policy deployment completion fails" + self.system_fault_code["F673124"] = "This fault occurs when loading firmware compatibility catalog fails." + self.system_fault_code["F673125"] = "This fault is raised when bringing ports in service after bootstrap completion fails" + self.system_fault_code["F673126"] = "This fault is raised when update bridge domain with static route fails" + self.system_fault_code["F673127"] = "This fault is raised when update private network with taboo configuration fails" + self.system_fault_code["F673128"] = "This fault is raised when update private network with EPG summary information fails" + self.system_fault_code["F673139"] = "This fault occurs when updating the fabric node vector fails." + self.system_fault_code["F673146"] = "None set." + self.system_fault_code["F673156"] = "This fault is raised when sending message to contract shard failed and graph instance could not be re-rendered." + self.system_fault_code["F673159"] = "This fault is raised when update bridge domain container fails" + self.system_fault_code["F673164"] = "This fault occurs when contract or bundle interface configuration fails to be delivered to contract or bundle" + self.system_fault_code["F673168"] = "This fault is raised when sending Fabric Node subscription to the Policy Manager via Appliance Element fails" + self.system_fault_code["F673196"] = "This fault is raised when register for node notification fails" + self.system_fault_code["F673197"] = "This fault occurs when an alias instance update fails" + self.system_fault_code["F673200"] = "This fault is raised when NAT entry creation for concrete device management interface failed." + self.system_fault_code["F673202"] = "This fault is raised when reporting fabric path group on an external connected node fails" + self.system_fault_code["F673203"] = "This fault is raised when send callhome inventory fails" + self.system_fault_code["F673206"] = "This fault is raised when notify spine proxy create fails" + self.system_fault_code["F673220"] = "This fault occurs when private network configuration fails to be updated with remote contract collection" + self.system_fault_code["F673225"] = "This fault is raised when security filters required to allow traffic from EPgs to L4-L7 service graph traffic could not" + self.system_fault_code["F673226"] = "This fault is raised when the update of security domain configuration to PolicyMgr fails. This is an internal task used" + self.system_fault_code["F673261"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F673262"] = "This fault is raised when L4-L7 service graph related information could not be configured on leafs." + self.system_fault_code["F673263"] = "None set." + self.system_fault_code["F673264"] = "None set." + self.system_fault_code["F673265"] = "None set." + self.system_fault_code["F673266"] = "None set." + self.system_fault_code["F673282"] = "None set." + self.system_fault_code["F673286"] = "None set." + self.system_fault_code["F673319"] = "This fault is raised when virtual IP address assignment fails" + self.system_fault_code["F673382"] = "This fault is raised when sending Fabric Node removal to Topology Manager fails" + self.system_fault_code["F673397"] = "This fault is raised when a configuration update to EPP failed." + self.system_fault_code["F673410"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F673411"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F673412"] = "This fault is raised when L4-L7 service graph could not create port groups on VCenter required for directing service graph" + self.system_fault_code["F673427"] = "This fault is raised when update of critirion information under the container fails" + self.system_fault_code["F673433"] = "This fault is raised when adding/deleting a Black Hole Porgroup for the Controller fails" + self.system_fault_code["F673441"] = "This fault is raised when system cannot validate vlan encap of this object." + self.system_fault_code["F673464"] = "This fault is raised when updating private network context with the virtual IP fails" + self.system_fault_code["F673476"] = "None set." + self.system_fault_code["F673477"] = "None set." + self.system_fault_code["F673478"] = "None set." + self.system_fault_code["F673479"] = "This fault is raised when configuration distribution of RbacRules fails" + self.system_fault_code["F673481"] = "This fault is raised when updating private network context with the virtual IP fails" + self.system_fault_code["F673590"] = "None set." + self.system_fault_code["F673595"] = "This fault is raised when task fails which is due to one shard being particularly busy." + self.system_fault_code["F673601"] = "This fault is raised when cleanup of path end-points fails." + self.system_fault_code["F673602"] = "This fault is raised when remove path end-points request fails" + self.system_fault_code["F673612"] = "This fault occurs when EPG policy enforcement tag fails to be reallocated from shared service pool" + self.system_fault_code["F673614"] = "None set." + self.system_fault_code["F673638"] = "None set." + self.system_fault_code["F673639"] = "This fault is raised when the node (leaf/spine) fails to send the message to controller to resolve all its policies." + self.system_fault_code["F673640"] = "None set." + self.system_fault_code["F673643"] = "This fault is raised when the message to notify leaf/spine about policy reconcilation fails" + self.system_fault_code["F673664"] = "This fault is raised when notification of the detach fails" + self.system_fault_code["F673668"] = "This fault is raised when notification of a policy demand message fails" + self.system_fault_code["F673685"] = "None set." + self.system_fault_code["F673690"] = "None set." + self.system_fault_code["F673691"] = "None set." + self.system_fault_code["F673697"] = "None set." + self.system_fault_code["F673698"] = "None set." + self.system_fault_code["F673699"] = "This fault is raised when handshake between PE and AD fails" + self.system_fault_code["F673703"] = "This fault is raised when delete controller tracker list for AVS techsupport collection fails" + self.system_fault_code["F673751"] = "This fault is raised when the message fails to be sent the destination shard." + self.system_fault_code["F673754"] = "None set." + self.system_fault_code["F673776"] = "None set." + self.system_fault_code["F673803"] = "This fault is raised when configuration distribution of RbacRules fails" + self.system_fault_code["F673805"] = "This fault is raised when task to reset policy status on policy deletion fails." + self.system_fault_code["F673810"] = "None set." + self.system_fault_code["F673833"] = "This fault is raised when adding or deleting microsegmentation IP set fails." + self.system_fault_code["F673834"] = "This fault is raised when adding or deleting microsegmentation MAC set fails." + self.system_fault_code["F673837"] = "This fault is raised when mac/ip address reporting to Policy Manager fails. This is an internal task." + self.system_fault_code["F673856"] = "None set." + self.system_fault_code["F673857"] = "None set." + self.system_fault_code["F673858"] = "This fault is raised when requesting an AREpP fails" + self.system_fault_code["F673868"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F673869"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F673870"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F673871"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F673872"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F673873"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F673878"] = "This fault is raised when adding/deleting microsegmentation firewall rules fail." + self.system_fault_code["F673879"] = "This fault is raised when adding/deleting microsegmentation filter profiles fail." + self.system_fault_code["F673880"] = "This fault is raised when adding or deleting microsegmentation end point criteria fails." + self.system_fault_code["F673881"] = "This fault is raised when microsegmentation member MAC update to Policy Manager fails." + self.system_fault_code["F673931"] = "This fault is raised when adding or deleting PVLAN configuration at the vCenter fails or when clean up of stale PVLAN" + self.system_fault_code["F673932"] = "None set." + self.system_fault_code["F673933"] = "None set." + self.system_fault_code["F673981"] = "None set." + self.system_fault_code["F673999"] = "None set." + self.system_fault_code["F674010"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F674011"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F674144"] = "None set." + self.system_fault_code["F674157"] = "None set." + self.system_fault_code["F674160"] = "None set." + self.system_fault_code["F674161"] = "None set." + self.system_fault_code["F674162"] = "None set." + self.system_fault_code["F674166"] = "None set." + self.system_fault_code["F674171"] = "This fault is raised when both the opflex channels for compHv are down." + self.system_fault_code["F674290"] = "None set." + self.system_fault_code["F674300"] = "None set." + self.system_fault_code["F674322"] = "This fault occurs when multisite mappings fails to be updated" + self.system_fault_code["F674331"] = "None set." + self.system_fault_code["F674351"] = "None set." + self.system_fault_code["F674397"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F674399"] = "None set." + self.system_fault_code["F674425"] = "None set." + self.system_fault_code["F674426"] = "None set." + self.system_fault_code["F674440"] = "This fault occurs when contract or bundle interface configuration fails to be delivered to contract or bundle" + self.system_fault_code["F674444"] = "None set." + self.system_fault_code["F674448"] = "None set." + self.system_fault_code["F674460"] = "None set." + self.system_fault_code["F674473"] = "This fault is raised when update between PE and PE fails" + self.system_fault_code["F674512"] = "This fault is raised when NAT entry creation for controller appliance failed." + self.system_fault_code["F674516"] = "This fault is raised when notification of an endpoint attach or detach fails" + self.system_fault_code["F674525"] = "None set." + self.system_fault_code["F674552"] = "This fault occurs when gipo allocation fails" + self.system_fault_code["F674553"] = "This fault occurs when syncing locally allocated gipo fails" + self.system_fault_code["F674554"] = "This fault occurs when gipo reallocation fails" + self.system_fault_code["F674562"] = "None set." + self.system_fault_code["F674589"] = "None set." + self.system_fault_code["F674607"] = "None set." + self.system_fault_code["F674622"] = "None set." + self.system_fault_code["F674629"] = "None set." + self.system_fault_code["F674636"] = "This fault is raised when cleanup of path end-points fails." + self.system_fault_code["F674637"] = "This fault is raised when sending the SVM information from vCenter controller to SVM container" + self.system_fault_code["F674664"] = "None set." + self.system_fault_code["F674677"] = "This fault occurs when updating the dhcp pool fails." + self.system_fault_code["F674695"] = "None set." + self.system_fault_code["F674696"] = "None set." + self.system_fault_code["F674697"] = "None set." + self.system_fault_code["F674727"] = "This fault is raised when send decommission message to vmmmgr fails" + self.system_fault_code["F674767"] = "None set." + self.system_fault_code["F674823"] = "None set." + self.system_fault_code["F674837"] = "None set." + self.system_fault_code["F674855"] = "This fault is raised when notification of an endpoint attach or detach fails" + self.system_fault_code["F674860"] = "This fault is raised if endpoint profile update for service graph service EPG fails." + self.system_fault_code["F674864"] = "None set." + self.system_fault_code["F674867"] = "This fault is raised when updating a VM Configuration fails. This typically happens if fhe Physical-NICs of the Hosts" + self.system_fault_code["F674868"] = "None set." + self.system_fault_code["F674869"] = "None set." + self.system_fault_code["F674873"] = "None set." + self.system_fault_code["F674874"] = "None set." + self.system_fault_code["F674887"] = "None set." + self.system_fault_code["F674888"] = "This fault is raised when notification about a destination ep fails" + self.system_fault_code["F674903"] = "None set." + self.system_fault_code["F674915"] = "This fault is raised when a configuration update to the VMM Controller fails." + self.system_fault_code["F674916"] = "None set." + self.system_fault_code["F674918"] = "None set." + self.system_fault_code["F674920"] = "None set." + self.system_fault_code["F674921"] = "None set." + self.system_fault_code["F674922"] = "None set." + self.system_fault_code["F674929"] = "This fault is raised when updating the Enhanced LACP Lag Policy at the DVS fails." + self.system_fault_code["F674943"] = "This fault is raised when sending the SVM information from vCenter controller to SVM container" + self.system_fault_code["F674944"] = "This fault is raised when adding/deleting a Black Hole Porgroup for the Controller fails" + self.system_fault_code["F674945"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F674946"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F674947"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F674948"] = "This fault is raised when notification of a network path endpoint update fails" + self.system_fault_code["F674959"] = "None set." + self.system_fault_code["F674960"] = "This fault is raised when FSM for Controller Remove operation fails." + self.system_fault_code["F674972"] = "None set." + self.system_fault_code["F674973"] = "None set." + self.system_fault_code["F674974"] = "None set." + self.system_fault_code["F674975"] = "None set." + self.system_fault_code["F674978"] = "None set." + self.system_fault_code["F674981"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F675011"] = "None set." + self.system_fault_code["F675014"] = "This fault is raised when fabric:SetupPol provisioning fails" + self.system_fault_code["F675021"] = "This fault is raised when reporting AVE timeout fails" + self.system_fault_code["F675038"] = "This fault is raised when send policy cleanup request fails" + self.system_fault_code["F675041"] = "None set." + self.system_fault_code["F675048"] = "None set." + self.system_fault_code["F675049"] = "None set." + self.system_fault_code["F675064"] = "None set." + self.system_fault_code["F675066"] = "None set." + self.system_fault_code["F675067"] = "This fault is raised when sending the updated set of managed Nics from vmmmgr to edmgr" + self.system_fault_code["F675068"] = "None set." + self.system_fault_code["F675083"] = "None set." + self.system_fault_code["F675084"] = "None set." + self.system_fault_code["F675087"] = "None set." + self.system_fault_code["F675089"] = "This fault is raised when the node (leaf/spine) fails to send the message to controller to resolve all its policies." + self.system_fault_code["F675094"] = "This fault is raised when task to sync cloudEpP fails" + self.system_fault_code["F675112"] = "None set." + self.system_fault_code["F675171"] = "None set." + self.system_fault_code["F675188"] = "None set." + self.system_fault_code["F675213"] = "None set." + self.system_fault_code["F675214"] = "None set." + self.system_fault_code["F675216"] = "This fault is raised when sending Fabric Node add to VMM Manager fails" + self.system_fault_code["F675220"] = "None set." + self.system_fault_code["F675243"] = "This fault is raised when an update for L4-L7 service policy fails" + self.system_fault_code["F675248"] = "None set." + self.system_fault_code["F675267"] = "None set." + self.system_fault_code["F675299"] = "None set." + self.system_fault_code["F92240"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92241"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92242"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92243"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92244"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92245"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92246"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92247"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92256"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92257"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92258"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92259"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92260"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92261"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92262"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92263"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92264"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92265"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92266"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92267"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92268"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92269"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92270"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92271"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92272"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92273"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92274"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92275"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92276"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92277"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92278"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92279"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92280"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92281"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92282"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92283"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92284"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92285"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92286"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92287"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92288"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92289"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92290"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92291"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92292"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92293"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92294"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92295"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92320"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92321"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92322"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92323"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92324"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92325"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92326"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92327"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92328"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92329"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92330"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92331"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92332"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92333"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92334"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92335"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92408"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92409"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92410"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92411"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92412"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92413"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92414"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92415"] = "This fault is caused by 'egress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92424"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92425"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92426"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92427"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92428"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92429"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92430"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92431"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92432"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92433"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92434"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92435"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92436"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92437"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92438"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92439"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92440"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92441"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92442"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92443"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92444"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92445"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92446"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92447"] = "This fault is caused by 'egress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92448"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92449"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92450"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92451"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92452"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92453"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92454"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92455"] = "This fault is caused by 'egress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92456"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92457"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92458"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92459"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92460"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92461"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92462"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92463"] = "This fault is caused by 'egress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92488"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92489"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92490"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92491"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92492"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92493"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92494"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92495"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92496"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92497"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92498"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92499"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92500"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92501"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92502"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92503"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92576"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92577"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92578"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92579"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92580"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92581"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92582"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92583"] = "This fault is caused by 'egress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92584"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92585"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92586"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92587"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92588"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92589"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92590"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92591"] = "This fault is caused by 'egress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92616"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92617"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92618"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92619"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92620"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92621"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92622"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92623"] = "This fault is caused by 'egress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92624"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92625"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92626"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92627"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92628"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92629"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92630"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92631"] = "This fault is caused by 'egress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92728"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92729"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92730"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92731"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92732"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92733"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92734"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92735"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92744"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92745"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92746"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92747"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92748"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92749"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92750"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92751"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92752"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92753"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92754"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92755"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92756"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92757"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92758"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92759"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92760"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92761"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92762"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92763"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92764"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92765"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92766"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92767"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92768"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92769"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92770"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92771"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92772"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92773"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92774"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92775"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92776"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92777"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92778"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92779"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92780"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92781"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92782"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92783"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92808"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92809"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92810"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92811"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92812"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92813"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92814"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92815"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92816"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92817"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92818"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92819"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92820"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92821"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92822"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92823"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92896"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92897"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92898"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92899"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92900"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92901"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92902"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92903"] = "This fault is caused by 'ingress hit packets current value' statistical property crossing threshold level." + self.system_fault_code["F92912"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92913"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92914"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92915"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92916"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92917"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92918"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92919"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F92920"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92921"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92922"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92923"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92924"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92925"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92926"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92927"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F92928"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92929"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92930"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92931"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92932"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92933"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92934"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92935"] = "This fault is caused by 'ingress hit packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F92936"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92937"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92938"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92939"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92940"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92941"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92942"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92943"] = "This fault is caused by 'ingress hit packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F92944"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92945"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92946"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92947"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92948"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92949"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92950"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92951"] = "This fault is caused by 'ingress hit packets average value' statistical property crossing threshold level." + self.system_fault_code["F92976"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92977"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92978"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92979"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92980"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92981"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92982"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92983"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F92984"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92985"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92986"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92987"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92988"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92989"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92990"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F92991"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93064"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93065"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93066"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93067"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93068"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93069"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93070"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93071"] = "This fault is caused by 'ingress hit packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93072"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93073"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93074"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93075"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93076"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93077"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93078"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93079"] = "This fault is caused by 'ingress hit packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93104"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93105"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93106"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93107"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93108"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93109"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93110"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93111"] = "This fault is caused by 'ingress hit packets trend' statistical property crossing threshold level." + self.system_fault_code["F93112"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93113"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93114"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93115"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93116"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93117"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93118"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93119"] = "This fault is caused by 'ingress hit packets rate' statistical property crossing threshold level." + self.system_fault_code["F93216"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93217"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93218"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93219"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93220"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93221"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93222"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93223"] = "This fault is caused by 'CPU usage current value' statistical property crossing threshold level." + self.system_fault_code["F93224"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93225"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93226"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93227"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93228"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93229"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93230"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93231"] = "This fault is caused by 'CPU usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93232"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93233"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93234"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93235"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93236"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93237"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93238"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93239"] = "This fault is caused by 'CPU usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93240"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93241"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93242"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93243"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93244"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93245"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93246"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93247"] = "This fault is caused by 'CPU usage average value' statistical property crossing threshold level." + self.system_fault_code["F93280"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93281"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93282"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93283"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93284"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93285"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93286"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93287"] = "This fault is caused by 'CPU usage trend' statistical property crossing threshold level." + self.system_fault_code["F93336"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93337"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93338"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93339"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93340"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93341"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93342"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93343"] = "This fault is caused by 'memory usage current value' statistical property crossing threshold level." + self.system_fault_code["F93344"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93345"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93346"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93347"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93348"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93349"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93350"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93351"] = "This fault is caused by 'memory usage minimum value' statistical property crossing threshold level." + self.system_fault_code["F93352"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93353"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93354"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93355"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93356"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93357"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93358"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93359"] = "This fault is caused by 'memory usage maximum value' statistical property crossing threshold level." + self.system_fault_code["F93360"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93361"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93362"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93363"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93364"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93365"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93366"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93367"] = "This fault is caused by 'memory usage average value' statistical property crossing threshold level." + self.system_fault_code["F93400"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93401"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93402"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93403"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93404"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93405"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93406"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93407"] = "This fault is caused by 'memory usage trend' statistical property crossing threshold level." + self.system_fault_code["F93456"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93457"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93458"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93459"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93460"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93461"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93462"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93463"] = "This fault is caused by 'received rate current value' statistical property crossing threshold level." + self.system_fault_code["F93488"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93489"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93490"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93491"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93492"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93493"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93494"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93495"] = "This fault is caused by 'received rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F93496"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93497"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93498"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93499"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93500"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93501"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93502"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93503"] = "This fault is caused by 'received rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F93504"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93505"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93506"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93507"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93508"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93509"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93510"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93511"] = "This fault is caused by 'received rate average value' statistical property crossing threshold level." + self.system_fault_code["F93536"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93537"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93538"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93539"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93540"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93541"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93542"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93543"] = "This fault is caused by 'received rate trend' statistical property crossing threshold level." + self.system_fault_code["F93624"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93625"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93626"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93627"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93628"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93629"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93630"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93631"] = "This fault is caused by 'received dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F93640"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93641"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93642"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93643"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93644"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93645"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93646"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93647"] = "This fault is caused by 'received dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93648"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93649"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93650"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93651"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93652"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93653"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93654"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93655"] = "This fault is caused by 'received dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93656"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93657"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93658"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93659"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93660"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93661"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93662"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93663"] = "This fault is caused by 'received dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93664"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93665"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93666"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93667"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93668"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93669"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93670"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93671"] = "This fault is caused by 'received dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93672"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93673"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93674"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93675"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93676"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93677"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93678"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93679"] = "This fault is caused by 'received dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F93704"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93705"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93706"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93707"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93708"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93709"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93710"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93711"] = "This fault is caused by 'received dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F93712"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93713"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93714"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93715"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93716"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93717"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93718"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93719"] = "This fault is caused by 'received dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F93792"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93793"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93794"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93795"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93796"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93797"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93798"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93799"] = "This fault is caused by 'received error packets current value' statistical property crossing threshold level." + self.system_fault_code["F93808"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93809"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93810"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93811"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93812"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93813"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93814"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93815"] = "This fault is caused by 'received error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93816"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93817"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93818"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93819"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93820"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93821"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93822"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93823"] = "This fault is caused by 'received error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93824"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93825"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93826"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93827"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93828"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93829"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93830"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93831"] = "This fault is caused by 'received error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93832"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93833"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93834"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93835"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93836"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93837"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93838"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93839"] = "This fault is caused by 'received error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F93840"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93841"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93842"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93843"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93844"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93845"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93846"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93847"] = "This fault is caused by 'received error packets average value' statistical property crossing threshold level." + self.system_fault_code["F93872"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93873"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93874"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93875"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93876"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93877"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93878"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93879"] = "This fault is caused by 'received error packets trend' statistical property crossing threshold level." + self.system_fault_code["F93880"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93881"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93882"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93883"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93884"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93885"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93886"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93887"] = "This fault is caused by 'received error packets rate' statistical property crossing threshold level." + self.system_fault_code["F93960"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93961"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93962"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93963"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93964"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93965"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93966"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93967"] = "This fault is caused by 'received broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F93976"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93977"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93978"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93979"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93980"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93981"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93982"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93983"] = "This fault is caused by 'received broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F93984"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93985"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93986"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93987"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93988"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93989"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93990"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93991"] = "This fault is caused by 'received broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F93992"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93993"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93994"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93995"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93996"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93997"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93998"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F93999"] = "This fault is caused by 'received broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94000"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94001"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94002"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94003"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94004"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94005"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94006"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94007"] = "This fault is caused by 'received broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94008"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94009"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94010"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94011"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94012"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94013"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94014"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94015"] = "This fault is caused by 'received broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94040"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94041"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94042"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94043"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94044"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94045"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94046"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94047"] = "This fault is caused by 'received broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94048"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94049"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94050"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94051"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94052"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94053"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94054"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94055"] = "This fault is caused by 'received broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94128"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94129"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94130"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94131"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94132"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94133"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94134"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94135"] = "This fault is caused by 'received multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94144"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94145"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94146"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94147"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94148"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94149"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94150"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94151"] = "This fault is caused by 'received multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94152"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94153"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94154"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94155"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94156"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94157"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94158"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94159"] = "This fault is caused by 'received multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94160"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94161"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94162"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94163"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94164"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94165"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94166"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94167"] = "This fault is caused by 'received multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94168"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94169"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94170"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94171"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94172"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94173"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94174"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94175"] = "This fault is caused by 'received multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94176"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94177"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94178"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94179"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94180"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94181"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94182"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94183"] = "This fault is caused by 'received multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F94208"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94209"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94210"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94211"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94212"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94213"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94214"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94215"] = "This fault is caused by 'received multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F94216"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94217"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94218"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94219"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94220"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94221"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94222"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94223"] = "This fault is caused by 'received multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F94296"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94297"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94298"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94299"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94300"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94301"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94302"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94303"] = "This fault is caused by 'received packets current value' statistical property crossing threshold level." + self.system_fault_code["F94312"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94313"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94314"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94315"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94316"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94317"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94318"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94319"] = "This fault is caused by 'received packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94320"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94321"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94322"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94323"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94324"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94325"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94326"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94327"] = "This fault is caused by 'received packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94328"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94329"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94330"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94331"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94332"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94333"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94334"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94335"] = "This fault is caused by 'received packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94336"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94337"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94338"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94339"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94340"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94341"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94342"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94343"] = "This fault is caused by 'received packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94344"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94345"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94346"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94347"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94348"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94349"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94350"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94351"] = "This fault is caused by 'received packets average value' statistical property crossing threshold level." + self.system_fault_code["F94376"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94377"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94378"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94379"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94380"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94381"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94382"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94383"] = "This fault is caused by 'received packets trend' statistical property crossing threshold level." + self.system_fault_code["F94384"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94385"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94386"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94387"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94388"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94389"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94390"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94391"] = "This fault is caused by 'received packets rate' statistical property crossing threshold level." + self.system_fault_code["F94464"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94465"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94466"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94467"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94468"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94469"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94470"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94471"] = "This fault is caused by 'transmitted rate current value' statistical property crossing threshold level." + self.system_fault_code["F94496"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94497"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94498"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94499"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94500"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94501"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94502"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94503"] = "This fault is caused by 'transmitted rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F94504"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94505"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94506"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94507"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94508"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94509"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94510"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94511"] = "This fault is caused by 'transmitted rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F94512"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94513"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94514"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94515"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94516"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94517"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94518"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94519"] = "This fault is caused by 'transmitted rate average value' statistical property crossing threshold level." + self.system_fault_code["F94544"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94545"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94546"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94547"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94548"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94549"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94550"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94551"] = "This fault is caused by 'transmitted rate trend' statistical property crossing threshold level." + self.system_fault_code["F94632"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94633"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94634"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94635"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94636"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94637"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94638"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94639"] = "This fault is caused by 'transmitted dropped packets current value' statistical property crossing threshold level." + self.system_fault_code["F94648"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94649"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94650"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94651"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94652"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94653"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94654"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94655"] = "This fault is caused by 'transmitted dropped packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94656"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94657"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94658"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94659"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94660"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94661"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94662"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94663"] = "This fault is caused by 'transmitted dropped packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94664"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94665"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94666"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94667"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94668"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94669"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94670"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94671"] = "This fault is caused by 'transmitted dropped packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94672"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94673"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94674"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94675"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94676"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94677"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94678"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94679"] = "This fault is caused by 'transmitted dropped packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94680"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94681"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94682"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94683"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94684"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94685"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94686"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94687"] = "This fault is caused by 'transmitted dropped packets average value' statistical property crossing threshold level." + self.system_fault_code["F94712"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94713"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94714"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94715"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94716"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94717"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94718"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94719"] = "This fault is caused by 'transmitted dropped packets trend' statistical property crossing threshold level." + self.system_fault_code["F94720"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94721"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94722"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94723"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94724"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94725"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94726"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94727"] = "This fault is caused by 'transmitted dropped packets rate' statistical property crossing threshold level." + self.system_fault_code["F94800"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94801"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94802"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94803"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94804"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94805"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94806"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94807"] = "This fault is caused by 'transmitted error packets current value' statistical property crossing threshold level." + self.system_fault_code["F94816"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94817"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94818"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94819"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94820"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94821"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94822"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94823"] = "This fault is caused by 'transmitted error packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94824"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94825"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94826"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94827"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94828"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94829"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94830"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94831"] = "This fault is caused by 'transmitted error packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94832"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94833"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94834"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94835"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94836"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94837"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94838"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94839"] = "This fault is caused by 'transmitted error packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F94840"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94841"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94842"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94843"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94844"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94845"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94846"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94847"] = "This fault is caused by 'transmitted error packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F94848"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94849"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94850"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94851"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94852"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94853"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94854"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94855"] = "This fault is caused by 'transmitted error packets average value' statistical property crossing threshold level." + self.system_fault_code["F94880"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94881"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94882"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94883"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94884"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94885"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94886"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94887"] = "This fault is caused by 'transmitted error packets trend' statistical property crossing threshold level." + self.system_fault_code["F94888"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94889"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94890"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94891"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94892"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94893"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94894"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94895"] = "This fault is caused by 'transmitted error packets rate' statistical property crossing threshold level." + self.system_fault_code["F94968"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94969"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94970"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94971"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94972"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94973"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94974"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94975"] = "This fault is caused by 'transmitted broadcast packets current value' statistical property crossing threshold level." + self.system_fault_code["F94984"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94985"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94986"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94987"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94988"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94989"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94990"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94991"] = "This fault is caused by 'transmitted broadcast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F94992"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94993"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94994"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94995"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94996"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94997"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94998"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F94999"] = "This fault is caused by 'transmitted broadcast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95000"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95001"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95002"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95003"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95004"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95005"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95006"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95007"] = "This fault is caused by 'transmitted broadcast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95008"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95009"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95010"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95011"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95012"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95013"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95014"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95015"] = "This fault is caused by 'transmitted broadcast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95016"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95017"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95018"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95019"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95020"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95021"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95022"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95023"] = "This fault is caused by 'transmitted broadcast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95048"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95049"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95050"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95051"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95052"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95053"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95054"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95055"] = "This fault is caused by 'transmitted broadcast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95056"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95057"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95058"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95059"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95060"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95061"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95062"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95063"] = "This fault is caused by 'transmitted broadcast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95136"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95137"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95138"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95139"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95140"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95141"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95142"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95143"] = "This fault is caused by 'transmitted multicast packets current value' statistical property crossing threshold level." + self.system_fault_code["F95152"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95153"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95154"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95155"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95156"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95157"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95158"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95159"] = "This fault is caused by 'transmitted multicast packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95160"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95161"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95162"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95163"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95164"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95165"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95166"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95167"] = "This fault is caused by 'transmitted multicast packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95168"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95169"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95170"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95171"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95172"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95173"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95174"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95175"] = "This fault is caused by 'transmitted multicast packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95176"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95177"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95178"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95179"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95180"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95181"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95182"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95183"] = "This fault is caused by 'transmitted multicast packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95184"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95185"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95186"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95187"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95188"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95189"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95190"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95191"] = "This fault is caused by 'transmitted multicast packets average value' statistical property crossing threshold level." + self.system_fault_code["F95216"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95217"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95218"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95219"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95220"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95221"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95222"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95223"] = "This fault is caused by 'transmitted multicast packets trend' statistical property crossing threshold level." + self.system_fault_code["F95224"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95225"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95226"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95227"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95228"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95229"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95230"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95231"] = "This fault is caused by 'transmitted multicast packets rate' statistical property crossing threshold level." + self.system_fault_code["F95304"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95305"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95306"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95307"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95308"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95309"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95310"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95311"] = "This fault is caused by 'transmitted packets current value' statistical property crossing threshold level." + self.system_fault_code["F95320"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95321"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95322"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95323"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95324"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95325"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95326"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95327"] = "This fault is caused by 'transmitted packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F95328"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95329"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95330"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95331"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95332"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95333"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95334"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95335"] = "This fault is caused by 'transmitted packets periodic' statistical property crossing threshold level." + self.system_fault_code["F95336"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95337"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95338"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95339"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95340"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95341"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95342"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95343"] = "This fault is caused by 'transmitted packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F95344"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95345"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95346"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95347"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95348"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95349"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95350"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95351"] = "This fault is caused by 'transmitted packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F95352"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95353"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95354"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95355"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95356"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95357"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95358"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95359"] = "This fault is caused by 'transmitted packets average value' statistical property crossing threshold level." + self.system_fault_code["F95384"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95385"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95386"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95387"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95388"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95389"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95390"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95391"] = "This fault is caused by 'transmitted packets trend' statistical property crossing threshold level." + self.system_fault_code["F95392"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95393"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95394"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95395"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95396"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95397"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95398"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95399"] = "This fault is caused by 'transmitted packets rate' statistical property crossing threshold level." + self.system_fault_code["F95472"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95473"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95474"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95475"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95476"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95477"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95478"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95479"] = "This fault is caused by 'Egress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95488"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95489"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95490"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95491"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95492"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95493"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95494"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95495"] = "This fault is caused by 'Egress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95496"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95497"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95498"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95499"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95500"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95501"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95502"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95503"] = "This fault is caused by 'Egress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95504"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95505"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95506"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95507"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95508"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95509"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95510"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95511"] = "This fault is caused by 'Egress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95512"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95513"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95514"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95515"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95516"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95517"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95518"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95519"] = "This fault is caused by 'Egress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95520"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95521"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95522"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95523"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95524"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95525"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95526"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95527"] = "This fault is caused by 'Egress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95552"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95553"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95554"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95555"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95556"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95557"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95558"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95559"] = "This fault is caused by 'Egress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95560"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95561"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95562"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95563"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95564"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95565"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95566"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95567"] = "This fault is caused by 'Egress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95688"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95689"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95690"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95691"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95692"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95693"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95694"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95695"] = "This fault is caused by 'Egress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F95704"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95705"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95706"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95707"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95708"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95709"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95710"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95711"] = "This fault is caused by 'Egress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F95712"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95713"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95714"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95715"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95716"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95717"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95718"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95719"] = "This fault is caused by 'Egress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F95720"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95721"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95722"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95723"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95724"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95725"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95726"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95727"] = "This fault is caused by 'Egress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F95728"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95729"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95730"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95731"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95732"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95733"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95734"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95735"] = "This fault is caused by 'Egress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F95736"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95737"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95738"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95739"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95740"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95741"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95742"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95743"] = "This fault is caused by 'Egress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F95768"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95769"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95770"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95771"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95772"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95773"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95774"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95775"] = "This fault is caused by 'Egress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F95776"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95777"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95778"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95779"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95780"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95781"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95782"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95783"] = "This fault is caused by 'Egress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F95904"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95905"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95906"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95907"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95908"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95909"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95910"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95911"] = "This fault is caused by 'Egress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F95912"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95913"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95914"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95915"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95916"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95917"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95918"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95919"] = "This fault is caused by 'Egress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F95920"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95921"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95922"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95923"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95924"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95925"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95926"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95927"] = "This fault is caused by 'Egress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F95928"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95929"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95930"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95931"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95932"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95933"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95934"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95935"] = "This fault is caused by 'Egress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F95968"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95969"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95970"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95971"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95972"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95973"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95974"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F95975"] = "This fault is caused by 'Egress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96072"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96073"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96074"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96075"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96076"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96077"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96078"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96079"] = "This fault is caused by 'Egress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F96088"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96089"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96090"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96091"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96092"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96093"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96094"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96095"] = "This fault is caused by 'Egress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F96096"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96097"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96098"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96099"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96100"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96101"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96102"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96103"] = "This fault is caused by 'Egress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F96104"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96105"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96106"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96107"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96108"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96109"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96110"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96111"] = "This fault is caused by 'Egress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F96112"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96113"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96114"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96115"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96116"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96117"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96118"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96119"] = "This fault is caused by 'Egress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F96120"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96121"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96122"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96123"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96124"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96125"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96126"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96127"] = "This fault is caused by 'Egress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F96152"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96153"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96154"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96155"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96156"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96157"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96158"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96159"] = "This fault is caused by 'Egress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F96160"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96161"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96162"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96163"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96164"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96165"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96166"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96167"] = "This fault is caused by 'Egress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F96288"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96289"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96290"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96291"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96292"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96293"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96294"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96295"] = "This fault is caused by 'Egress Unicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F96296"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96297"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96298"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96299"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96300"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96301"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96302"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96303"] = "This fault is caused by 'Egress Unicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F96304"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96305"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96306"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96307"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96308"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96309"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96310"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96311"] = "This fault is caused by 'Egress Unicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F96312"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96313"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96314"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96315"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96316"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96317"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96318"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96319"] = "This fault is caused by 'Egress Unicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F96352"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96353"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96354"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96355"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96356"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96357"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96358"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96359"] = "This fault is caused by 'Egress Unicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F96456"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96457"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96458"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96459"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96460"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96461"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96462"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96463"] = "This fault is caused by 'Egress AFD WRED Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96472"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96473"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96474"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96475"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96476"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96477"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96478"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96479"] = "This fault is caused by 'Egress AFD WRED Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96480"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96481"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96482"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96483"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96484"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96485"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96486"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96487"] = "This fault is caused by 'Egress AFD WRED Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96488"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96489"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96490"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96491"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96492"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96493"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96494"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96495"] = "This fault is caused by 'Egress AFD WRED Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96496"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96497"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96498"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96499"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96500"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96501"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96502"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96503"] = "This fault is caused by 'Egress AFD WRED Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96504"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96505"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96506"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96507"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96508"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96509"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96510"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96511"] = "This fault is caused by 'Egress AFD WRED Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96536"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96537"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96538"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96539"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96540"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96541"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96542"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96543"] = "This fault is caused by 'Egress AFD WRED Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96544"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96545"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96546"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96547"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96548"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96549"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96550"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96551"] = "This fault is caused by 'Egress AFD WRED Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96672"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96673"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96674"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96675"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96676"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96677"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96678"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96679"] = "This fault is caused by 'Egress Buffer Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96688"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96689"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96690"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96691"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96692"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96693"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96694"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96695"] = "This fault is caused by 'Egress Buffer Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96696"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96697"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96698"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96699"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96700"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96701"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96702"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96703"] = "This fault is caused by 'Egress Buffer Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96704"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96705"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96706"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96707"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96708"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96709"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96710"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96711"] = "This fault is caused by 'Egress Buffer Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96712"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96713"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96714"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96715"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96716"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96717"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96718"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96719"] = "This fault is caused by 'Egress Buffer Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96720"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96721"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96722"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96723"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96724"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96725"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96726"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96727"] = "This fault is caused by 'Egress Buffer Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96752"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96753"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96754"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96755"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96756"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96757"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96758"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96759"] = "This fault is caused by 'Egress Buffer Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96760"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96761"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96762"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96763"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96764"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96765"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96766"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96767"] = "This fault is caused by 'Egress Buffer Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96888"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96889"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96890"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96891"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96892"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96893"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96894"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96895"] = "This fault is caused by 'Egress Error Drop Packets current value' statistical property crossing threshold level." + self.system_fault_code["F96904"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96905"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96906"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96907"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96908"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96909"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96910"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96911"] = "This fault is caused by 'Egress Error Drop Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F96912"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96913"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96914"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96915"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96916"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96917"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96918"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96919"] = "This fault is caused by 'Egress Error Drop Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F96920"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96921"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96922"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96923"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96924"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96925"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96926"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96927"] = "This fault is caused by 'Egress Error Drop Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F96928"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96929"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96930"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96931"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96932"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96933"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96934"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96935"] = "This fault is caused by 'Egress Error Drop Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F96936"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96937"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96938"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96939"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96940"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96941"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96942"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96943"] = "This fault is caused by 'Egress Error Drop Packets average value' statistical property crossing threshold level." + self.system_fault_code["F96968"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96969"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96970"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96971"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96972"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96973"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96974"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96975"] = "This fault is caused by 'Egress Error Drop Packets trend' statistical property crossing threshold level." + self.system_fault_code["F96976"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96977"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96978"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96979"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96980"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96981"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96982"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F96983"] = "This fault is caused by 'Egress Error Drop Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97104"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97105"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97106"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97107"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97108"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97109"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97110"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97111"] = "This fault is caused by 'Egress Flood Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97120"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97121"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97122"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97123"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97124"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97125"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97126"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97127"] = "This fault is caused by 'Egress Flood Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97128"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97129"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97130"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97131"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97132"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97133"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97134"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97135"] = "This fault is caused by 'Egress Flood Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97136"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97137"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97138"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97139"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97140"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97141"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97142"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97143"] = "This fault is caused by 'Egress Flood Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97144"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97145"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97146"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97147"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97148"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97149"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97150"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97151"] = "This fault is caused by 'Egress Flood Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97152"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97153"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97154"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97155"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97156"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97157"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97158"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97159"] = "This fault is caused by 'Egress Flood Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97184"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97185"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97186"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97187"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97188"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97189"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97190"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97191"] = "This fault is caused by 'Egress Flood Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97192"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97193"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97194"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97195"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97196"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97197"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97198"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97199"] = "This fault is caused by 'Egress Flood Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97320"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97321"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97322"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97323"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97324"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97325"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97326"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97327"] = "This fault is caused by 'Egress Multicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97336"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97337"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97338"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97339"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97340"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97341"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97342"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97343"] = "This fault is caused by 'Egress Multicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97344"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97345"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97346"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97347"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97348"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97349"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97350"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97351"] = "This fault is caused by 'Egress Multicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97352"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97353"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97354"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97355"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97356"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97357"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97358"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97359"] = "This fault is caused by 'Egress Multicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97360"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97361"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97362"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97363"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97364"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97365"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97366"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97367"] = "This fault is caused by 'Egress Multicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97368"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97369"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97370"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97371"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97372"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97373"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97374"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97375"] = "This fault is caused by 'Egress Multicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97400"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97401"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97402"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97403"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97404"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97405"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97406"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97407"] = "This fault is caused by 'Egress Multicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97408"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97409"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97410"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97411"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97412"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97413"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97414"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97415"] = "This fault is caused by 'Egress Multicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97536"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97537"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97538"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97539"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97540"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97541"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97542"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97543"] = "This fault is caused by 'Egress Unicast Packets current value' statistical property crossing threshold level." + self.system_fault_code["F97552"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97553"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97554"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97555"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97556"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97557"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97558"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97559"] = "This fault is caused by 'Egress Unicast Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F97560"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97561"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97562"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97563"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97564"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97565"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97566"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97567"] = "This fault is caused by 'Egress Unicast Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F97568"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97569"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97570"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97571"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97572"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97573"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97574"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97575"] = "This fault is caused by 'Egress Unicast Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F97576"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97577"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97578"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97579"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97580"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97581"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97582"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97583"] = "This fault is caused by 'Egress Unicast Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F97584"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97585"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97586"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97587"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97588"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97589"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97590"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97591"] = "This fault is caused by 'Egress Unicast Packets average value' statistical property crossing threshold level." + self.system_fault_code["F97616"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97617"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97618"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97619"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97620"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97621"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97622"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97623"] = "This fault is caused by 'Egress Unicast Packets trend' statistical property crossing threshold level." + self.system_fault_code["F97624"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97625"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97626"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97627"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97628"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97629"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97630"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97631"] = "This fault is caused by 'Egress Unicast Packets rate' statistical property crossing threshold level." + self.system_fault_code["F97752"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97753"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97754"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97755"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97756"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97757"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97758"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97759"] = "This fault is caused by 'Total Egress Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F97768"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97769"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97770"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97771"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97772"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97773"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97774"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97775"] = "This fault is caused by 'Total Egress Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F97776"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97777"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97778"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97779"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97780"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97781"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97782"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97783"] = "This fault is caused by 'Total Egress Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F97784"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97785"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97786"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97787"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97788"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97789"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97790"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97791"] = "This fault is caused by 'Total Egress Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F97792"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97793"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97794"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97795"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97796"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97797"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97798"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97799"] = "This fault is caused by 'Total Egress Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F97800"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97801"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97802"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97803"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97804"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97805"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97806"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97807"] = "This fault is caused by 'Total Egress Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F97832"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97833"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97834"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97835"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97836"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97837"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97838"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97839"] = "This fault is caused by 'Total Egress Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F97840"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97841"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97842"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97843"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97844"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97845"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97846"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97847"] = "This fault is caused by 'Total Egress Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F97968"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97969"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97970"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97971"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97972"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97973"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97974"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97975"] = "This fault is caused by 'Total Egress Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F97976"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97977"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97978"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97979"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97980"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97981"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97982"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97983"] = "This fault is caused by 'Total Egress Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F97984"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97985"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97986"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97987"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97988"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97989"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97990"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97991"] = "This fault is caused by 'Total Egress Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F97992"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97993"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97994"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97995"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97996"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97997"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97998"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F97999"] = "This fault is caused by 'Total Egress Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F98032"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98033"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98034"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98035"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98036"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98037"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98038"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98039"] = "This fault is caused by 'Total Egress Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F98136"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98137"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98138"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98139"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98140"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98141"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98142"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98143"] = "This fault is caused by 'Total Egress Packets current value' statistical property crossing threshold level." + self.system_fault_code["F98152"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98153"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98154"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98155"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98156"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98157"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98158"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98159"] = "This fault is caused by 'Total Egress Packets cumulative' statistical property crossing threshold level." + self.system_fault_code["F98160"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98161"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98162"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98163"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98164"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98165"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98166"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98167"] = "This fault is caused by 'Total Egress Packets periodic' statistical property crossing threshold level." + self.system_fault_code["F98168"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98169"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98170"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98171"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98172"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98173"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98174"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98175"] = "This fault is caused by 'Total Egress Packets minimum value' statistical property crossing threshold level." + self.system_fault_code["F98176"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98177"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98178"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98179"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98180"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98181"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98182"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98183"] = "This fault is caused by 'Total Egress Packets maximum value' statistical property crossing threshold level." + self.system_fault_code["F98184"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98185"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98186"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98187"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98188"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98189"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98190"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98191"] = "This fault is caused by 'Total Egress Packets average value' statistical property crossing threshold level." + self.system_fault_code["F98216"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98217"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98218"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98219"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98220"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98221"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98222"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98223"] = "This fault is caused by 'Total Egress Packets trend' statistical property crossing threshold level." + self.system_fault_code["F98224"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98225"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98226"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98227"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98228"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98229"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98230"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98231"] = "This fault is caused by 'Total Egress Packets rate' statistical property crossing threshold level." + self.system_fault_code["F98352"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98353"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98354"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98355"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98356"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98357"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98358"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98359"] = "This fault is caused by 'Total Egress Packets rate current value' statistical property crossing threshold level." + self.system_fault_code["F98360"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98361"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98362"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98363"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98364"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98365"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98366"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98367"] = "This fault is caused by 'Total Egress Packets rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F98368"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98369"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98370"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98371"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98372"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98373"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98374"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98375"] = "This fault is caused by 'Total Egress Packets rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F98376"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98377"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98378"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98379"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98380"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98381"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98382"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98383"] = "This fault is caused by 'Total Egress Packets rate average value' statistical property crossing threshold level." + self.system_fault_code["F98416"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98417"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98418"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98419"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98420"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98421"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98422"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98423"] = "This fault is caused by 'Total Egress Packets rate trend' statistical property crossing threshold level." + self.system_fault_code["F98520"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98521"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98522"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98523"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98524"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98525"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98526"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98527"] = "This fault is caused by 'Egress Link Utilization current value' statistical property crossing threshold level." + self.system_fault_code["F98528"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98529"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98530"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98531"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98532"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98533"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98534"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98535"] = "This fault is caused by 'Egress Link Utilization minimum value' statistical property crossing threshold level." + self.system_fault_code["F98536"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98537"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98538"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98539"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98540"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98541"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98542"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98543"] = "This fault is caused by 'Egress Link Utilization maximum value' statistical property crossing threshold level." + self.system_fault_code["F98544"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98545"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98546"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98547"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98548"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98549"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98550"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98551"] = "This fault is caused by 'Egress Link Utilization average value' statistical property crossing threshold level." + self.system_fault_code["F98584"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98585"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98586"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98587"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98588"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98589"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98590"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98591"] = "This fault is caused by 'Egress Link Utilization trend' statistical property crossing threshold level." + self.system_fault_code["F98688"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98689"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98690"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98691"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98692"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98693"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98694"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98695"] = "This fault is caused by 'pulse width modulation current value' statistical property crossing threshold level." + self.system_fault_code["F98696"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98697"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98698"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98699"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98700"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98701"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98702"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98703"] = "This fault is caused by 'pulse width modulation minimum value' statistical property crossing threshold level." + self.system_fault_code["F98704"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98705"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98706"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98707"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98708"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98709"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98710"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98711"] = "This fault is caused by 'pulse width modulation maximum value' statistical property crossing threshold level." + self.system_fault_code["F98712"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98713"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98714"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98715"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98716"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98717"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98718"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98719"] = "This fault is caused by 'pulse width modulation average value' statistical property crossing threshold level." + self.system_fault_code["F98752"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98753"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98754"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98755"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98756"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98757"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98758"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98759"] = "This fault is caused by 'pulse width modulation trend' statistical property crossing threshold level." + self.system_fault_code["F98856"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98857"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98858"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98859"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98860"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98861"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98862"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98863"] = "This fault is caused by 'speed current value' statistical property crossing threshold level." + self.system_fault_code["F98864"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98865"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98866"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98867"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98868"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98869"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98870"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98871"] = "This fault is caused by 'speed minimum value' statistical property crossing threshold level." + self.system_fault_code["F98872"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98873"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98874"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98875"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98876"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98877"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98878"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98879"] = "This fault is caused by 'speed maximum value' statistical property crossing threshold level." + self.system_fault_code["F98880"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98881"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98882"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98883"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98884"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98885"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98886"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98887"] = "This fault is caused by 'speed average value' statistical property crossing threshold level." + self.system_fault_code["F98920"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98921"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98922"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98923"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98924"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98925"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98926"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F98927"] = "This fault is caused by 'speed trend' statistical property crossing threshold level." + self.system_fault_code["F99024"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99025"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99026"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99027"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99028"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99029"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99030"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99031"] = "This fault is caused by 'power consumed current value' statistical property crossing threshold level." + self.system_fault_code["F99032"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99033"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99034"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99035"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99036"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99037"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99038"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99039"] = "This fault is caused by 'power consumed minimum value' statistical property crossing threshold level." + self.system_fault_code["F99040"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99041"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99042"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99043"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99044"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99045"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99046"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99047"] = "This fault is caused by 'power consumed maximum value' statistical property crossing threshold level." + self.system_fault_code["F99048"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99049"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99050"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99051"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99052"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99053"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99054"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99055"] = "This fault is caused by 'power consumed average value' statistical property crossing threshold level." + self.system_fault_code["F99088"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99089"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99090"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99091"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99092"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99093"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99094"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99095"] = "This fault is caused by 'power consumed trend' statistical property crossing threshold level." + self.system_fault_code["F99192"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99193"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99194"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99195"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99196"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99197"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99198"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99199"] = "This fault is caused by 'Ingress Flood Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99208"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99209"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99210"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99211"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99212"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99213"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99214"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99215"] = "This fault is caused by 'Ingress Flood Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99216"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99217"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99218"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99219"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99220"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99221"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99222"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99223"] = "This fault is caused by 'Ingress Flood Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99224"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99225"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99226"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99227"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99228"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99229"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99230"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99231"] = "This fault is caused by 'Ingress Flood Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99232"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99233"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99234"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99235"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99236"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99237"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99238"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99239"] = "This fault is caused by 'Ingress Flood Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99240"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99241"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99242"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99243"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99244"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99245"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99246"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99247"] = "This fault is caused by 'Ingress Flood Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99272"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99273"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99274"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99275"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99276"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99277"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99278"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99279"] = "This fault is caused by 'Ingress Flood Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99280"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99281"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99282"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99283"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99284"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99285"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99286"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99287"] = "This fault is caused by 'Ingress Flood Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99408"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99409"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99410"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99411"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99412"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99413"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99414"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99415"] = "This fault is caused by 'Ingress Multicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99424"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99425"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99426"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99427"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99428"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99429"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99430"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99431"] = "This fault is caused by 'Ingress Multicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99432"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99433"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99434"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99435"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99436"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99437"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99438"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99439"] = "This fault is caused by 'Ingress Multicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99440"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99441"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99442"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99443"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99444"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99445"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99446"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99447"] = "This fault is caused by 'Ingress Multicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99448"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99449"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99450"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99451"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99452"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99453"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99454"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99455"] = "This fault is caused by 'Ingress Multicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99456"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99457"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99458"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99459"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99460"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99461"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99462"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99463"] = "This fault is caused by 'Ingress Multicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99488"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99489"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99490"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99491"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99492"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99493"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99494"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99495"] = "This fault is caused by 'Ingress Multicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99496"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99497"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99498"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99499"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99500"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99501"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99502"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99503"] = "This fault is caused by 'Ingress Multicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99624"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99625"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99626"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99627"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99628"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99629"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99630"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99631"] = "This fault is caused by 'Ingress Multicast Bytes rate current value' statistical property crossing threshold level." + self.system_fault_code["F99632"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99633"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99634"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99635"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99636"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99637"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99638"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99639"] = "This fault is caused by 'Ingress Multicast Bytes rate minimum value' statistical property crossing threshold level." + self.system_fault_code["F99640"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99641"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99642"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99643"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99644"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99645"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99646"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99647"] = "This fault is caused by 'Ingress Multicast Bytes rate maximum value' statistical property crossing threshold level." + self.system_fault_code["F99648"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99649"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99650"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99651"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99652"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99653"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99654"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99655"] = "This fault is caused by 'Ingress Multicast Bytes rate average value' statistical property crossing threshold level." + self.system_fault_code["F99688"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99689"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99690"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99691"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99692"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99693"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99694"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99695"] = "This fault is caused by 'Ingress Multicast Bytes rate trend' statistical property crossing threshold level." + self.system_fault_code["F99792"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99793"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99794"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99795"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99796"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99797"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99798"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99799"] = "This fault is caused by 'Ingress Unicast Bytes current value' statistical property crossing threshold level." + self.system_fault_code["F99808"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99809"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99810"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99811"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99812"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99813"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99814"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99815"] = "This fault is caused by 'Ingress Unicast Bytes cumulative' statistical property crossing threshold level." + self.system_fault_code["F99816"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99817"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99818"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99819"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99820"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99821"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99822"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99823"] = "This fault is caused by 'Ingress Unicast Bytes periodic' statistical property crossing threshold level." + self.system_fault_code["F99824"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99825"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99826"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99827"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99828"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99829"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99830"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99831"] = "This fault is caused by 'Ingress Unicast Bytes minimum value' statistical property crossing threshold level." + self.system_fault_code["F99832"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99833"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99834"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99835"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99836"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99837"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99838"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99839"] = "This fault is caused by 'Ingress Unicast Bytes maximum value' statistical property crossing threshold level." + self.system_fault_code["F99840"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99841"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99842"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99843"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99844"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99845"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99846"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99847"] = "This fault is caused by 'Ingress Unicast Bytes average value' statistical property crossing threshold level." + self.system_fault_code["F99872"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99873"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99874"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99875"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99876"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99877"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99878"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99879"] = "This fault is caused by 'Ingress Unicast Bytes trend' statistical property crossing threshold level." + self.system_fault_code["F99880"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99881"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99882"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99883"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99884"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99885"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99886"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." + self.system_fault_code["F99887"] = "This fault is caused by 'Ingress Unicast Bytes rate' statistical property crossing threshold level." diff --git a/lib/aci/system/fault/info.py b/lib/aci/system/fault/info.py new file mode 100644 index 00000000..74a5f0d1 --- /dev/null +++ b/lib/aci/system/fault/info.py @@ -0,0 +1,517 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class SystemFaultInfo(): + def __init__(self): + self.system_fault = None + + self.system_fault_type = {} + self.system_fault_type['environmental'] = 'Environmental' + self.system_fault_type['communications'] = 'Communications' + self.system_fault_type['config'] = 'Config' + self.system_fault_type['operational'] = 'Operational' + self.system_fault_type['total'] = 'Total' + + self.system_fault_domain = {} + self.system_fault_domain['access'] = 'Access' + self.system_fault_domain['apps'] = 'Apps' + self.system_fault_domain['external'] = 'External' + self.system_fault_domain['framework'] = 'Framework' + self.system_fault_domain['infra'] = 'Infra' + self.system_fault_domain['management'] = 'Management' + self.system_fault_domain['security'] = 'Security' + self.system_fault_domain['tenant'] = 'Tenant' + self.system_fault_domain['total'] = 'Total' + + self.system_fault_severity_name = {} + self.system_fault_severity_name['critical'] = 'Crit' + self.system_fault_severity_name['major'] = 'Maj' + self.system_fault_severity_name['minor'] = 'Min' + self.system_fault_severity_name['warning'] = 'Warn' + self.system_fault_severity_name['info'] = 'Info' + self.system_fault_severity_name['cleared'] = '--' + + self.system_fault_severity_color = {} + self.system_fault_severity_color['critical'] = 'Red' + self.system_fault_severity_color['major'] = 'Magenta' + self.system_fault_severity_color['minor'] = 'Yellow' + self.system_fault_severity_color['warning'] = 'Green' + self.system_fault_severity_color['cleared'] = 'Blue' + self.system_fault_severity_color['info'] = 'Blue' + + def get_system_faults_max_severity(self, faults): + if faults is None or len(faults) == 0: + return None + + severity = None + for fault in faults: + if severity is None: + severity = fault['severity'] + continue + + if severity == 'warning': + severity = fault['severity'] + continue + + if severity == 'minor': + if fault['severity'] == 'major': + severity = fault['severity'] + continue + + return severity + + def get_system_fault_scope_tenant_epg_dn(self, managed_object): + scope = {} + + if 'uni/epp/br-[' in managed_object['dn']: + scope['epgDn'] = managed_object['dn'].split('uni/epp/br-[')[1].split(']')[0] + scope['epgType'] = 'l2out' + if len(scope['epgDn'].split('/')) != 3: + scope['reason'] = 'Unexpected l2out dn structure' + return scope + + # "dn": "uni/tn-k8s/l2out-Test/instP-L2Out-ext-epg" + scope['tenant'] = scope['epgDn'].split('/')[1][3:] + scope['l2outName'] = scope['epgDn'].split('/')[2][6:] + scope['epgName'] = scope['epgDn'].split('/')[3][6:] + scope['resolved'] = True + return scope + + if 'uni/epp/fv-[' in managed_object['dn']: + scope['epgDn'] = managed_object['dn'].split('uni/epp/fv-[')[1].split(']')[0] + scope['epgType'] = 'aepg' + if len(scope['epgDn'].split('/')) != 4: + scope['reason'] = 'Unexpected l2out dn structure' + return scope + + # "dn": "uni/epp/fv-[uni/tn-common/ap-privIP_TEST/epg-privIP_TEST]/node-301/polDelSt/fault-F1298" + scope['tenant'] = scope['epgDn'].split('/')[1][3:] + scope['application_profile'] = scope['epgDn'].split('/')[2][3:] + scope['name'] = scope['epgDn'].split('/')[3][4:] + scope['nameApTenant'] = '%s/%s/%s' % ( + scope['tenant'], + scope['application_profile'], + scope['name'] + ) + scope['resolved'] = True + return scope + + scope['reason'] = 'Unsupported epg dn' + return scope + + def get_system_fault_scope_tenant_epg(self, managed_object): + scope = {} + scope['domain'] = managed_object['domain'] + scope['subject'] = managed_object['subject'] + scope['resolved'] = False + scope['reason'] = '' + scope.update( + self.get_system_fault_scope_tenant_epg_dn( + managed_object + ) + ) + return scope + + def get_system_fault_scope_tenant_management(self, managed_object): + scope = {} + scope['domain'] = managed_object['domain'] + scope['subject'] = managed_object['subject'] + scope['resolved'] = False + scope['reason'] = '' + scope.update( + self.get_system_fault_scope_tenant_epg_dn( + managed_object + ) + ) + + return scope + + def get_system_fault_scope_tenant(self, managed_object): + if managed_object['subject'] == 'epg': + scope = self.get_system_fault_scope_tenant_epg(managed_object) + return scope + + if managed_object['subject'] == 'management': + scope = self.get_system_fault_scope_tenant_management(managed_object) + return scope + + scope = {} + scope['domain'] = managed_object['domain'] + scope['subject'] = managed_object['subject'] + scope['resolved'] = False + scope['reason'] = 'Unsupported tenant subject: %s' % (managed_object['subject']) + + return scope + + def get_system_fault_scope_external(self, managed_object): + scope = {} + scope['resolved'] = False + scope['reason'] = 'Not implemented' + scope['domain'] = managed_object['domain'] + return scope + + def get_system_fault_scope_infra(self, managed_object): + scope = {} + scope['resolved'] = False + scope['reason'] = 'Not implemented' + scope['domain'] = managed_object['domain'] + return scope + + def get_system_fault_scope_framework(self, managed_object): + scope = {} + scope['resolved'] = False + scope['reason'] = 'Not implemented' + scope['domain'] = managed_object['domain'] + return scope + + def get_system_fault_scope_access(self, managed_object): + scope = {} + scope['resolved'] = False + scope['reason'] = 'Not implemented' + scope['domain'] = managed_object['domain'] + return scope + + def get_system_fault_scope(self, managed_object): + if managed_object['domain'] == 'tenant': + scope = self.get_system_fault_scope_tenant(managed_object) + return scope + + if managed_object['domain'] == 'infra': + scope = self.get_system_fault_scope_infra(managed_object) + return scope + + if managed_object['domain'] == 'access': + scope = self.get_system_fault_scope_access(managed_object) + return scope + + if managed_object['domain'] == 'framework': + scope = self.get_system_fault_scope_framework(managed_object) + return scope + + if managed_object['domain'] == 'external': + scope = self.get_system_fault_scope_external(managed_object) + return scope + + scope = {} + scope['resolved'] = False + scope['reason'] = 'Unsupported domain: %s' % (managed_object['domain']) + scope['domain'] = managed_object['domain'] + + return scope + + def get_system_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['codeInt'] = int(info['code'][1:]) + info['codeT'] = info['code'] + if info['code'] in self.system_fault_code: + info['codeT'] = self.system_fault_code[info['code']] + + info['count'] = int(info['occur']) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # info['scope'] = self.get_system_fault_scope( + # managed_object + # ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + return info + + def get_system_faults_info(self): + if self.system_fault is not None: + return self.system_fault + + managed_objects = self.get_system_fault_mo() + if managed_objects is None: + return None + + self.system_fault = [] + for managed_object in managed_objects: + self.system_fault.append( + self.get_system_fault_info( + managed_object + ) + ) + + self.log.apic_mo( + 'faultInst.info', + self.system_fault + ) + + return self.system_fault + + def remove_system_fault_timestamp_filter(self, system_fault_filter): + if system_fault_filter is None: + return None + + new_filter = [] + for rule in system_fault_filter: + (key, value) = rule.split(':') + if key == 'timestamp': + continue + new_filter.append( + rule + ) + + return new_filter + + def match_system_fault(self, system_fault_info, system_fault_filter, exclude_cleared=True): + if exclude_cleared: + if system_fault_info['severity'] == 'cleared': + return False + + if system_fault_filter is None or len(system_fault_filter) == 0: + return True + + for aepg_rule in system_fault_filter: + (key, value) = aepg_rule.split(':') + found = False + + if key == 'epg': + found = True + if not system_fault_info['scope']['resolved']: + return False + + if system_fault_info['scope']['domain'] != 'tenant': + return False + + if system_fault_info['scope']['subject'] != 'epg': + return False + + if system_fault_info['scope']['epgType'] != 'aepg': + return False + + if not filter_helper.match_tenant_ap_name(value, system_fault_info['scope']['nameApTenant']): + return False + + if key == 'severity': + found = True + if not filter_helper.match_string(value, system_fault_info['severity']): + return False + + if key == 'domain': + found = True + if not filter_helper.match_string(value, system_fault_info['domain']): + return False + + if key == 'type': + found = True + if not filter_helper.match_string(value, system_fault_info['type']): + return False + + if key == 'code': + found = True + matched = False + + if value.startswith('gt'): + if not filter_helper.match_integer(value, system_fault_info['codeInt']): + return False + matched = True + + if value.startswith('ge'): + if not filter_helper.match_integer(value, system_fault_info['codeInt']): + return False + matched = True + + if value.startswith('lt'): + if not filter_helper.match_integer(value, system_fault_info['codeInt']): + return False + matched = True + + if value.startswith('le'): + if not filter_helper.match_integer(value, system_fault_info['codeInt']): + return False + matched = True + + if '-' in value: + if not filter_helper.match_integer(value, system_fault_info['codeInt']): + return False + matched = True + + if not matched: + if not filter_helper.match_string(value, system_fault_info['code']): + return False + + if key == 'timestamp': + found = True + if not filter_helper.match_timestamp(value, system_fault_info['timestamp']): + return False + + if key == 'dn': + found = True + if not filter_helper.match_string(value, system_fault_info['dn']): + return False + + if key == 'cause': + found = True + if not filter_helper.match_string(value, system_fault_info['cause']): + return False + + if key == 'description': + found = True + if not filter_helper.match_string(value, system_fault_info['descr']): + return False + + if not found: + if key in system_fault_info: + found = True + if not filter_helper.match_string(value, system_fault_info[key]): + return False + + if not found: + self.log.error( + 'match_system_fault', + 'Unsupported filtering key: %s' % (key) + ) + + return True + + def get_system_faults(self, system_fault_filter=None): + all_system_faults = self.get_system_faults_info() + if all_system_faults is None: + return None + + system_faults = [] + + for system_fault_info in all_system_faults: + if not self.match_system_fault(system_fault_info, system_fault_filter): + continue + + system_faults.append( + system_fault_info + ) + + system_faults = sorted( + system_faults, + key=lambda i: i['severity'].lower() + ) + + return system_faults + + def get_system_faults_summary(self, system_fault_filter=None): + all_system_faults = self.get_system_faults_info() + if all_system_faults is None: + return None + + system_faults = [] + + for system_fault_info in all_system_faults: + if not self.match_system_fault(system_fault_info, system_fault_filter): + continue + + found = False + for system_fault in system_faults: + if system_fault['code'] == system_fault_info['code']: + system_fault['count'] = system_fault['count'] + system_fault_info['count'] + found = True + break + + if found: + continue + + system_faults.append( + system_fault_info + ) + + system_faults = sorted( + system_faults, + key=lambda i: i['severity'].lower() + ) + + return system_faults + + def get_system_faults_domain_count(self, system_fault_filter=None): + all_system_faults = self.get_system_faults_info() + if all_system_faults is None: + return None + + info = {} + for fault_domain in self.system_fault_domain: + info[fault_domain] = {} + for fault_severity in self.system_fault_severity_name: + info[fault_domain][fault_severity] = 0 + + info['total'] = {} + for fault_severity in self.system_fault_severity_name: + info['total'][fault_severity] = 0 + + for system_fault_info in all_system_faults: + if not self.match_system_fault(system_fault_info, system_fault_filter): + continue + + info[system_fault_info['domain']][system_fault_info['severity']] = info[system_fault_info['domain']][system_fault_info['severity']] + 1 + info['total'][system_fault_info['severity']] = info['total'][system_fault_info['severity']] + 1 + + system_faults = [] + for item in info: + entry = info[item] + entry['domain'] = item + entry['domainT'] = self.system_fault_domain[item] + system_faults.append( + entry + ) + + return system_faults + + def get_system_faults_type_count(self, system_fault_filter=None): + all_system_faults = self.get_system_faults_info() + if all_system_faults is None: + return None + + info = {} + for fault_type in self.system_fault_type: + info[fault_type] = {} + for fault_severity in self.system_fault_severity_name: + info[fault_type][fault_severity] = 0 + + info['total'] = {} + for fault_severity in self.system_fault_severity_name: + info['total'][fault_severity] = 0 + + for system_fault_info in all_system_faults: + if not self.match_system_fault(system_fault_info, system_fault_filter): + continue + + info[system_fault_info['type']][system_fault_info['severity']] = info[system_fault_info['type']][system_fault_info['severity']] + 1 + info['total'][system_fault_info['severity']] = info['total'][system_fault_info['severity']] + 1 + + system_faults = [] + for item in info: + entry = info[item] + entry['type'] = item + entry['typeT'] = self.system_fault_type[item] + system_faults.append( + entry + ) + + return system_faults diff --git a/lib/aci/system/fault/main.py b/lib/aci/system/fault/main.py new file mode 100644 index 00000000..1d7fbdfc --- /dev/null +++ b/lib/aci/system/fault/main.py @@ -0,0 +1,10 @@ +from lib.aci.system.fault.api import SystemFaultApi +from lib.aci.system.fault.info import SystemFaultInfo +from lib.aci.system.fault.code.main import SystemFaultCode + + +class SystemFault(SystemFaultApi, SystemFaultInfo, SystemFaultCode): + def __init__(self): + SystemFaultApi.__init__(self) + SystemFaultInfo.__init__(self) + SystemFaultCode.__init__(self) diff --git a/lib/aci/system/fault/output.py b/lib/aci/system/fault/output.py new file mode 100644 index 00000000..98edcc55 --- /dev/null +++ b/lib/aci/system/fault/output.py @@ -0,0 +1,163 @@ +class SystemFaultOutput(): + def __init__(self): + pass + + def print_system_faults(self, info, title=False): + if len(info) == 0: + return + + if title: + self.my_output.default( + 'System Faults Details [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'severity', + 'domain', + 'type', + 'code', + 'cause', + 'dnT', + 'descrT' + ] + + headers = [ + 'Severity', + 'Domain', + 'Type', + 'Code', + 'Cause', + 'Object', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['dnT', 'descrT'] + ), + order=order, + headers=headers, + underline=True, + remove_empty_columns=True, + row_separator=True, + table=True + ) + + def print_system_faults_summary(self, info, title=False): + if len(info) == 0: + return + + if title: + self.my_output.default( + 'System Faults Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'severity', + 'domain', + 'type', + 'code', + 'count', + 'cause', + 'codeT' + ] + + headers = [ + 'Severity', + 'Domain', + 'Type', + 'Code', + 'Count', + 'Cause', + 'Explanation' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + remove_empty_columns=True, + row_separator=True, + table=True + ) + + def print_system_faults_type_count(self, info, title=False): + if len(info) == 0: + return + + if title: + self.my_output.default( + 'System Fault Counts by Type', + underline=True, + before_newline=True + ) + + order = [ + 'typeT', + 'critical', + 'major', + 'minor', + 'warning' + ] + + headers = [ + 'Type', + 'Critical', + 'Major', + 'Minor', + 'Warning' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + remove_empty_columns=True, + row_separator=True, + table=True + ) + + def print_system_faults_domain_count(self, info, title=False): + if len(info) == 0: + return + + if title: + self.my_output.default( + 'System Fault Counts by Domain', + underline=True, + before_newline=True + ) + + order = [ + 'domainT', + 'critical', + 'major', + 'minor', + 'warning' + ] + + headers = [ + 'Domain', + 'Critical', + 'Major', + 'Minor', + 'Warning' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + remove_empty_columns=True, + row_separator=True, + table=True + ) diff --git a/lib/aci/system/main.py b/lib/aci/system/main.py new file mode 100644 index 00000000..2925808a --- /dev/null +++ b/lib/aci/system/main.py @@ -0,0 +1,6 @@ +from lib.aci.system.fault.main import SystemFault + + +class System(SystemFault): + def __init__(self): + SystemFault.__init__(self) diff --git a/lib/aci/system/output.py b/lib/aci/system/output.py new file mode 100644 index 00000000..b2b66da7 --- /dev/null +++ b/lib/aci/system/output.py @@ -0,0 +1,6 @@ +from lib.aci.system.fault.output import SystemFaultOutput + + +class SystemOutput(SystemFaultOutput): + def __init__(self): + SystemFaultOutput.__init__(self) diff --git a/lib/aci/tenant/__init__.py b/lib/aci/tenant/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/tenant/__pycache__/__init__.cpython-310.pyc b/lib/aci/tenant/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..68b7116a Binary files /dev/null and b/lib/aci/tenant/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/tenant/__pycache__/api.cpython-310.pyc b/lib/aci/tenant/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..08d42fb1 Binary files /dev/null and b/lib/aci/tenant/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/tenant/__pycache__/info.cpython-310.pyc b/lib/aci/tenant/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..523dc703 Binary files /dev/null and b/lib/aci/tenant/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/tenant/__pycache__/main.cpython-310.pyc b/lib/aci/tenant/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3de4a2d7 Binary files /dev/null and b/lib/aci/tenant/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/tenant/__pycache__/output.cpython-310.pyc b/lib/aci/tenant/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..83506be0 Binary files /dev/null and b/lib/aci/tenant/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/tenant/api.py b/lib/aci/tenant/api.py new file mode 100644 index 00000000..5a1c8de3 --- /dev/null +++ b/lib/aci/tenant/api.py @@ -0,0 +1,72 @@ +class TenantApi(): + def __init__(self): + self.tenant_mo = None + + def get_tenant_mo(self): + # "attributes": { + # "annotation": "orchestrator:ansible", + # "childAction": "", + # "descr": "User Tenant CDC SR L3out (Managed with Ansible)", + # "dn": "uni/tn-MPC-E", + # "extMngdBy": "", + # "lcOwn": "local", + # "modTs": "2023-01-03T20:33:37.125+01:00", + # "monPolDn": "uni/tn-common/monepg-default", + # "name": "MPC-E", + # "nameAlias": "", + # "ownerKey": "", + # "ownerTag": "", + # "status": "", + # "uid": "15374", + # "userdom": ":all:" + # } + if self.tenant_mo is not None: + return self.tenant_mo + + cache = self.get_object_cache( + 'fvTenant' + ) + if cache is not None: + self.tenant_mo = cache + self.log.apic_mo( + 'fvTenant', + self.tenant_mo + ) + return self.tenant_mo + + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + 'fvTenant', + query=query + ) + if managed_objects is None: + return None + + self.tenant_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvTenant']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'fvTenant', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'fvTenant', + managed_object, + 'faultCounts' + ) + self.tenant_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvTenant', + self.tenant_mo + ) + + self.set_object_cache( + 'fvTenant', + self.tenant_mo + ) + + return self.tenant_mo diff --git a/lib/aci/tenant/audit/__init__.py b/lib/aci/tenant/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/tenant/audit/api.py b/lib/aci/tenant/audit/api.py new file mode 100644 index 00000000..43c4f229 --- /dev/null +++ b/lib/aci/tenant/audit/api.py @@ -0,0 +1,48 @@ +class TenantAuditApi(): + def __init__(self): + self.tenant_audit_mo = None + + def get_tenant_audit_mo(self): + cache = self.get_object_cache( + 'fvTenant.audit' + ) + if cache is not None: + self.tenant_audit_mo = cache + self.log.apic_mo( + 'fvTenant.audit', + self.tenant_audit_mo + ) + return self.tenant_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'fvTenant', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_tenant_audit_mo', + 'API failed' + ) + return None + + self.tenant_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.tenant_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvTenant.audit', + self.tenant_audit_mo + ) + + self.set_object_cache( + 'fvTenant.audit', + self.tenant_audit_mo + ) + + return self.tenant_audit_mo diff --git a/lib/aci/tenant/audit/info.py b/lib/aci/tenant/audit/info.py new file mode 100644 index 00000000..a047e22c --- /dev/null +++ b/lib/aci/tenant/audit/info.py @@ -0,0 +1,98 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class TenantAuditInfo(): + def __init__(self): + self.tenant_audit = None + + def get_tenant_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + + if 'uni/tn-' in info['affected']: + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_tenant_audit(self): + if self.tenant_audit is not None: + return self.tenant_audit + + managed_objects = self.get_tenant_audit_mo() + if managed_objects is None: + return None + + self.tenant_audit = [] + for managed_object in managed_objects: + audit_info = self.get_tenant_audit_info( + managed_object + ) + self.tenant_audit.append( + audit_info + ) + + self.log.apic_mo( + 'fvTenant.auditRecord.info', + self.tenant_audit + ) + + return self.tenant_audit + + def get_tenant_id_audit(self, tenant_name, audit_filter=None): + audits = [] + + all_audits = self.get_tenant_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None: + if audit_info['tenantName'] == tenant_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/tenant/audit/main.py b/lib/aci/tenant/audit/main.py new file mode 100644 index 00000000..d7cc9748 --- /dev/null +++ b/lib/aci/tenant/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.tenant.audit.api import TenantAuditApi +from lib.aci.tenant.audit.info import TenantAuditInfo + + +class TenantAudit(TenantAuditApi, TenantAuditInfo): + def __init__(self): + TenantAuditApi.__init__(self) + TenantAuditInfo.__init__(self) diff --git a/lib/aci/tenant/event/__init__.py b/lib/aci/tenant/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/tenant/event/api.py b/lib/aci/tenant/event/api.py new file mode 100644 index 00000000..99a6a181 --- /dev/null +++ b/lib/aci/tenant/event/api.py @@ -0,0 +1,51 @@ +class TenantEventApi(): + def __init__(self): + self.tenant_event_mo = None + + def get_tenant_event_mo(self): + if self.tenant_event_mo is not None: + return self.tenant_event_mo + + cache = self.get_object_cache( + 'fvTenant.eventLog' + ) + if cache is not None: + self.tenant_event_mo = cache + self.log.apic_mo( + 'fvTenant.eventLog', + self.tenant_event_mo + ) + return self.tenant_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'fvTenant', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_tenant_event_mo', + 'API failed' + ) + return None + + self.tenant_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.tenant_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvTenant.eventLog', + self.tenant_event_mo + ) + + self.set_object_cache( + 'fvTenant.eventLog', + self.tenant_event_mo + ) + + return self.tenant_event_mo diff --git a/lib/aci/tenant/event/info.py b/lib/aci/tenant/event/info.py new file mode 100644 index 00000000..3e6cc2f9 --- /dev/null +++ b/lib/aci/tenant/event/info.py @@ -0,0 +1,109 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class TenantEventInfo(): + def __init__(self): + self.tenant_event = None + + def get_tenant_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-vk8s_1 + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_tenant_event(self, deduplicate=True): + if self.tenant_event is not None: + return self.tenant_event + + managed_objects = self.get_tenant_event_mo() + if managed_objects is None: + return None + + self.tenant_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_tenant_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.tenant_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'fvTenant.eventLog.info', + self.tenant_event + ) + + return self.tenant_event + + def get_tenant_id_event(self, tenant_name, event_filter=None): + events = [] + + all_events = self.get_tenant_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None: + if event_info['tenantName'] == tenant_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/tenant/event/main.py b/lib/aci/tenant/event/main.py new file mode 100644 index 00000000..aa3f6c9d --- /dev/null +++ b/lib/aci/tenant/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.tenant.event.api import TenantEventApi +from lib.aci.tenant.event.info import TenantEventInfo + + +class TenantEvent(TenantEventApi, TenantEventInfo): + def __init__(self): + TenantEventApi.__init__(self) + TenantEventInfo.__init__(self) diff --git a/lib/aci/tenant/fault/__init__.py b/lib/aci/tenant/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/tenant/fault/api.py b/lib/aci/tenant/fault/api.py new file mode 100644 index 00000000..c7194327 --- /dev/null +++ b/lib/aci/tenant/fault/api.py @@ -0,0 +1,112 @@ +class TenantFaultApi(): + def __init__(self): + self.tenant_fault_mo = None + self.tenant_fault_record_mo = None + + def get_tenant_fault_mo(self): + cache = self.get_object_cache( + 'fvTenant.fault' + ) + if cache is not None: + self.tenant_fault_mo = cache + self.log.apic_mo( + 'fvTenant.fault', + self.tenant_fault_mo + ) + return self.tenant_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'fvTenant', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_tenant_fault_mo', + 'API failed' + ) + return None + + self.tenant_fault_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + + self.tenant_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvTenant.fault', + self.tenant_fault_mo + ) + + self.set_object_cache( + 'fvTenant.fault', + self.tenant_fault_mo + ) + + return self.tenant_fault_mo + + def get_tenant_fault_record_mo(self): + cache = self.get_object_cache( + 'fvTenant.faultRecord' + ) + if cache is not None: + self.tenant_fault_record_mo = cache + self.log.apic_mo( + 'fvTenant.faultRecord', + self.tenant_fault_record_mo + ) + return self.tenant_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'fvTenant', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_tenant_fault_record_mo', + 'API failed' + ) + return None + + self.tenant_fault_record_mo = [] + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + + self.tenant_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvTenant.faultRecord', + self.tenant_fault_record_mo + ) + + self.set_object_cache( + 'fvTenant.faultRecord', + self.tenant_fault_record_mo + ) + + return self.tenant_fault_record_mo diff --git a/lib/aci/tenant/fault/info.py b/lib/aci/tenant/fault/info.py new file mode 100644 index 00000000..b2774862 --- /dev/null +++ b/lib/aci/tenant/fault/info.py @@ -0,0 +1,139 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class TenantFaultInfo(): + def __init__(self): + self.tenant_fault = None + self.tenant_fault_record = None + + def get_tenant_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ap-k8s_ANP/epg-vk8s_1 + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_tenant_fault(self): + if self.tenant_fault is not None: + return self.tenant_fault + + managed_objects = self.get_tenant_fault_mo() + if managed_objects is None: + return None + + self.tenant_fault = [] + for managed_object in managed_objects: + fault_info = self.get_tenant_fault_info( + managed_object + ) + self.tenant_fault.append( + fault_info + ) + + self.log.apic_mo( + 'fvTenant.fault.info', + self.tenant_fault + ) + + return self.tenant_fault + + def get_tenant_fault_record(self, deduplicate=True): + if self.tenant_fault_record is not None: + return self.tenant_fault_record + + managed_objects = self.get_tenant_fault_record_mo() + if managed_objects is None: + return None + + self.tenant_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_tenant_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.tenant_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'fvTenant.faultRecord.info', + self.tenant_fault_record + ) + + return self.tenant_fault_record + + def get_tenant_id_fault(self, tenant_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_tenant_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_tenant_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None: + if fault_info['tenantName'] == tenant_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/tenant/fault/main.py b/lib/aci/tenant/fault/main.py new file mode 100644 index 00000000..e20594a6 --- /dev/null +++ b/lib/aci/tenant/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.tenant.fault.api import TenantFaultApi +from lib.aci.tenant.fault.info import TenantFaultInfo + + +class TenantFault(TenantFaultApi, TenantFaultInfo): + def __init__(self): + TenantFaultApi.__init__(self) + TenantFaultInfo.__init__(self) diff --git a/lib/aci/tenant/info.py b/lib/aci/tenant/info.py new file mode 100644 index 00000000..1b5f82fe --- /dev/null +++ b/lib/aci/tenant/info.py @@ -0,0 +1,151 @@ +from lib import filter_helper + + +class TenantInfo(): + def __init__(self): + self.tenant = None + + def get_tenant_info(self, managed_object): + keys = [ + 'descr', + 'dn', + 'lcOwn', + 'name', + 'userdom' + ] + + info = {} + info['__Output'] = {} + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + return info + + def get_tenants_info(self): + if self.tenant is not None: + return self.tenant + + managed_objects = self.get_tenant_mo() + if managed_objects is None: + return None + + self.tenant = [] + for managed_object in managed_objects: + self.tenant.append( + self.get_tenant_info( + managed_object + ) + ) + + return self.tenant + + def match_tenant(self, tenant_info, tenant_filter): + if tenant_filter is None or len(tenant_filter) == 0: + return True + + for aepg_rule in tenant_filter: + (key, value) = aepg_rule.split(':') + if key == 'name': + if not filter_helper.match_string(value, tenant_info['name']): + return False + + return True + + def get_tenants( + self, + tenant_filter=None, + count_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_tenants = self.get_tenants_info() + if all_tenants is None: + return None + + tenants = [] + + for tenant_info in all_tenants: + if not self.match_tenant(tenant_info, tenant_filter): + continue + + if count_info: + tenant_info['bdCount'] = self.get_bridge_domain_count( + tenant_name=tenant_info['name'] + ) + tenant_info['vrfCount'] = self.get_vrf_count( + tenant_name=tenant_info['name'] + ) + tenant_info['apCount'] = self.get_application_profile_count( + tenant_name=tenant_info['name'] + ) + tenant_info['aEpgCount'] = self.get_epg_count( + tenant_name=tenant_info['name'] + ) + tenant_info['l2OutCount'] = self.get_l2out_count( + tenant_name=tenant_info['name'] + ) + tenant_info['l3OutCount'] = self.get_l3out_count( + tenant_name=tenant_info['name'], + mpls='no' + ) + tenant_info['mplsL3OutCount'] = self.get_l3out_count( + tenant_name=tenant_info['name'], + mpls='yes' + ) + tenant_info['contractStandardCount'] = self.get_standard_contract_count( + tenant_name=tenant_info['name'] + ) + tenant_info['contractTabooCount'] = self.get_taboo_contract_count( + tenant_name=tenant_info['name'] + ) + tenant_info['contractFilterCount'] = self.get_contract_filter_count( + tenant_name=tenant_info['name'] + ) + tenant_info['endpointCount'] = self.get_endpoint_count( + tenant_name=tenant_info['name'] + ) + + if fault_info: + tenant_info['faultInst'] = self.get_tenant_id_fault( + tenant_info['name'], + 'faultInst' + ) + + if hfault_info: + tenant_info['faultRecord'] = self.get_tenant_id_fault( + tenant_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + tenant_info['eventLog'] = self.get_tenant_id_event( + tenant_info['name'], + event_filter=event_filter + ) + + if audit_info: + tenant_info['auditLog'] = self.get_tenant_id_audit( + tenant_info['name'], + audit_filter=audit_filter + ) + + tenants.append(tenant_info) + + tenants = sorted( + tenants, + key=lambda i: i['name'].lower() + ) + + return tenants diff --git a/lib/aci/tenant/main.py b/lib/aci/tenant/main.py new file mode 100644 index 00000000..1981c4b2 --- /dev/null +++ b/lib/aci/tenant/main.py @@ -0,0 +1,20 @@ +from lib.aci.tenant.api import TenantApi +from lib.aci.tenant.info import TenantInfo +from lib.aci.tenant.audit.main import TenantAudit +from lib.aci.tenant.event.main import TenantEvent +from lib.aci.tenant.fault.main import TenantFault + + +class Tenant( + TenantApi, + TenantInfo, + TenantAudit, + TenantEvent, + TenantFault + ): + def __init__(self): + TenantApi.__init__(self) + TenantInfo.__init__(self) + TenantAudit.__init__(self) + TenantEvent.__init__(self) + TenantFault.__init__(self) diff --git a/lib/aci/tenant/output.py b/lib/aci/tenant/output.py new file mode 100644 index 00000000..c0ae68c4 --- /dev/null +++ b/lib/aci/tenant/output.py @@ -0,0 +1,294 @@ +class TenantOutput(): + def __init__(self): + pass + + def print_tenants(self, info, title=False): + if title: + self.my_output.default( + 'Tenant [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'health', + 'name' + ] + + headers = [ + 'Health', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + remove_empty_columns=True, + table=True + ) + + def print_tenants_count(self, info, title=False): + if title: + self.my_output.default( + 'Tenant - Object Counts [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'health', + 'name', + 'apCount', + 'aEpgCount', + 'bdCount', + 'vrfCount', + 'l2OutCount', + 'l3OutCount', + 'mplsL3OutCount', + 'contractStandardCount', + 'contractTabooCount', + 'contractFilterCount', + 'endpointCount' + ] + + headers = [ + 'Health', + 'Name', + 'App Profile', + 'EPG', + 'BD', + 'VRF', + 'L2Out', + 'L3Out', + 'MPLS-SR L3Out', + 'Standard Contr', + 'Taboo Contr', + 'Filter', + 'Endpoint' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + remove_empty_columns=True, + table=True + ) + + def print_tenants_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Tenant - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Tenant - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenantName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Tenant', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_tenants_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'Tenant - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenantName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Tenant', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_tenants_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Tenant - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Tenant - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenantName', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'Tenant', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_tenants_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'Tenant - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'Tenant - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenantName', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'Tenant', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/vrf/TODO.md b/lib/aci/vrf/TODO.md new file mode 100644 index 00000000..35eed6c2 --- /dev/null +++ b/lib/aci/vrf/TODO.md @@ -0,0 +1,7 @@ +VRF +- deployed nodes +- endpoints show option +- ports (incl. context) based on endpoints or broader EPG (due to static port members?) +- usage +- stats (counters) +- events \ No newline at end of file diff --git a/lib/aci/vrf/__init__.py b/lib/aci/vrf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/vrf/__pycache__/__init__.cpython-310.pyc b/lib/aci/vrf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..503e1c6c Binary files /dev/null and b/lib/aci/vrf/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/aci/vrf/__pycache__/api.cpython-310.pyc b/lib/aci/vrf/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..ba3a3623 Binary files /dev/null and b/lib/aci/vrf/__pycache__/api.cpython-310.pyc differ diff --git a/lib/aci/vrf/__pycache__/info.cpython-310.pyc b/lib/aci/vrf/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..517fa6b3 Binary files /dev/null and b/lib/aci/vrf/__pycache__/info.cpython-310.pyc differ diff --git a/lib/aci/vrf/__pycache__/main.cpython-310.pyc b/lib/aci/vrf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3988e93e Binary files /dev/null and b/lib/aci/vrf/__pycache__/main.cpython-310.pyc differ diff --git a/lib/aci/vrf/__pycache__/output.cpython-310.pyc b/lib/aci/vrf/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..c6e74761 Binary files /dev/null and b/lib/aci/vrf/__pycache__/output.cpython-310.pyc differ diff --git a/lib/aci/vrf/api.py b/lib/aci/vrf/api.py new file mode 100644 index 00000000..e4a94aa5 --- /dev/null +++ b/lib/aci/vrf/api.py @@ -0,0 +1,170 @@ +class VrfApi(): + def __init__(self): + self.vrf_mo = None + self.vrf_ipv4_mo = {} + self.vrf_ipv6_mo = {} + + def get_vrf_ipv4_mo(self, tenant, name): + key = '%s:%s' % (tenant, name) + if key in self.vrf_ipv4_mo: + return self.vrf_ipv4_mo[key] + + cache = self.get_object_cache( + 'uribv4Nexthop', + object_selector=key + ) + if cache is not None: + self.vrf_ipv4_mo[key] = cache + self.log.apic_mo( + 'uribv4Nexthop.%s' % (key), + self.vrf_ipv4_mo[key] + ) + return self.vrf_ipv4_mo[key] + + query = 'query-target-filter=wcard(uribv4Nexthop.dn,"sys/uribv4/dom-%s:%s/db-rt")' % ( + tenant, + name + ) + managed_objects = self.get_class( + 'uribv4Nexthop', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_ipv4_mo', + 'API failed' + ) + return None + + self.vrf_ipv4_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['uribv4Nexthop']['attributes'] + self.vrf_ipv4_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'uribv4Nexthop.%s.%s' % (tenant, name), + self.vrf_ipv4_mo[key] + ) + + self.set_object_cache( + 'uribv4Nexthop', + self.vrf_ipv4_mo[key], + object_selector=key + ) + + return self.vrf_ipv4_mo[key] + + def get_vrf_ipv6_mo(self, tenant, name): + key = '%s:%s' % (tenant, name) + if key in self.vrf_ipv6_mo: + return self.vrf_ipv6_mo[key] + + cache = self.get_object_cache( + 'uribv6Nexthop', + object_selector=key + ) + if cache is not None: + self.vrf_ipv6_mo[key] = cache + self.log.apic_mo( + 'uribv6Nexthop.%s' % (key), + self.vrf_ipv6_mo[key] + ) + return self.vrf_ipv6_mo[key] + + query = 'query-target-filter=wcard(uribv6Nexthop.dn,"sys/uribv6/dom-%s:%s/db-rt")' % ( + tenant, + name + ) + managed_objects = self.get_class( + 'uribv6Nexthop', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_ipv6_mo', + 'API failed' + ) + return None + + self.vrf_ipv6_mo[key] = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['uribv6Nexthop']['attributes'] + self.vrf_ipv6_mo[key].append( + attributes + ) + + self.log.apic_mo( + 'uribv6Nexthop.%s.%s' % (tenant, name), + self.vrf_ipv6_mo[key] + ) + + self.set_object_cache( + 'uribv6Nexthop', + self.vrf_ipv6_mo[key], + object_selector=key + ) + + return self.vrf_ipv6_mo[key] + + def get_vrfs_mo(self): + if self.vrf_mo is not None: + return self.vrf_mo + + cache = self.get_object_cache( + 'fvCtx' + ) + if cache is not None: + self.vrf_mo = cache + self.log.apic_mo( + 'fvCtx', + self.vrf_mo + ) + return self.vrf_mo + + query = 'rsp-subtree=children&rsp-subtree-include=health,fault-count' + managed_objects = self.get_class( + 'fvCtx', + query=query + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_mo', + 'API failed' + ) + return None + + self.vrf_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvCtx']['attributes'] + attributes['healthInst'] = self.get_mo_child_attributes( + 'fvCtx', + managed_object, + 'healthInst' + ) + attributes['faultCounts'] = self.get_mo_child_attributes( + 'fvCtx', + managed_object, + 'faultCounts' + ) + self.vrf_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvCtx', + self.vrf_mo + ) + + self.set_object_cache( + 'fvCtx', + self.vrf_mo + ) + + return self.vrf_mo diff --git a/lib/aci/vrf/audit/__init__.py b/lib/aci/vrf/audit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/vrf/audit/api.py b/lib/aci/vrf/audit/api.py new file mode 100644 index 00000000..fd99c1d3 --- /dev/null +++ b/lib/aci/vrf/audit/api.py @@ -0,0 +1,48 @@ +class VrfAuditApi(): + def __init__(self): + self.vrf_audit_mo = None + + def get_vrf_audit_mo(self): + cache = self.get_object_cache( + 'fvCtx.audit' + ) + if cache is not None: + self.vrf_audit_mo = cache + self.log.apic_mo( + 'fvCtx.audit', + self.vrf_audit_mo + ) + return self.vrf_audit_mo + + query = 'rsp-subtree-include=audit-logs,no-scoped,subtree&order-by=aaaModLR.created|desc&page=0&page-size=%s' % (self.api_audit_limit) + managed_objects = self.get_class( + 'fvCtx', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_audit_mo', + 'API failed' + ) + return None + + self.vrf_audit_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['aaaModLR']['attributes'] + self.vrf_audit_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvCtx.audit', + self.vrf_audit_mo + ) + + self.set_object_cache( + 'fvCtx.audit', + self.vrf_audit_mo + ) + + return self.vrf_audit_mo diff --git a/lib/aci/vrf/audit/info.py b/lib/aci/vrf/audit/info.py new file mode 100644 index 00000000..f4542160 --- /dev/null +++ b/lib/aci/vrf/audit/info.py @@ -0,0 +1,110 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class VrfAuditInfo(): + def __init__(self): + self.vrf_audit = None + + def get_vrf_audit_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['vrfName'] = None + + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ctx-k8s_VRF + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ctx-' in info['affected']: + info['vrfName'] = info['affected'].split('/ctx-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['vrfName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['vrfName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_vrf_audit(self): + if self.vrf_audit is not None: + return self.vrf_audit + + managed_objects = self.get_vrf_audit_mo() + if managed_objects is None: + return None + + self.vrf_audit = [] + for managed_object in managed_objects: + audit_info = self.get_vrf_audit_info( + managed_object + ) + self.vrf_audit.append( + audit_info + ) + + self.log.apic_mo( + 'fvCtx.auditRecord.info', + self.vrf_audit + ) + + return self.vrf_audit + + def get_vrf_id_audit(self, tenant_name, vrf_name, audit_filter=None): + audits = [] + + all_audits = self.get_vrf_audit() + if all_audits is None: + return audits + + for audit_info in all_audits: + if audit_info['tenantName'] is not None and audit_info['vrfName'] is not None: + if audit_info['tenantName'] == tenant_name and audit_info['vrfName'] == vrf_name: + if not self.match_system_fault(audit_info, audit_filter, exclude_cleared=False): + continue + + audits.append( + audit_info + ) + + return audits diff --git a/lib/aci/vrf/audit/main.py b/lib/aci/vrf/audit/main.py new file mode 100644 index 00000000..0bbc6347 --- /dev/null +++ b/lib/aci/vrf/audit/main.py @@ -0,0 +1,8 @@ +from lib.aci.vrf.audit.api import VrfAuditApi +from lib.aci.vrf.audit.info import VrfAuditInfo + + +class VrfAudit(VrfAuditApi, VrfAuditInfo): + def __init__(self): + VrfAuditApi.__init__(self) + VrfAuditInfo.__init__(self) diff --git a/lib/aci/vrf/event/__init__.py b/lib/aci/vrf/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/vrf/event/api.py b/lib/aci/vrf/event/api.py new file mode 100644 index 00000000..f7e2a827 --- /dev/null +++ b/lib/aci/vrf/event/api.py @@ -0,0 +1,51 @@ +class VrfEventApi(): + def __init__(self): + self.vrf_event_mo = None + + def get_vrf_event_mo(self): + if self.vrf_event_mo is not None: + return self.vrf_event_mo + + cache = self.get_object_cache( + 'fvCtx.eventLog' + ) + if cache is not None: + self.vrf_event_mo = cache + self.log.apic_mo( + 'fvCtx.eventLog', + self.vrf_event_mo + ) + return self.vrf_event_mo + + query = 'rsp-subtree-include=event-logs,no-scoped,subtree&order-by=eventRecord.created|desc&page=0&page-size=%s' % (self.api_event_limit) + managed_objects = self.get_class( + 'fvCtx', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_event_mo', + 'API failed' + ) + return None + + self.vrf_event_mo = [] + for managed_object in managed_objects['imdata']: + attributes = managed_object['eventRecord']['attributes'] + self.vrf_event_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvCtx.eventLog', + self.vrf_event_mo + ) + + self.set_object_cache( + 'fvCtx.eventLog', + self.vrf_event_mo + ) + + return self.vrf_event_mo diff --git a/lib/aci/vrf/event/info.py b/lib/aci/vrf/event/info.py new file mode 100644 index 00000000..abb54684 --- /dev/null +++ b/lib/aci/vrf/event/info.py @@ -0,0 +1,124 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class VrfEventInfo(): + def __init__(self): + self.vrf_event = None + + def get_vrf_event_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['vrfName'] = None + + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ctx-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ctx-' in info['affected']: + info['vrfName'] = info['affected'].split('/ctx-')[1].split('/')[0] + + if 'affected' not in info and 'dn' in info: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/ctx-bmk8s_2_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/ctx-' in info['dn']: + info['vrfName'] = info['dn'].split('/ctx-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['vrfName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['vrfName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['changeSetT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['changeSet'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_vrf_event(self, deduplicate=True): + if self.vrf_event is not None: + return self.vrf_event + + managed_objects = self.get_vrf_event_mo() + if managed_objects is None: + return None + + self.vrf_event = [] + transaction_ids = [] + for managed_object in managed_objects: + event_info = self.get_vrf_event_info( + managed_object + ) + if not deduplicate or event_info['txId'] not in transaction_ids: + self.vrf_event.append( + event_info + ) + transaction_ids.append( + event_info['txId'] + ) + + self.log.apic_mo( + 'fvCtx.eventLog.info', + self.vrf_event + ) + + return self.vrf_event + + def get_vrf_id_event(self, tenant_name, vrf_name, event_filter=None): + events = [] + + all_events = self.get_vrf_event() + if all_events is None: + return events + + for event_info in all_events: + if event_info['tenantName'] is not None and event_info['vrfName'] is not None: + if event_info['tenantName'] == tenant_name and event_info['vrfName'] == vrf_name: + if not self.match_system_fault(event_info, event_filter): + continue + + events.append( + event_info + ) + + return events diff --git a/lib/aci/vrf/event/main.py b/lib/aci/vrf/event/main.py new file mode 100644 index 00000000..c0a1cf4a --- /dev/null +++ b/lib/aci/vrf/event/main.py @@ -0,0 +1,8 @@ +from lib.aci.vrf.event.api import VrfEventApi +from lib.aci.vrf.event.info import VrfEventInfo + + +class VrfEvent(VrfEventApi, VrfEventInfo): + def __init__(self): + VrfEventApi.__init__(self) + VrfEventInfo.__init__(self) diff --git a/lib/aci/vrf/fault/__init__.py b/lib/aci/vrf/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/vrf/fault/api.py b/lib/aci/vrf/fault/api.py new file mode 100644 index 00000000..2326ed43 --- /dev/null +++ b/lib/aci/vrf/fault/api.py @@ -0,0 +1,118 @@ +class VrfFaultApi(): + def __init__(self): + self.vrf_fault_mo = None + self.vrf_fault_record_mo = None + + def get_vrf_fault_mo(self): + cache = self.get_object_cache( + 'fvCtx.fault' + ) + if cache is not None: + self.vrf_fault_mo = cache + self.log.apic_mo( + 'fvCtx.fault', + self.vrf_fault_mo + ) + return self.vrf_fault_mo + + query = 'rsp-subtree-include=faults,no-scoped,subtree' + managed_objects = self.get_class( + 'fvCtx', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_fault_mo', + 'API failed' + ) + return None + + self.vrf_fault_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultInst' in managed_object: + attributes = managed_object['faultInst']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = False + self.vrf_fault_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultInst' + attributes['delegated'] = True + self.vrf_fault_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvCtx.fault', + self.vrf_fault_mo + ) + + self.set_object_cache( + 'fvCtx.fault', + self.vrf_fault_mo + ) + + return self.vrf_fault_mo + + def get_vrf_fault_record_mo(self): + cache = self.get_object_cache( + 'fvCtx.faultRecord' + ) + if cache is not None: + self.vrf_fault_record_mo = cache + self.log.apic_mo( + 'fvCtx.faultRecord', + self.vrf_fault_record_mo + ) + return self.vrf_fault_record_mo + + query = 'rsp-subtree-include=fault-records,no-scoped,subtree&order-by=faultRecord.created|desc&page=0&page-size=%s' % (self.api_fault_limit) + managed_objects = self.get_class( + 'fvCtx', + query=query, + node_class=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_fault_record_mo', + 'API failed' + ) + return None + + self.vrf_fault_record_mo = [] + + for managed_object in managed_objects['imdata']: + if 'faultRecord' in managed_object: + attributes = managed_object['faultRecord']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = False + self.vrf_fault_record_mo.append( + attributes + ) + + if 'faultDelegate' in managed_object: + attributes = managed_object['faultDelegate']['attributes'] + attributes['object'] = 'faultRecord' + attributes['delegated'] = True + self.vrf_fault_record_mo.append( + attributes + ) + + self.log.apic_mo( + 'fvCtx.faultRecord', + self.vrf_fault_record_mo + ) + + self.set_object_cache( + 'fvCtx.faultRecord', + self.vrf_fault_record_mo + ) + + return self.vrf_fault_record_mo diff --git a/lib/aci/vrf/fault/info.py b/lib/aci/vrf/fault/info.py new file mode 100644 index 00000000..deeeae5e --- /dev/null +++ b/lib/aci/vrf/fault/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class VrfFaultInfo(): + def __init__(self): + self.vrf_fault = None + self.vrf_fault_record = None + + def get_vrf_fault_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + info['tenantName'] = None + info['vrfName'] = None + + if not managed_object['delegated']: + if 'affected' in info: + if 'uni/tn-' in info['affected']: + # uni/tn-k8s/ctx-bmk8s_2_BD + info['tenantName'] = info['affected'].split('uni/tn-')[1].split('/')[0] + + if '/ctx-' in info['affected']: + info['vrfName'] = info['affected'].split('/ctx-')[1].split('/')[0] + + if info['tenantName'] is None: + if 'uni/tn-' in info['dn']: + # uni/tn-k8s/ctx-bmk8s_2_BD + info['tenantName'] = info['dn'].split('uni/tn-')[1].split('/')[0] + + if '/ctx-' in info['dn']: + info['vrfName'] = info['dn'].split('/ctx-')[1].split('/')[0] + + info['nameTenant'] = '--' + if info['tenantName'] is not None and info['vrfName'] is not None: + info['nameTenant'] = '%s/%s' % ( + info['tenantName'], + info['vrfName'] + ) + + info['descrT'] = filter_helper.get_string_chunks( + filter_helper.sanitize_string( + info['descr'] + ), + 80 + ) + + info['dnT'] = filter_helper.get_string_chunks( + info['dn'], + 40, + separator='/' + ) + + # "2022-04-29T13:32:45.167+02:00" + info['timestamp'] = int( + time.mktime( + datetime.strptime( + info['created'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + + info['severityT'] = self.system_fault_severity_name[info['severity']] + info['__Output']['severityT'] = self.system_fault_severity_color[info['severity']] + + return info + + def get_vrf_fault(self): + if self.vrf_fault is not None: + return self.vrf_fault + + managed_objects = self.get_vrf_fault_mo() + if managed_objects is None: + return None + + self.vrf_fault = [] + + for managed_object in managed_objects: + fault_info = self.get_vrf_fault_info( + managed_object + ) + self.vrf_fault.append( + fault_info + ) + + self.log.apic_mo( + 'fvCtx.fault.info', + self.vrf_fault + ) + + return self.vrf_fault + + def get_vrf_fault_record(self, deduplicate=True): + if self.vrf_fault_record is not None: + return self.vrf_fault_record + + managed_objects = self.get_vrf_fault_record_mo() + if managed_objects is None: + return None + + self.vrf_fault_record = [] + fault_ids = [] + + for managed_object in managed_objects: + fault_info = self.get_vrf_fault_info( + managed_object + ) + if not deduplicate or fault_info['id'] not in fault_ids: + self.vrf_fault_record.append( + fault_info + ) + fault_ids.append( + fault_info['id'] + ) + + self.log.apic_mo( + 'fvCtx.faultRecord.info', + self.vrf_fault_record + ) + + return self.vrf_fault_record + + def get_vrf_id_fault(self, tenant_name, vrf_name, fault_object, fault_filter=None): + faults = [] + + if fault_object == 'faultInst': + all_faults = self.get_vrf_fault() + if all_faults is None: + return faults + + fault_filter = self.remove_system_fault_timestamp_filter( + fault_filter + ) + + if fault_object == 'faultRecord': + all_faults = self.get_vrf_fault_record() + if all_faults is None: + return faults + + for fault_info in all_faults: + if fault_info['tenantName'] is not None and fault_info['vrfName'] is not None: + if fault_info['tenantName'] == tenant_name and fault_info['vrfName'] == vrf_name: + if not self.match_system_fault(fault_info, fault_filter, exclude_cleared=False): + continue + + faults.append( + fault_info + ) + + return faults diff --git a/lib/aci/vrf/fault/main.py b/lib/aci/vrf/fault/main.py new file mode 100644 index 00000000..f66d3931 --- /dev/null +++ b/lib/aci/vrf/fault/main.py @@ -0,0 +1,8 @@ +from lib.aci.vrf.fault.api import VrfFaultApi +from lib.aci.vrf.fault.info import VrfFaultInfo + + +class VrfFault(VrfFaultApi, VrfFaultInfo): + def __init__(self): + VrfFaultApi.__init__(self) + VrfFaultInfo.__init__(self) diff --git a/lib/aci/vrf/info.py b/lib/aci/vrf/info.py new file mode 100644 index 00000000..428a2540 --- /dev/null +++ b/lib/aci/vrf/info.py @@ -0,0 +1,428 @@ +import copy + +from lib import filter_helper +from lib import ip_helper + + +class VrfInfo(): + def __init__(self): + self.vrfs = None + self.vrf_ipv4 = {} + self.vrf_ipv6 = {} + + def get_vrf_count(self, tenant_name=None): + vrf_filter = None + if tenant_name is not None: + vrf_filter = ['tenant:%s' % (tenant_name)] + + vrfs = self.get_vrfs( + vrf_filter=vrf_filter + ) + return len(vrfs) + + def get_vrf_info(self, managed_object): + keys = [ + 'bdEnforcedEnable', + 'descr', + 'dn', + 'ipDataPlaneLearning', + 'knwMcastAct', + 'name', + 'pcEnfDir', + 'pcEnfPref', + 'pcTag', + 'seg', + 'userdom', + 'vrfIndex' + ] + + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + # Dn format + # [0]: uni/tn-{name}/ctx-{name} + info['tenant'] = info['dn'].split('/')[1][3:] + + info['nameTenant'] = '%s/%s' % ( + info['tenant'], + info['name'] + ) + + # pcTag Number Ranges + # System Reserved pcTag – This pcTag is used for system internal rules (1-15). + # Globally scoped pcTag – This pcTag is used for shared service (16-16385). + # Locally scoped pcTag – This pcTag is locally used per VRF (range from 16386-65535). + info['pcTagT'] = info['pcTag'] + if 15 < int(info['pcTag']) < 16386: + info['pcTagT'] = '%s (global)' % (info['pcTag']) + info['__Output']['pcTagT'] = 'Red' + + if int(info['pcTag']) < 16: + info['pcTagT'] = '%s (system)' % (info['pcTag']) + info['__Output']['pcTagT'] = 'Red' + + if info['ipDataPlaneLearning'] == 'enabled': + info['ipDataPlaneLearningTick'] = '\u2713' + else: + info['ipDataPlaneLearningTick'] = '\u2717' + + if info['bdEnforcedEnable'] == 'yes': + info['bdEnforcedEnableTick'] = '\u2713' + else: + info['bdEnforcedEnableTick'] = '\u2717' + + if info['knwMcastAct'] == 'permit': + info['knwMcastActTick'] = '\u2713' + else: + info['knwMcastActTick'] = '\u2717' + + (info['__Output']['health'], info['health']) = self.get_health_info( + managed_object['healthInst']['cur'] + ) + + (info['__Output']['faults'], info['faults']) = self.get_faults_info( + managed_object['faultCounts'] + ) + + info['isAnyFault'] = self.is_any_fault( + managed_object['faultCounts'] + ) + + return info + + def get_vrfs_info(self): + if self.vrfs is not None: + return self.vrfs + + vrfs_mo = self.get_vrfs_mo() + if vrfs_mo is not None: + self.vrfs = [] + for managed_object in vrfs_mo: + self.vrfs.append( + self.get_vrf_info( + managed_object + ) + ) + + return self.vrfs + + def get_vrf_v4_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['types'] = info['type'].split(',') + + info['pod'] = '' + info['node'] = '' + if info['dn'].split('/')[0] == 'topology': + info['pod'] = info['dn'].split('/')[1] + info['node'] = info['dn'].split('/')[2] + + info['prefix'] = info['dn'].split('rt-[')[1].split(']')[0] + + return info + + def get_vrf_v4s_info(self, tenant, name): + key = '%s:%s' % (tenant, name) + if key in self.vrf_ipv4: + return self.vrf_ipv4[key] + + ipv4_mo = self.get_vrf_ipv4_mo(tenant, name) + if ipv4_mo is not None: + self.vrf_ipv4[key] = [] + for managed_object in ipv4_mo: + self.vrf_ipv4[key].append( + self.get_vrf_v4_info( + managed_object + ) + ) + + self.vrf_ipv4[key] = sorted( + self.vrf_ipv4[key], + key=lambda i: i['prefix'] + ) + + return self.vrf_ipv4[key] + + def match_vrf(self, vrf_info, vrf_filter): + if vrf_filter is None or len(vrf_filter) == 0: + return True + + for vrf_rule in vrf_filter: + (key, value) = vrf_rule.split(':') + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, vrf_info['nameTenant']): + return False + + if key == 'dn': + key_found = True + if not filter_helper.match_string(value, vrf_info['dn']): + return False + + if key == 'tenant': + key_found = True + if not filter_helper.match_string(value, vrf_info['tenant']): + return False + + if key == 'bd': + key_found = True + + if 'fvBD' not in vrf_info or vrf_info['fvBD'] is None: + return False + + found = False + for bd_info in vrf_info['fvBD']: + if filter_helper.match_string(value, bd_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'epg': + key_found = True + + if 'fvAEPg' not in vrf_info or vrf_info['fvAEPg'] is None: + return False + + found = False + for epg_info in vrf_info['fvAEPg']: + if filter_helper.match_string(value, epg_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'l3out': + key_found = True + + if 'l3out' not in vrf_info or vrf_info['l3out'] is None: + return False + + found = False + for l3out_info in vrf_info['l3out']: + if filter_helper.match_string(value, l3out_info['nameTenant']): + found = True + break + + if not found: + return False + + if key == 'subnet': + key_found = True + + if 'fvSubnet' not in vrf_info or vrf_info['fvSubnet'] is None: + return False + + found = False + for bd_subnet in vrf_info['fvSubnet']: + if ip_helper.is_subnet_in_subnet(value, bd_subnet['network']): + found = True + break + + if not found: + return False + + if key == 'ip': + key_found = True + + if 'fvSubnet' not in vrf_info or vrf_info['fvSubnet'] is None: + return False + + found = False + for bd_subnet in vrf_info['fvSubnet']: + if ip_helper.is_ipv4_in_cidr(value, bd_subnet['network']): + found = True + break + + if not found: + return False + + if key == 'pctag': + key_found = True + + if value == 'global': + if int(vrf_info['pcTag']) >= 16386: + return False + + if value == 'system': + if int(vrf_info['pcTag']) >= 16: + return False + + if value not in ['global', 'system']: + if not filter_helper.match_integer(value, vrf_info['pcTag']): + return False + + if key == 'vnid': + key_found = True + + if not filter_helper.match_integer(value, vrf_info['seg']): + return False + + if key == 'fault': + key_found = True + if value == 'any': + if not vrf_info['isAnyFault']: + return False + + if value not in ['any']: + self.log.error( + 'match_vrf', + 'Unsupported fault filtering value: %s' % (value) + ) + + if not key_found: + self.log.error( + 'match_vrf', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_vrf(self, vrf_distinguished_name): + vrf_filter = ['dn:%s' % (vrf_distinguished_name)] + vrfs = self.get_vrfs( + vrf_filter=vrf_filter + ) + + if len(vrfs) == 1: + return vrfs[0] + + return None + + def get_vrfs( + self, + vrf_filter=None, + bridge_domain_info=False, + l3out_info=False, + epg_info=False, + route_info=False, + node_info=False, + fault_info=False, + hfault_info=False, + event_info=False, + audit_info=False, + hfault_filter=None, + event_filter=None, + audit_filter=None + ): + all_vrfs = self.get_vrfs_info() + if all_vrfs is None: + return None + + vrfs = [] + + for vrf_info in all_vrfs: + if epg_info or bridge_domain_info: + vrf_info['endpointCount'] = 0 + + vrf_info['fvBD'] = copy.deepcopy( + self.get_bridge_domains( + bridge_domain_filter=['vrf:%s/%s' % (vrf_info['tenant'], vrf_info['name'])], + endpoint_info=True + ) + ) + + vrf_info['fvSubnet'] = [] + for bd_info in vrf_info['fvBD']: + vrf_info['fvSubnet'] = vrf_info['fvSubnet'] + bd_info['fvSubnet'] + vrf_info['endpointCount'] = vrf_info['endpointCount'] + bd_info['endpointCount'] + + if epg_info: + vrf_info['fvAEPg'] = [] + + for bd_info in vrf_info['fvBD']: + bd_epg_info = copy.deepcopy( + self.get_epgs( + epg_filter=['bd:%s/%s' % (bd_info['tenant'], bd_info['name'])], + bd_info=True, + locale_info=True, + endpoint_info=True + ) + ) + if bd_epg_info is not None: + vrf_info['fvAEPg'] = vrf_info['fvAEPg'] + bd_epg_info + + if l3out_info: + vrf_info['l3out'] = copy.deepcopy( + self.get_l3outs( + l3out_filter=['vrf:%s/%s' % (vrf_info['tenant'], vrf_info['name'])] + ) + ) + + if not self.match_vrf(vrf_info, vrf_filter): + continue + + if route_info: + vrf_info['v4route'] = copy.deepcopy( + self.get_vrf_v4s_info( + vrf_info['tenant'], + vrf_info['name'] + ) + ) + + if node_info: + ap_node_info = self.get_vrf_node( + vrf_info['tenant'], + vrf_info['name'] + ) + vrf_info['node'] = None + vrf_info['interface'] = None + if ap_node_info is not None: + vrf_info['node'] = ap_node_info['node'] + vrf_info['interface'] = ap_node_info['interface'] + + if fault_info: + vrf_info['faultInst'] = self.get_vrf_id_fault( + vrf_info['tenant'], + vrf_info['name'], + 'faultInst' + ) + + if hfault_info: + vrf_info['faultRecord'] = self.get_vrf_id_fault( + vrf_info['tenant'], + vrf_info['name'], + 'faultRecord', + fault_filter=hfault_filter + ) + + if event_info: + vrf_info['eventLog'] = self.get_vrf_id_event( + vrf_info['tenant'], + vrf_info['name'], + event_filter=event_filter + ) + + if audit_info: + vrf_info['auditLog'] = self.get_vrf_id_audit( + vrf_info['tenant'], + vrf_info['name'], + audit_filter=audit_filter + ) + + vrfs.append(vrf_info) + + vrfs = sorted( + vrfs, + key=lambda i: i['nameTenant'].lower() + ) + + self.log.apic_mo( + 'fvCtx.info', + vrfs + ) + + return vrfs diff --git a/lib/aci/vrf/main.py b/lib/aci/vrf/main.py new file mode 100644 index 00000000..7d72b030 --- /dev/null +++ b/lib/aci/vrf/main.py @@ -0,0 +1,23 @@ +from lib.aci.vrf.api import VrfApi +from lib.aci.vrf.info import VrfInfo +from lib.aci.vrf.audit.main import VrfAudit +from lib.aci.vrf.event.main import VrfEvent +from lib.aci.vrf.fault.main import VrfFault +from lib.aci.vrf.node.main import VrfNode + + +class Vrf( + VrfApi, + VrfInfo, + VrfAudit, + VrfEvent, + VrfFault, + VrfNode + ): + def __init__(self): + VrfApi.__init__(self) + VrfInfo.__init__(self) + VrfAudit.__init__(self) + VrfEvent.__init__(self) + VrfFault.__init__(self) + VrfNode.__init__(self) \ No newline at end of file diff --git a/lib/aci/vrf/node/__init__.py b/lib/aci/vrf/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/aci/vrf/node/api.py b/lib/aci/vrf/node/api.py new file mode 100644 index 00000000..c4c6107b --- /dev/null +++ b/lib/aci/vrf/node/api.py @@ -0,0 +1,61 @@ +class VrfNodeApi(): + def __init__(self): + self.vrf_node_mo = {} + + def get_vrf_node_mo(self, tenant_name, vrf_name): + key = '%s.%s' % (tenant_name, vrf_name) + if key in self.vrf_node_mo: + return self.vrf_node_mo[key] + + cache = self.get_object_cache( + 'fvCtx.%s' % (key) + ) + if cache is not None: + self.vrf_node_mo[key] = cache + self.log.apic_mo( + 'fvCtx.%s' % (key), + self.vrf_node_mo[key] + ) + return self.vrf_node_mo[key] + + distinguished_name = 'uni/tn-%s/ctx-%s' % (tenant_name, vrf_name) + query = 'rsp-subtree-include=full-deployment&target-node=all&target-path=CtxToNwIf' + managed_objects = self.get_managed_object( + distinguished_name, + query=query, + node_mo=True + ) + + if managed_objects is None: + self.log.error( + 'get_vrf_node_mo', + 'API failed' + ) + return None + + if managed_objects['totalCount'] != '1': + self.log.error( + 'get_vrf_node_mo', + 'Unexpected object count' + ) + return None + + for managed_object in managed_objects['imdata']: + attributes = managed_object['fvCtx']['attributes'] + attributes['pconsResourceCtx'] = self.get_mo_node_resource_ctx( + 'fvCtx', + managed_object + ) + self.vrf_node_mo[key] = attributes + + self.log.apic_mo( + 'fvCtx.%s' % (key), + self.vrf_node_mo[key] + ) + + self.set_object_cache( + 'fvCtx.%s' % (key), + self.vrf_node_mo[key] + ) + + return self.vrf_node_mo[key] diff --git a/lib/aci/vrf/node/info.py b/lib/aci/vrf/node/info.py new file mode 100644 index 00000000..c37bc8c7 --- /dev/null +++ b/lib/aci/vrf/node/info.py @@ -0,0 +1,82 @@ +class VrfNodeInfo(): + def __init__(self): + self.vrf_node = {} + + def get_vrf_node_info(self, managed_object): + info = {} + info['__Output'] = {} + info['name'] = managed_object['name'] + + node = {} + info['interface'] = [] + for item in managed_object['pconsResourceCtx']: + node_name = self.get_node_name( + item['nodeId'] + ) + + if node_name not in node: + node[node_name] = {} + node[node_name]['node_id'] = item['nodeId'] + node[node_name]['interfaces'] = 0 + + port_info = {} + port_info['__Output'] = {} + port_info['pod_id'] = item['ctxDn'].split('/')[1].split('-')[1] + port_info['node_id'] = item['nodeId'] + port_info['node_name'] = self.get_node_name( + item['nodeId'] + ) + port_info['intf_type'] = item['ctxClass'] + # "topology/pod-1/node-2201/sys/vmms-[eth1/43]" + port_info['intf_name'] = item['ctxDn'].split('[')[1].split(']')[0] + info['interface'].append( + port_info + ) + + node[node_name]['interfaces'] = node[node_name]['interfaces'] + 1 + + info['node'] = [] + for key in node: + node_info = {} + node_info['id'] = node[key]['node_id'] + node_info['name'] = key + node_info['interfaces'] = node[key]['interfaces'] + info['node'].append( + node_info + ) + + info['node'] = sorted( + info['node'], + key=lambda i: i['name'] + ) + + info['interface'] = sorted( + info['interface'], + key=lambda i: ( + i['node_name'], + i['intf_name'] + ) + ) + + return info + + def get_vrf_node(self, tenant_name, vrf_name): + key = '%s.%s' % (tenant_name, vrf_name) + if key in self.vrf_node: + return self.vrf_node[key] + + # one object or None value is expected + nodes_mo = self.get_vrf_node_mo(tenant_name, vrf_name) + if nodes_mo is None: + return None + + self.vrf_node[key] = self.get_vrf_node_info( + nodes_mo + ) + + self.log.apic_mo( + 'fvCtx.%s.info' % (key), + self.vrf_node[key] + ) + + return self.vrf_node[key] diff --git a/lib/aci/vrf/node/main.py b/lib/aci/vrf/node/main.py new file mode 100644 index 00000000..c8a19cf1 --- /dev/null +++ b/lib/aci/vrf/node/main.py @@ -0,0 +1,8 @@ +from lib.aci.vrf.node.api import VrfNodeApi +from lib.aci.vrf.node.info import VrfNodeInfo + + +class VrfNode(VrfNodeApi, VrfNodeInfo): + def __init__(self): + VrfNodeApi.__init__(self) + VrfNodeInfo.__init__(self) diff --git a/lib/aci/vrf/output.py b/lib/aci/vrf/output.py new file mode 100644 index 00000000..87c7a2ee --- /dev/null +++ b/lib/aci/vrf/output.py @@ -0,0 +1,531 @@ +class VrfOutput(): + def __init__(self): + pass + + def print_vrf_properties(self, info): + order = [ + 'health', + 'faults', + 'name', + 'tenant', + 'ipDataPlaneLearningTick', + 'knwMcastActTick', + 'pcEnfDir', + 'pcEnfPref', + 'bdEnforcedEnableTick', + 'pcTag', + 'seg' + ] + + headers = [ + 'Health', + 'Faults', + 'Name', + 'Tenant', + 'Data Plane Learning', + 'Multicast', + 'Policy Control Enforcement Direction', + 'Policy Control Enforcement Preference', + 'Bridge Domain Enforcement Status', + 'Class ID', + 'VNID' + ] + + if 'endpointCount' in info: + order.append('endpointCount') + headers.append('Endpoints') + + self.my_output.dictionary( + info, + title='VRF Properties', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_vrf_v4_route(self, info, title=False): + if title: + self.my_output.default( + 'VRF %s - IPv4 Routes [#%s]' % (info['nameTenant'], len(info['v4route'])), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'pod', + 'node', + 'prefix', + 'addr', + 'vrf', + 'routeType', + 'types', + 'pref', + 'owner' + ] + + headers = [ + 'Pod', + 'Node', + 'Prefix', + 'Next Hop', + 'Next Hop VRF', + 'Type', + 'Details', + 'Preference', + 'Source' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info['v4route'], + order, + ['types'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_vrf(self, info): + self.print_vrf_properties( + info + ) + + if 'fvAEPg' in info and len(info['fvAEPg']) > 0: + self.my_output.default( + 'Associated EPGs', + underline=True + ) + self.print_epgs( + info['fvAEPg'] + ) + + if 'fvBD' in info and len(info['fvBD']) > 0: + self.my_output.default( + 'Associated Bridge Domains', + underline=True, + before_newline=True + ) + self.print_bridge_domains( + info['fvBD'] + ) + + if 'l3out' in info and len(info['l3out']) > 0: + self.my_output.default( + 'Associated L3 Outs', + underline=True, + before_newline=True + ) + self.print_l3outs( + info['l3out'] + ) + + if 'v4route' in info and len(info['v4route']) > 0: + self.my_output.default( + 'Route Table (IPv4)', + underline=True, + before_newline=True + ) + self.print_vrf_v4_route( + info + ) + + def print_vrfs(self, info, title=False): + if title: + self.my_output.default( + 'VRF [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'health', + 'faults', + 'nameTenant', + 'pcTag', + 'seg', + 'pcEnfPref', + 'pcEnfDir', + 'fvAEPg.nameApTenant', + 'fvBD.nameTenant', + 'fvSubnet.ip', + 'l3out.nameTenant' + ] + + headers = [ + 'Health', + 'Faults', + 'VRF', + 'Class ID', + 'VNID', + 'PCE Preference', + 'PCE Direction', + 'Associated EPG', + 'Associated BD', + 'BD Subnets', + 'Associated L3Out' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fvBD', 'fvSubnet', 'l3out', 'fvAEPg'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_vrfs_properties(self, info, title=False): + if title: + self.my_output.default( + 'VRF - Properties [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'ipDataPlaneLearningTick', + 'knwMcastAct', + 'pcEnfPref', + 'pcEnfDir', + 'bdEnforcedEnableTick', + 'pcTag', + 'seg' + ] + + headers = [ + 'VRF', + 'DP Learning', + 'Mcast', + 'PCE Preference', + 'PCE Direction', + 'BD Enforced', + 'Class ID', + 'VNID' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_vrfs_node(self, info, title=False): + if title: + self.my_output.default( + 'VRF - Nodes [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'health', + 'faults', + 'nameTenant', + 'node.name', + 'node.interfaces' + ] + + headers = [ + 'Health', + 'Faults', + 'VRF', + 'Node', + 'Interfaces' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_vrfs_interface(self, info, title=False): + if title: + self.my_output.default( + 'VRF - Interfaces [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'health', + 'faults', + 'nameTenant', + 'interface.node_name', + 'interface.intf_name' + ] + + headers = [ + 'Health', + 'Faults', + 'VRF', + 'Node', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_vrfs_event_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'VRF - Event Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'VRF - Event Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'VRF', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_vrfs_fault_inst(self, info, title=False): + if title: + self.my_output.default( + 'VRF - Faults [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'VRF', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_vrfs_fault_record(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'VRF - Fault Records [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'VRF - Fault Records last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'lc', + 'descrT' + ] + + headers = [ + 'VRF', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Lifecycle', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_vrfs_audit_logs(self, info, when=None, title=False): + if title: + if when is None: + self.my_output.default( + 'VRF - Audit Logs [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + else: + self.my_output.default( + 'VRF - Audit Logs last %s [#%s]' % (when, len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameTenant', + 'severityT', + 'code', + 'cause', + 'created', + 'descrT', + 'changeSetT' + ] + + headers = [ + 'VRF', + 'Sev', + 'Code', + 'Cause', + 'Created Time', + 'Description', + 'Change Set' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['descrT', 'changeSetT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/aci/ws.py b/lib/aci/ws.py new file mode 100644 index 00000000..48002561 --- /dev/null +++ b/lib/aci/ws.py @@ -0,0 +1,146 @@ +import os +import json +import time +import ssl +import uuid +import threading +import websocket +import requests + + +class WebSocket(): + def __init__(self, apic_ip, debug=False): + self.ws_apic_ip = apic_ip + self.ws_token = None + self.ws_monitored_objects = [] + self.ws_timeout = 120 + self.ws_handler = None + self.ws_subscription_ids = '/tmp/ws_apic_%s.json' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.ws_debug = debug + + def ws_on_open(self, ws_obj): + subscription_ids = [] + + print('Object subscriptions:') + for monitored_object in self.ws_monitored_objects: + subscription_url = 'https://%s%s.json?subscription=yes&refresh-timeout=%s' % ( + self.ws_apic_ip, + monitored_object, + self.ws_timeout + ) + if self.ws_debug: + print('- GET %s' % (subscription_url)) + + response = requests.get( + subscription_url, + headers={'Cookie': 'APIC-cookie=%s' % (self.get_token(generate_if_none=True))}, + verify=False + ) + + if self.ws_debug: + print('- Response %s' % (response.status_code)) + + if response.status_code >= 300: + print('[ERROR] object %s subscription request failed (%s)' % (monitored_object, response.status_code)) + self.ws_handler.close() + return + + subscription_id = json.loads(response.text)['subscriptionId'] + subscription_ids.append( + subscription_id + ) + print('- %s with subscription ID: %s' % ( + monitored_object, + subscription_id + )) + + with open(self.ws_subscription_ids, 'w+', encoding='utf-8') as handle: + json.dump(subscription_ids, handle) + + print('Press Ctrl-C to exit') + + def ws_on_message(self, ws_obj, ws_message): + print(ws_message) + + def ws_on_error(self, ws_obj, ws_error): + if ws_error is not None and len(str(ws_error)) > 0: + print('[ERROR] %s' % (ws_error)) + + def ws_on_close(self, ws_obj, ws_close_status_code, ws_close_msg): + os.remove(self.ws_subscription_ids) + + if ws_close_msg is None: + print('Socket closed') + if ws_close_msg is not None: + print('Socket closed (%s)' % (ws_close_msg)) + + def ws_refresh(self): + while True: + timeout_epoch = int(time.time()) + self.ws_timeout - 60 + while True: + if not os.path.isfile(self.ws_subscription_ids): + print('Subscription refresh thread finished') + return + + time.sleep(5) + if int(time.time()) > timeout_epoch: + break + + if not os.path.isfile(self.ws_subscription_ids): + print('Subscription refresh thread finished') + return + + with open(self.ws_subscription_ids, "r", encoding='utf-8') as handle: + subscription_ids = json.load(handle) + + self.generate_token() + self.ws_token = self.get_token() + if self.ws_token is None: + print('[ERROR] APIC token generation') + return + + print('Subscriptions refresh:') + for subscription_id in subscription_ids: + subscription_url = 'https://%s/api/subscriptionRefresh.json?id=%s' % (self.ws_apic_ip, subscription_id) + response = requests.get( + subscription_url, + headers={'Cookie': 'APIC-cookie=%s' % (self.ws_token)}, + verify=False + ) + if self.ws_debug: + print('- GET %s' % (subscription_url)) + + if json.loads(response.text)['totalCount'] != '0': + print('[ERROR] subscription refresh failed (%s)' % (subscription_id)) + self.ws_handler.close() + return + + print('- subscription %s refreshed' % (subscription_id)) + + def ws_run(self, objects): + self.ws_monitored_objects = objects + with open(self.ws_subscription_ids, 'w+', encoding='utf-8') as handle: + json.dump([], handle) + + self.ws_token = self.get_token(generate_if_none=True) + if self.ws_token is None: + print('[ERROR] APIC authentication failed') + return + + refresh_thread = threading.Thread(target=self.ws_refresh) + refresh_thread.start() + + websocket.enableTrace(self.ws_debug) + + ws_url = 'wss://%s/socket%s' % (self.ws_apic_ip, self.ws_token) + self.ws_handler = websocket.WebSocketApp( + ws_url, + on_message=self.ws_on_message, + on_error=self.ws_on_error, + on_close=self.ws_on_close, + on_open=self.ws_on_open + ) + + self.ws_handler.run_forever( + sslopt={"cert_reqs": ssl.CERT_NONE} + ) diff --git a/lib/context.py b/lib/context.py new file mode 100644 index 00000000..eaee7b77 --- /dev/null +++ b/lib/context.py @@ -0,0 +1,74 @@ +import os + +from lib.settings_helper import Settings +from lib import file_helper + + +class Context(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.context_dirname = os.path.join( + self.settings_dir, + 'context' + ) + + self.initialize() + + def initialize(self): + if os.path.isfile(self.context_dirname): + os.remove(self.context_dirname) + + if not os.path.isdir(self.context_dirname): + os.makedirs(self.context_dirname, exist_ok=True) + + def initialize_apic(self, apic_name): + context = {} + context['apic'] = [apic_name] + context['node'] = {} + context['node'][apic_name] = [] + context['interface'] = {} + context['interface'][apic_name] = [] + return context + + def is_interface_defined(self, context): + for apic_name in context['apic']: + if len(context['interface'][apic_name]) > 0: + return True + return False + + def clear(self, key): + filename = os.path.join( + self.context_dirname, + key + ) + if os.path.isfile(filename): + os.remove(filename) + + return True + + def get(self, key): + filename = os.path.join( + self.context_dirname, + key + ) + return file_helper.get_file_json(filename) + + def set(self, key, value): + filename = os.path.join( + self.context_dirname, + key + ) + return file_helper.set_file_json(filename, value) + + def append(self, key, value): + values = self.get(key) + if values is None: + values = [] + + if isinstance(value, list): + values = values + value + else: + values.append(value) + + return self.set(key, values) diff --git a/lib/cvim/__init__.py b/lib/cvim/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/cvim/main.py b/lib/cvim/main.py new file mode 100644 index 00000000..dfe39d5f --- /dev/null +++ b/lib/cvim/main.py @@ -0,0 +1,25 @@ +from lib import log_helper + +from lib.cvim import settings +from lib.openstack import main as openstack + + +class Cvim(): + def __init__(self, ocp_cluster_name, verbose=False, debug=False, log_id=None): + self.log = log_helper.Log(log_id=log_id) + self.verbose = verbose + self.debug = debug + self.log_id = log_id + + self.settings_handler = settings.CvimSettings(log_id=log_id) + self.cvim_cluster_settings = self.settings_handler.get_cvim_cluster(ocp_cluster_name) + if self.cvim_cluster_settings is None: + raise ValueError('Cisco VIM cluster handler initialization failed') + + self.openstack_handler = openstack.Openstack( + self.cvim_cluster_settings['openrc'], + cluster_type='cvim', + verbose=verbose, + debug=debug, + log_id=log_id + ) diff --git a/lib/cvim/output.py b/lib/cvim/output.py new file mode 100644 index 00000000..b5346204 --- /dev/null +++ b/lib/cvim/output.py @@ -0,0 +1,11 @@ +from lib import output_helper + + +class CvimOutput( + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) diff --git a/lib/cvim/settings.py b/lib/cvim/settings.py new file mode 100644 index 00000000..e63f4368 --- /dev/null +++ b/lib/cvim/settings.py @@ -0,0 +1,324 @@ +import os +import json +import shutil +import traceback + +from lib import filter_helper +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class CvimSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.cvim_settings_filename = os.path.join( + self.settings_dir, + 'cvim' + ) + + self.cvim_clusters_directory = os.path.join( + self.settings_dir, + 'cvim-clusters' + ) + + if not self.initialize_cvim_settings(): + raise ValueError('CVIM settings initialization failed') + + def get_cvim_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Defaults'] = {} + settings['Defaults']['Cluster'] = None + settings['Clusters'] = [] + return settings + + def initialize_cvim_settings(self): + if not os.path.isfile(self.cvim_settings_filename): + settings = self.get_cvim_default_settings() + if not self.set_cvim_settings(settings): + return False + + if not os.path.isdir(self.cvim_clusters_directory): + os.makedirs( + self.cvim_clusters_directory, + exist_ok=True + ) + + fixup = False + + settings = self.get_cvim_settings() + for cluster in settings['Clusters']: + for key in ['cli']: + if key not in cluster: + fixup = True + cluster[key] = None + + if fixup: + return self.set_cvim_settings(settings) + + return True + + def get_cvim_settings(self): + if not os.path.isfile(self.cvim_settings_filename): + return None + + try: + with open(self.cvim_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_cvim_settings', traceback.format_exc()) + return None + + return settings + + def set_cvim_settings(self, settings): + try: + with open(self.cvim_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_cvim_settings', traceback.format_exc()) + return False + + return True + + def get_default_cluster(self): + settings = self.get_cvim_settings() + if settings is None: + return None + + try: + default_cluster_name = settings['Defaults']['Cluster'] + except BaseException: + default_cluster_name = None + + return default_cluster_name + + def set_default_cluster(self, name): + settings = self.get_cvim_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Cluster'] = name + return self.set_cvim_settings(settings) + + def get_cvim_cluster_names(self): + clusters = self.get_cvim_clusters() + if clusters is None: + return None + + names = [] + for cluster in clusters: + names.append( + cluster['name'] + ) + + return names + + def match_cluster(self, cluster_settings, cluster_filter): + if cluster_filter is None or len(cluster_filter) == 0: + return True + + for ap_rule in cluster_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cluster_settings['name']): + return False + + if not key_found: + self.log.error( + 'match_cluster', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cvim_clusters(self, cluster_filter=None): + settings = self.get_cvim_settings() + if settings is None: + return None + + all_clusters = settings['Clusters'] + clusters = [] + for cluster in all_clusters: + if not self.match_cluster(cluster, cluster_filter): + continue + + clusters.append( + cluster + ) + + clusters = sorted( + clusters, + key=lambda i: i['name'] + ) + + return clusters + + def get_cvim_cluster(self, cvim_name, strict_match=True): + clusters = self.get_cvim_clusters() + if clusters is None: + return None + + candidates = [] + for cluster in clusters: + if cluster['name'] == cvim_name: + return cluster + + if not strict_match: + if cvim_name.lower() in cluster['name'].lower(): + candidates.append(cluster) + + if not strict_match and len(candidates) == 1: + return candidates[0] + + return None + + def set_cvim_clusters(self, clusters): + settings = self.get_cvim_settings() + if settings is None: + return False + + settings['Clusters'] = clusters + return self.set_cvim_settings(settings) + + def get_cvim_cluster_directory(self, cvim_name): + cluster_directory = os.path.join( + self.cvim_clusters_directory, + cvim_name + ) + return cluster_directory + + def create_cvim_cluster(self, name, openrc): + new_cluster = {} + new_cluster['name'] = name + new_cluster['openrc'] = self.get_cvim_cluster_openrc_filename(name) + for key in ['cli']: + new_cluster[key] = None + + clusters = self.get_cvim_clusters() + if clusters is None: + self.log.error( + 'create_cvim_cluster', + 'Failed to get clusters' + ) + return False + + clusters.append(new_cluster) + if not self.set_cvim_clusters(clusters): + self.log.error( + 'create_cvim_cluster', + 'Failed to set clusters' + ) + return False + + return self.set_cvim_cluster_openrc(name, openrc) + + def set_cvim_cluster(self, cluster_settings): + clusters = self.get_cvim_clusters() + if clusters is None: + self.log.error( + 'set_cvim_cluster', + 'Failed to get clusters' + ) + return False + + new_clusters = [] + for cluster in clusters: + if cluster['name'] == cluster_settings['name']: + new_clusters.append( + cluster_settings + ) + continue + + new_clusters.append( + cluster + ) + + return self.set_cvim_clusters(new_clusters) + + def get_cvim_cluster_openrc_filename(self, cvim_name): + cluster_directory = self.get_cvim_cluster_directory(cvim_name) + target_openrc_filename = os.path.join( + cluster_directory, + 'openrc' + ) + return target_openrc_filename + + def set_cvim_cluster_openrc(self, cvim_name, openrc_filename): + if not os.path.isfile(openrc_filename): + self.log.error( + 'set_cvim_cluster_openrc', + 'Kubeconfig file not found: %s' % (openrc_filename) + ) + return False + + cluster = self.get_cvim_cluster(cvim_name) + if cluster is None: + self.log.error( + 'set_cvim_cluster_openrc', + 'Cluster not found: %s' % (cvim_name) + ) + return False + + cluster_directory = self.get_cvim_cluster_directory(cvim_name) + if not os.path.isdir(cluster_directory): + os.makedirs( + cluster_directory, + exist_ok=True + ) + + target_openrc_filename = os.path.join( + cluster_directory, + 'openrc' + ) + + shutil.copy( + openrc_filename, + target_openrc_filename + ) + if not os.path.isfile(target_openrc_filename): + self.log.error( + 'set_cvim_cluster_openrc', + 'Kubeconfig file copy failed: %s => %s' % (openrc_filename, target_openrc_filename) + ) + return False + + return self.set_cvim_cluster(cluster) + + def delete_cvim_cluster(self, cvim_name): + clusters = self.get_cvim_clusters() + if clusters is None: + return False + + new_clusters = [] + for cluster in clusters: + if cluster['name'] != cvim_name: + new_clusters.append(cluster) + + cluster_directory = os.path.join( + self.cvim_clusters_directory, + cvim_name + ) + if os.path.isdir(cluster_directory): + shutil.rmtree(cluster_directory) + + return self.set_cvim_clusters(new_clusters) diff --git a/lib/endpoint_helper.py b/lib/endpoint_helper.py new file mode 100644 index 00000000..9d13ac12 --- /dev/null +++ b/lib/endpoint_helper.py @@ -0,0 +1,129 @@ +import os +import json +import traceback + +from lib import log_helper +from lib.settings_helper import Settings + + +class EndpointSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self) + self.log = log_helper.Log(log_id=log_id) + self.endpoint_directory = os.path.join( + self.settings_dir, + 'endpoint' + ) + + if not self.initialize_endpoint_directory(): + raise ValueError('Endpoints initialization failed') + + def initialize_endpoint_directory(self): + try: + if not os.path.isdir(self.endpoint_directory): + os.makedirs(self.endpoint_directory) + + for filename in os.listdir(self.endpoint_directory): + filename_path = os.path.join( + self.endpoint_directory, + filename + ) + if os.path.isdir(filename_path): + continue + + try: + with open(filename_path, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error( + 'initialize_endpoint_directory', + 'File read failed: %s' % (filename_path) + ) + continue + + os.remove(filename_path) + os.makedirs(filename_path, exist_ok=True) + + settings_filename = os.path.join( + filename_path, + 'settings' + ) + + try: + with open(settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + settings, + indent=4 + ) + ) + + except BaseException: + self.log.error( + 'initialize_endpoint_directory', + 'File write failed: %s' % (settings_filename) + ) + + except BaseException: + return False + return True + + def get_endpoint_ids(self): + return os.listdir(self.endpoint_directory) + + def get_endpoint_settings(self, endpoint_id, filename='settings'): + endpoint_directory = os.path.join( + self.endpoint_directory, + endpoint_id + ) + endpoint_filename = os.path.join( + endpoint_directory, + filename + ) + if not os.path.isfile(endpoint_filename): + return None + + try: + with open(endpoint_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error( + 'get_endpoint_settings', + 'File read failed: %s' % (endpoint_filename) + ) + return None + + return settings + + def set_endpoint_settings(self, endpoint_id, settings, filename='settings'): + endpoint_directory = os.path.join( + self.endpoint_directory, + endpoint_id + ) + if not os.path.isdir(endpoint_directory): + os.makedirs(endpoint_directory, exist_ok=True) + + endpoint_filename = os.path.join( + endpoint_directory, + filename + ) + + try: + with open(endpoint_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + settings, + indent=4 + ) + ) + + except BaseException: + self.log.error( + 'set_endpoint_settings', + 'File write failed: %s' % (endpoint_filename) + ) + return False + + return True diff --git a/lib/file_helper.py b/lib/file_helper.py new file mode 100644 index 00000000..4b1eb566 --- /dev/null +++ b/lib/file_helper.py @@ -0,0 +1,188 @@ +import sys +import os +import json +import platform +import uuid +import yaml +import hashlib + + +def get_main_dir(): + if getattr(sys, 'frozen', False): + main_dir = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) + return main_dir + + main_dir = os.path.dirname( + getattr(sys, '_MEIPASS', os.path.abspath(__file__)) + ) + + while True: + if os.path.basename(main_dir) == 'lib': + break + main_dir = os.path.dirname(main_dir) + + main_dir = os.path.dirname(main_dir) + return main_dir + + +def get_file(filename): + if not os.path.isfile(filename): + return None + + my_os = platform.system() + try: + with open(filename, 'rb') as file_handler: + content = file_handler.read() + + if my_os == 'Windows': + content.replace(b'\r\n', b'\n') + + content = content.decode('utf-8') + + except BaseException: + return None + + return content + + +def get_file_text(filename): + if not os.path.isfile(filename): + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + except BaseException: + return None + + return content + + +def get_file_json(filename): + if not os.path.isfile(filename): + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + return None + + return content + + +def get_file_yaml(filename): + if not os.path.isfile(filename): + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = yaml.safe_load(file_handler) + + except BaseException: + return None + + return content + + +def set_file(filename, content): + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + except BaseException: + return False + + return True + + +def set_file_json(filename, content): + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(content, indent=4)) + + except BaseException: + return False + + return True + + +def set_tmp_file(content): + filename = '/tmp/%s' % (str(uuid.uuid4())) + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + except BaseException: + return None + + return filename + + +def decode_ascii(content): + char_map = {} + char_map['0A'] = '\n' + char_map['20'] = ' ' + char_map['21'] = '!' + char_map['22'] = '"' + char_map['23'] = '#' + char_map['24'] = '$' + char_map['25'] = '%' + char_map['26'] = '&' + char_map['27'] = '\'' + char_map['28'] = '(' + char_map['29'] = ')' + char_map['2A'] = '*' + char_map['2B'] = '+' + char_map['2C'] = ',' + char_map['2D'] = '-' + char_map['2E'] = '.' + char_map['2F'] = '/' + char_map['30'] = '0' + char_map['31'] = '1' + char_map['32'] = '2' + char_map['33'] = '3' + char_map['34'] = '4' + char_map['35'] = '5' + char_map['36'] = '6' + char_map['37'] = '7' + char_map['38'] = '8' + char_map['39'] = '9' + char_map['3A'] = ':' + char_map['3B'] = ';' + char_map['3C'] = '<' + char_map['3D'] = '=' + char_map['3E'] = '>' + char_map['3F'] = '?' + char_map['40'] = '@' + char_map['5B'] = '[' + char_map['5C'] = '\\' + char_map['5D'] = ']' + char_map['5E'] = '^' + char_map['5F'] = '_' + char_map['60'] = '`' + char_map['7B'] = '{' + char_map['7C'] = '|' + char_map['7D'] = '}' + char_map['7E'] = '~' + + for char_key in char_map: + content = content.replace('%%%s' % (char_key), char_map[char_key]) + + return content + + +def get_md5(filename): + if not os.path.isfile(filename): + return None + hasher = hashlib.md5() + blocksize = 65536 + with open(filename, 'rb') as file_handler: + buf = file_handler.read(blocksize) + while len(buf) > 0: + hasher.update(buf) + buf = file_handler.read(blocksize) + md5 = hasher.hexdigest() + return md5 diff --git a/lib/filter_helper.py b/lib/filter_helper.py new file mode 100644 index 00000000..cfe8e61c --- /dev/null +++ b/lib/filter_helper.py @@ -0,0 +1,583 @@ +import re +import time + + +def format_subtring_match(value): + if not value.startswith('*'): + value = '*%s' % (value) + + if not value.endswith('*'): + value = '%s*' % (value) + + return value + + +def sanitize_string(value): + value = value.strip() + value = re.sub(' +', ' ', value) + return value + + +def get_string_chunks(value, length, separator=' ', extra_separator='-'): + lines = [] + + if value is None: + return lines + + words = [] + for word in value.split(separator): + if len(word) < length: + words.append( + '%s%s' % (word, separator) + ) + continue + + chunks = len(word.split(extra_separator)) + chunk_index = 1 + for word_chunk in word.split(extra_separator): + if len(word_chunk) >= length: + words.append( + '%s...-' % (word_chunk[(length - 4):]) + ) + continue + + if chunk_index < chunks: + words.append( + '%s%s' % (word_chunk, extra_separator) + ) + else: + words.append( + '%s%s' % (word_chunk, separator) + ) + + chunk_index = chunk_index + 1 + + line = '' + for word in words: + if len(word) > length: + continue + + if len(line) + len(word) > length: + lines.append(line) + line = word + continue + + line = '%s%s' % (line, word) + + if separator == ' ': + lines.append(line.strip()) + else: + lines.append(line[:-1]) + + return lines + + +def get_values_from_range(value): + values = [] + + if value is not None and len(value) > 0: + # 1,9-20,22-23,37-38 + for item in value.split(','): + if len(item.split('-')) == 1: + values.append(int(item)) + + if len(item.split('-')) == 2: + (start, end) = item.split('-') + for idx in range(int(start), int(end) + 1): + values.append(idx) + + values = sorted(values) + return values + + +def get_range_from_values(values): + range_items = [] + + values = sorted(values) + start = None + stop = None + for value in values: + value = int(value) + + if start is None: + start = value + stop = value + continue + + if value == stop + 1: + stop = value + continue + + if start == stop: + range_items.append( + str(start) + ) + else: + range_items.append( + '%s-%s' % (str(start), str(stop)) + ) + + start = value + stop = value + + if start is not None: + if start == stop: + range_items.append( + str(start) + ) + else: + range_items.append( + '%s-%s' % (str(start), str(stop)) + ) + + return ','.join(range_items) + + +def get_tenant_name(value, delimiter='/'): + if len(value.split(delimiter)) == 1: + return (None, value) + + if len(value.split(delimiter)) == 2: + return value.split(delimiter) + + return None, None + + +def match_tenant_name(key, value, strict=False, delimiter='/'): + if key is None and value is None: + return True + + if key is None and value is not None: + return False + + if key is not None and value is None: + return False + + if not isinstance(key, str): + return False + + if not isinstance(value, str): + return False + + if len(key) == 0: + return True + + if len(value) == 0: + return False + + if len(value.split(delimiter)) != 2: + return False + + if len(key.split(delimiter)) > 2: + return False + + (key_tenant, key_name) = get_tenant_name(key, delimiter=delimiter) + (value_tenant, value_name) = get_tenant_name(value, delimiter=delimiter) + + if key_tenant is not None: + if not match_string(key_tenant, value_tenant): + return False + if not match_string(key_name, value_name): + return False + + if key_tenant is None: + if not match_string(key_name, value_name): + return False + + return True + + +def get_tenant_ap_name(value): + if len(value.split('/')) == 1: + return (None, None, value) + + if len(value.split('/')) == 2: + return (None, value.split('/')[0], value.split('/')[1]) + + if len(value.split('/')) == 3: + return value.split('/') + + return None, None, None + + +def match_tenant_ap_name(key, value, strict=False): + if key is None and value is None: + return True + + if key is None and value is not None: + return False + + if key is not None and value is None: + return False + + if not isinstance(key, str): + return False + + if not isinstance(value, str): + return False + + if len(key) == 0: + return True + + if len(value) == 0: + return False + + if len(value.split('/')) != 3: + return False + + if len(key.split('/')) > 3: + return False + + (key_tenant, key_ap, key_name) = get_tenant_ap_name(key) + (value_tenant, value_ap, value_name) = get_tenant_ap_name(value) + + if key_tenant is not None: + if not match_string(key_tenant, value_tenant): + return False + if not match_string(key_ap, value_ap): + return False + if not match_string(key_name, value_name): + return False + + if key_tenant is None and key_ap is not None: + if not match_string(key_ap, value_ap): + return False + if not match_string(key_name, value_name): + return False + + if key_tenant is None and key_ap is None: + if not match_string(key_name, value_name): + return False + + return True + + +def match_integer(key, value): + if key is None and value is None: + return True + + if key is None and value is not None: + return False + + if key is not None and value is None: + return False + + if isinstance(value, str): + try: + value = int(value) + except BaseException: + return False + + if key.startswith('gt'): + try: + reference = int(key[2:]) + except BaseException: + return False + + if value <= reference: + return False + + return True + + if key.startswith('ge'): + try: + reference = int(key[2:]) + except BaseException: + return False + + if value < reference: + return False + + return True + + if key.startswith('lt'): + try: + reference = int(key[2:]) + except BaseException: + return False + + if value >= reference: + return False + + return True + + if key.startswith('le'): + try: + reference = int(key[2:]) + except BaseException: + return False + + if value < reference: + return False + + return True + + if key.startswith('eq'): + try: + reference = int(key[2:]) + except BaseException: + return False + + if value != reference: + return False + + return True + + if key.startswith('ne'): + try: + reference = int(key[2:]) + except BaseException: + return False + + if value == reference: + return False + + return True + + if len(key.split('-')) == 2: + (start, end) = key.split('-') + try: + start = int(start) + except BaseException: + return False + + try: + end = int(end) + except BaseException: + return False + + if start <= value <= end: + return True + + return False + + try: + reference = int(key) + except BaseException: + return False + + if reference != value: + return False + + return True + + +def match_string(key, value, strict=False): + if key is None and value is None: + return True + + if key is None and value is not None: + return False + + if key is not None and value is None: + return False + + if not isinstance(key, str): + return False + + if not isinstance(value, str): + return False + + if len(key) == 0: + return True + + if len(value) == 0: + return False + + if strict: + if key == value: + return True + return False + + key = key.lower() + value = value.lower() + + if '*' not in key: + if key == value: + return True + return False + + if key == '*': + return True + + if key.startswith('*') and key.endswith('*'): + if key[1:][:-1] in value: + return True + return False + + if key.startswith('*'): + if value.endswith(key[1:]): + return True + return False + + if key.endswith('*'): + if value.startswith(key[:-1]): + return True + return False + + return False + + +def match_mac(key, value, strict=False): + key = '*%s*' % ( + key.replace(':', '').replace(':', '').lower() + ) + value = value.replace(':', '').replace('.', '').lower() + return match_string(key, value, strict=strict) + + +def match_wwn(key, value, strict=False): + key = '*%s*' % ( + key.replace(':', '').replace(':', '').lower() + ) + value = value.replace(':', '').replace('.', '').lower() + return match_string(key, value, strict=strict) + + +def match_id(key, values): + try: + ikey = int(key) + except BaseException: + return False + + for value in values.split(','): + if '-' in value: + (start, end) = value.split('-') + try: + istart = int(start) + except BaseException: + return False + + try: + iend = int(end) + except BaseException: + return False + + if istart <= ikey <= iend: + return True + + if '-' not in value: + try: + ivalue = int(value) + except BaseException: + return False + + if ikey == ivalue: + return True + + return False + + +def match_timestamp(key, value): + if key is None and value is None: + return True + + if key is None and value is not None: + return False + + if key is not None and value is None: + return False + + if not isinstance(key, str): + return False + + if not isinstance(value, int): + return False + + now = int(time.time()) + if key.endswith('m'): + try: + reference = now - int(key[:-1]) * 60 + except BaseException: + return False + + if key.endswith('h'): + try: + reference = now - int(key[:-1]) * 60 * 60 + except BaseException: + return False + + if key.endswith('d'): + try: + reference = now - int(key[:-1]) * 60 * 60 * 24 + except BaseException: + return False + + if key.endswith('y'): + try: + reference = now - int(key[:-1]) * 60 * 60 * 24 * 365 + except BaseException: + return False + + if reference < value: + return True + + return False + + +def get_namespace_name(value, delimiter='/'): + if len(value.split(delimiter)) == 1: + return (None, value) + + if len(value.split(delimiter)) == 2: + return value.split(delimiter) + + return None, None + + +def match_namespace_name(key, value, strict=False, delimiter='/'): + if key is None and value is None: + return True + + if key is None and value is not None: + return False + + if key is not None and value is None: + return False + + if not isinstance(key, str): + return False + + if not isinstance(value, str): + return False + + if len(key) == 0: + return True + + if len(value) == 0: + return False + + if len(value.split(delimiter)) != 2: + return False + + if len(key.split(delimiter)) > 2: + return False + + (key_namespace, key_name) = get_namespace_name(key, delimiter=delimiter) + (value_namespace, value_name) = get_namespace_name(value, delimiter=delimiter) + + if key_namespace is not None: + if not match_string(key_namespace, value_namespace): + return False + if not match_string(key_name, value_name): + return False + + if key_namespace is None: + if not match_string(key_name, value_name): + return False + + return True + + +def split_list_of_dict(items, key): + keys = {} + for item in items: + if item[key] not in keys: + keys[item[key]] = [] + + for item in items: + keys[item[key]].append( + item + ) + + return keys diff --git a/lib/helm/__init__.py b/lib/helm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/helm/chart/__init__.py b/lib/helm/chart/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/helm/chart/main.py b/lib/helm/chart/main.py new file mode 100644 index 00000000..b595277b --- /dev/null +++ b/lib/helm/chart/main.py @@ -0,0 +1,340 @@ +import os + +from lib import filter_helper + + +class HelmChart(): + def __init__(self): + self.chart_directory = '.\ichart' + self.chart_names = None + self.chart_mo = None + self.chart = None + + def get_chart_names(self, cache_enabled=True): + if cache_enabled and self.chart_names is not None: + return self.chart_names + + self.chart_names = self.ssh_handler.get_directories( + self.chart_directory + ) + if self.chart_names is None: + self.log.error( + 'get_chart_mo', + 'Helm command failed' + ) + + return self.chart_names + + def get_chart_filenames_info(self, chart_name): + info = {} + info['base'] = [] + info['templates'] = [] + info['charts'] = [] + info['crds'] = [] + info['tests'] = [] + info['day0'] = [] + info['custom'] = [] + + directory = os.path.join( + self.chart_directory, + chart_name + ) + info['files'] = self.ssh_handler.get_filenames( + directory, + relative=True + ) + + if info['files'] is not None: + for filename in info['files']: + if filename in ['Chart.yaml', 'values.yaml', '.helmignore']: + info['base'].append(filename) + continue + + if filter_helper.match_string('templates/tests/*', filename): + info['tests'].append(filename[len('templates/tests/'):]) + continue + + if filter_helper.match_string('templates/*', filename): + if filename in ['templates/NOTES.txt', 'templates/_helpers.tpl']: + continue + info['templates'].append(filename[len('templates/'):]) + continue + + if filter_helper.match_string('charts/*', filename): + info['charts'].append(filename[len('charts/'):]) + continue + + if filter_helper.match_string('crds/*', filename): + info['crds'].append(filename[len('crds/'):]) + continue + + if filter_helper.match_string('day0/*', filename): + info['day0'].append(filename[len('day0/'):]) + continue + + info['custom'].append(filename) + + return info + + def get_chart_file(self, chart_name, filename, directory=None, convert_yaml=False): + if directory is None: + chart_filename = os.path.join( + os.path.join( + self.chart_directory, + chart_name + ), + filename + ) + else: + chart_filename = os.path.join( + os.path.join( + os.path.join( + self.chart_directory, + chart_name + ), + directory + ), + filename + ) + + content = self.ssh_handler.get_file( + chart_filename, + convert_yaml=convert_yaml + ) + if content is None: + self.log.error( + 'get_chart_file', + 'Yaml file not found: %s' % (chart_filename) + ) + return None + + return content + + def get_chart_info(self, chart_name, cache_enabled=True): + if cache_enabled: + if self.chart is not None and chart_name in self.chart: + return self.chart[chart_name] + + info = {} + info['chart'] = chart_name + info['directory'] = os.path.join( + self.chart_directory, + chart_name + ).replace('\\', '/') + + value = self.get_chart_file(chart_name, 'Chart.yaml', convert_yaml=True) + if value is None: + self.log.error( + 'get_chart_info', + 'Failed to get Chart.yaml: %s' % (chart_name) + ) + return None + + for key in value: + info[key] = value[key] + + info['chart_release'] = '%s-%s' % ( + info['name'], + info['version'] + ) + if self.chart is None: + self.chart = {} + + self.chart[chart_name] = info + return self.chart[chart_name] + + def match_chart(self, chart_info, chart_filter): + if chart_filter is None or len(chart_filter) == 0: + return True + + for ap_rule in chart_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'chart': + key_found = True + if not filter_helper.match_string(value, chart_info['chart']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, chart_info['name']): + return False + + if key == 'chart_version': + key_found = True + if not filter_helper.match_string(value, '%s-%s' % (chart_info['chart'], chart_info['version'])): + return False + + if not key_found: + self.log.error( + 'match_chart', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_charts(self, chart_filter=[], release_info=False, values_info=False, files_info=False, cache_enabled=True): + chart_names = self.get_chart_names(cache_enabled=cache_enabled) + if chart_names is None: + return None + + charts = [] + for chart_name in chart_names: + chart_info = self.get_chart_info(chart_name, cache_enabled=cache_enabled) + if chart_info is None: + continue + + if not self.match_chart(chart_info, chart_filter=chart_filter): + continue + + if values_info: + chart_info['values'] = self.get_chart_file( + chart_info['chart'], + 'values.yaml' + ) + + if files_info: + filenames_info = self.get_chart_filenames_info(chart_name) + if filenames_info is not None: + chart_info.update(filenames_info) + + if release_info: + release_filter = ['chart:%s' % (chart_info['chart_release'])] + chart_info['release'] = self.get_releases( + release_filter=release_filter, + cache_enabled=cache_enabled + ) + + charts.append( + chart_info + ) + + charts = sorted( + charts, + key=lambda i: i['chart'] + ) + + return charts + + def get_chart(self, chart_name, release_info=False, files_info=False, cache_enabled=True): + chart_filter = [] + chart_filter.append('name:%s' % (chart_name)) + charts = self.get_charts(chart_filter=chart_filter, release_info=release_info, files_info=files_info, cache_enabled=cache_enabled) + if charts is None or len(charts) != 1: + return None + return charts[0] + + def is_chart(self, chart_name, cache_enabled=True): + if self.get_chart(chart_name, cache_enabled=cache_enabled) is None: + return False + return True + + def is_chart_release(self, chart_name, cache_enabled=True): + chart_info = self.get_chart(chart_name, release_info=True, cache_enabled=cache_enabled) + if chart_info is None: + return False + + if len(chart_info['release']) == 0: + return False + + return True + + def create_chart(self, chart_name, chart_directory, values_filename, verbose=False): + destination_chart_directory = os.path.join( + self.chart_directory, + chart_name + ) + + if not self.ssh_handler.create_directory(destination_chart_directory): + self.log.error( + 'create_chart', + 'Directory create failed: %s' % (destination_chart_directory) + ) + return False + + for chart_component in os.listdir(chart_directory): + chart_component_path = os.path.join( + chart_directory, + chart_component + ) + + if os.path.isdir(chart_component_path): + destination_directory = os.path.join( + destination_chart_directory, + chart_component + ) + + if not self.ssh_handler.create_directory(destination_directory): + self.log.error( + 'create_chart', + 'Directory create failed: %s' % (destination_directory) + ) + return False + + if verbose: + print('- %s => %s (dir)' % (chart_component_path, destination_directory)) + + if not self.ssh_handler.scp_directory(chart_component_path, destination_directory): + self.log.error( + 'create_chart', + 'Directory copy failed: %s => %s' % (chart_component_path, destination_directory) + ) + return False + + self.log.debug( + 'create_chart', + 'Directory copied: %s => %s' % (chart_component_path, destination_directory) + ) + continue + + destination_filename = os.path.join( + destination_chart_directory, + chart_component + ) + + if chart_component in ['Chart.yaml', '.helmignore']: + if verbose: + print('- %s => %s (file)' % (chart_component_path, destination_filename)) + + if not self.ssh_handler.scp_file(chart_component_path, destination_filename): + self.log.error( + 'create_chart', + 'File copy failed: %s' % (chart_component_path) + ) + return False + + self.log.debug( + 'create_chart', + 'File copied: %s => %s' % (chart_component_path, destination_chart_directory) + ) + continue + + if os.path.basename(destination_filename) == os.path.basename(values_filename): + destination_values_filename = os.path.join( + destination_chart_directory, + 'values.yaml' + ) + + if verbose: + print('- %s => %s (file)' % (chart_component_path, destination_values_filename)) + + if not self.ssh_handler.scp_file(chart_component_path, destination_values_filename): + self.log.error( + 'create_chart', + 'File copy failed: %s' % (chart_component_path) + ) + return False + + self.log.debug( + 'create_chart', + 'File copied: %s => %s' % (chart_component_path, destination_values_filename) + ) + + return True + + def delete_chart(self, chart_name): + directory_name = os.path.join(self.chart_directory, chart_name) + return self.ssh_handler.delete_directory(directory_name) diff --git a/lib/helm/chart/output.py b/lib/helm/chart/output.py new file mode 100644 index 00000000..cbef0478 --- /dev/null +++ b/lib/helm/chart/output.py @@ -0,0 +1,126 @@ +class HelmChartOutput(): + def __init__(self): + pass + + def print_charts(self, info, title=False): + if title: + self.my_output.default( + 'Chart [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'directory', + 'apiVersion', + 'version', + 'appVersion', + 'release.namespace_name' + ] + + headers = [ + 'Name', + 'Directory', + 'API', + 'Version', + 'App', + 'Release' + ] + + for item in info: + if len(item['release']) == 0: + item['release'].append( + dict( + namespace_name='--' + ) + ) + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['release'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_chart_values(self, info): + for item in info: + self.my_output.default( + 'Chart: %s' % (item['chart']), + underline=True, + before_newline=True, + after_newline=True + ) + + self.my_output.default( + 'Path: %s/values.yaml' % (item['directory']), + after_newline=True + ) + + self.my_output.default( + item['values'] + ) + + def print_chart_files(self, info, title=False): + if title: + self.my_output.default( + 'Chart Files [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + for key in ['base', 'templates', 'charts', 'tests', 'crds', 'day0', 'custom']: + if len(item[key]) == 0: + item[key].append('--') + + order = [ + 'chart', + 'base', + 'templates', + 'charts', + 'tests', + 'crds', + 'day0', + 'custom' + ] + + headers = [ + 'Chart', + 'Base', + 'Template', + 'Chart Dependency', + 'Test', + 'CRD', + 'Day0', + 'Custom' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['base', 'templates', 'charts', 'tests', 'crds', 'day0', 'custom'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/helm/main.py b/lib/helm/main.py new file mode 100644 index 00000000..a8d72065 --- /dev/null +++ b/lib/helm/main.py @@ -0,0 +1,26 @@ +from lib import log_helper + +from lib.helm.chart.main import HelmChart +from lib.helm.release.main import HelmRelease +from lib import ssh + + +class Helm( + HelmChart, + HelmRelease + ): + def __init__(self, ip_address, username, password=None, key_filename=None, verbose=False, debug=False, log_id=None): + HelmChart.__init__(self) + HelmRelease.__init__(self) + + self.helm_ip = ip_address + self.log = log_helper.Log(log_id=log_id) + self.ssh_handler = ssh.Ssh( + ip_address, + username, + password=password, + key_filename=key_filename, + verbose=verbose, + debug=debug, + log_id=log_id + ) diff --git a/lib/helm/output.py b/lib/helm/output.py new file mode 100644 index 00000000..5eab51a9 --- /dev/null +++ b/lib/helm/output.py @@ -0,0 +1,19 @@ +from lib import output_helper + +from lib.helm.chart.output import HelmChartOutput +from lib.helm.release.output import HelmReleaseOutput + + +class HelmOutput( + HelmChartOutput, + HelmReleaseOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + HelmChartOutput.__init__(self) + HelmReleaseOutput.__init__(self) diff --git a/lib/helm/release/__init__.py b/lib/helm/release/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/helm/release/main.py b/lib/helm/release/main.py new file mode 100644 index 00000000..e3820e8b --- /dev/null +++ b/lib/helm/release/main.py @@ -0,0 +1,468 @@ +import json +import yaml + +from lib import filter_helper + + +class HelmRelease(): + def __init__(self): + self.release_mo = None + self.release = None + self.release_values = {} + + def get_release_mo(self, cache_enabled=True): + if cache_enabled and self.release_mo is not None: + return self.release_mo + + command = 'helm ls -A --output json' + success, output, error = self.ssh_handler.run_cmd( + command + ) + if not success: + self.log.error( + 'get_release_mo', + 'Helm command failed at %s: %s' % (self.helm_ip, command) + ) + return None + + release_mo = '' + for line in output.split('\n'): + if line.startswith('WARNING:'): + continue + release_mo = '%s%s' % ( + release_mo, + line + ) + + try: + self.release_mo = json.loads( + release_mo + ) + except BaseException: + self.log.error( + 'get_release_mo', + 'Helm output parse failed: %s' % (release_mo) + ) + return None + + return self.release_mo + + def get_release_values(self, namespace, name, cache_enabled=True): + key = '%s/%s' % (namespace, name) + if cache_enabled and key in self.release_values: + return self.release_values[key] + + command = 'helm get all %s -n %s' % ( + name, + namespace + ) + success, output, error = self.ssh_handler.run_cmd( + command + ) + if not success: + self.log.error( + 'get_release_values', + 'Helm command failed at %s: %s' % (self.helm_ip, command) + ) + return None + + values_mo = '' + values_section = False + for line in output.split('\n'): + if line == 'COMPUTED VALUES:': + values_section = True + continue + + if line == 'HOOKS:': + values_section = False + continue + + if values_section: + if line == '': + continue + if values_mo == '': + values_mo = line + continue + + values_mo = '%s\n%s' % (values_mo, line) + + try: + if len(values_mo) == 0: + values = dict() + else: + values = yaml.safe_load(values_mo) + except BaseException: + self.log.error( + 'get_release_values', + 'Failed to json load values: %s' % (values_mo) + ) + return None + + self.release_values[key] = values + return self.release_values[key] + + def get_release_info(self, release_mo, cache_enabled=True): + if cache_enabled and self.release is not None: + return self.release + + self.release = [] + + keys = [ + 'name', + 'namespace', + 'revision', + 'updated', + 'status', + 'chart', + 'app_version' + ] + for item in release_mo: + release = {} + release['__Output'] = {} + for key in keys: + release[key] = item[key] + + release['namespace_name'] = '%s/%s' % ( + release['namespace'], + release['name'] + ) + + if release['status'] == 'deployed': + release['__Output']['status'] = 'Green' + else: + release['__Output']['status'] = 'Red' + + self.release.append( + release + ) + + return self.release + + def match_release(self, release_info, release_filter): + if release_filter is None or len(release_filter) == 0: + return True + + for ap_rule in release_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, release_info['namespace_name']): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, release_info['namespace']): + return False + + if key == 'chart': + key_found = True + if not filter_helper.match_string(value, release_info['chart']): + return False + + if not key_found: + self.log.error( + 'match_release', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_releases(self, release_filter=[], values_info=False, chart_info=False, day0_info=False, cache_enabled=True): + release_mo = self.get_release_mo( + cache_enabled=cache_enabled + ) + if release_mo is None: + return None + + release_info = self.get_release_info( + release_mo, + cache_enabled=cache_enabled + ) + if release_info is None: + return None + + release = [] + for item in release_info: + if not self.match_release(item, release_filter): + continue + + if values_info or day0_info: + item['values'] = self.get_release_values(item['namespace'], item['name'], cache_enabled=cache_enabled) + if item['values'] is None: + self.log.error( + 'get_releases', + 'Values none: %s/%s' % (item['namespace'], item['name']) + ) + + if chart_info or day0_info: + item['chart_name'] = None + charts = self.get_charts( + chart_filter=['chart_version:%s' % (item['chart'])], + files_info=True + ) + if charts is None: + self.log.error( + 'get_releases', + 'Charts none: %s/%s' % (item['namespace'], item['name']) + ) + + if charts is not None and len(charts) > 1: + self.log.error( + 'get_releases', + 'Multiple charts: %s/%s' % (item['namespace'], item['name']) + ) + + if charts is not None and len(charts) == 1: + item['chart_name'] = charts[0]['chart'] + + if day0_info: + item['day0'] = None + if item['chart_name'] is not None and item['values'] is not None: + item['day0'] = self.get_release_day0( + item['chart_name'], + item['namespace'], + item['name'], + item['values'] + ) + if item['day0'] is None: + self.log.error( + 'get_releases', + 'Day0 failed: %s/%s' % (item['namespace'], item['name']) + ) + + release.append( + item + ) + + return release + + def get_release(self, namespace, name, values_info=False, chart_info=False, day0_info=False, cache_enabled=True): + release_filter = [] + release_filter.append('namespace:%s' % (namespace)) + release_filter.append('name:%s' % (name)) + releases = self.get_releases( + release_filter=release_filter, + values_info=values_info, + chart_info=chart_info, + day0_info=day0_info, + cache_enabled=cache_enabled + ) + if releases is None or len(releases) != 1: + return None + + return releases[0] + + def is_release(self, namespace, name, cache_enabled=True): + if self.get_release(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def serialize_values(self, values): + serialized_values = {} + for key in values: + if isinstance(values[key], str): + serialized_values[key] = values[key] + if isinstance(values[key], int): + serialized_values[key] = values[key] + if isinstance(values[key], bool): + serialized_values[key] = values[key] + if isinstance(values[key], dict): + sub_values = self.serialize_values(values[key]) + for sub_key in sub_values: + serialized_values['%s.%s' % (key, sub_key)] = sub_values[sub_key] + return serialized_values + + def apply_values(self, content, namespace, name, values): + if content is None: + return None + + content = content.replace('{{ .Release.Namespace }}', namespace) + content = content.replace('{{ .Release.Name }}', name) + + serialized_values = self.serialize_values(values) + for key in serialized_values: + content = content.replace('{{ .Values.%s }}' % (key), str(serialized_values[key])) + + if '{{ ' in content: + self.log.error( + 'apply_values', + 'Not all variables replaced: %s' % (content) + ) + for key in serialized_values: + self.log.error( + 'apply_values', + '%s => %s' % ( + key, + serialized_values[key] + ) + ) + return None + + return content + + def get_release_day0(self, chart_name, namespace, name, values): + chart_info = self.get_chart(chart_name, files_info=True) + if chart_info is None: + self.log.error( + 'get_release_day0', + 'Chart not found: %s' % (chart_name) + ) + return None + + if len(chart_info['day0']) == 0: + return [] + + day0 = [] + + directory_names = [] + for item in chart_info['day0']: + if item.split('/')[0] not in directory_names: + directory_names.append( + item.split('/')[0] + ) + + for directory_name in directory_names: + day0_item = {} + day0_item['dv'] = None + day0_item['filename'] = None + day0_item['content'] = None + + for item in chart_info['day0']: + if item.split('/')[0] == directory_name: + if item.split('/')[1] == 'day0.yaml': + content = self.apply_values( + self.get_chart_file( + chart_name, + item.split('/')[1], + directory='day0/%s' % (directory_name) + ), + namespace, + name, + values + ) + if content is None: + self.log.error( + 'get_release_day0', + 'File read failed: %s' % (item) + ) + return None + + try: + day0_item['dv'] = yaml.safe_load( + content + ) + except BaseException: + self.log.error( + 'get_release_day0', + 'File yaml read failed: %s' % (item) + ) + return None + + if item.split('/')[1] != 'day0.yaml': + day0_item['filename'] = item.split('/')[1] + day0_item['content'] = self.apply_values( + self.get_chart_file( + chart_name, + item.split('/')[1], + directory='day0/%s' % (directory_name) + ), + namespace, + name, + values + ) + + if day0_item['content'] is None: + self.log.error( + 'get_release_day0', + 'Configuration file read failed: %s' % (item) + ) + return None + + day0.append( + day0_item + ) + + return day0 + + def create_release(self, chart_name, namespace, name, values): + if self.is_release(namespace, name, cache_enabled=False): + self.log.error( + 'create_release', + 'Release already exists: %s/%s' % (namespace, name) + ) + return False, 'Release already exists: %s/%s' % (namespace, name) + + chart_info = self.get_chart(chart_name) + if chart_info is None: + self.log.error( + 'create_release', + 'Chart not found: %s' % (chart_name) + ) + return False, 'Chart not found: %s' % (chart_name) + + values_filename = self.ssh_handler.create_file( + yaml.safe_dump( + values + ) + ) + if values_filename is None: + self.log.error( + 'create_release', + 'Failed to create values file' + ) + return False, 'Failed to create values file' + + command = 'helm install %s -n %s -f %s %s' % ( + name, + namespace, + values_filename, + chart_info['directory'] + ) + success, output, error = self.ssh_handler.run_cmd( + command + ) + self.ssh_handler.delete_file(values_filename) + + if not success: + reason = 'Helm command failed' + self.log.error( + 'create_release', + 'Helm command failed at %s: %s' % (self.helm_ip, command) + ) + + if output is not None and len(output) > 0: + reason = '%s output [%s]' % (reason, output) + self.log.error( + 'create_release', + output + ) + if error is not None and len(error) > 0: + reason = '%s error [%s]' % (reason, error) + self.log.error( + 'create_release', + error + ) + + return False, reason + + return True, None + + def delete_release(self, namespace, name): + if not self.is_release(namespace, name, cache_enabled=False): + return True + + command = 'helm uninstall %s -n %s' % (name, namespace) + success, output, error = self.ssh_handler.run_cmd( + command + ) + if not success: + self.log.error( + 'delete_release', + 'Helm command failed at %s: %s' % (self.helm_ip, command) + ) + return False + return True diff --git a/lib/helm/release/output.py b/lib/helm/release/output.py new file mode 100644 index 00000000..06c06934 --- /dev/null +++ b/lib/helm/release/output.py @@ -0,0 +1,132 @@ +import json +from lib import filter_helper + + +class HelmReleaseOutput(): + def __init__(self): + pass + + def print_releases(self, info, title=False): + if title: + self.my_output.default( + 'Helm Release [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'revision', + 'updated', + 'status', + 'chart', + 'app_version' + ] + + headers = [ + 'Namespace', + 'Name', + 'Revision', + 'Updated', + 'Status', + 'Chart - Version', + 'App Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_releases_day0(self, info, title=False): + if title: + self.my_output.default( + 'Helm Release - Generated Day0 [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'day0.dv.metadata.namespace', + 'day0.dv.metadata.name' + ] + + headers = [ + 'Namespace', + 'Name', + 'Day0 PVC Namespace', + 'Day0 PVC Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['day0'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_release_values(self, info, title=False): + if title: + self.my_output.default( + 'Helm Release Values [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['valuesT'] = json.dumps(item['values'], indent=4).split('\n') + + order = [ + 'namespace', + 'name', + 'chart', + 'valuesT' + ] + + headers = [ + 'Namespace', + 'Name', + 'Chart - Version', + 'Values' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['valuesT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/iaccount_helper.py b/lib/iaccount_helper.py new file mode 100644 index 00000000..c63514b2 --- /dev/null +++ b/lib/iaccount_helper.py @@ -0,0 +1,211 @@ +import os +import traceback +import subprocess +import shutil + +from lib.settings_helper import Settings +from lib import file_helper + + +class IntersightAccount(Settings): + def __init__(self): + Settings.__init__(self) + + self.isctl_configuration_filename = os.path.join( + self.home_dir, + '.isctl.yaml' + ) + + def get_isctl_version(self): + try: + command = 'isctl version' + with subprocess.Popen( + args=command, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + env=os.environ + ) as process: + output, error = process.communicate() + if process.returncode == 0: + return True, output.decode('utf-8') + self.log.error('iaccount_helper.get_isctl_version', 'command execution failed') + self.log.error('iaccount_helper.get_isctl_version', traceback.format_exc()) + return False, 'isctl command execution failed' + except BaseException: + self.log.error('iaccount_helper.get_isctl_version', traceback.format_exc()) + return False, 'Exception in running isctl command' + + def is_isctl(self): + success, version = self.get_isctl_version() + return success + + def is_iaccount(self, name): + if self.get_iaccount_configuration(name) is None: + return False + return True + + def get_iaccounts(self): + iaccounts = [] + for name in os.listdir(self.iaccount_dir): + if self.is_iaccount_valid(name): + configuration = self.get_iaccount_configuration(name) + iaccount = {} + iaccount['name'] = name + for key in configuration: + iaccount[key] = configuration[key] + + description = self.get_iaccount_description(name) + if description is None: + iaccount['account'] = '--' + iaccount['role'] = '--' + else: + iaccount['account'] = description['account'] + iaccount['role'] = description['role'] + + iaccounts.append(iaccount) + + return iaccounts + + def get_iaccount_configuration_filename(self, iaccount): + directory = os.path.join(self.iaccount_dir, iaccount) + return os.path.join(directory, 'iaccount.yaml') + + def get_iaccount_configuration(self, iaccount): + ''' + keyfile: /root/intersight.pem + keyid: lalala + output: default + server: intersight.com + ''' + filename = self.get_iaccount_configuration_filename(iaccount) + + content = file_helper.get_file_yaml( + filename + ) + if content is None: + self.log.error( + 'iaccount_helper.get_iaccount_configuration', + 'Yaml load failed: %s' % (filename) + ) + + return content + + def get_iaccount_description_filename(self, iaccount): + directory = os.path.join(self.iaccount_dir, iaccount) + return os.path.join(directory, 'description.yaml') + + def get_iaccount_description(self, iaccount): + ''' + account: EU-SPN + role: EU-SPDC-admin + ''' + filename = self.get_iaccount_description_filename(iaccount) + + if not os.path.isfile(filename): + return None + + content = file_helper.get_file_yaml( + filename + ) + if content is None: + self.log.error( + 'iaccount_helper.get_iaccount_description', + 'Yaml load failed: %s' % (filename) + ) + + return content + + def copy_key_file(self, iaccount, source): + if not os.path.isfile(source): + return None + directory = os.path.join(self.iaccount_dir, iaccount) + destination = os.path.join(directory, 'key.pem') + shutil.copyfile(source, destination) + return destination + + def set_iaccount_configuration(self, iaccount, configuration): + ''' + keyfile: /root/intersight.pem + keyid: lalala + output: default + server: intersight.com + ''' + filename = self.get_iaccount_configuration_filename(iaccount) + try: + key_filename = self.copy_key_file(iaccount, configuration['keyfile']) + if key_filename is None: + self.log.error('iaccount_helper.set_iaccount_configuration', 'Key file copy failed') + return False + + with open(filename, 'w', encoding='utf-8') as file_handler: + for key in configuration: + if key == 'keyfile': + file_handler.write('%s: %s\n' % (key, key_filename)) + else: + file_handler.write('%s: %s\n' % (key, configuration[key])) + + except BaseException: + self.log.error('iaccount_helper.set_iaccount_configuration', traceback.format_exc()) + return False + return True + + def is_iaccount_valid(self, iaccount): + configuration = self.get_iaccount_configuration(iaccount) + if configuration is None: + self.log.error('iaccount_helper.is_iaccount_valid', 'isctl configuration not found') + return False + + for key in ['keyfile', 'keyid', 'output', 'server']: + if key not in configuration: + self.log.error('iaccount_helper.is_iaccount_valid', 'Key %s not found' % (key)) + return False + + return True + + def create_iaccount(self, iaccount, configuration): + directory = os.path.join(self.iaccount_dir, iaccount) + if not os.path.isdir(directory): + os.makedirs(directory) + + return self.set_iaccount_configuration(iaccount, configuration) + + def delete_iaccount(self, iaccount): + try: + directory = os.path.join(self.iaccount_dir, iaccount) + if not os.path.isdir(directory): + return False, 'Account does not exist' + + if self.is_default_account(iaccount): + if not self.clear_default_iaccount(): + return False, 'Default iaccount change failed' + + shutil.rmtree(directory) + + except BaseException: + self.log.error('iaccount_helper.delete_iaccount', traceback.format_exc()) + return False, 'Exception' + + return True, None + + def is_default_account(self, iaccount_name): + default_iacccount_name = self.get_setting('iaccount') + if default_iacccount_name == iaccount_name: + return True + return False + + def clear_default_iaccount(self): + return self.set_setting('iaccount', None) + + def set_default_iaccount(self, iaccount): + if self.is_iaccount_valid(iaccount): + return self.set_setting('iaccount', iaccount) + return False + + def get_iaccount_json_file(self, iaccount, filename): + directory = os.path.join(self.iaccount_dir, iaccount) + return file_helper.get_file_json(os.path.join(directory, filename)) + + def set_iaccount_json_file(self, iaccount, filename, content): + directory = os.path.join(self.iaccount_dir, iaccount) + return file_helper.set_file_json(os.path.join(directory, filename), content) diff --git a/lib/imc/__init__.py b/lib/imc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/__init__.py b/lib/imc/cli/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/adapter/__init__.py b/lib/imc/cli/adapter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/adapter/main.py b/lib/imc/cli/adapter/main.py new file mode 100644 index 00000000..1ef4c8b7 --- /dev/null +++ b/lib/imc/cli/adapter/main.py @@ -0,0 +1,113 @@ +import json + + +class ImcCliAdapter(): + def __init__(self): + self.adapter_mo = None + + def get_adapter_mo(self, cache_enabled=True): + if cache_enabled: + if self.adapter_mo is not None: + return self.adapter_mo + + self.adapter_mo = self.get_icm_cli_cache_entry( + 'adapter' + ) + if self.adapter_mo is not None: + return self.adapter_mo + + # PCI Slot MLOM: + # Product Name: UCS VIC 1457 + # Serial Number: FCH24157D1V + # Product ID: UCSC-MLOM-C25Q-04 + # Adapter Hardware Revision: 5 + # Current FW Version: 5.2(2b) + # VNTAG: Disabled + # FIP: Disabled + # LLDP: Disabled + # PORT CHANNEL: Disabled + # Physical NIC Mode (Experimental): Disabled + # Configuration Pending: no + # Cisco IMC Management Enabled: no + # VID: V05 + # Vendor: Cisco Systems Inc + # Description: + # Bootloader Version: 5.0(2a) + # FW Image 1 Version: 5.2(2b) + # FW Image 1 State: RUNNING ACTIVATED + # FW Image 2 Version: 5.1(3d) + # FW Image 2 State: BACKUP INACTIVATED + # FW Update Status: Fwupdate never issued + # FW Update Error: No error + # FW Update Stage: No operation (0%) + # FW Update Overall Progress: 0% + + self.adapter_mo = self.show_list( + 'show adapter detail', + 'PCI Slot', + 'Slot', + method='last word', + scope='chassis' + ) + + if self.adapter_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'adapter', + self.adapter_mo + ) + + self.log.debug( + 'get_adapter_mo', + json.dumps(self.adapter_mo, indent=4) + ) + return self.adapter_mo + + def get_adapter_info(self, adapter_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in adapter_mo: + info[key] = adapter_mo[key] + + info['__Key'] = 'Slot' + info['__Value'] = info[info['__Key']] + + self.log.debug( + 'get_adapter_info', + json.dumps(info, indent=4) + ) + return info + + def get_adapter(self, cache_enabled=True): + adapters_mo = self.get_adapter_mo(cache_enabled=cache_enabled) + if adapters_mo is None: + return None + + adapters_info = [] + + for adapter_mo in adapters_mo: + adapters_info.append( + self.get_adapter_info( + adapter_mo + ) + ) + + return adapters_info + + def get_adapter_slots(self, cache_enabled=True): + adapters = self.get_adapter( + cache_enabled=cache_enabled + ) + if adapters is None: + return None + + slots = [] + for adapter in adapters: + slots.append( + adapter['Slot'] + ) + + return slots diff --git a/lib/imc/cli/adapter/output.py b/lib/imc/cli/adapter/output.py new file mode 100644 index 00000000..7827d22f --- /dev/null +++ b/lib/imc/cli/adapter/output.py @@ -0,0 +1,15 @@ +class ImcCliAdapterOutput(): + def __init__(self): + pass + + def print_imc_adapter(self, info): + self.print_list_dict( + info, + 'Adapter' + ) + + def print_imc_adapter_compare(self, info): + self.print_compare( + info, + 'Adapter' + ) diff --git a/lib/imc/cli/admin/__init__.py b/lib/imc/cli/admin/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/admin/main.py b/lib/imc/cli/admin/main.py new file mode 100644 index 00000000..9254b011 --- /dev/null +++ b/lib/imc/cli/admin/main.py @@ -0,0 +1,79 @@ +class ImcCliAdmin(): + def __init__(self): + pass + + def get_admin( + self, + all_info=False, + fault_info=False, + http_info=False, + ip_info=False, + ipmi_info=False, + kvm_info=False, + ntp_info=False, + redfish_info=False, + sel_info=False, + smtp_info=False, + snmp_info=False, + sol_info=False, + ssh_info=False, + syslog_info=False, + vmedia_info=False, + cache_enabled=True, + xml_info=False + ): + info = {} + info['endpoint_ip'] = self.endpoint_ip + + if all_info or fault_info: + info['fault'] = self.get_fault(cache_enabled=cache_enabled) + + if all_info or http_info: + info['http'] = self.get_http(cache_enabled=cache_enabled) + + if all_info or ip_info: + info['ip'] = self.get_ip( + network_info=True, + icmp_info=True, + blocking_info=True, + filtering_info=True, + cache_enabled=cache_enabled + ) + + if all_info or ipmi_info: + info['ipmi'] = self.get_ipmi(cache_enabled=cache_enabled) + + if all_info or kvm_info: + info['kvm'] = self.get_kvm(cache_enabled=cache_enabled) + + if all_info or ntp_info: + info['ntp'] = self.get_ntp(cache_enabled=cache_enabled) + + if all_info or redfish_info: + info['redfish'] = self.get_redfish(cache_enabled=cache_enabled) + + if all_info or sel_info: + info['sel'] = self.get_sel(cache_enabled=cache_enabled) + + if all_info or smtp_info: + info['smtp'] = self.get_smtp(cache_enabled=cache_enabled) + + if all_info or snmp_info: + info['snmp'] = self.get_snmp(cache_enabled=cache_enabled) + + if all_info or sol_info: + info['sol'] = self.get_sol(cache_enabled=cache_enabled) + + if all_info or ssh_info: + info['ssh'] = self.get_ssh(cache_enabled=cache_enabled) + + if all_info or syslog_info: + info['syslog'] = self.get_syslog(cache_enabled=cache_enabled) + + if all_info or vmedia_info: + info['vmedia'] = self.get_vmedia(cache_enabled=cache_enabled) + + if all_info or xml_info: + info['xml'] = self.get_xml(cache_enabled=cache_enabled) + + return info diff --git a/lib/imc/cli/admin/output.py b/lib/imc/cli/admin/output.py new file mode 100644 index 00000000..6b4d5678 --- /dev/null +++ b/lib/imc/cli/admin/output.py @@ -0,0 +1,56 @@ +class ImcCliAdminOutput(): + def __init__(self): + pass + + def print_imc_admin(self, info): + for item in info: + self.my_output.default( + 'Endpoint: %s' % (item['endpoint_ip']), + before_newline=True, + underline=True + ) + + if 'fault' in item: + self.print_imc_fault(item['fault']) + + if 'http' in item: + self.print_imc_http(item['http']) + + if 'ip' in item: + self.print_imc_ip(item['ip']) + + if 'ipmi' in item: + self.print_imc_ipmi(item['ipmi']) + + if 'kvm' in item: + self.print_imc_kvm(item['kvm']) + + if 'ntp' in item: + self.print_imc_ntp(item['ntp']) + + if 'redfish' in item: + self.print_imc_redfish(item['redfish']) + + if 'sel' in item: + self.print_imc_sel(item['sel']) + + if 'smtp' in item: + self.print_imc_smtp(item['smtp']) + + if 'snmp' in item: + self.print_imc_snmp(item['snmp']) + + if 'sol' in item: + self.print_imc_sol(item['sol']) + + if 'ssh' in item: + self.print_imc_ssh(item['ssh']) + + if 'syslog' in item: + self.print_imc_syslog(item['syslog']) + + if 'vmedia' in item: + self.print_imc_vmedia(item['vmedia']) + + if 'xml' in item: + self.print_imc_xml(item['xml']) diff --git a/lib/imc/cli/bbu/__init__.py b/lib/imc/cli/bbu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/bbu/main.py b/lib/imc/cli/bbu/main.py new file mode 100644 index 00000000..23afada6 --- /dev/null +++ b/lib/imc/cli/bbu/main.py @@ -0,0 +1,139 @@ +import json + + +class ImcCliBbu(): + def __init__(self): + self.bbu_mo = None + + def get_bbu_mo(self, cache_enabled=True): + if cache_enabled: + if self.bbu_mo is not None: + return self.bbu_mo + + self.bbu_mo = self.get_icm_cli_cache_entry( + 'bbu' + ) + if self.bbu_mo is not None: + return self.bbu_mo + + # Controller MRAID: + # BBU Type: TMM-C SuperCap + # BBU Health: Good + # BBU Status: Optimal + # Learn Cycle Status: Successful + # Charging Status: N/A + # Learn Mode: Auto + # Battery Present: true + # Serial Number: 26487 + # Temperature: 20 degrees C + # Temperature High: false + # Retention Time: N/A + # Relative State of Charge: N/A + # Absolute State of Charge: N/A + # Capacitance: 100 % + # Manufacturer: LSI + # Date of Manufacture: 2019-12-21 + # Firmware Version: 05668-01 + # Design Voltage: 9.800 V + # Voltage: 9.734 V + # Current: 0.000 A + # Design Capacity: 374 Joules + # Full Capacity: N/A + # Remaining Capacity: N/A + # Pack Energy: 334 Joules + # Expected Margin of Error: N/A + # Completed Charge Cycles: N/A + # Learn Cycle Requested: false + # Next Learn Cycle: 2024-06-23 03:33 + # Learn Cycle Active: false + # Learn Cycle Failed: false + # Learn Cycle Timeout: false + # I2c Errors Detected: false + + slots = self.get_storage_adapter_slots() + if slots is None: + return None + + output = '' + for slot in slots: + commands = [ + 'top', + 'scope chassis', + 'scope storageadapter %s' % (slot), + 'show bbu detail' + ] + + success, slot_output = self.run_commands( + commands + ) + + if not success: + return None + + output = output + slot_output['show bbu detail'] + + self.bbu_mo = self.parse_list( + output, + 'Controller', + 'Controller', + method='last word' + ) + + if self.bbu_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'bbu', + self.bbu_mo + ) + + self.log.debug( + 'get_bbu_mo', + json.dumps(self.bbu_mo, indent=4) + ) + return self.bbu_mo + + def get_bbu_info(self, bbu_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in bbu_mo: + info[key] = bbu_mo[key] + + if 'BBU Health' in info: + if info['BBU Health'] == 'Good': + info['__Output']['BBU Health'] = 'Green' + else: + info['__Output']['BBU Health'] = 'Red' + + if 'BBU Status' in info: + if info['BBU Status'] == 'Optimal': + info['__Output']['BBU Status'] = 'Green' + else: + info['__Output']['BBU Status'] = 'Red' + + info['__Key'] = 'Controller' + info['__Value'] = info[info['__Key']] + + self.log.debug( + 'get_bbu_info', + json.dumps(info, indent=4) + ) + return info + + def get_bbu(self, cache_enabled=True): + bbus_mo = self.get_bbu_mo(cache_enabled=cache_enabled) + if bbus_mo is None: + return None + + bbus_info = [] + + for bbu_mo in bbus_mo: + bbus_info.append( + self.get_bbu_info( + bbu_mo + ) + ) + + return bbus_info diff --git a/lib/imc/cli/bbu/output.py b/lib/imc/cli/bbu/output.py new file mode 100644 index 00000000..0a95cb51 --- /dev/null +++ b/lib/imc/cli/bbu/output.py @@ -0,0 +1,15 @@ +class ImcCliBbuOutput(): + def __init__(self): + pass + + def print_imc_bbu(self, info): + self.print_list_dict( + info, + 'Battery Backup Unit' + ) + + def print_imc_bbu_compare(self, info): + self.print_compare( + info, + 'Battery Backup Unit' + ) diff --git a/lib/imc/cli/bios/__init__.py b/lib/imc/cli/bios/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/bios/main.py b/lib/imc/cli/bios/main.py new file mode 100644 index 00000000..196ea245 --- /dev/null +++ b/lib/imc/cli/bios/main.py @@ -0,0 +1,181 @@ +import json +from lib import filter_helper + + +class ImcCliBios(): + def __init__(self): + self.bios_mo = None + self.bios_params_mo = None + + def get_bios_mo(self, cache_enabled=True): + if cache_enabled: + if self.bios_mo is not None: + return self.bios_mo + + self.bios_mo = self.get_icm_cli_cache_entry( + 'bios' + ) + if self.bios_mo is not None: + return self.bios_mo + + # BIOS: + # BIOS Version: C220M5.4.2.2b.0.0613220203 + # Backup BIOS Version: C220M5.4.1.3i.0.0713210713 + # Boot Order: HDD + # FW Update Status: None, OK + # UEFI Secure Boot: disabled + # Configured Boot Mode: Uefi + # Actual Boot Mode: Uefi + # Last Configured Boot Order Source: CIMC + # One time boot device: (none) + + self.bios_mo = self.show_dict( + 'show bios detail', + start='BIOS:' + ) + + if self.bios_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'bios', + self.bios_mo + ) + + self.log.debug( + 'get_bios_mo', + json.dumps(self.bios_mo, indent=4) + ) + + return self.bios_mo + + def get_bios_params_mo(self, cache_enabled=True): + if cache_enabled: + if self.bios_params_mo is not None: + return self.bios_params_mo + + self.bios_params_mo = self.get_icm_cli_cache_entry( + 'bios_params' + ) + if self.bios_params_mo is not None: + return self.bios_params_mo + + # Set-up parameters: + # Intel VTD ATS support: Enabled + # All Onboard LOM Ports: Enabled + # Intel VTD Coherency Support: Disabled + + self.bios_params_mo = {} + param_types = [ + 'input-output', + 'memory', + 'power-or-performance', + 'processor', + 'security', + 'server-management' + ] + self.set_scope('bios') + for param_type in param_types: + self.bios_params_mo[param_type] = [] + bios_params = self.show_dict( + 'show %s detail' % (param_type), + start='Set-up parameters:', + top=False + ) + if bios_params is not None: + for bios_param in bios_params: + bios_param_mo = {} + bios_param_mo[bios_param] = bios_params[bios_param] + self.bios_params_mo[param_type].append( + bios_param_mo + ) + + self.set_imc_cli_cache_entry( + 'bios_params', + self.bios_params_mo + ) + + self.log.debug( + 'get_bios_mo', + json.dumps(self.bios_params_mo, indent=4) + ) + + return self.bios_params_mo + + def get_bios_info(self, bios_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in bios_mo: + info[key] = bios_mo[key] + + self.log.debug( + 'get_bios_info', + json.dumps(info, indent=4) + ) + + return info + + def get_bios_params_info(self, bios_mo, key_filter=None, type_filter=None): + info = {} + + for key in bios_mo: + if type_filter is not None and len(type_filter) > 0: + is_match = False + for item in type_filter: + is_match = is_match or filter_helper.match_string('*%s*' % (item), key) + + if not is_match: + continue + + info[key] = {} + info[key]['__Output'] = {} + info[key]['__IP'] = self.endpoint_ip + + for item in bios_mo[key]: + for ikey in item: + if key_filter is not None and len(key_filter) > 0: + is_match = False + for key_filter_item in key_filter: + is_match = is_match or filter_helper.match_string('*%s*' % (key_filter_item), ikey) + + if not is_match: + continue + + info[key][ikey] = item[ikey] + + if len(info[key]) == 2: + del info[key] + + self.log.debug( + 'get_bios_param_info', + json.dumps(info, indent=4) + ) + + return info + + def get_bios(self, key_filter=None, type_filter=None, state_info=True, params_info=True, cache_enabled=True): + bios_info = {} + + if state_info: + bios_mo = self.get_bios_mo(cache_enabled=cache_enabled) + if bios_mo is None: + return None + + bios_info['state'] = self.get_bios_info( + bios_mo + ) + + if params_info: + bios_params_mo = self.get_bios_params_mo(cache_enabled=cache_enabled) + if bios_params_mo is None: + return None + + bios_info['params'] = self.get_bios_params_info( + bios_params_mo, + key_filter=key_filter, + type_filter=type_filter + ) + + return bios_info diff --git a/lib/imc/cli/bios/output.py b/lib/imc/cli/bios/output.py new file mode 100644 index 00000000..8877ed26 --- /dev/null +++ b/lib/imc/cli/bios/output.py @@ -0,0 +1,63 @@ +class ImcCliBiosOutput(): + def __init__(self): + pass + + def print_imc_bios(self, info): + items = [] + for item in info: + items.append( + item['state'] + ) + + self.print_list_dict( + items, + 'BIOS State' + ) + + def print_imc_bios_compare(self, info): + items = [] + for item in info: + items.append( + item['state'] + ) + + self.print_compare( + items, + 'BIOS State' + ) + + def print_imc_bios_params(self, info): + items = [] + for item in info: + items.append( + item['params'] + ) + + for item in items: + for key in item: + self.print_list_dict( + [item[key]], + 'BIOS Parameters: %s' % (key), + allow_order_subkeys=False + ) + + def print_imc_bios_params_compare(self, info): + param_types = [] + for item in info: + for key in item['params']: + if key not in param_types: + param_types.append(key) + + for param_type in param_types: + items = [] + for item in info: + for key in item['params']: + if key == param_type: + items.append( + item['params'][key] + ) + + self.print_compare( + items, + 'BIOS Parameters: %s' % (param_type) + ) diff --git a/lib/imc/cli/boot/__init__.py b/lib/imc/cli/boot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/boot/main.py b/lib/imc/cli/boot/main.py new file mode 100644 index 00000000..72e735f1 --- /dev/null +++ b/lib/imc/cli/boot/main.py @@ -0,0 +1,342 @@ +import json + + +class ImcCliBoot(): + def __init__(self): + self.boot_mo = None + self.boot_device_mo = None + + def get_boot_mo(self, cache_enabled=True): + if cache_enabled: + if self.boot_mo is not None: + return self.boot_mo + + self.boot_mo = self.get_icm_cli_cache_entry( + 'boot' + ) + if self.boot_mo is not None: + return self.boot_mo + + # Boot Order 1: + # Boot Device: (Bus 18 Dev 00)PCI RAID Adapter + # Device Type: HDD + # Boot Policy: NonPolicyTarget + # Slot Num: + # Lun Id: + + self.boot_mo = self.show_list( + 'show actual-boot-order detail', + 'Boot Order', + 'Boot Order', + method='last word', + scope='bios' + ) + + if self.boot_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'boot', + self.boot_mo + ) + + self.log.debug( + 'get_boot_mo', + json.dumps(self.boot_mo, indent=4) + ) + + return self.boot_mo + + def get_boot_device_mo(self, cache_enabled=True): + if cache_enabled: + if self.boot_device_mo is not None: + return self.boot_device_mo + + self.boot_device_mo = self.get_icm_cli_cache_entry( + 'boot_device' + ) + if self.boot_device_mo is not None: + return self.boot_device_mo + + # Boot Device localhdd: + # Device Type: LOCALHDD + # Device State: Disabled + # Device Order: 1 + # Slot Id: + # Boot Loader Name: + # Boot Loader Path: + # Boot Loader Description: + + self.boot_device_mo = self.show_list( + 'show boot-device detail', + 'Boot Device', + 'Boot Device', + method='last word', + scope='bios' + ) + + if self.boot_device_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'boot_device', + self.boot_device_mo + ) + + self.log.debug( + 'get_boot_mo', + json.dumps(self.boot_device_mo, indent=4) + ) + + return self.boot_device_mo + + def get_boot_info(self, boot_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in boot_mo: + info[key] = boot_mo[key] + + info['__Key'] = 'Boot Order' + info['__Value'] = info[info['__Key']] + self.log.debug( + 'get_boot_info', + json.dumps(info, indent=4) + ) + + return info + + def get_boot_device_info(self, boot_device_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in boot_device_mo: + info[key] = boot_device_mo[key] + + self.log.debug( + 'get_boot_device_info', + json.dumps(info, indent=4) + ) + + return info + + def get_boot(self, order_info=True, device_info=True, cache_enabled=True): + boot_info = {} + + if order_info: + boot_mo = self.get_boot_mo(cache_enabled=cache_enabled) + if boot_mo is None: + return None + + boot_info['order'] = [] + for item in boot_mo: + boot_info['order'].append( + self.get_boot_info( + item + ) + ) + + if device_info: + boot_device_mo = self.get_boot_device_mo(cache_enabled=cache_enabled) + if boot_device_mo is None: + return None + + boot_info['device'] = [] + for item in boot_device_mo: + boot_info['device'].append( + self.get_boot_device_info( + item + ) + ) + + return boot_info + + def validate_boot_order(self, boot_order): + if boot_order is None: + self.log.error( + 'validate_boot_order', + 'None value invalid' + ) + return False + + if not isinstance(boot_order, list): + self.log.error( + 'validate_boot_order', + 'list expected' + ) + return False + + allowed = ['hdd', 'pxe', 'fdd', 'efi', 'cdrom'] + for item in boot_order: + if item not in allowed: + self.log.error( + 'validate_boot_order', + 'invalid item: %s' % (item) + ) + return False + + return True + + def set_boot_order(self, boot_order): + commands = [] + commands.append('top') + commands.append('scope bios') + commands.append('set boot-order %s' % (','.join(boot_order))) + + success, output = self.run_commands( + commands + ) + + if not success: + self.log.error( + 'set_boot_order', + 'Failed to set boot order' + ) + return False + + self.log.debug( + 'set_boot_order', + output + ) + + return True + + def is_top_boot_order_from_device_type(self, device_type, cache_enabled=True): + boot_order = self.get_boot( + order_info=True, + cache_enabled=cache_enabled + ) + if boot_order is None: + self.log.error( + 'is_boot_from_device_type', + 'Failed to get current boot order' + ) + return False + + for item in boot_order['order']: + if item['Boot Order'] == '1': + if item['Device Type'] == device_type: + return True + return False + + self.log.error( + 'is_boot_from_device_type', + 'Failed to get current 1st boot order' + ) + return False + + def validate_boot_device_type(self, device_type): + allowed = [ + 'PXE', + 'ISCSI', + 'LOCALHDD', + 'SAN', + 'USB', + 'VMEDIA', + 'PCHSTORAGE', + 'UEFISHELL', + 'NVME', + 'LOCALCDD', + 'HTTP', + 'EMBEDDEDSTORAGE' + ] + if device_type not in allowed: + self.log.error( + 'validate_boot_device_type', + 'invalid device type: %s' % (device_type) + ) + return False + + return True + + def is_boot_device_type(self, device_type, cache_enabled=False): + boot_devices = self.get_boot( + device_info=True, + cache_enabled=cache_enabled + ) + if boot_devices is None: + self.log.error( + 'is_boot_device_type', + 'Failed to get current boot devices' + ) + return False + + for item in boot_devices['device']: + if item['Device Type'] == device_type: + return True + + return False + + def is_boot_device_name(self, device_name, cache_enabled=False): + boot_devices = self.get_boot( + device_info=True, + cache_enabled=cache_enabled + ) + if boot_devices is None: + self.log.error( + 'is_boot_device', + 'Failed to get current boot devices' + ) + return False + + for item in boot_devices['device']: + if item['Boot Device'] == device_name: + return True + + return False + + def create_boot_device(self, device_name, device_type, device_order=None): + if not self.validate_boot_device_type(device_type): + return False + + commands = [] + commands.append('top') + commands.append('scope bios') + commands.append('create-boot-device %s %s' % (device_name, device_type)) + commands.append('enable-all-boot-device') + if device_order is not None: + commands.append('rearrange-boot-device %s:%s' % (device_name, device_order)) + + success, output = self.run_commands( + commands + ) + + if not success: + self.log.error( + 'create_boot_device', + 'Failed to set boot order' + ) + return False + + self.log.debug( + 'create_boot_device', + output + ) + + return True + + def delete_boot_device(self, device_name): + commands = [] + commands.append('top') + commands.append('scope bios') + commands.append('remove-boot-device %s' % (device_name)) + + success, output = self.run_commands( + commands + ) + + if not success: + self.log.error( + 'delete_boot_device', + 'Failed to delete boot order' + ) + return False + + self.log.debug( + 'delete_boot_device', + output + ) + + return True diff --git a/lib/imc/cli/boot/output.py b/lib/imc/cli/boot/output.py new file mode 100644 index 00000000..32803cc1 --- /dev/null +++ b/lib/imc/cli/boot/output.py @@ -0,0 +1,18 @@ +from lib import filter_helper + + +class ImcCliBootOutput(): + def __init__(self): + pass + + def print_imc_boot(self, info): + self.print_list_table( + info, + title='Boot Order' + ) + + def print_imc_boot_device(self, info): + self.print_list_table( + info, + title='Boot Device' + ) diff --git a/lib/imc/cli/cache.py b/lib/imc/cli/cache.py new file mode 100644 index 00000000..baed153f --- /dev/null +++ b/lib/imc/cli/cache.py @@ -0,0 +1,77 @@ +import os +import json +import time + +from lib import file_helper +from lib import log_helper + +from lib.imc import settings + + +class ImcCliCache(): + def __init__(self, endpoint_id, cache_ttl, log_id=None): + self.log = log_helper.Log(log_id=log_id) + self.cache_ttl = cache_ttl + self.cache_endpoint_id = endpoint_id + self.endpoint_settings_handler = settings.ImcEndpointSettings(log_id=log_id) + + def get_icm_cli_cache_entry(self, cache_entry_name): + if self.cache_ttl < 0: + return None + + directory_name = self.endpoint_settings_handler.get_endpoint_directory( + self.cache_endpoint_id + ) + + filename = os.path.join( + directory_name, + 'cli_%s' % (cache_entry_name) + ) + + cache_entry = file_helper.get_file_json( + filename + ) + if cache_entry is None: + return None + + for key in ['data', 'timestamp']: + if key not in cache_entry: + self.log.error('get_icm_cli_cache_entry', 'Invalid cache content: %s' % (filename)) + return None + + if self.cache_ttl > 0: + entry_ttl = int(time.time()) - cache_entry['timestamp'] + if entry_ttl > self.cache_ttl: + return None + + return cache_entry['data'] + + def set_imc_cli_cache_entry(self, cache_entry_name, data): + directory_name = self.endpoint_settings_handler.get_endpoint_directory( + self.cache_endpoint_id + ) + + if not os.path.isdir(directory_name): + os.makedirs( + directory_name, + exist_ok=True + ) + + filename = os.path.join( + directory_name, + 'cli_%s' % (cache_entry_name) + ) + + content = {} + content['timestamp'] = int(time.time()) + content['data'] = data + + success = file_helper.set_file_json( + filename, + content + ) + if not success: + self.log.error('set_imc_cli_cache_entry', 'Cache set failed: %s' % (filename)) + return False + + return True diff --git a/lib/imc/cli/chassis/__init__.py b/lib/imc/cli/chassis/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/chassis/main.py b/lib/imc/cli/chassis/main.py new file mode 100644 index 00000000..36e7c39e --- /dev/null +++ b/lib/imc/cli/chassis/main.py @@ -0,0 +1,92 @@ +import json + + +class ImcCliChassis(): + def __init__(self): + self.chassis_mo = None + + def get_chassis_mo(self, cache_enabled=True): + if cache_enabled: + if self.chassis_mo is not None: + return self.chassis_mo + + self.chassis_mo = self.get_icm_cli_cache_entry( + 'chassis' + ) + if self.chassis_mo is not None: + return self.chassis_mo + + # Chassis: + # Power: on + # Serial Number: WMP24040061 + # Product Name: UCS C220 M5SX + # PID : UCSC-C220-M5SX + # UUID: B947D1F9-F0A0-4D6F-AF63-16A48DD0A96E + # Locator LED: off + # Description: comp-7-p2b-eu-spdc-WMP24040061 + # Asset Tag: 022C32A + # Post Completion Status: Completed + + self.chassis_mo = self.show_dict( + 'show chassis detail', + start='Chassis:' + ) + + if self.chassis_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'chassis', + self.chassis_mo + ) + + self.log.debug( + 'get_chassis_mo', + json.dumps(self.chassis_mo, indent=4) + ) + return self.chassis_mo + + def get_chassis_info(self, chassis_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in chassis_mo: + info[key] = chassis_mo[key] + + self.log.debug( + 'get_chassis_info', + json.dumps(info, indent=4) + ) + return info + + def get_chassis(self, version_info=True, cache_enabled=True): + chassis_mo = self.get_chassis_mo(cache_enabled=cache_enabled) + if chassis_mo is None: + return None + + chassis_info = self.get_chassis_info( + chassis_mo + ) + + if version_info: + version = self.get_version( + cache_enabled=cache_enabled + ) + if version is not None: + chassis_info['Firmware Version'] = version['Firmware Version'] + + return chassis_info + + def power_cycle(self): + commands = [] + commands.append('top') + commands.append('scope chassis') + commands.append('power cycle') + + success, output = self.run_commands( + commands, + continue_prompt=True + ) + + return success diff --git a/lib/imc/cli/chassis/output.py b/lib/imc/cli/chassis/output.py new file mode 100644 index 00000000..d5c24c7b --- /dev/null +++ b/lib/imc/cli/chassis/output.py @@ -0,0 +1,15 @@ +class ImcCliChassisOutput(): + def __init__(self): + pass + + def print_imc_chassis(self, info): + self.print_list_dict( + info, + 'Chassis' + ) + + def print_imc_chassis_compare(self, info): + self.print_compare( + info, + 'Chassis' + ) diff --git a/lib/imc/cli/command.py b/lib/imc/cli/command.py new file mode 100644 index 00000000..8cf3e694 --- /dev/null +++ b/lib/imc/cli/command.py @@ -0,0 +1,330 @@ +import time + +from lib import filter_helper +from lib import ssh + + +class ImcCliCommand(): + def __init__(self, endpoint_ip, endpoint_port, username, password, log_id): + self.ssh_handler = ssh.Ssh( + endpoint_ip, + username, + port=endpoint_port, + password=password, + endpoint_type='cisco', + timeout=30, + log_id=log_id + ) + + self.session = None + self.shell = None + self.prompt = None + + def __del__(self): + if self.session is not None: + self.session.close() + + def is_cli_ready(self): + session = self.ssh_handler.create_session(max_attempts=1) + if session is None: + return False + + try: + chan = session.invoke_shell() + except BaseException: + return False + + session.close() + return True + + def create_session(self, max_attempts=1): + if self.session is not None: + return True + + self.session = self.ssh_handler.create_session(max_attempts=max_attempts) + if self.session is None: + self.log.error( + 'create_session', + 'Session create failed: %s@%s:%s pass:%s' % ( + self.username, + self.endpoint_ip, + self.endpoint_port, + self.password + ) + ) + + return False + + return True + + def set_prompt(self, prompt_sleep=10): + if self.prompt is not None: + return True + + success = True + self.shell = self.session.invoke_shell( + height=1000 + ) + + response = '' + for index in range(0, prompt_sleep): + time.sleep(1) + response = response + self.shell.recv(9999).decode('utf-8') + response = response.strip() + if response.endswith('#'): + break + + try: + self.prompt = None + lines = response.replace('\r\n', '\n').split('\n') + for line in lines: + if len(line) > 0: + self.prompt = line.strip().strip('\n') + + if self.prompt is None: + success = False + self.log.error( + 'set_prompt', + 'Prompt detection failed' + ) + + self.prompt = self.prompt.split('#')[0] + + self.log.debug( + 'set_prompt', + 'Prompt: %s' % (self.prompt) + ) + except BaseException: + success = False + self.prompt = None + self.log.error( + 'set_prompt', + 'Prompt detection failed (traceback)' + ) + + return success + + def run_commands(self, commands, max_attempts=1, prompt_sleep=10, command_sleep=10, continue_prompt=False): + success = True + output = {} + + if not self.create_session(max_attempts=max_attempts): + return False, output + + if not self.set_prompt(prompt_sleep=prompt_sleep): + return False, output + + for command in commands: + self.shell.send(command) + self.shell.send('\n') + + response = '' + for index in range(0, command_sleep): + time.sleep(1) + command_response = self.shell.recv(9999) + if command_response is None: + continue + + response = response + command_response.decode('utf-8').replace('\r\n', '\n') + last_line = response.split('\n')[-1].strip() + if last_line.startswith(self.prompt) and last_line.endswith('#'): + break + + if 'Do you want to continue?[y|N]' in last_line: + self.log.debug( + 'run_commands', + 'Detected confirmation requst: %s' % (last_line) + ) + if continue_prompt: + self.shell.send('y') + self.shell.send('\n') + self.log.debug( + 'run_commands', + 'Confirmation: y' + ) + else: + self.shell.send('N') + self.shell.send('\n') + self.log.debug( + 'run_commands', + 'Confirmation: N' + ) + break + + try: + command_output = [] + for line in response.split('\n'): + line = line.strip() + if line == command: + continue + if line.startswith(self.prompt) and line.endswith('#'): + continue + + command_output.append(line) + + output[command] = '\n'.join(command_output) + + self.log.debug( + 'run_commands', + 'Command successful: %s' % (command) + ) + self.log.debug( + 'run_commands', + output[command] + ) + + except BaseException: + output[command] = None + self.log.error( + 'run_commands', + 'Command failed: %s' % (command) + ) + + return success, output + + def goto_top(self): + self.run_commands(['top']) + + def set_scope(self, scope): + commands = [] + commands.append('top') + for item in scope.split(','): + commands.append('scope %s' % (item)) + self.run_commands(commands) + + def parse_list(self, output, delimiter, item_key, method='all'): + items = [] + item = None + for line in output.split('\n'): + new_section = False + if line.startswith(delimiter): + new_section = True + else: + if '__INDEX__' in delimiter: + (before_index, after_index) = delimiter.split('__INDEX__') + if line.startswith(before_index) and line.endswith(after_index): + try: + middle = int(line[len(before_index):][:-len(after_index)]) + new_section = True + except BaseException: + middle = None + + if new_section: + if item is not None: + items.append( + item + ) + + item = {} + if item_key is not None: + if method == 'all': + item[item_key] = line + if method == 'last word': + item[item_key] = line.split(':')[0].split(' ')[-1] + + continue + + if len(line.split(':')) == 2: + key = line.split(':')[0].strip() + value = line.split(':')[1].strip() + if item is not None: + item[key] = value + + if item is not None: + items.append( + item + ) + + return items + + def parse_dict(self, output, start=None, ignore_keys=None, ignore_start=None): + started = False + if start is None: + started = True + + items = {} + for line in output.split('\n'): + if not started: + if not filter_helper.match_string('%s*' % (start), line.strip()): + continue + started = True + continue + + if len(line.split(':')) == 2: + key = line.split(':')[0].strip() + value = line.split(':')[1].strip() + + if ignore_keys is not None: + ignore = False + for ignore_key in ignore_keys: + if filter_helper.match_string('%s*' % (ignore_key), key): + ignore = True + break + + if ignore: + continue + + if ignore_start is not None: + if filter_helper.match_string('%s*' % (ignore_start), key): + break + + items[key] = value + + return items + + def show_dict(self, command, scope=None, start=None, top=True, ignore_keys=None, ignore_start=None): + commands = [] + if top: + commands.append('top') + + if scope is not None: + for item in scope.split(','): + commands.append('scope %s' % (item)) + + commands.append( + command + ) + + success, output = self.run_commands( + commands + ) + + if not success: + return None + + response = self.parse_dict( + output[command], + start=start, + ignore_keys=ignore_keys, + ignore_start=ignore_start + ) + + return response + + def show_list(self, command, delimiter, key, method='all', scope=None, top=True): + commands = [] + if top: + commands.append('top') + + if scope is not None: + commands.append('scope %s' % (scope)) + + commands.append( + command + ) + + success, output = self.run_commands( + commands + ) + + if not success: + return None + + response = self.parse_list( + output[command], + delimiter, + key, + method=method + ) + + return response diff --git a/lib/imc/cli/cpu/__init__.py b/lib/imc/cli/cpu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/cpu/main.py b/lib/imc/cli/cpu/main.py new file mode 100644 index 00000000..aaf84b47 --- /dev/null +++ b/lib/imc/cli/cpu/main.py @@ -0,0 +1,169 @@ +import json + + +class ImcCliCpu(): + def __init__(self): + self.cpu_mo = None + self.cpu_pid_mo = None + + def get_cpu_mo(self, cache_enabled=True): + if cache_enabled: + if self.cpu_mo is not None: + return self.cpu_mo + + self.cpu_mo = self.get_icm_cli_cache_entry( + 'cpu' + ) + if self.cpu_mo is not None: + return self.cpu_mo + + # Name CPU1: + # Manufacturer: Intel(R) Corporation + # Family: Xeon + # Thread Count : 40 + # Cores : 20 + # Version: Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz + # Speed (Mhz) : 2500 + # Signature: Type 0, Family 6, Model 85, Stepping 7 + # Status: Enabled + # Name CPU2: + # Manufacturer: Intel(R) Corporation + # Family: Xeon + # Thread Count : 40 + # Cores : 20 + # Version: Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz + # Speed (Mhz) : 2500 + # Signature: Type 0, Family 6, Model 85, Stepping 7 + # Status: Enabled + + + self.cpu_mo = self.show_list( + 'show cpu detail', + 'Name', + 'Name', + method='last word', + scope='chassis' + ) + + if self.cpu_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'cpu', + self.cpu_mo + ) + + self.log.debug( + 'get_cpu_mo', + json.dumps(self.cpu_mo, indent=4) + ) + return self.cpu_mo + + def get_cpu_pid_mo(self, cache_enabled=True): + if cache_enabled: + if self.cpu_pid_mo is not None: + return self.cpu_pid_mo + + self.cpu_pid_mo = self.get_icm_cli_cache_entry( + 'cpu_pid' + ) + if self.cpu_pid_mo is not None: + return self.cpu_pid_mo + + # Socket CPU1: + # Description: Intel(R) Xeon(R) Gold 6248 2.50 GHz 150W 20C 27.50MB Cache DDR4 2933MHz 1TB + # Product ID: UCS-CPU-I6248 + # Model: Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz + # Signature: Type 0, Family 6, Model 85, Stepping 7 + # Current Speed: 2500 + # Status: Enabled + + self.cpu_pid_mo = self.show_list( + 'show cpu-pid detail', + 'Socket', + 'Name', + method='last word', + scope='chassis' + ) + + if self.cpu_pid_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'cpu_pid', + self.cpu_pid_mo + ) + + self.log.debug( + 'get_cpu_pid_mo', + json.dumps(self.cpu_pid_mo, indent=4) + ) + return self.cpu_pid_mo + + def get_cpu_info(self, cpu_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in cpu_mo: + info[key] = cpu_mo[key] + + if 'Status' in info: + if info['Status'] == 'Enabled': + info['__Output']['Status'] = 'Green' + else: + info['__Output']['Status'] = 'Red' + + info['__Key'] = 'Name' + info['__Value'] = info[info['__Key']] + + return info + + def get_cpu_pid_info(self, cpu_mo): + info = {} + for key in cpu_mo: + info[key] = cpu_mo[key] + return info + + def get_cpu(self, cache_enabled=True): + cpus_mo = self.get_cpu_mo(cache_enabled=cache_enabled) + if cpus_mo is None: + return None + + cpus_pid_mo = self.get_cpu_pid_mo(cache_enabled=cache_enabled) + if cpus_pid_mo is None: + return None + + cpus_info = [] + + for cpu_mo in cpus_mo: + cpus_info.append( + self.get_cpu_info( + cpu_mo + ) + ) + + keys = [ + 'Description', + 'Product ID', + 'Model' + ] + for cpu_info in cpus_info: + for key in keys: + cpu_info[key] = 'NA' + + for cpu_pid_mo in cpus_pid_mo: + cpu_pid_info = self.get_cpu_pid_info( + cpu_pid_mo + ) + for cpu_info in cpus_info: + if cpu_info['Name'] == cpu_pid_info['Name']: + for key in keys: + cpu_info[key] = cpu_pid_info[key] + + self.log.debug( + 'get_cpu_info', + json.dumps(cpus_info, indent=4) + ) + + return cpus_info diff --git a/lib/imc/cli/cpu/output.py b/lib/imc/cli/cpu/output.py new file mode 100644 index 00000000..0a9674cc --- /dev/null +++ b/lib/imc/cli/cpu/output.py @@ -0,0 +1,16 @@ +class ImcCliCpuOutput(): + def __init__(self): + pass + + def print_imc_cpu(self, info): + self.print_list_dict( + info, + 'CPU', + allow_order_subkeys=False + ) + + def print_imc_cpu_compare(self, info): + self.print_compare( + info, + 'CPU' + ) diff --git a/lib/imc/cli/dimm/__init__.py b/lib/imc/cli/dimm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/dimm/main.py b/lib/imc/cli/dimm/main.py new file mode 100644 index 00000000..adf58cab --- /dev/null +++ b/lib/imc/cli/dimm/main.py @@ -0,0 +1,168 @@ +import json + + +class ImcCliDimm(): + def __init__(self): + self.dimm_mo = None + self.dimm_pid_mo = None + + def get_dimm_mo(self, cache_enabled=True): + if cache_enabled: + if self.dimm_mo is not None: + return self.dimm_mo + + self.dimm_mo = self.get_icm_cli_cache_entry( + 'dimm' + ) + if self.dimm_mo is not None: + return self.dimm_mo + + # Name DIMM_L1: + # Capacity: 32768 MB + # Channel Speed (MHz): 2933 + # Channel Type: DDR4 + # Memory Type Detail: Synchronous Registered (Buffered) + # Bank Locator: NODE 1 CHANNEL 4 DIMM 0 + # Visibility: Yes + # Operability: Operable + # Manufacturer: 0x2C00 + # Part Number: 36ASF4G72PZ-2G9E2 + # Serial Number: F0F73494 + # Asset Tag: 252006 (Mfg Location:0x25, Mfg Year:20, Mfg Week:06) + # Data Width: 64 bits + + self.dimm_mo = self.show_list( + 'show dimm detail', + 'Name', + 'Name', + method='last word', + scope='chassis' + ) + + if self.dimm_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'dimm', + self.dimm_mo + ) + + self.log.debug( + 'get_dimm_mo', + json.dumps(self.dimm_mo, indent=4) + ) + return self.dimm_mo + + def get_dimm_pid_mo(self, cache_enabled=True): + if cache_enabled: + if self.dimm_pid_mo is not None: + return self.dimm_pid_mo + + self.dimm_pid_mo = self.get_icm_cli_cache_entry( + 'dimm_pid' + ) + if self.dimm_pid_mo is not None: + return self.dimm_pid_mo + + # Name DIMM_M1: + # Description: 32GB DDR4-2933-MHz RDIMM/2Rx4/1.2v + # Product ID: UCS-MR-X32G2RT-H + # Vendor ID: 0xCE00 + # Vendor Name: Samsung + # Model: M393A4K40CB2-CVF + # SerialNumber: 120AD606 + # Operability: Operable + # Capacity: 32768 MB + # Speed: 2933 + # Data Width: 64 bits + + self.dimm_pid_mo = self.show_list( + 'show dimm-pid detail', + 'Name', + 'Name', + method='last word', + scope='chassis' + ) + + if self.dimm_pid_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'dimm_pid', + self.dimm_pid_mo + ) + self.log.debug( + 'get_dimm_pid_mo', + json.dumps(self.dimm_pid_mo, indent=4) + ) + return self.dimm_pid_mo + + def get_dimm_info(self, dimm_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in dimm_mo: + info[key] = dimm_mo[key] + + if 'Operability' in info: + if info['Operability'] == 'Operable': + info['__Output']['Operability'] = 'Green' + else: + info['__Output']['Operability'] = 'Red' + + info['__Key'] = 'Name' + info['__Value'] = info[info['__Key']] + + return info + + def get_dimm_pid_info(self, dimm_mo): + info = {} + for key in dimm_mo: + info[key] = dimm_mo[key] + return info + + def get_dimm(self, cache_enabled=True): + dimms_mo = self.get_dimm_mo(cache_enabled=cache_enabled) + if dimms_mo is None: + return None + + dimms_pid_mo = self.get_dimm_pid_mo(cache_enabled=cache_enabled) + if dimms_pid_mo is None: + return None + + dimms_info = [] + + for dimm_mo in dimms_mo: + dimms_info.append( + self.get_dimm_info( + dimm_mo + ) + ) + + keys = [ + 'Description', + 'Product ID', + 'Vendor ID', + 'Vendor Name', + 'Model' + ] + for dimm_info in dimms_info: + for key in keys: + dimm_info[key] = 'NA' + + for dimm_pid_mo in dimms_pid_mo: + dimm_pid_info = self.get_dimm_pid_info( + dimm_pid_mo + ) + for dimm_info in dimms_info: + if dimm_info['Name'] == dimm_pid_info['Name']: + for key in keys: + dimm_info[key] = dimm_pid_info[key] + + self.log.debug( + 'get_dimm_info', + json.dumps(dimms_info, indent=4) + ) + + return dimms_info diff --git a/lib/imc/cli/dimm/output.py b/lib/imc/cli/dimm/output.py new file mode 100644 index 00000000..3e772585 --- /dev/null +++ b/lib/imc/cli/dimm/output.py @@ -0,0 +1,10 @@ +class ImcCliDimmOutput(): + def __init__(self): + pass + + def print_imc_dimm(self, info): + self.print_list_dict( + info, + 'DIMM', + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/endpoint.py b/lib/imc/cli/endpoint.py new file mode 100644 index 00000000..bf5a85a8 --- /dev/null +++ b/lib/imc/cli/endpoint.py @@ -0,0 +1,135 @@ +from lib import log_helper + +from lib.imc.cli.cache import ImcCliCache +from lib.imc.cli.command import ImcCliCommand + +from lib.imc.cli.adapter.main import ImcCliAdapter +from lib.imc.cli.admin.main import ImcCliAdmin +from lib.imc.cli.bbu.main import ImcCliBbu +from lib.imc.cli.bios.main import ImcCliBios +from lib.imc.cli.boot.main import ImcCliBoot +from lib.imc.cli.chassis.main import ImcCliChassis +from lib.imc.cli.cpu.main import ImcCliCpu +from lib.imc.cli.dimm.main import ImcCliDimm +from lib.imc.cli.fault.main import ImcCliFault +from lib.imc.cli.flex.main import ImcCliFlex +from lib.imc.cli.fw.main import ImcCliFw +from lib.imc.cli.hardware.main import ImcCliHardware +from lib.imc.cli.hdd.main import ImcCliHdd +from lib.imc.cli.http.main import ImcCliHttp +from lib.imc.cli.ip.main import ImcCliIp +from lib.imc.cli.ipmi.main import ImcCliIpmi +from lib.imc.cli.kvm.main import ImcCliKvm +from lib.imc.cli.led.main import ImcCliLed +from lib.imc.cli.memory.main import ImcCliMemory +from lib.imc.cli.net.main import ImcCliNet +from lib.imc.cli.ntp.main import ImcCliNtp +from lib.imc.cli.pci.main import ImcCliPci +from lib.imc.cli.psu.main import ImcCliPsu +from lib.imc.cli.redfish.main import ImcCliRedfish +from lib.imc.cli.sel.main import ImcCliSel +from lib.imc.cli.sensor.main import ImcCliSensor +from lib.imc.cli.smtp.main import ImcCliSmtp +from lib.imc.cli.snmp.main import ImcCliSnmp +from lib.imc.cli.sol.main import ImcCliSol +from lib.imc.cli.ssh.main import ImcCliSsh +from lib.imc.cli.storageadapter.main import ImcCliStorageAdapter +from lib.imc.cli.syslog.main import ImcCliSyslog +from lib.imc.cli.tpm.main import ImcCliTpm +from lib.imc.cli.user import ImcCliUser +from lib.imc.cli.utilization.main import ImcCliUtilization +from lib.imc.cli.version.main import ImcCliVersion +from lib.imc.cli.vmedia.main import ImcCliVmedia +from lib.imc.cli.xml.main import ImcCliXml + + +class ImcCliEndpoint( + ImcCliCache, + ImcCliCommand, + ImcCliAdapter, + ImcCliAdmin, + ImcCliBbu, + ImcCliBios, + ImcCliBoot, + ImcCliChassis, + ImcCliCpu, + ImcCliDimm, + ImcCliFault, + ImcCliFlex, + ImcCliFw, + ImcCliHardware, + ImcCliHdd, + ImcCliHttp, + ImcCliIp, + ImcCliIpmi, + ImcCliKvm, + ImcCliLed, + ImcCliMemory, + ImcCliNet, + ImcCliNtp, + ImcCliPci, + ImcCliPsu, + ImcCliRedfish, + ImcCliSel, + ImcCliSensor, + ImcCliSmtp, + ImcCliSnmp, + ImcCliSol, + ImcCliSsh, + ImcCliStorageAdapter, + ImcCliSyslog, + ImcCliTpm, + ImcCliUser, + ImcCliUtilization, + ImcCliVersion, + ImcCliVmedia, + ImcCliXml + ): + def __init__(self, endpoint_ip, endpoint_port, username, password, cache_ttl=600, log_id=None): + ImcCliCache.__init__(self, endpoint_ip, cache_ttl, log_id=log_id) + ImcCliCommand.__init__(self, endpoint_ip, endpoint_port, username, password, log_id) + + ImcCliAdapter.__init__(self) + ImcCliAdmin.__init__(self) + ImcCliBbu.__init__(self) + ImcCliBios.__init__(self) + ImcCliBoot.__init__(self) + ImcCliChassis.__init__(self) + ImcCliCpu.__init__(self) + ImcCliDimm.__init__(self) + ImcCliFault.__init__(self) + ImcCliFlex.__init__(self) + ImcCliFw.__init__(self) + ImcCliHardware.__init__(self) + ImcCliHdd.__init__(self) + ImcCliHttp.__init__(self) + ImcCliIp.__init__(self) + ImcCliIpmi.__init__(self) + ImcCliKvm.__init__(self) + ImcCliLed.__init__(self) + ImcCliMemory.__init__(self) + ImcCliNet.__init__(self) + ImcCliNtp.__init__(self) + ImcCliPci.__init__(self) + ImcCliPsu.__init__(self) + ImcCliRedfish.__init__(self) + ImcCliSel.__init__(self) + ImcCliSensor.__init__(self) + ImcCliSmtp.__init__(self) + ImcCliSnmp.__init__(self) + ImcCliSol.__init__(self) + ImcCliSsh.__init__(self) + ImcCliStorageAdapter.__init__(self) + ImcCliSyslog.__init__(self) + ImcCliTpm.__init__(self) + ImcCliUser.__init__(self) + ImcCliUtilization.__init__(self) + ImcCliVersion.__init__(self) + ImcCliVmedia.__init__(self) + ImcCliXml.__init__(self) + + self.log = log_helper.Log(log_id=log_id) + self.endpoint_ip = endpoint_ip + self.endpoint_port = endpoint_port + self.username = username + self.password = password diff --git a/lib/imc/cli/fault/__init__.py b/lib/imc/cli/fault/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/fault/main.py b/lib/imc/cli/fault/main.py new file mode 100644 index 00000000..bfde9453 --- /dev/null +++ b/lib/imc/cli/fault/main.py @@ -0,0 +1,207 @@ +import json + + +class ImcCliFault(): + def __init__(self): + self.fault_mo = None + self.fault_filter_mo = None + self.fault_entry_mo = None + + def get_fault_mo(self, cache_enabled=True): + if cache_enabled: + if self.fault_mo is not None: + return self.fault_mo + + self.fault_mo = self.get_icm_cli_cache_entry( + 'fault' + ) + if self.fault_mo is not None: + return self.fault_mo + + # PEF Setting: + # Platform Event Enabled: yes + + self.fault_mo = self.show_dict( + 'show detail', + start='PEF Settings:', + scope='fault' + ) + + if self.fault_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'fault', + self.fault_mo + ) + + self.log.debug( + 'get_fault_mo', + json.dumps(self.fault_mo, indent=4) + ) + return self.fault_mo + + def get_fault_filter_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.fault_filter_mo is not None: + return self.fault_filter_mo + + self.fault_filter_mo = self.get_icm_cli_cache_entry( + 'fault_filter' + ) + if self.fault_filter_mo is not None: + return self.fault_filter_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /fault # show pef detail + # Platform Event Filter 1: + # Event: Temperature Critical Assert Filter + # Action: none + + if keep_scope: + self.fault_filter_mo = self.show_list( + 'show pef detail', + 'Platform Event Filter __INDEX__:', + None, + method='last word', + top=False + ) + else: + self.fault_filter_mo = self.show_list( + 'show pef detail', + 'Platform Event Filter __INDEX__:', + None, + method='last word', + scope='fault' + ) + + if self.fault_filter_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'fault_filter', + self.fault_filter_mo + ) + + self.log.debug( + 'get_fault_filter_mo', + json.dumps(self.fault_filter_mo, indent=4) + ) + return self.fault_filter_mo + + def get_fault_entry_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.fault_entry_mo is not None: + return self.fault_entry_mo + + self.fault_entry_mo = self.get_icm_cli_cache_entry( + 'fault_entry' + ) + if self.fault_entry_mo is not None: + return self.fault_entry_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /fault # show fault-entries detail + # Fault Engine Log: + # Time: 2024-04-07T13:48:40 + # Severity: info + # Fault DN: sys/rack-unit-1/mgmt/log-SEL-0/fault-F0462 + # Code: F0462 + # DN: sys/rack-unit-1/mgmt/log-SEL-0 + # Cause: log-capacity + # Description: "CSCO_SEL_FULNESS: System Event log is Full: Clear the log" + + if keep_scope: + self.fault_entry_mo = self.show_list( + 'show fault-entries detail', + 'Fault Engine Log:', + None, + method='last word', + top=False + ) + else: + self.fault_entry_mo = self.show_list( + 'show fault-entries detail', + 'Fault Engine Log:', + None, + method='last word', + scope='fault' + ) + + if self.fault_entry_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'fault_entry', + self.fault_entry_mo + ) + + self.log.debug( + 'get_fault_entry_mo', + json.dumps(self.fault_entry_mo, indent=4) + ) + return self.fault_entry_mo + + def get_fault_info(self, fault_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in fault_mo: + info[key] = fault_mo[key] + + return info + + def get_fault_filter_info(self, fault_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in fault_mo: + info[key] = fault_mo[key] + + return info + + def get_fault_entry_info(self, fault_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in fault_mo: + info[key] = fault_mo[key] + + return info + + def get_fault(self, cache_enabled=True): + fault_mo = self.get_fault_mo(cache_enabled=cache_enabled) + if fault_mo is None: + return None + + fault_info = self.get_fault_info( + fault_mo + ) + + fault_info['Platform Event Filter'] = [] + fault_filter_mo = self.get_fault_filter_mo(keep_scope=True, cache_enabled=cache_enabled) + if fault_filter_mo is not None: + for server_mo in fault_filter_mo: + fault_info['Platform Event Filter'].append( + self.get_fault_filter_info( + server_mo + ) + ) + + fault_info['Fault'] = [] + fault_entry_mo = self.get_fault_entry_mo(keep_scope=True, cache_enabled=cache_enabled) + if fault_entry_mo is not None: + for user_mo in fault_entry_mo: + fault_info['Fault'].append( + self.get_fault_entry_info( + user_mo + ) + ) + + self.log.debug( + 'get_fault_info', + json.dumps(fault_info, indent=4) + ) + + return fault_info diff --git a/lib/imc/cli/fault/output.py b/lib/imc/cli/fault/output.py new file mode 100644 index 00000000..8629b454 --- /dev/null +++ b/lib/imc/cli/fault/output.py @@ -0,0 +1,9 @@ +class ImcCliFaultOutput(): + def __init__(self): + pass + + def print_imc_fault(self, info): + self.print_list_dict( + info, + 'Fault' + ) diff --git a/lib/imc/cli/flex/__init__.py b/lib/imc/cli/flex/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/flex/main.py b/lib/imc/cli/flex/main.py new file mode 100644 index 00000000..0fcf0f89 --- /dev/null +++ b/lib/imc/cli/flex/main.py @@ -0,0 +1,70 @@ +import json + + +class ImcCliFlex(): + def __init__(self): + self.flex_mo = None + + def get_flex_mo(self, cache_enabled=True): + if cache_enabled: + if self.flex_mo is not None: + return self.flex_mo + + self.flex_mo = self.get_icm_cli_cache_entry( + 'flex' + ) + if self.flex_mo is not None: + return self.flex_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /chassis # show flexutil detail + # Controller Flexutil: + # Product Name: Cisco Flexutil + # Internal State: Failed + # Controller Status: Card is Absent + # Physical Drive Count: 0 + # Virtual Drive Count: 0 + + self.flex_mo = self.show_dict( + 'show flexutil detail', + start='Controller Flexutil:', + scope='chassis' + ) + + if self.flex_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'flex', + self.flex_mo + ) + + self.log.debug( + 'get_flex_mo', + json.dumps(self.flex_mo, indent=4) + ) + return self.flex_mo + + def get_flex_info(self, flex_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in flex_mo: + info[key] = flex_mo[key] + + self.log.debug( + 'get_flex_info', + json.dumps(info, indent=4) + ) + return info + + def get_flex(self, cache_enabled=True): + flex_mo = self.get_flex_mo(cache_enabled=cache_enabled) + if flex_mo is None: + return None + + flex_info = self.get_flex_info( + flex_mo + ) + + return flex_info diff --git a/lib/imc/cli/flex/output.py b/lib/imc/cli/flex/output.py new file mode 100644 index 00000000..c08ce177 --- /dev/null +++ b/lib/imc/cli/flex/output.py @@ -0,0 +1,15 @@ +class ImcCliFlexOutput(): + def __init__(self): + pass + + def print_imc_flex(self, info): + self.print_list_dict( + info, + 'Flexutil Controller' + ) + + def print_imc_flex_compare(self, info): + self.print_compare( + info, + 'Flexutil Controller' + ) diff --git a/lib/imc/cli/fw/__init__.py b/lib/imc/cli/fw/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/fw/main.py b/lib/imc/cli/fw/main.py new file mode 100644 index 00000000..78063cd4 --- /dev/null +++ b/lib/imc/cli/fw/main.py @@ -0,0 +1,74 @@ +import json + + +class ImcCliFw(): + def __init__(self): + self.fw_mo = None + + def get_fw_mo(self, cache_enabled=True): + if cache_enabled: + if self.fw_mo is not None: + return self.fw_mo + + self.fw_mo = self.get_icm_cli_cache_entry( + 'fw' + ) + if self.fw_mo is not None: + return self.fw_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc # show firmware detail + # Firmware Image Information: + # Update Stage: NONE + # Update Progress: 0 + # Current FW Version: 4.2(2a) + # FW Image 1 Version: 4.2(2a) + # FW Image 1 State: RUNNING ACTIVATED + # FW Image 2 Version: 4.1(3d) + # FW Image 2 State: BACKUP INACTIVATED + # Boot-loader Version: 4.2(2a) + # Secure Boot: ENABLED + + self.fw_mo = self.show_dict( + 'show firmware detail', + start='Firmware Image Information:', + scope='cimc' + ) + + if self.fw_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'fw', + self.fw_mo + ) + + self.log.debug( + 'get_fw_mo', + json.dumps(self.fw_mo, indent=4) + ) + return self.fw_mo + + def get_fw_info(self, fw_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in fw_mo: + info[key] = fw_mo[key] + + self.log.debug( + 'get_fw_info', + json.dumps(info, indent=4) + ) + return info + + def get_fw(self, cache_enabled=True): + fw_mo = self.get_fw_mo(cache_enabled=cache_enabled) + if fw_mo is None: + return None + + fw_info = self.get_fw_info( + fw_mo + ) + + return fw_info diff --git a/lib/imc/cli/fw/output.py b/lib/imc/cli/fw/output.py new file mode 100644 index 00000000..b9a2eb1b --- /dev/null +++ b/lib/imc/cli/fw/output.py @@ -0,0 +1,15 @@ +class ImcCliFwOutput(): + def __init__(self): + pass + + def print_imc_fw(self, info): + self.print_list_dict( + info, + 'Firmware' + ) + + def print_imc_fw_compare(self, info): + self.print_compare( + info, + 'Firmware' + ) diff --git a/lib/imc/cli/hardware/__init__.py b/lib/imc/cli/hardware/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/hardware/main.py b/lib/imc/cli/hardware/main.py new file mode 100644 index 00000000..51dd654b --- /dev/null +++ b/lib/imc/cli/hardware/main.py @@ -0,0 +1,61 @@ +class ImcCliHardware(): + def __init__(self): + pass + + def get_hardware( + self, + all_info=False, + bbu_info=False, + cpu_info=False, + dimm_info=False, + flex_info=False, + hdd_info=False, + memory_info=False, + net_info=False, + pci_info=False, + psu_info=False, + sc_info=False, + tpm_info=False, + vic_info=False, + cache_enabled=True + ): + info = {} + info['endpoint_ip'] = self.endpoint_ip + + if all_info or bbu_info: + info['bbu'] = self.get_bbu(cache_enabled=cache_enabled) + + if all_info or cpu_info: + info['cpu'] = self.get_cpu(cache_enabled=cache_enabled) + + if all_info or dimm_info: + info['dimm'] = self.get_dimm(cache_enabled=cache_enabled) + + if all_info or hdd_info: + info['hdd'] = self.get_hdd(cache_enabled=cache_enabled) + + if all_info or flex_info: + info['flex'] = self.get_flex(cache_enabled=cache_enabled) + + if all_info or memory_info: + info['memory'] = self.get_memory(cache_enabled=cache_enabled) + + if all_info or net_info: + info['net'] = self.get_net(cache_enabled=cache_enabled) + + if all_info or pci_info: + info['pci'] = self.get_pci(cache_enabled=cache_enabled) + + if all_info or psu_info: + info['psu'] = self.get_psu(cache_enabled=cache_enabled) + + if all_info or sc_info: + info['sc'] = self.get_storage_adapter(cache_enabled=cache_enabled) + + if all_info or tpm_info: + info['tpm'] = self.get_tpm(cache_enabled=cache_enabled) + + if all_info or vic_info: + info['vic'] = self.get_adapter(cache_enabled=cache_enabled) + + return info diff --git a/lib/imc/cli/hardware/output.py b/lib/imc/cli/hardware/output.py new file mode 100644 index 00000000..aab5cf4d --- /dev/null +++ b/lib/imc/cli/hardware/output.py @@ -0,0 +1,47 @@ +class ImcCliHardwareOutput(): + def __init__(self): + pass + + def print_imc_hardware(self, info): + for item in info: + self.my_output.default( + 'Endpoint: %s' % (item['endpoint_ip']), + before_newline=True, + underline=True + ) + + if 'cpu' in item: + self.print_imc_cpu(item['cpu']) + + if 'memory' in item: + self.print_imc_memory(item['memory']) + + if 'dimm' in item: + self.print_imc_dimm(item['dimm']) + + if 'sc' in item: + self.print_imc_storage_adapter(item['sc']) + + if 'bbu' in item: + self.print_imc_bbu(item['bbu']) + + if 'hdd' in item: + self.print_imc_hdd(item['hdd']) + + if 'flex' in item: + self.print_imc_flex(item['flex']) + + if 'pci' in item: + self.print_imc_pci(item['pci']) + + if 'net' in item: + self.print_imc_net(item['net']) + + if 'vic' in item: + self.print_imc_adapter(item['vic']) + + if 'tpm' in item: + self.print_imc_tpm(item['tpm']) + + if 'psu' in item: + self.print_imc_psu(item['psu']) diff --git a/lib/imc/cli/hdd/__init__.py b/lib/imc/cli/hdd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/hdd/main.py b/lib/imc/cli/hdd/main.py new file mode 100644 index 00000000..aacab5d5 --- /dev/null +++ b/lib/imc/cli/hdd/main.py @@ -0,0 +1,159 @@ +import json + + +class ImcCliHdd(): + def __init__(self): + self.hdd_mo = None + self.hdd_pid_mo = None + + def get_hdd_mo(self, cache_enabled=True): + if cache_enabled: + if self.hdd_mo is not None: + return self.hdd_mo + + self.hdd_mo = self.get_icm_cli_cache_entry( + 'hdd' + ) + if self.hdd_mo is not None: + return self.hdd_mo + + # Name HDD1_STATUS: + # Status : absent + # LocateLEDStatus : TurnOFF + + self.hdd_mo = self.show_list( + 'show hdd detail', + 'Name', + 'Name', + method='last word', + scope='chassis' + ) + + if self.hdd_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'hdd', + self.hdd_mo + ) + + self.log.debug( + 'get_hdd_mo', + json.dumps(self.hdd_mo, indent=4) + ) + return self.hdd_mo + + def get_hdd_pid_mo(self, cache_enabled=True): + if cache_enabled: + if self.hdd_pid_mo is not None: + return self.hdd_pid_mo + + self.hdd_pid_mo = self.get_icm_cli_cache_entry( + 'hdd_pid' + ) + if self.hdd_pid_mo is not None: + return self.hdd_pid_mo + + # Disk 3: + # Controller: MRAID + # Description: 1.2TB 12G SAS 10K RPM SFF HDD + # Product ID: UCS-HD12TB10K12N + # Vendor: TOSHIBA + # Model: AL15SEB120N + # SerialNumber: Z820A08VFJRG + + self.hdd_pid_mo = self.show_list( + 'show hdd-pid detail', + 'Disk', + 'Id', + method='last word', + scope='chassis' + ) + + if self.hdd_pid_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'hdd_pid', + self.hdd_pid_mo + ) + + self.log.debug( + 'get_hdd_pid_mo', + json.dumps(self.hdd_pid_mo, indent=4) + ) + return self.hdd_pid_mo + + def get_hdd_info(self, hdd_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in hdd_mo: + info[key] = hdd_mo[key] + + info['Name'] = info['Name'].split('_STATUS')[0] + info['Id'] = info['Name'].split('HDD')[1] + + if 'Operability' in info: + if info['Operability'] == 'Operable': + info['__Output']['Operability'] = 'Green' + else: + info['__Output']['Operability'] = 'Red' + + info['__Key'] = 'Name' + info['__Value'] = info[info['__Key']] + + return info + + def get_hdd_pid_info(self, hdd_mo): + info = {} + for key in hdd_mo: + info[key] = hdd_mo[key] + return info + + def get_hdd(self, cache_enabled=True): + hdds_mo = self.get_hdd_mo(cache_enabled=cache_enabled) + if hdds_mo is None: + return None + + hdds_pid_mo = self.get_hdd_pid_mo(cache_enabled=cache_enabled) + if hdds_pid_mo is None: + return None + + hdds_info = [] + + for hdd_mo in hdds_mo: + hdds_info.append( + self.get_hdd_info( + hdd_mo + ) + ) + + keys = [ + 'Controller', + 'Description', + 'Product ID', + 'Vendor', + 'Model', + 'SerialNumber' + ] + for hdd_info in hdds_info: + for key in keys: + hdd_info[key] = '' + + for hdd_pid_mo in hdds_pid_mo: + hdd_pid_info = self.get_hdd_pid_info( + hdd_pid_mo + ) + for hdd_info in hdds_info: + if hdd_info['Id'] == hdd_pid_info['Id']: + for key in keys: + hdd_info[key] = hdd_pid_info[key] + + self.log.debug( + 'get_hdd_info', + json.dumps(hdds_info, indent=4) + ) + + return hdds_info diff --git a/lib/imc/cli/hdd/output.py b/lib/imc/cli/hdd/output.py new file mode 100644 index 00000000..82b1d9e2 --- /dev/null +++ b/lib/imc/cli/hdd/output.py @@ -0,0 +1,10 @@ +class ImcCliHddOutput(): + def __init__(self): + pass + + def print_imc_hdd(self, info): + self.print_list_dict( + info, + 'HDD', + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/http/__init__.py b/lib/imc/cli/http/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/http/main.py b/lib/imc/cli/http/main.py new file mode 100644 index 00000000..57ccc87b --- /dev/null +++ b/lib/imc/cli/http/main.py @@ -0,0 +1,72 @@ +import json + + +class ImcCliHttp(): + def __init__(self): + self.http_mo = None + + def get_http_mo(self, cache_enabled=True): + if cache_enabled: + if self.http_mo is not None: + return self.http_mo + + self.http_mo = self.get_icm_cli_cache_entry( + 'http' + ) + if self.http_mo is not None: + return self.http_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show http detail + # HTTP Settings: + # HTTP Port: 80 + # HTTPS Port: 443 + # Timeout: 10800 + # Max Sessions: 4 + # Active Sessions: 0 + # HTTPS Enabled: yes + # HTTP Redirected: yes + # HTTP Enabled: yes + + self.http_mo = self.show_dict( + 'show http detail', + start='HTTP Settings:' + ) + + if self.http_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'http', + self.http_mo + ) + + self.log.debug( + 'get_http_mo', + json.dumps(self.http_mo, indent=4) + ) + return self.http_mo + + def get_http_info(self, http_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in http_mo: + info[key] = http_mo[key] + + self.log.debug( + 'get_http_info', + json.dumps(info, indent=4) + ) + return info + + def get_http(self, cache_enabled=True): + http_mo = self.get_http_mo(cache_enabled=cache_enabled) + if http_mo is None: + return None + + http_info = self.get_http_info( + http_mo + ) + + return http_info diff --git a/lib/imc/cli/http/output.py b/lib/imc/cli/http/output.py new file mode 100644 index 00000000..8a28c450 --- /dev/null +++ b/lib/imc/cli/http/output.py @@ -0,0 +1,12 @@ +class ImcCliHttpOutput(): + def __init__(self): + pass + + def print_imc_http(self, info): + self.print_list_dict( + info, + 'HTTP', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/ip/__init__.py b/lib/imc/cli/ip/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/ip/main.py b/lib/imc/cli/ip/main.py new file mode 100644 index 00000000..8179fbc7 --- /dev/null +++ b/lib/imc/cli/ip/main.py @@ -0,0 +1,290 @@ +import json + + +class ImcCliIp(): + def __init__(self): + self.network_mo = None + self.icmp_mo = None + self.blocking_mo = None + self.filtering_mo = None + + def get_network_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.network_mo is not None: + return self.network_mo + + self.network_mo = self.get_icm_cli_cache_entry( + 'network' + ) + if self.network_mo is not None: + return self.network_mo + + # hostname /cimc # show network detail + # Network Setting: + # IPv4 Enabled: yes + # IPv4 Address: + # IPv4 Netmask: + + if keep_scope: + self.network_mo = self.show_dict( + 'show detail', + start='Network Setting:', + top=False + ) + else: + self.network_mo = self.show_dict( + 'show detail', + start='Network Setting:', + scope='cimc,network' + ) + + if self.network_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'network', + self.network_mo + ) + + self.log.debug( + 'get_network_mo', + json.dumps(self.network_mo, indent=4) + ) + return self.network_mo + + def get_network_info(self, network_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in network_mo: + info[key] = network_mo[key] + + self.log.debug( + 'get_network_info', + json.dumps(info, indent=4) + ) + return info + + def get_icmp_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.icmp_mo is not None: + return self.icmp_mo + + self.icmp_mo = self.get_icm_cli_cache_entry( + 'icmp' + ) + if self.icmp_mo is not None: + return self.icmp_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc/network # show icmp-configuration detail + # ICMP Settings: + # Destination Unreachable Enabled: no + # Redirect Enabled: no + + if keep_scope: + self.icmp_mo = self.show_dict( + 'show icmp-configuration detail', + start='ICMP Settings', + top=False + ) + else: + self.icmp_mo = self.show_dict( + 'show icmp-configuration detail', + start='ICMP Settings', + scope='cimc,network' + ) + + if self.icmp_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'icmp', + self.icmp_mo + ) + + self.log.debug( + 'get_icmp_mo', + json.dumps(self.icmp_mo, indent=4) + ) + return self.icmp_mo + + def get_icmp_info(self, icmp_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in icmp_mo: + info[key] = icmp_mo[key] + + self.log.debug( + 'get_icmp_info', + json.dumps(info, indent=4) + ) + return info + + def get_blocking_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.blocking_mo is not None: + return self.blocking_mo + + self.blocking_mo = self.get_icm_cli_cache_entry( + 'blocking' + ) + if self.blocking_mo is not None: + return self.blocking_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc/network # show ipblocking detail + # IP Blocking Setting: + # Enabled: no + # Fail Count: 3 + # Fail Window: 90 + # Blocking Time: 300 + + if keep_scope: + self.blocking_mo = self.show_dict( + 'show ipblocking detail', + start='IP Blocking Setting:', + top=False + ) + else: + self.blocking_mo = self.show_dict( + 'show ipblocking detail', + start='IP Blocking Setting:', + scope='cimc,network' + ) + + if self.blocking_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'blocking', + self.blocking_mo + ) + + self.log.debug( + 'get_blocking_mo', + json.dumps(self.blocking_mo, indent=4) + ) + return self.blocking_mo + + def get_blocking_info(self, blocking_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in blocking_mo: + info[key] = blocking_mo[key] + + self.log.debug( + 'get_blocking_info', + json.dumps(info, indent=4) + ) + return info + + def get_filtering_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.filtering_mo is not None: + return self.filtering_mo + + self.filtering_mo = self.get_icm_cli_cache_entry( + 'filtering' + ) + if self.filtering_mo is not None: + return self.filtering_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc/network # show ipfiltering detail + # IP Filter Service Settings: + # Enabled: no + # Filter 1: + # Filter 2: + # Filter 3: + # Filter 4: + + if keep_scope: + self.filtering_mo = self.show_dict( + 'show ipfiltering detail', + start='IP Filter Service Settings:', + top=False + ) + else: + self.filtering_mo = self.show_dict( + 'show ipfiltering detail', + start='IP Filter Service Settings:', + scope='cimc,network' + ) + + if self.filtering_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'filtering', + self.filtering_mo + ) + + self.log.debug( + 'get_filtering_mo', + json.dumps(self.filtering_mo, indent=4) + ) + return self.filtering_mo + + def get_filtering_info(self, filtering_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in filtering_mo: + info[key] = filtering_mo[key] + + self.log.debug( + 'get_filtering_info', + json.dumps(info, indent=4) + ) + return info + + def get_ip(self, network_info=False, icmp_info=False, blocking_info=False, filtering_info=False, cache_enabled=True): + ip_info = {} + + self.set_scope('cimc,network') + + if network_info: + network_mo = self.get_network_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if network_mo is not None: + ip_info['network'] = self.get_network_info( + network_mo + ) + + if icmp_info: + icmp_mo = self.get_icmp_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if icmp_mo is not None: + ip_info['icmp'] = self.get_icmp_info( + icmp_mo + ) + + if blocking_info: + blocking_mo = self.get_blocking_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if blocking_mo is not None: + ip_info['blocking'] = self.get_blocking_info( + blocking_mo + ) + + if filtering_info: + filtering_mo = self.get_filtering_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if filtering_mo is not None: + ip_info['filtering'] = self.get_filtering_info( + filtering_mo + ) + + return ip_info diff --git a/lib/imc/cli/ip/output.py b/lib/imc/cli/ip/output.py new file mode 100644 index 00000000..1cba3c27 --- /dev/null +++ b/lib/imc/cli/ip/output.py @@ -0,0 +1,38 @@ +class ImcCliIpOutput(): + def __init__(self): + pass + + def print_imc_ip_network(self, info): + self.print_list_dict( + info, + 'IMC - Network' + ) + + def print_imc_ip_icmp(self, info): + self.print_list_dict( + info, + 'IMC - ICMP' + ) + + def print_imc_ip_blocking(self, info): + self.print_list_dict( + info, + 'IMC - IP Blocking' + ) + + def print_imc_ip_filtering(self, info): + self.print_list_dict( + info, + 'IMC - IP Filtering' + ) + + def print_imc_ip(self, info): + for item in info: + if 'network' in item: + self.print_imc_ip_network(item['network']) + if 'icmp' in item: + self.print_imc_ip_icmp(item['icmp']) + if 'blocking' in item: + self.print_imc_ip_blocking(item['blocking']) + if 'filtering' in item: + self.print_imc_ip_filtering(item['filtering']) diff --git a/lib/imc/cli/ipmi/__init__.py b/lib/imc/cli/ipmi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/ipmi/main.py b/lib/imc/cli/ipmi/main.py new file mode 100644 index 00000000..ffc50512 --- /dev/null +++ b/lib/imc/cli/ipmi/main.py @@ -0,0 +1,67 @@ +import json + + +class ImcCliIpmi(): + def __init__(self): + self.ipmi_mo = None + + def get_ipmi_mo(self, cache_enabled=True): + if cache_enabled: + if self.ipmi_mo is not None: + return self.ipmi_mo + + self.ipmi_mo = self.get_icm_cli_cache_entry( + 'ipmi' + ) + if self.ipmi_mo is not None: + return self.ipmi_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show ipmi detail + # IPMI over LAN Settings: + # Enabled: no + # Encryption Key: 0000000000000000000000000000000000000000 + # Privilege Level Limit: admin + + self.ipmi_mo = self.show_dict( + 'show ipmi detail', + start='IPMI over LAN Settings:' + ) + + if self.ipmi_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'ipmi', + self.ipmi_mo + ) + + self.log.debug( + 'get_ipmi_mo', + json.dumps(self.ipmi_mo, indent=4) + ) + return self.ipmi_mo + + def get_ipmi_info(self, ipmi_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in ipmi_mo: + info[key] = ipmi_mo[key] + + self.log.debug( + 'get_ipmi_info', + json.dumps(info, indent=4) + ) + return info + + def get_ipmi(self, cache_enabled=True): + ipmi_mo = self.get_ipmi_mo(cache_enabled=cache_enabled) + if ipmi_mo is None: + return None + + ipmi_info = self.get_ipmi_info( + ipmi_mo + ) + + return ipmi_info diff --git a/lib/imc/cli/ipmi/output.py b/lib/imc/cli/ipmi/output.py new file mode 100644 index 00000000..98ec7216 --- /dev/null +++ b/lib/imc/cli/ipmi/output.py @@ -0,0 +1,12 @@ +class ImcCliIpmiOutput(): + def __init__(self): + pass + + def print_imc_ipmi(self, info): + self.print_list_dict( + info, + 'IPMI', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/kvm/__init__.py b/lib/imc/cli/kvm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/kvm/main.py b/lib/imc/cli/kvm/main.py new file mode 100644 index 00000000..458c7946 --- /dev/null +++ b/lib/imc/cli/kvm/main.py @@ -0,0 +1,69 @@ +import json + + +class ImcCliKvm(): + def __init__(self): + self.kvm_mo = None + + def get_kvm_mo(self, cache_enabled=True): + if cache_enabled: + if self.kvm_mo is not None: + return self.kvm_mo + + self.kvm_mo = self.get_icm_cli_cache_entry( + 'kvm' + ) + if self.kvm_mo is not None: + return self.kvm_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show kvm detail + # KVM Settings: + # Max Sessions: 4 + # Local Video: yes + # Active Sessions: 0 + # Enabled: yes + # KVM Port: 2068 + + self.kvm_mo = self.show_dict( + 'show kvm detail', + start='KVM Settings:' + ) + + if self.kvm_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'kvm', + self.kvm_mo + ) + + self.log.debug( + 'get_kvm_mo', + json.dumps(self.kvm_mo, indent=4) + ) + return self.kvm_mo + + def get_kvm_info(self, kvm_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in kvm_mo: + info[key] = kvm_mo[key] + + self.log.debug( + 'get_kvm_info', + json.dumps(info, indent=4) + ) + return info + + def get_kvm(self, cache_enabled=True): + kvm_mo = self.get_kvm_mo(cache_enabled=cache_enabled) + if kvm_mo is None: + return None + + kvm_info = self.get_kvm_info( + kvm_mo + ) + + return kvm_info diff --git a/lib/imc/cli/kvm/output.py b/lib/imc/cli/kvm/output.py new file mode 100644 index 00000000..9b3905e9 --- /dev/null +++ b/lib/imc/cli/kvm/output.py @@ -0,0 +1,12 @@ +class ImcCliKvmOutput(): + def __init__(self): + pass + + def print_imc_kvm(self, info): + self.print_list_dict( + info, + 'KVM', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) \ No newline at end of file diff --git a/lib/imc/cli/led/__init__.py b/lib/imc/cli/led/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/led/main.py b/lib/imc/cli/led/main.py new file mode 100644 index 00000000..7d11885e --- /dev/null +++ b/lib/imc/cli/led/main.py @@ -0,0 +1,82 @@ +import json + + +class ImcCliLed(): + def __init__(self): + self.led_mo = None + + def get_led_mo(self, cache_enabled=True): + if cache_enabled: + if self.led_mo is not None: + return self.led_mo + + self.led_mo = self.get_icm_cli_cache_entry( + 'led' + ) + if self.led_mo is not None: + return self.led_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /sensor # show led detail + # LEDs: + # LED Name: LED_PSU_STATUS + # LED State: ON + # LED Color: GREEN + # : + # LEDs: + # LED Name: LED_TEMP_STATUS + # LED State: ON + # LED Color: GREEN + + self.led_mo = self.show_list( + 'show led detail', + 'LEDs', + 'LED Name', + method='last word', + scope='sensor' + ) + + if self.led_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'led', + self.led_mo + ) + + self.log.debug( + 'get_led_mo', + json.dumps(self.led_mo, indent=4) + ) + return self.led_mo + + def get_led_info(self, led_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in led_mo: + if len(key) > 0: + info[key] = led_mo[key] + + return info + + def get_led(self, cache_enabled=True): + leds_mo = self.get_led_mo(cache_enabled=cache_enabled) + if leds_mo is None: + return None + + leds_info = [] + + for led_mo in leds_mo: + leds_info.append( + self.get_led_info( + led_mo + ) + ) + + self.log.debug( + 'get_led_info', + json.dumps(leds_info, indent=4) + ) + + return leds_info diff --git a/lib/imc/cli/led/output.py b/lib/imc/cli/led/output.py new file mode 100644 index 00000000..687d68a4 --- /dev/null +++ b/lib/imc/cli/led/output.py @@ -0,0 +1,12 @@ +class ImcCliLedOutput(): + def __init__(self): + pass + + def print_imc_led(self, info): + self.print_list_dict( + info, + 'LED', + add_endpoint_ip=False, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/memory/__init__.py b/lib/imc/cli/memory/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/memory/main.py b/lib/imc/cli/memory/main.py new file mode 100644 index 00000000..54a982b9 --- /dev/null +++ b/lib/imc/cli/memory/main.py @@ -0,0 +1,74 @@ +import json + + +class ImcCliMemory(): + def __init__(self): + self.memory_mo = None + + def get_memory_mo(self, cache_enabled=True): + if cache_enabled: + if self.memory_mo is not None: + return self.memory_mo + + self.memory_mo = self.get_icm_cli_cache_entry( + 'memory' + ) + if self.memory_mo is not None: + return self.memory_mo + + # DIMM Summary: + # Memory Speed: 2933 MHz + # Total Memory: 393216 MB + # Effective Memory: 393216 MB + # Redundant Memory: 0 MB + # Failed Memory: 0 MB + # Ignored Memory: 0 MB + # Number of Ignored Dimms: 0 + # Number of Failed Dimms: 0 + # Memory RAS possible: MaximumPerformance Mirroring PartialMirror + # Memory Configuration: MaximumPerformance + + self.memory_mo = self.show_dict( + 'show dimm-summary', + start='DIMM Summary:', + scope='chassis' + ) + + if self.memory_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'memory', + self.memory_mo + ) + + self.log.debug( + 'get_memory_mo', + json.dumps(self.memory_mo, indent=4) + ) + return self.memory_mo + + def get_memory_info(self, memory_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in memory_mo: + info[key] = memory_mo[key] + + self.log.debug( + 'get_memory_info', + json.dumps(info, indent=4) + ) + return info + + def get_memory(self, cache_enabled=True): + memory_mo = self.get_memory_mo(cache_enabled=cache_enabled) + if memory_mo is None: + return None + + memory_info = self.get_memory_info( + memory_mo + ) + + return memory_info diff --git a/lib/imc/cli/memory/output.py b/lib/imc/cli/memory/output.py new file mode 100644 index 00000000..14a77c06 --- /dev/null +++ b/lib/imc/cli/memory/output.py @@ -0,0 +1,15 @@ +class ImcCliMemoryOutput(): + def __init__(self): + pass + + def print_imc_memory(self, info): + self.print_list_dict( + info, + 'Memory' + ) + + def print_imc_memory_compare(self, info): + self.print_compare( + info, + 'Memory' + ) diff --git a/lib/imc/cli/net/__init__.py b/lib/imc/cli/net/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/net/main.py b/lib/imc/cli/net/main.py new file mode 100644 index 00000000..2a9399b7 --- /dev/null +++ b/lib/imc/cli/net/main.py @@ -0,0 +1,149 @@ +import json + + +class ImcCliNet(): + def __init__(self): + self.net_mo = None + self.net_mac_mo = {} + + def get_net_mo(self, cache_enabled=True): + if cache_enabled: + if self.net_mo is not None: + return self.net_mo + + self.net_mo = self.get_icm_cli_cache_entry( + 'net' + ) + if self.net_mo is not None: + return self.net_mo + + # Network Adapter: + # Slot: 1 + # Product Name: Cisco(R) Ethernet Converged NIC XXV710-DA2 + # No Of Interfaces: 2 + + self.net_mo = self.show_list( + 'show network-adapter detail', + 'Network Adapter', + None, + scope='chassis' + ) + + if self.net_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'net', + self.net_mo + ) + + self.log.debug( + 'get_net_mo', + json.dumps(self.net_mo, indent=4) + ) + return self.net_mo + + def get_net_mac_mo(self, slot_id, cache_enabled=True): + if cache_enabled: + if slot_id in self.net_mac_mo and self.net_mac_mo[slot_id] is not None: + return self.net_mac_mo[slot_id] + + self.net_mac_mo[slot_id] = self.get_icm_cli_cache_entry( + 'net_mac_%s' % (slot_id) + ) + if self.net_mac_mo[slot_id] is not None: + return self.net_mac_mo[slot_id] + + commands = [ + 'top', + 'scope chassis', + 'scope network-adapter %s' % (slot_id), + 'show mac-list detail' + ] + + success, output = self.run_commands( + commands + ) + + if not success: + return None + + # Interface ID: 1 + # MAC Address: 5c:71:0d:26:37:b2 + # Interface ID: 2 + # MAC Address: 5c:71:0d:26:37:b3 + + self.net_mac_mo[slot_id] = [] + for line in output['show mac-list detail'].split('\n'): + self.net_mac_mo[slot_id].append( + line + ) + + self.set_imc_cli_cache_entry( + 'net_mac_%s' % (slot_id), + self.net_mac_mo[slot_id] + ) + + self.log.debug( + 'get_net_mac_mo', + json.dumps(self.net_mac_mo[slot_id], indent=4) + ) + return self.net_mac_mo[slot_id] + + def get_net_info(self, net_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in net_mo: + info[key] = net_mo[key] + + info['__Key'] = 'Slot' + info['__Value'] = info[info['__Key']] + + return info + + def get_net_mac_info(self, net_mac_mo): + macs_info = [] + mac_info = {} + + for item in net_mac_mo: + key = item.split(':')[0] + value = ':'.join(item.split(':')[1:]) + + if key == 'MAC Address': + mac_info['MAC Address'] = value + macs_info.append(mac_info) + else: + mac_info = {} + mac_info['Interface ID'] = value + + return macs_info + + def get_net(self, cache_enabled=True): + nets_mo = self.get_net_mo(cache_enabled=cache_enabled) + if nets_mo is None: + return None + + nets_info = [] + + for net_mo in nets_mo: + nets_info.append( + self.get_net_info( + net_mo + ) + ) + + for net_info in nets_info: + net_info['Interfaces'] = self.get_net_mac_info( + self.get_net_mac_mo( + net_info['Slot'], + cache_enabled=cache_enabled + ) + ) + + self.log.debug( + 'get_net_info', + json.dumps(nets_info, indent=4) + ) + return nets_info diff --git a/lib/imc/cli/net/output.py b/lib/imc/cli/net/output.py new file mode 100644 index 00000000..d3296510 --- /dev/null +++ b/lib/imc/cli/net/output.py @@ -0,0 +1,10 @@ +class ImcCliNetOutput(): + def __init__(self): + pass + + def print_imc_net(self, info): + self.print_list_dict( + info, + 'Network Adapter', + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/ntp/__init__.py b/lib/imc/cli/ntp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/ntp/main.py b/lib/imc/cli/ntp/main.py new file mode 100644 index 00000000..3361c9c5 --- /dev/null +++ b/lib/imc/cli/ntp/main.py @@ -0,0 +1,72 @@ +import json + + +class ImcCliNtp(): + def __init__(self): + self.ntp_mo = None + + def get_ntp_mo(self, cache_enabled=True): + if cache_enabled: + if self.ntp_mo is not None: + return self.ntp_mo + + self.ntp_mo = self.get_icm_cli_cache_entry( + 'ntp' + ) + if self.ntp_mo is not None: + return self.ntp_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc/network # show ntp detail + # NTP Service Settings: + # Enabled: yes + # Server 1: + # Server 2: + # Server 3: + # Server 4: + # Status: ok + + self.ntp_mo = self.show_dict( + 'show ntp detail', + start='NTP Service Settings:', + scope='cimc,network' + ) + + if self.ntp_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'ntp', + self.ntp_mo + ) + + + self.log.debug( + 'get_ntp_mo', + json.dumps(self.ntp_mo, indent=4) + ) + return self.ntp_mo + + def get_ntp_info(self, ntp_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in ntp_mo: + info[key] = ntp_mo[key] + + self.log.debug( + 'get_ntp_info', + json.dumps(info, indent=4) + ) + return info + + def get_ntp(self, cache_enabled=True): + ntp_mo = self.get_ntp_mo(cache_enabled=cache_enabled) + if ntp_mo is None: + return None + + ntp_info = self.get_ntp_info( + ntp_mo + ) + + return ntp_info diff --git a/lib/imc/cli/ntp/output.py b/lib/imc/cli/ntp/output.py new file mode 100644 index 00000000..7dbb26f8 --- /dev/null +++ b/lib/imc/cli/ntp/output.py @@ -0,0 +1,12 @@ +class ImcCliNtpOutput(): + def __init__(self): + pass + + def print_imc_ntp(self, info): + self.print_list_dict( + info, + 'NTP', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/output.py b/lib/imc/cli/output.py new file mode 100644 index 00000000..5fc584bc --- /dev/null +++ b/lib/imc/cli/output.py @@ -0,0 +1,456 @@ +from lib import filter_helper +from lib import output_helper + +from lib.imc.cli.adapter.output import ImcCliAdapterOutput +from lib.imc.cli.admin.output import ImcCliAdminOutput +from lib.imc.cli.bbu.output import ImcCliBbuOutput +from lib.imc.cli.bios.output import ImcCliBiosOutput +from lib.imc.cli.boot.output import ImcCliBootOutput +from lib.imc.cli.chassis.output import ImcCliChassisOutput +from lib.imc.cli.cpu.output import ImcCliCpuOutput +from lib.imc.cli.dimm.output import ImcCliDimmOutput +from lib.imc.cli.fault.output import ImcCliFaultOutput +from lib.imc.cli.flex.output import ImcCliFlexOutput +from lib.imc.cli.fw.output import ImcCliFwOutput +from lib.imc.cli.hardware.output import ImcCliHardwareOutput +from lib.imc.cli.hdd.output import ImcCliHddOutput +from lib.imc.cli.http.output import ImcCliHttpOutput +from lib.imc.cli.ip.output import ImcCliIpOutput +from lib.imc.cli.ipmi.output import ImcCliIpmiOutput +from lib.imc.cli.kvm.output import ImcCliKvmOutput +from lib.imc.cli.led.output import ImcCliLedOutput +from lib.imc.cli.memory.output import ImcCliMemoryOutput +from lib.imc.cli.net.output import ImcCliNetOutput +from lib.imc.cli.ntp.output import ImcCliNtpOutput +from lib.imc.cli.pci.output import ImcCliPciOutput +from lib.imc.cli.psu.output import ImcCliPsuOutput +from lib.imc.cli.redfish.output import ImcCliRedfishOutput +from lib.imc.cli.sel.output import ImcCliSelOutput +from lib.imc.cli.sensor.output import ImcCliSensorOutput +from lib.imc.cli.smtp.output import ImcCliSmtpOutput +from lib.imc.cli.snmp.output import ImcCliSnmpOutput +from lib.imc.cli.sol.output import ImcCliSolOutput +from lib.imc.cli.ssh.output import ImcCliSshOutput +from lib.imc.cli.storageadapter.output import ImcCliStorageAdapterOutput +from lib.imc.cli.syslog.output import ImcCliSyslogOutput +from lib.imc.cli.tpm.output import ImcCliTpmOutput +from lib.imc.cli.utilization.output import ImcCliUtilizationOutput +from lib.imc.cli.version.output import ImcCliVersionOutput +from lib.imc.cli.vmedia.output import ImcCliVmediaOutput +from lib.imc.cli.xml.output import ImcCliXmlOutput + + +class ImcCliOutput( + ImcCliAdapterOutput, + ImcCliAdminOutput, + ImcCliBbuOutput, + ImcCliBiosOutput, + ImcCliBootOutput, + ImcCliChassisOutput, + ImcCliCpuOutput, + ImcCliDimmOutput, + ImcCliFaultOutput, + ImcCliFlexOutput, + ImcCliFwOutput, + ImcCliHardwareOutput, + ImcCliHddOutput, + ImcCliHttpOutput, + ImcCliIpOutput, + ImcCliIpmiOutput, + ImcCliKvmOutput, + ImcCliLedOutput, + ImcCliMemoryOutput, + ImcCliNetOutput, + ImcCliNtpOutput, + ImcCliPciOutput, + ImcCliPsuOutput, + ImcCliRedfishOutput, + ImcCliSelOutput, + ImcCliSensorOutput, + ImcCliSmtpOutput, + ImcCliSnmpOutput, + ImcCliSolOutput, + ImcCliSshOutput, + ImcCliStorageAdapterOutput, + ImcCliSyslogOutput, + ImcCliTpmOutput, + ImcCliUtilizationOutput, + ImcCliVersionOutput, + ImcCliVmediaOutput, + ImcCliXmlOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + ImcCliAdapterOutput.__init__(self) + ImcCliAdminOutput.__init__(self) + ImcCliBbuOutput.__init__(self) + ImcCliBiosOutput.__init__(self) + ImcCliBootOutput.__init__(self) + ImcCliChassisOutput.__init__(self) + ImcCliCpuOutput.__init__(self) + ImcCliDimmOutput.__init__(self) + ImcCliFaultOutput.__init__(self) + ImcCliFlexOutput.__init__(self) + ImcCliFwOutput.__init__(self) + ImcCliHardwareOutput.__init__(self) + ImcCliHddOutput.__init__(self) + ImcCliHttpOutput.__init__(self) + ImcCliIpOutput.__init__(self) + ImcCliIpmiOutput.__init__(self) + ImcCliKvmOutput.__init__(self) + ImcCliLedOutput.__init__(self) + ImcCliMemoryOutput.__init__(self) + ImcCliNetOutput.__init__(self) + ImcCliNtpOutput.__init__(self) + ImcCliPciOutput.__init__(self) + ImcCliPsuOutput.__init__(self) + ImcCliRedfishOutput.__init__(self) + ImcCliSelOutput.__init__(self) + ImcCliSensorOutput.__init__(self) + ImcCliSmtpOutput.__init__(self) + ImcCliSnmpOutput.__init__(self) + ImcCliSolOutput.__init__(self) + ImcCliSshOutput.__init__(self) + ImcCliStorageAdapterOutput.__init__(self) + ImcCliSyslogOutput.__init__(self) + ImcCliTpmOutput.__init__(self) + ImcCliUtilizationOutput.__init__(self) + ImcCliVersionOutput.__init__(self) + ImcCliVmediaOutput.__init__(self) + ImcCliXmlOutput.__init__(self) + + def print_imc_cli_endpoint_settings(self, endpoints, verify=False, show_password=True, title=False): + if title: + self.my_output.default( + 'IMC Cli Endpoint [#%s]' % (len(endpoints)), + underline=True, + before_newline=True + ) + + if len(endpoints) == 0: + self.my_output.default('None') + return + + entries = [] + for item in endpoints: + item['__Output'] = {} + + if 'verified' in item: + if item['verified']: + item['AuthenticatedTick'] = '\u2713' + item['__Output']['AuthenticatedTick'] = 'Green' + else: + item['AuthenticatedTick'] = '\u2717' + item['__Output']['AuthenticatedTick'] = 'Red' + + if not show_password: + item['password'] = '******' + + entries.append(item) + + order = [ + 'ip', + 'port', + 'username', + 'password' + ] + + headers = [ + 'IP', + 'Port', + 'Username', + 'Password' + ] + + if verify: + order.append('AuthenticatedTick') + headers.append('Authenticated') + + self.my_output.my_table( + entries, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_dict(self, info, title, add_endpoint_ip=True, underline=True, allow_order_subkeys=True): + order = [] + headers = [] + + if add_endpoint_ip: + order.append('__IP') + headers.append('Endpoint') + + endpoint_ip = None + for key in info: + if key == '__IP': + endpoint_ip = info[key] + continue + + if key in ['__Output', '__Key', '__Value']: + continue + + order.append(key) + headers.append(key) + + self.my_output.dictionary( + info, + title=title, + underline=underline, + prefix="- ", + justify=True, + keys=order, + title_keys=headers, + allow_order_subkeys=allow_order_subkeys + ) + + def print_list_table(self, info, title=None, allow_order_subkeys=False, add_endpoint_ip=True): + if isinstance(info, dict): + info = [info] + + if len(info) == 0: + if title is not None: + self.my_output.default( + title, + underline=True, + before_newline=True + ) + self.my_output.default('None') + return + + endpoints = [] + for item in info: + if item['__IP'] not in endpoints: + endpoints.append(item['__IP']) + + if title is not None: + if len(endpoints) == 1: + add_endpoint_ip = False + + if add_endpoint_ip: + self.my_output.default( + title, + underline=True, + before_newline=True + ) + else: + self.my_output.default( + '%s [%s]' % (title, info[0]['__IP']), + underline=True, + before_newline=True + ) + + order = [] + headers = [] + + if add_endpoint_ip: + order.append('__IP') + headers.append('Endpoint') + + for item in info: + for key in item: + if key in ['__Output', '__IP', '__Key', '__Value']: + continue + + if key not in order: + order.append( + key + ) + headers.append( + key + ) + + for item in info: + for key in order: + if key not in item or item[key] is None or len(item[key]) == 0: + item[key] = '--' + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=False, + allow_order_subkeys=allow_order_subkeys, + table=True + ) + + def print_list_dict(self, info, title, allow_order_subkeys=True, add_endpoint_ip=True, underline=False): + if isinstance(info, dict): + info = [info] + + if len(info) == 0: + self.my_output.default( + title, + underline=True, + before_newline=True + ) + self.my_output.default('None') + return + + for item in info: + self.print_dict( + item, + title, + add_endpoint_ip=add_endpoint_ip, + underline=underline, + allow_order_subkeys=allow_order_subkeys + ) + + def print_compare(self, info, title, expand=[], max_expand_column=30): + order = [ + 'key' + ] + headers = [ + 'Property' + ] + + endpoint_ips = [] + for item in info: + endpoint_ip = None + for key in item: + if key == '__IP': + endpoint_ip = item[key] + + if endpoint_ip is not None: + if endpoint_ip not in endpoint_ips: + endpoint_ips.append( + endpoint_ip + ) + + endpoint_ip_items = {} + endpoint_ip_key = {} + endpoint_ip_values = {} + for endpoint_ip in endpoint_ips: + endpoint_ip_items[endpoint_ip] = 0 + endpoint_ip_values[endpoint_ip] = [] + for item in info: + if '__IP' not in item: + continue + + if item['__IP'] == endpoint_ip: + endpoint_ip_items[endpoint_ip] = endpoint_ip_items[endpoint_ip] + 1 + if '__Key' in item: + endpoint_ip_key[endpoint_ip] = item['__Key'] + if '__Value' in item: + if item['__Value'] not in endpoint_ip_values[endpoint_ip]: + endpoint_ip_values[endpoint_ip].append( + item['__Value'] + ) + + for endpoint_ip in endpoint_ips: + if endpoint_ip_items[endpoint_ip] == 1: + order.append(endpoint_ip) + headers.append(endpoint_ip) + else: + if endpoint_ip not in endpoint_ip_key: + self.my_output.error('Input data invalid: incorrect keys') + return + + if endpoint_ip_items[endpoint_ip] != len(endpoint_ip_values[endpoint_ip]): + self.my_output.error('Input data invalid: insufficien primary key values') + return + + for index in range(0, endpoint_ip_items[endpoint_ip]): + order.append('%s #%s' % (endpoint_ip, endpoint_ip_values[endpoint_ip][index])) + headers.append(endpoint_ip) + + keys = [] + for item in info: + for key in item: + if key in ['__Output', '__IP', '__Key', '__Value']: + continue + + if key not in keys: + keys.append( + key + ) + + values = [] + for key in keys: + value = {} + value['__Output'] = {} + value['key'] = key + + for item in info: + for endpoint_ip in endpoint_ips: + if endpoint_ip_items[endpoint_ip] == 1: + if item['__IP'] == endpoint_ip: + if key in item: + if key in item['__Output']: + value['__Output'][endpoint_ip] = item['__Output'][key] + + if key in expand: + value[endpoint_ip] = filter_helper.get_string_chunks( + item[key], + max_expand_column + ) + else: + value[endpoint_ip] = item[key] + else: + if key in expand: + value[endpoint_ip] = ['--'] + else: + value[endpoint_ip] = '--' + + if endpoint_ip_items[endpoint_ip] > 1: + for key_value in endpoint_ip_values[endpoint_ip]: + if item['__IP'] == endpoint_ip and item[endpoint_ip_key[endpoint_ip]] == key_value: + if key in item: + if key in item['__Output']: + value['__Output']['%s #%s' % (endpoint_ip, key_value)] = item['__Output'][key] + + if key in expand: + value['%s #%s' % (endpoint_ip, key_value)] = filter_helper.get_string_chunks( + item[key], + max_expand_column + ) + else: + value['%s #%s' % (endpoint_ip, key_value)] = item[key] + else: + if key in expand: + value['%s #%s' % (endpoint_ip, key_value)] = ['--'] + else: + value['%s #%s' % (endpoint_ip, key_value)] = '--' + + values.append( + value + ) + + if title is not None: + self.my_output.default( + title, + underline=True, + before_newline=True + ) + + if len(expand) == 0: + self.my_output.my_table( + values, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=False, + table=True + ) + else: + self.my_output.my_table( + self.my_output.auto_expand_lists( + values, + order + ), + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/imc/cli/pci/__init__.py b/lib/imc/cli/pci/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/pci/main.py b/lib/imc/cli/pci/main.py new file mode 100644 index 00000000..39c3ad9b --- /dev/null +++ b/lib/imc/cli/pci/main.py @@ -0,0 +1,150 @@ +import json + + +class ImcCliPci(): + def __init__(self): + self.pci_mo = None + self.pci_pid_mo = None + + def get_pci_mo(self, cache_enabled=True): + if cache_enabled: + if self.pci_mo is not None: + return self.pci_mo + + self.pci_mo = self.get_icm_cli_cache_entry( + 'pci' + ) + if self.pci_mo is not None: + return self.pci_mo + + # Slot 1: + # Vendor ID: 0x8086 + # Device ID: 0x158b + # SubVendor ID: 0x1137 + # SubDevice ID: 0x0225 + # Firmware Version: 0x8000B900-1.826.0 + # Product Name: Cisco(R) Ethernet Converged NIC XXV710-DA2 + # Option ROM Status : Not-Loaded + + self.pci_mo = self.show_list( + 'show pci-adapter detail', + 'Slot', + 'Slot', + method='last word', + scope='chassis' + ) + + if self.pci_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'pci', + self.pci_mo + ) + + self.log.debug( + 'get_pci_mo', + json.dumps(self.pci_mo, indent=4) + ) + return self.pci_mo + + def get_pci_pid_mo(self, cache_enabled=True): + if cache_enabled: + if self.pci_pid_mo is not None: + return self.pci_pid_mo + + self.pci_pid_mo = self.get_icm_cli_cache_entry( + 'pci_pid' + ) + if self.pci_pid_mo is not None: + return self.pci_pid_mo + + # Slot 1: + # Description: Cisco(R) Ethernet Converged NIC XXV710-DA2 + # Product ID: UCSC-PCIE-ID25GF + # Vendor ID: 0x8086 + # Device ID: 0x158b + # SubVendor ID: 0x1137 + # SubDevice ID: 0x0225 + + self.pci_pid_mo = self.show_list( + 'show pciadapter-pid detail', + 'Slot', + 'Slot', + method='last word', + scope='chassis' + ) + + if self.pci_pid_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'pci_pid', + self.pci_pid_mo + ) + + self.log.debug( + 'get_pci_pid_mo', + json.dumps(self.pci_pid_mo, indent=4) + ) + return self.pci_pid_mo + + def get_pci_info(self, pci_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in pci_mo: + info[key] = pci_mo[key] + + info['__Key'] = 'Slot' + info['__Value'] = info[info['__Key']] + + return info + + def get_pci_pid_info(self, pci_mo): + info = {} + for key in pci_mo: + info[key] = pci_mo[key] + return info + + def get_pci(self, cache_enabled=True): + pcis_mo = self.get_pci_mo(cache_enabled=cache_enabled) + if pcis_mo is None: + return None + + pcis_pid_mo = self.get_pci_pid_mo(cache_enabled=cache_enabled) + if pcis_pid_mo is None: + return None + + pcis_info = [] + + for pci_mo in pcis_mo: + pcis_info.append( + self.get_pci_info( + pci_mo + ) + ) + + keys = [ + 'Description', + 'Product ID' + ] + for pci_info in pcis_info: + for key in keys: + pci_info[key] = '' + + for pci_pid_mo in pcis_pid_mo: + pci_pid_info = self.get_pci_pid_info( + pci_pid_mo + ) + for pci_info in pcis_info: + if pci_info['Slot'] == pci_pid_info['Slot']: + for key in keys: + pci_info[key] = pci_pid_info[key] + + self.log.debug( + 'get_pci_info', + json.dumps(pcis_info, indent=4) + ) + return pcis_info diff --git a/lib/imc/cli/pci/output.py b/lib/imc/cli/pci/output.py new file mode 100644 index 00000000..b5ce4e1a --- /dev/null +++ b/lib/imc/cli/pci/output.py @@ -0,0 +1,10 @@ +class ImcCliPciOutput(): + def __init__(self): + pass + + def print_imc_pci(self, info): + self.print_list_dict( + info, + 'PCI', + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/psu/__init__.py b/lib/imc/cli/psu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/psu/main.py b/lib/imc/cli/psu/main.py new file mode 100644 index 00000000..63badd1f --- /dev/null +++ b/lib/imc/cli/psu/main.py @@ -0,0 +1,91 @@ +import json + + +class ImcCliPsu(): + def __init__(self): + self.psu_mo = None + + def get_psu_mo(self, cache_enabled=True): + if cache_enabled: + if self.psu_mo is not None: + return self.psu_mo + + self.psu_mo = self.get_icm_cli_cache_entry( + 'psu' + ) + if self.psu_mo is not None: + return self.psu_mo + + # Name PSU1: + # In. Power (Watts): 150 + # Out. Power (Watts): 123 + # Firmware : 10252046 + # Status : Present + # Product ID : UCSC-PSU1-1050W + # Name PSU2: + # In. Power (Watts): 146 + # Out. Power (Watts): 122 + # Firmware : 10252046 + # Status : Present + # Product ID : UCSC-PSU1-1050W + + self.psu_mo = self.show_list( + 'show psu detail', + 'Name', + 'Name', + method='last word', + scope='chassis' + ) + + if self.psu_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'psu', + self.psu_mo + ) + + self.log.debug( + 'get_psu_mo', + json.dumps(self.psu_mo, indent=4) + ) + return self.psu_mo + + def get_psu_info(self, psu_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in psu_mo: + info[key] = psu_mo[key] + + if 'Status' in info: + if info['Status'] == 'Present': + info['__Output']['Status'] = 'Green' + else: + info['__Output']['Status'] = 'Red' + + info['__Key'] = 'Name' + info['__Value'] = info[info['__Key']] + + self.log.debug( + 'get_psu_info', + json.dumps(info, indent=4) + ) + return info + + def get_psu(self, cache_enabled=True): + psus_mo = self.get_psu_mo(cache_enabled=cache_enabled) + if psus_mo is None: + return None + + psus_info = [] + + for psu_mo in psus_mo: + psus_info.append( + self.get_psu_info( + psu_mo + ) + ) + + return psus_info diff --git a/lib/imc/cli/psu/output.py b/lib/imc/cli/psu/output.py new file mode 100644 index 00000000..631d8e61 --- /dev/null +++ b/lib/imc/cli/psu/output.py @@ -0,0 +1,16 @@ +class ImcCliPsuOutput(): + def __init__(self): + pass + + def print_imc_psu(self, info): + self.print_list_dict( + info, + 'PSU', + allow_order_subkeys=False + ) + + def print_imc_psu_compare(self, info): + self.print_compare( + info, + 'PSU' + ) diff --git a/lib/imc/cli/redfish/__init__.py b/lib/imc/cli/redfish/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/redfish/main.py b/lib/imc/cli/redfish/main.py new file mode 100644 index 00000000..d0e2cbc6 --- /dev/null +++ b/lib/imc/cli/redfish/main.py @@ -0,0 +1,93 @@ +import json + + +class ImcCliRedfish(): + def __init__(self): + self.redfish_mo = None + + def get_redfish_mo(self, cache_enabled=True): + if cache_enabled: + if self.redfish_mo is not None: + return self.redfish_mo + + self.redfish_mo = self.get_icm_cli_cache_entry( + 'redfish' + ) + if self.redfish_mo is not None: + return self.redfish_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show redfish detail + # REDFISH Settings: + # Enabled: yes + # Active Sessions: 0 + # Max Sessions: 4 + + self.redfish_mo = self.show_dict( + 'show redfish detail', + start='REDFISH Settings:' + ) + + if self.redfish_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'redfish', + self.redfish_mo + ) + + self.log.debug( + 'get_redfish_mo', + json.dumps(self.redfish_mo, indent=4) + ) + return self.redfish_mo + + def get_redfish_info(self, redfish_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in redfish_mo: + info[key] = redfish_mo[key] + + self.log.debug( + 'get_redfish_info', + json.dumps(info, indent=4) + ) + return info + + def get_redfish(self, cache_enabled=True): + redfish_mo = self.get_redfish_mo(cache_enabled=cache_enabled) + if redfish_mo is None: + return None + + redfish_info = self.get_redfish_info( + redfish_mo + ) + + return redfish_info + + def enable_redfish(self): + commands = [ + 'scope redfish', + 'set enabled yes', + 'commit' + ] + + success, output = self.run_commands( + commands + ) + + return success + + def disable_redfish(self): + commands = [ + 'scope redfish', + 'set enabled no', + 'commit' + ] + + success, output = self.run_commands( + commands + ) + + return success \ No newline at end of file diff --git a/lib/imc/cli/redfish/output.py b/lib/imc/cli/redfish/output.py new file mode 100644 index 00000000..831c1605 --- /dev/null +++ b/lib/imc/cli/redfish/output.py @@ -0,0 +1,12 @@ +class ImcCliRedfishOutput(): + def __init__(self): + pass + + def print_imc_redfish(self, info): + self.print_list_dict( + info, + 'Redfish', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/sel/__init__.py b/lib/imc/cli/sel/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/sel/main.py b/lib/imc/cli/sel/main.py new file mode 100644 index 00000000..0ac6724d --- /dev/null +++ b/lib/imc/cli/sel/main.py @@ -0,0 +1,68 @@ +import json + + +class ImcCliSel(): + def __init__(self): + self.sel_mo = None + + def get_sel_mo(self, cache_enabled=True): + if cache_enabled: + if self.sel_mo is not None: + return self.sel_mo + + self.sel_mo = self.get_icm_cli_cache_entry( + 'sel' + ) + if self.sel_mo is not None: + return self.sel_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show sel detail + # SEL Information: + # No of Entries: 3008 + # Max Entries: 3008 + # Percent Used: 100 + # Capacity: low + + self.sel_mo = self.show_dict( + 'show sel detail', + start='SEL Information:' + ) + + if self.sel_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sel', + self.sel_mo + ) + + self.log.debug( + 'get_sel_mo', + json.dumps(self.sel_mo, indent=4) + ) + return self.sel_mo + + def get_sel_info(self, sel_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sel_mo: + info[key] = sel_mo[key] + + self.log.debug( + 'get_sel_info', + json.dumps(info, indent=4) + ) + return info + + def get_sel(self, cache_enabled=True): + sel_mo = self.get_sel_mo(cache_enabled=cache_enabled) + if sel_mo is None: + return None + + sel_info = self.get_sel_info( + sel_mo + ) + + return sel_info diff --git a/lib/imc/cli/sel/output.py b/lib/imc/cli/sel/output.py new file mode 100644 index 00000000..a112caa4 --- /dev/null +++ b/lib/imc/cli/sel/output.py @@ -0,0 +1,12 @@ +class ImcCliSelOutput(): + def __init__(self): + pass + + def print_imc_sel(self, info): + self.print_list_dict( + info, + 'SEL', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/sensor/__init__.py b/lib/imc/cli/sensor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/sensor/main.py b/lib/imc/cli/sensor/main.py new file mode 100644 index 00000000..b52c533c --- /dev/null +++ b/lib/imc/cli/sensor/main.py @@ -0,0 +1,410 @@ +import json + + +class ImcCliSensor(): + def __init__(self): + self.sensor_current_mo = None + self.sensor_fan_mo = None + self.sensor_psu_mo = None + self.sensor_temperature_mo = None + self.sensor_voltage_mo = None + + def get_sensor_current_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.sensor_current_mo is not None: + return self.sensor_current_mo + + self.sensor_current_mo = self.get_icm_cli_cache_entry( + 'sensor_current' + ) + if self.sensor_current_mo is not None: + return self.sensor_current_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /sensor # show current detail + # Name PSU1_IOUT: + # Sensor Status: Normal + # Reading: 8.00 + # Units: AMP + # Critical Min: N/A + # Critical Max: 87.00 + # Non-Recoverable Min: N/A + # Non-Recoverable Max: 96.00 + + if keep_scope: + self.sensor_current_mo = self.show_list( + 'show current detail', + 'Name', + 'Name', + method='last word', + top=False + ) + else: + self.sensor_current_mo = self.show_list( + 'show current detail', + 'Name', + 'Name', + method='last word', + scope='sensor' + ) + + if self.sensor_current_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sensor_current', + self.sensor_current_mo + ) + + self.log.debug( + 'get_sensor_current_mo', + json.dumps(self.sensor_current_mo, indent=4) + ) + return self.sensor_current_mo + + def get_sensor_current_info(self, sensor_current_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sensor_current_mo: + info[key] = sensor_current_mo[key] + + return info + + def get_sensor_fan_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.sensor_fan_mo is not None: + return self.sensor_fan_mo + + self.sensor_fan_mo = self.get_icm_cli_cache_entry( + 'sensor_fan' + ) + if self.sensor_fan_mo is not None: + return self.sensor_fan_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /sensor # show fan detail + # Name PSU1_IOUT: + # Sensor Status: Normal + # Reading: 8.00 + # Units: AMP + # Critical Min: N/A + # Critical Max: 87.00 + # Non-Recoverable Min: N/A + # Non-Recoverable Max: 96.00 + + if keep_scope: + self.sensor_fan_mo = self.show_list( + 'show fan detail', + 'Name', + 'Name', + method='last word', + top=False + ) + else: + self.sensor_fan_mo = self.show_list( + 'show fan detail', + 'Name', + 'Name', + method='last word', + scope='sensor' + ) + + if self.sensor_fan_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sensor_fan', + self.sensor_fan_mo + ) + + self.log.debug( + 'get_sensor_fan_mo', + json.dumps(self.sensor_fan_mo, indent=4) + ) + return self.sensor_fan_mo + + def get_sensor_fan_info(self, sensor_fan_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sensor_fan_mo: + info[key] = sensor_fan_mo[key] + + return info + + def get_sensor_psu_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.sensor_psu_mo is not None: + return self.sensor_psu_mo + + self.sensor_psu_mo = self.get_icm_cli_cache_entry( + 'sensor_psu' + ) + if self.sensor_psu_mo is not None: + return self.sensor_psu_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /sensor # show psu detail + # Name PSU1_POUT: + # Sensor Status: Normal + # Reading: 96 + # Units: Watts + # Critical Min: N/A + # Critical Max: 1048 + # Non-Recoverable Min: N/A + # Non-Recoverable Max: 1152 + + if keep_scope: + self.sensor_psu_mo = self.show_list( + 'show psu detail', + 'Name', + 'Name', + method='last word', + top=False + ) + else: + self.sensor_psu_mo = self.show_list( + 'show psu detail', + 'Name', + 'Name', + method='last word', + scope='sensor' + ) + + if self.sensor_psu_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sensor_psu', + self.sensor_psu_mo + ) + + self.log.debug( + 'get_sensor_psu_mo', + json.dumps(self.sensor_psu_mo, indent=4) + ) + return self.sensor_psu_mo + + def get_sensor_psu_info(self, sensor_psu_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sensor_psu_mo: + info[key] = sensor_psu_mo[key] + + return info + + def get_sensor_temperature_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.sensor_temperature_mo is not None: + return self.sensor_temperature_mo + + self.sensor_temperature_mo = self.get_icm_cli_cache_entry( + 'sensor_temperature' + ) + if self.sensor_temperature_mo is not None: + return self.sensor_temperature_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /sensor # show temperature detail + # Name MLOM_TEMP: + # Sensor Status: Normal + # Reading: 60.0 + # Units: C + # Critical Min: N/A + # Critical Max: 90.0 + # Non-Recoverable Min: N/A + # Non-Recoverable Max: 95.0 + + if keep_scope: + self.sensor_temperature_mo = self.show_list( + 'show temperature detail', + 'Name', + 'Name', + method='last word', + top=False + ) + else: + self.sensor_temperature_mo = self.show_list( + 'show temperature detail', + 'Name', + 'Name', + method='last word', + scope='sensor' + ) + + if self.sensor_temperature_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sensor_temperature', + self.sensor_temperature_mo + ) + + self.log.debug( + 'get_sensor_temperature_mo', + json.dumps(self.sensor_temperature_mo, indent=4) + ) + return self.sensor_temperature_mo + + def get_sensor_temperature_info(self, sensor_temperature_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sensor_temperature_mo: + info[key] = sensor_temperature_mo[key] + + return info + + def get_sensor_voltage_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.sensor_voltage_mo is not None: + return self.sensor_voltage_mo + + self.sensor_voltage_mo = self.get_icm_cli_cache_entry( + 'sensor_voltage' + ) + if self.sensor_voltage_mo is not None: + return self.sensor_voltage_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /sensor # show voltage detail + # Name PSU1_VOUT: + # Sensor Status: Normal + # Reading: 12.100 + # Units: V + # Critical Min: N/A + # Critical Max: 14.000 + # Non-Recoverable Min: N/A + # Non-Recoverable Max: 15.000 + + if keep_scope: + self.sensor_voltage_mo = self.show_list( + 'show voltage detail', + 'Name', + 'Name', + method='last word', + top=False + ) + else: + self.sensor_voltage_mo = self.show_list( + 'show voltage detail', + 'Name', + 'Name', + method='last word', + scope='sensor' + ) + + if self.sensor_voltage_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sensor_voltage', + self.sensor_voltage_mo + ) + + self.log.debug( + 'get_sensor_voltage_mo', + json.dumps(self.sensor_voltage_mo, indent=4) + ) + return self.sensor_voltage_mo + + def get_sensor_voltage_info(self, sensor_voltage_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sensor_voltage_mo: + info[key] = sensor_voltage_mo[key] + + return info + + def get_sensor( + self, + current_info=False, + fan_info=False, + psu_info=False, + temperature_info=False, + voltage_info=False, + cache_enabled=True + ): + sensor = {} + + self.set_scope('sensor') + + if current_info: + sensors_current_mo = self.get_sensor_current_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if sensors_current_mo is not None: + sensor['current'] = [] + for sensor_current_mo in sensors_current_mo: + sensor['current'].append( + self.get_sensor_current_info( + sensor_current_mo + ) + ) + + if fan_info: + sensors_fan_mo = self.get_sensor_fan_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if sensors_fan_mo is not None: + sensor['fan'] = [] + for sensor_fan_mo in sensors_fan_mo: + sensor['fan'].append( + self.get_sensor_fan_info( + sensor_fan_mo + ) + ) + + if psu_info: + sensors_psu_mo = self.get_sensor_psu_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if sensors_psu_mo is not None: + sensor['psu'] = [] + for sensor_psu_mo in sensors_psu_mo: + sensor['psu'].append( + self.get_sensor_psu_info( + sensor_psu_mo + ) + ) + + if temperature_info: + sensors_temperature_mo = self.get_sensor_temperature_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if sensors_temperature_mo is not None: + sensor['temperature'] = [] + for sensor_temperature_mo in sensors_temperature_mo: + sensor['temperature'].append( + self.get_sensor_temperature_info( + sensor_temperature_mo + ) + ) + + if voltage_info: + sensors_voltage_mo = self.get_sensor_voltage_mo( + keep_scope=True, + cache_enabled=cache_enabled + ) + if sensors_voltage_mo is not None: + sensor['voltage'] = [] + for sensor_voltage_mo in sensors_voltage_mo: + sensor['voltage'].append( + self.get_sensor_voltage_info( + sensor_voltage_mo + ) + ) + + self.log.debug( + 'get_sensor_info', + json.dumps(sensor, indent=4) + ) + + return sensor diff --git a/lib/imc/cli/sensor/output.py b/lib/imc/cli/sensor/output.py new file mode 100644 index 00000000..89808336 --- /dev/null +++ b/lib/imc/cli/sensor/output.py @@ -0,0 +1,65 @@ +class ImcCliSensorOutput(): + def __init__(self): + pass + + def print_imc_sensor_current(self, info): + self.print_list_dict( + info, + 'Sensor Current', + allow_order_subkeys=False + ) + + def print_imc_sensor_fan(self, info): + self.print_list_dict( + info, + 'Sensor Fan', + allow_order_subkeys=False + ) + + def print_imc_sensor_psu(self, info): + self.print_list_dict( + info, + 'Sensor PSU', + allow_order_subkeys=False + ) + + def print_imc_sensor_temperature(self, info): + self.print_list_dict( + info, + 'Sensor Temperature', + allow_order_subkeys=False + ) + + def print_imc_sensor_voltage(self, info): + self.print_list_dict( + info, + 'Sensor Voltage', + allow_order_subkeys=False + ) + + def print_imc_sensor(self, info): + for item in info: + if 'current' in item: + self.print_imc_sensor_current( + item['current'] + ) + + if 'fan' in item: + self.print_imc_sensor_fan( + item['fan'] + ) + + if 'psu' in item: + self.print_imc_sensor_psu( + item['psu'] + ) + + if 'temperature' in item: + self.print_imc_sensor_temperature( + item['temperature'] + ) + + if 'voltage' in item: + self.print_imc_sensor_voltage( + item['voltage'] + ) diff --git a/lib/imc/cli/smtp/__init__.py b/lib/imc/cli/smtp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/smtp/main.py b/lib/imc/cli/smtp/main.py new file mode 100644 index 00000000..dc85d877 --- /dev/null +++ b/lib/imc/cli/smtp/main.py @@ -0,0 +1,105 @@ +import json + + +class ImcCliSmtp(): + def __init__(self): + self.smtp_mo = None + + def get_smtp_mo(self, cache_enabled=True): + if cache_enabled: + if self.smtp_mo is not None: + return self.smtp_mo + + self.smtp_mo = self.get_icm_cli_cache_entry( + 'smtp' + ) + if self.smtp_mo is not None: + return self.smtp_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /smtp # show detail + # SMTP Setting: + # Enabled: no + # Port Number: 25 + # Server Address: + # From Address: + # Recipient1: + # Mail-ID : + # Reachable: na + # Minimum Severity to Report: critical + # Recipient2: + # Mail-ID : + # Reachable: na + # Minimum Severity to Report: critical + # Recipient3: + # Mail-ID : + # Reachable: na + # Minimum Severity to Report: critical + # Recipient4: + # Mail-ID : + # Reachable: na + # Minimum Severity to Report: critical + + commands = [ + 'top', + 'scope smtp', + 'show detail' + ] + + success, output = self.run_commands( + commands + ) + + if not success: + return None + + self.smtp_mo = self.parse_dict( + output['show detail'], + start='SMTP Setting:', + ignore_start='Recipient' + ) + + if self.smtp_mo is None: + return None + + self.smtp_mo['Recipient'] = self.parse_list( + output['show detail'], + 'Recipient', + 'Recipient', + method='all' + ) + + self.set_imc_cli_cache_entry( + 'smtp', + self.smtp_mo + ) + + self.log.debug( + 'get_smtp_mo', + json.dumps(self.smtp_mo, indent=4) + ) + return self.smtp_mo + + def get_smtp_info(self, smtp_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in smtp_mo: + info[key] = smtp_mo[key] + + self.log.debug( + 'get_smtp_info', + json.dumps(info, indent=4) + ) + return info + + def get_smtp(self, cache_enabled=True): + smtp_mo = self.get_smtp_mo(cache_enabled=cache_enabled) + if smtp_mo is None: + return None + + smtp_info = self.get_smtp_info( + smtp_mo + ) + + return smtp_info diff --git a/lib/imc/cli/smtp/output.py b/lib/imc/cli/smtp/output.py new file mode 100644 index 00000000..87e1a3ab --- /dev/null +++ b/lib/imc/cli/smtp/output.py @@ -0,0 +1,15 @@ +class ImcCliSmtpOutput(): + def __init__(self): + pass + + def print_imc_smtp(self, info): + self.print_list_dict( + info, + 'SMTP' + ) + + def print_imc_smtp_compare(self, info): + self.print_compare( + info, + 'SMTP' + ) diff --git a/lib/imc/cli/snmp/__init__.py b/lib/imc/cli/snmp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/snmp/main.py b/lib/imc/cli/snmp/main.py new file mode 100644 index 00000000..8757e762 --- /dev/null +++ b/lib/imc/cli/snmp/main.py @@ -0,0 +1,225 @@ +import json + + +class ImcCliSnmp(): + def __init__(self): + self.snmp_mo = None + self.snmp_destination_mo = None + self.snmp_user_mo = None + + def get_snmp_mo(self, cache_enabled=True): + if cache_enabled: + if self.snmp_mo is not None: + return self.snmp_mo + + self.snmp_mo = self.get_icm_cli_cache_entry( + 'snmp' + ) + if self.snmp_mo is not None: + return self.snmp_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /snmp # show detail + # SNMP Settings: + # Enabled: yes + # SNMP Port: 161 + # System Contact: who@where + # System Location: unknown + # SNMP v2 Enabled: yes + # Access Community String: cimcpublic + # Trap Community String: public + # SNMP Community access: full + # SNMP v3 Enabled: no + # User Input EngineID: + # SNMP Engine ID: 80 00 1F 88 80 F5 6B A8 01 5F 88 12 66 + # Serial Number Enabled: no + + self.snmp_mo = self.show_dict( + 'show detail', + start='SNMP Settings:', + scope='snmp' + ) + + if self.snmp_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'snmp', + self.snmp_mo + ) + + self.log.debug( + 'get_snmp_mo', + json.dumps(self.snmp_mo, indent=4) + ) + return self.snmp_mo + + def get_snmp_destination_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.snmp_destination_mo is not None: + return self.snmp_destination_mo + + self.snmp_destination_mo = self.get_icm_cli_cache_entry( + 'snmp_destination' + ) + if self.snmp_destination_mo is not None: + return self.snmp_destination_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /snmp # show trap-destinations detail + # Trap Destination 1: + # Enabled: yes + # SNMP version: 2 + # Trap type: trap + # SNMP user: + # Trap Address(IPv4/IPv6/FQDN): + # Trap Port: 7162 + # Delete Trap: no + # Trap Community String: public + + if keep_scope: + self.snmp_destination_mo = self.show_list( + 'show trap-destinations detail', + 'Trap Destination __INDEX__:', + None, + method='last word', + top=False + ) + else: + self.snmp_destination_mo = self.show_list( + 'show trap-destinations detail', + 'Trap Destination __INDEX__:', + None, + method='last word', + scope='snmp' + ) + + if self.snmp_destination_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'snmp_destination', + self.snmp_destination_mo + ) + + self.log.debug( + 'get_snmp_destination_mo', + json.dumps(self.snmp_destination_mo, indent=4) + ) + return self.snmp_destination_mo + + def get_snmp_user_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.snmp_user_mo is not None: + return self.snmp_user_mo + + self.snmp_user_mo = self.get_icm_cli_cache_entry( + 'snmp_user' + ) + if self.snmp_user_mo is not None: + return self.snmp_user_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /snmp # show v3users detail + # User 1: + # Add User: no + # Security Name: (n/a) + # Security Level: (n/a) + # Auth Type: (n/a) + # Auth Key: ****** + # Encryption: (n/a) + # Private Key: ****** + + if keep_scope: + self.snmp_user_mo = self.show_list( + 'show v3users detail', + 'User __INDEX__:', + None, + method='last word', + top=False + ) + else: + self.snmp_user_mo = self.show_list( + 'show v3users detail', + 'User __INDEX__:', + None, + method='last word', + scope='snmp' + ) + + if self.snmp_user_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'snmp_user', + self.snmp_user_mo + ) + + self.log.debug( + 'get_snmp_user_mo', + json.dumps(self.snmp_user_mo, indent=4) + ) + return self.snmp_user_mo + + def get_snmp_info(self, snmp_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in snmp_mo: + info[key] = snmp_mo[key] + + return info + + def get_snmp_destination_info(self, snmp_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in snmp_mo: + info[key] = snmp_mo[key] + + return info + + def get_snmp_user_info(self, snmp_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in snmp_mo: + info[key] = snmp_mo[key] + + return info + + def get_snmp(self, cache_enabled=True): + snmp_mo = self.get_snmp_mo(cache_enabled=cache_enabled) + if snmp_mo is None: + return None + + snmp_info = self.get_snmp_info( + snmp_mo + ) + + snmp_info['Server'] = [] + snmp_destination_mo = self.get_snmp_destination_mo(keep_scope=True, cache_enabled=cache_enabled) + if snmp_destination_mo is not None: + for server_mo in snmp_destination_mo: + snmp_info['Server'].append( + self.get_snmp_destination_info( + server_mo + ) + ) + + snmp_info['User'] = [] + snmp_user_mo = self.get_snmp_user_mo(keep_scope=True, cache_enabled=cache_enabled) + if snmp_user_mo is not None: + for user_mo in snmp_user_mo: + snmp_info['User'].append( + self.get_snmp_user_info( + user_mo + ) + ) + + self.log.debug( + 'get_snmp_info', + json.dumps(snmp_info, indent=4) + ) + + return snmp_info diff --git a/lib/imc/cli/snmp/output.py b/lib/imc/cli/snmp/output.py new file mode 100644 index 00000000..73b2acd5 --- /dev/null +++ b/lib/imc/cli/snmp/output.py @@ -0,0 +1,9 @@ +class ImcCliSnmpOutput(): + def __init__(self): + pass + + def print_imc_snmp(self, info): + self.print_list_dict( + info, + 'SNMP' + ) diff --git a/lib/imc/cli/sol/__init__.py b/lib/imc/cli/sol/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/sol/main.py b/lib/imc/cli/sol/main.py new file mode 100644 index 00000000..15fa0917 --- /dev/null +++ b/lib/imc/cli/sol/main.py @@ -0,0 +1,68 @@ +import json + + +class ImcCliSol(): + def __init__(self): + self.sol_mo = None + + def get_sol_mo(self, cache_enabled=True): + if cache_enabled: + if self.sol_mo is not None: + return self.sol_mo + + self.sol_mo = self.get_icm_cli_cache_entry( + 'sol' + ) + if self.sol_mo is not None: + return self.sol_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show sol detail + # Serial Over LAN: + # Enabled: yes + # Baud Rate(bps): 115200 + # Com Port: com0 + # SOL SSH Port: 2400 + + self.sol_mo = self.show_dict( + 'show sol detail', + start='Serial Over LAN:' + ) + + if self.sol_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'sol', + self.sol_mo + ) + + self.log.debug( + 'get_sol_mo', + json.dumps(self.sol_mo, indent=4) + ) + return self.sol_mo + + def get_sol_info(self, sol_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in sol_mo: + info[key] = sol_mo[key] + + self.log.debug( + 'get_sol_info', + json.dumps(info, indent=4) + ) + return info + + def get_sol(self, cache_enabled=True): + sol_mo = self.get_sol_mo(cache_enabled=cache_enabled) + if sol_mo is None: + return None + + sol_info = self.get_sol_info( + sol_mo + ) + + return sol_info diff --git a/lib/imc/cli/sol/output.py b/lib/imc/cli/sol/output.py new file mode 100644 index 00000000..3cd34cb5 --- /dev/null +++ b/lib/imc/cli/sol/output.py @@ -0,0 +1,12 @@ +class ImcCliSolOutput(): + def __init__(self): + pass + + def print_imc_sol(self, info): + self.print_list_dict( + info, + 'Serial over LAN', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/ssh/__init__.py b/lib/imc/cli/ssh/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/ssh/main.py b/lib/imc/cli/ssh/main.py new file mode 100644 index 00000000..e829492c --- /dev/null +++ b/lib/imc/cli/ssh/main.py @@ -0,0 +1,69 @@ +import json + + +class ImcCliSsh(): + def __init__(self): + self.ssh_mo = None + + def get_ssh_mo(self, cache_enabled=True): + if cache_enabled: + if self.ssh_mo is not None: + return self.ssh_mo + + self.ssh_mo = self.get_icm_cli_cache_entry( + 'ssh' + ) + if self.ssh_mo is not None: + return self.ssh_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show ssh detail + # SSH Settings: + # SSH Port: 22 + # Timeout: 1800 + # Max Sessions: 4 + # Active Sessions: 1 + # Enabled: yes + + self.ssh_mo = self.show_dict( + 'show ssh detail', + start='SSH Settings:' + ) + + if self.ssh_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'ssh', + self.ssh_mo + ) + + self.log.debug( + 'get_ssh_mo', + json.dumps(self.ssh_mo, indent=4) + ) + return self.ssh_mo + + def get_ssh_info(self, ssh_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in ssh_mo: + info[key] = ssh_mo[key] + + self.log.debug( + 'get_ssh_info', + json.dumps(info, indent=4) + ) + return info + + def get_ssh(self, cache_enabled=True): + ssh_mo = self.get_ssh_mo(cache_enabled=cache_enabled) + if ssh_mo is None: + return None + + ssh_info = self.get_ssh_info( + ssh_mo + ) + + return ssh_info diff --git a/lib/imc/cli/ssh/output.py b/lib/imc/cli/ssh/output.py new file mode 100644 index 00000000..79f9a8ef --- /dev/null +++ b/lib/imc/cli/ssh/output.py @@ -0,0 +1,12 @@ +class ImcCliSshOutput(): + def __init__(self): + pass + + def print_imc_ssh(self, info): + self.print_list_dict( + info, + 'SSH', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/storageadapter/__init__.py b/lib/imc/cli/storageadapter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/storageadapter/main.py b/lib/imc/cli/storageadapter/main.py new file mode 100644 index 00000000..a9a35ad9 --- /dev/null +++ b/lib/imc/cli/storageadapter/main.py @@ -0,0 +1,120 @@ +import json + + +class ImcCliStorageAdapter(): + def __init__(self): + self.storage_adapter_mo = None + + def get_storage_adapter_mo(self, cache_enabled=True): + if cache_enabled: + if self.storage_adapter_mo is not None: + return self.storage_adapter_mo + + self.storage_adapter_mo = self.get_icm_cli_cache_entry( + 'storage_adapter' + ) + if self.storage_adapter_mo is not None: + return self.storage_adapter_mo + + # PCI Slot MRAID: + # Health: Good + # Controller Status: Optimal + # ROC Temperature: 62 degrees C + # Product Name: Cisco 12G Modular Raid Controller with 2GB cache (max 16 drives) + # Serial Number: SK00576315 + # Firmware Package Build: 51.19.0-4296 + # Product ID: LSI Logic + # Battery Status: Optimal + # NVRAM Size: 128 KB + # Memory Size: 2048 MB + # Flash Memory Size: 16 MB + # Cache Memory Size: 1374 MB + # Boot Drive: 0 + # Boot Drive is PD: false + # Product PID: UCSC-RAID-M5 + # Storage Firmware Log Status: Not Downloaded + # Controller is Secured: 0 + # Controller cache pinned status: false + # Foreign config PD count: 0 + + self.storage_adapter_mo = self.show_list( + 'show storageadapter detail', + 'PCI Slot', + 'Slot', + method='last word', + scope='chassis' + ) + + if self.storage_adapter_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'storage_adapter', + self.storage_adapter_mo + ) + + self.log.debug( + 'get_storage_adapter_mo', + json.dumps(self.storage_adapter_mo, indent=4) + ) + return self.storage_adapter_mo + + def get_storage_adapter_info(self, storage_adapter_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in storage_adapter_mo: + info[key] = storage_adapter_mo[key] + + if 'Health' in info: + if info['Health'] == 'Good': + info['__Output']['Health'] = 'Green' + else: + info['__Output']['Health'] = 'Red' + + if 'Controller Status' in info: + if info['Controller Status'] == 'Optimal': + info['__Output']['Controller Status'] = 'Green' + else: + info['__Output']['Controller Status'] = 'Red' + + info['__Key'] = 'Slot' + info['__Value'] = info[info['__Key']] + + self.log.debug( + 'get_storage_adapter_info', + json.dumps(info, indent=4) + ) + return info + + def get_storage_adapter(self, cache_enabled=True): + storage_adapters_mo = self.get_storage_adapter_mo(cache_enabled=cache_enabled) + if storage_adapters_mo is None: + return None + + storage_adapters_info = [] + + for storage_adapter_mo in storage_adapters_mo: + storage_adapters_info.append( + self.get_storage_adapter_info( + storage_adapter_mo + ) + ) + + return storage_adapters_info + + def get_storage_adapter_slots(self, cache_enabled=True): + storage_adapters = self.get_storage_adapter( + cache_enabled=cache_enabled + ) + if storage_adapters is None: + return None + + slots = [] + for storage_adapter in storage_adapters: + slots.append( + storage_adapter['Slot'] + ) + + return slots diff --git a/lib/imc/cli/storageadapter/output.py b/lib/imc/cli/storageadapter/output.py new file mode 100644 index 00000000..af4cebf1 --- /dev/null +++ b/lib/imc/cli/storageadapter/output.py @@ -0,0 +1,16 @@ +class ImcCliStorageAdapterOutput(): + def __init__(self): + pass + + def print_imc_storage_adapter(self, info): + self.print_list_dict( + info, + 'Storage Adapter' + ) + + def print_imc_storage_adapter_compare(self, info): + self.print_compare( + info, + 'Storage Adapter', + expand=['Product Name'] + ) diff --git a/lib/imc/cli/syslog/__init__.py b/lib/imc/cli/syslog/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/syslog/main.py b/lib/imc/cli/syslog/main.py new file mode 100644 index 00000000..2d8e9664 --- /dev/null +++ b/lib/imc/cli/syslog/main.py @@ -0,0 +1,148 @@ +import json + + +class ImcCliSyslog(): + def __init__(self): + self.syslog_mo = None + self.syslog_server_mo = None + + def get_syslog_mo(self, cache_enabled=True): + if cache_enabled: + if self.syslog_mo is not None: + return self.syslog_mo + + self.syslog_mo = self.get_icm_cli_cache_entry( + 'syslog' + ) + if self.syslog_mo is not None: + return self.syslog_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc/log # show detail + # LOG: + # Local Syslog Severity: debug + # Remote Syslog Severity: warning + # Log User Name on Failed Login: disabled + + self.syslog_mo = self.show_dict( + 'show detail', + start='LOG:', + scope='cimc,log' + ) + + if self.syslog_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'syslog', + self.syslog_mo + ) + + self.log.debug( + 'get_syslog_mo', + json.dumps(self.syslog_mo, indent=4) + ) + return self.syslog_mo + + def get_syslog_server_mo(self, keep_scope=False, cache_enabled=True): + if cache_enabled: + if self.syslog_server_mo is not None: + return self.syslog_server_mo + + self.syslog_server_mo = self.get_icm_cli_cache_entry( + 'syslog_server' + ) + if self.syslog_server_mo is not None: + return self.syslog_server_mo + + # comp-7-p2b-eu-spdc-WMP24040061 /cimc/log # show server detail + # Syslog Server 1: + # Syslog Server Address: + # Syslog Server Port: 5140 + # Enabled: yes + # Syslog Server protocol: udp + # Secure Remote Syslog Enabled: no + # Certificate Exists: no + # Syslog Server 2: + # Syslog Server Address: + # Syslog Server Port: 514 + # Enabled: no + # Syslog Server protocol: udp + # Secure Remote Syslog Enabled: no + # Certificate Exists: no + + if keep_scope: + self.syslog_server_mo = self.show_list( + 'show server detail', + 'Syslog Server __INDEX__:', + None, + method='last word', + top=False + ) + else: + self.syslog_server_mo = self.show_list( + 'show server detail', + 'Syslog Server __INDEX__:', + None, + method='last word', + scope='cimc,log' + ) + + if self.syslog_server_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'syslog_server', + self.syslog_server_mo + ) + + self.log.debug( + 'get_syslog_server_mo', + json.dumps(self.syslog_server_mo, indent=4) + ) + return self.syslog_server_mo + + def get_syslog_info(self, syslog_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in syslog_mo: + info[key] = syslog_mo[key] + + return info + + def get_syslog_server_info(self, syslog_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in syslog_mo: + info[key] = syslog_mo[key] + + return info + + def get_syslog(self, cache_enabled=True): + syslog_mo = self.get_syslog_mo(cache_enabled=cache_enabled) + if syslog_mo is None: + return None + + syslog_info = self.get_syslog_info( + syslog_mo + ) + syslog_info['Server'] = [] + + syslog_server_mo = self.get_syslog_server_mo(keep_scope=True, cache_enabled=cache_enabled) + if syslog_server_mo is not None: + for server_mo in syslog_server_mo: + syslog_info['Server'].append( + self.get_syslog_server_info( + server_mo + ) + ) + + self.log.debug( + 'get_syslog_info', + json.dumps(syslog_info, indent=4) + ) + + return syslog_info diff --git a/lib/imc/cli/syslog/output.py b/lib/imc/cli/syslog/output.py new file mode 100644 index 00000000..440e34de --- /dev/null +++ b/lib/imc/cli/syslog/output.py @@ -0,0 +1,9 @@ +class ImcCliSyslogOutput(): + def __init__(self): + pass + + def print_imc_syslog(self, info): + self.print_list_dict( + info, + 'Syslog' + ) diff --git a/lib/imc/cli/tpm/__init__.py b/lib/imc/cli/tpm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/tpm/main.py b/lib/imc/cli/tpm/main.py new file mode 100644 index 00000000..6d56afcd --- /dev/null +++ b/lib/imc/cli/tpm/main.py @@ -0,0 +1,73 @@ +import json + + +class ImcCliTpm(): + def __init__(self): + self.tpm_mo = None + + def get_tpm_mo(self, cache_enabled=True): + if cache_enabled: + if self.tpm_mo is not None: + return self.tpm_mo + + self.tpm_mo = self.get_icm_cli_cache_entry( + 'tpm' + ) + if self.tpm_mo is not None: + return self.tpm_mo + + # Version NA: + # Presence: empty + # Enabled-Status: unknown + # Active-Status: unknown + # Ownership: unknown + # Revision: NA + # Model: NA + # Vendor: NA + # Serial: NA + # Firmare Version : NA + + self.tpm_mo = self.show_dict( + 'show tpm-inventory detail', + start='Version ', + scope='chassis' + ) + + if self.tpm_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'tpm', + self.tpm_mo + ) + + self.log.debug( + 'get_tpm_mo', + json.dumps(self.tpm_mo, indent=4) + ) + return self.tpm_mo + + def get_tpm_info(self, tpm_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in tpm_mo: + info[key] = tpm_mo[key] + + self.log.debug( + 'get_tpm_info', + json.dumps(info, indent=4) + ) + return info + + def get_tpm(self, cache_enabled=True): + tpm_mo = self.get_tpm_mo(cache_enabled=cache_enabled) + if tpm_mo is None: + return None + + tpm_info = self.get_tpm_info( + tpm_mo + ) + + return tpm_info diff --git a/lib/imc/cli/tpm/output.py b/lib/imc/cli/tpm/output.py new file mode 100644 index 00000000..b65df3ec --- /dev/null +++ b/lib/imc/cli/tpm/output.py @@ -0,0 +1,15 @@ +class ImcCliTpmOutput(): + def __init__(self): + pass + + def print_imc_tpm(self, info): + self.print_list_dict( + info, + 'TPM' + ) + + def print_imc_tpm_compare(self, info): + self.print_compare( + info, + 'TPM' + ) diff --git a/lib/imc/cli/user.py b/lib/imc/cli/user.py new file mode 100644 index 00000000..3a668fa2 --- /dev/null +++ b/lib/imc/cli/user.py @@ -0,0 +1,50 @@ +class ImcCliUser(): + def __init__(self): + pass + + def add_user(self, user_id, username, password, role): + commands = [ + 'scope user %s' % (user_id), + 'set enabled yes', + 'set name %s' % (username), + 'set password', + password, + password, + 'set role %s' % (role), + 'commit' + ] + + success, output = self.run_commands( + commands + ) + + return success + + def set_user(self, user_id, password, role): + commands = [ + 'scope user %s' % (user_id), + 'set password', + password, + password, + 'set role %s' % (role), + 'commit' + ] + + success, output = self.run_commands( + commands + ) + + return success + + def delete_user(self, user_id): + commands = [ + 'scope user %s' % (user_id), + 'restore', + 'yes' + ] + + success, output = self.run_commands( + commands + ) + + return success diff --git a/lib/imc/cli/utilization/__init__.py b/lib/imc/cli/utilization/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/utilization/main.py b/lib/imc/cli/utilization/main.py new file mode 100644 index 00000000..fce83c67 --- /dev/null +++ b/lib/imc/cli/utilization/main.py @@ -0,0 +1,66 @@ +import json + + +class ImcCliUtilization(): + def __init__(self): + self.utilization_mo = None + + def get_utilization_mo(self, cache_enabled=True): + if cache_enabled: + if self.utilization_mo is not None: + return self.utilization_mo + + self.utilization_mo = self.get_icm_cli_cache_entry( + 'utilization' + ) + if self.utilization_mo is not None: + return self.utilization_mo + + # CPU Utilization (%): 3 + # Memory Utilization (%): 2 + # I/O Utilization (%): 0 + # Overall Utilization (%): 3 + + self.utilization_mo = self.show_dict( + 'show cups-utilization detail', + scope='chassis' + ) + + if self.utilization_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'utilization', + self.utilization_mo + ) + + self.log.debug( + 'get_utilization_mo', + json.dumps(self.utilization_mo, indent=4) + ) + return self.utilization_mo + + def get_utilization_info(self, utilization_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in utilization_mo: + info[key] = utilization_mo[key] + + self.log.debug( + 'get_utilization_mo', + json.dumps(info, indent=4) + ) + return info + + def get_utilization(self, cache_enabled=True): + utilization_mo = self.get_utilization_mo(cache_enabled=cache_enabled) + if utilization_mo is None: + return None + + utilization_info = self.get_utilization_info( + utilization_mo + ) + + return utilization_info diff --git a/lib/imc/cli/utilization/output.py b/lib/imc/cli/utilization/output.py new file mode 100644 index 00000000..1bfddea6 --- /dev/null +++ b/lib/imc/cli/utilization/output.py @@ -0,0 +1,15 @@ +class ImcCliUtilizationOutput(): + def __init__(self): + pass + + def print_imc_utilization(self, info): + self.print_list_dict( + info, + 'Utilization' + ) + + def print_imc_utilization_compare(self, info): + self.print_compare( + info, + 'Utilization' + ) diff --git a/lib/imc/cli/version/__init__.py b/lib/imc/cli/version/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/version/main.py b/lib/imc/cli/version/main.py new file mode 100644 index 00000000..015b125c --- /dev/null +++ b/lib/imc/cli/version/main.py @@ -0,0 +1,68 @@ +import json + + +class ImcCliVersion(): + def __init__(self): + self.version_mo = None + + def get_version_mo(self, cache_enabled=True): + if cache_enabled: + if self.version_mo is not None: + return self.version_mo + + self.version_mo = self.get_icm_cli_cache_entry( + 'version' + ) + if self.version_mo is not None: + return self.version_mo + + # Firmware Version + # -------------------- + # 4.2(2a) + + commands = [ + 'show version' + ] + + success, output = self.run_commands( + commands + ) + + if not success: + return None + + self.version_mo = output['show version'].split('\n')[-1] + + self.set_imc_cli_cache_entry( + 'version', + self.version_mo + ) + + self.log.debug( + 'get_version_mo', + json.dumps(self.version_mo, indent=4) + ) + return self.version_mo + + def get_version_info(self, version_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + info['Firmware Version'] = version_mo + + self.log.debug( + 'get_version_mo', + json.dumps(info, indent=4) + ) + return info + + def get_version(self, cache_enabled=True): + version_mo = self.get_version_mo(cache_enabled=cache_enabled) + if version_mo is None: + return None + + version_info = self.get_version_info( + version_mo + ) + + return version_info diff --git a/lib/imc/cli/version/output.py b/lib/imc/cli/version/output.py new file mode 100644 index 00000000..64e6992f --- /dev/null +++ b/lib/imc/cli/version/output.py @@ -0,0 +1,15 @@ +class ImcCliVersionOutput(): + def __init__(self): + pass + + def print_imc_version(self, info): + self.print_list_dict( + info, + 'Version' + ) + + def print_imc_version_compare(self, info): + self.print_compare( + info, + 'Version' + ) diff --git a/lib/imc/cli/vmedia/__init__.py b/lib/imc/cli/vmedia/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/vmedia/main.py b/lib/imc/cli/vmedia/main.py new file mode 100644 index 00000000..65e9b2de --- /dev/null +++ b/lib/imc/cli/vmedia/main.py @@ -0,0 +1,68 @@ +import json + + +class ImcCliVmedia(): + def __init__(self): + self.vmedia_mo = None + + def get_vmedia_mo(self, cache_enabled=True): + if cache_enabled: + if self.vmedia_mo is not None: + return self.vmedia_mo + + self.vmedia_mo = self.get_icm_cli_cache_entry( + 'vmedia' + ) + if self.vmedia_mo is not None: + return self.vmedia_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show vmedia detail + # vMedia Settings: + # Enabled: yes + # Max Sessions: 1 + # Active Sessions: 0 + # Low Power USB Enabled: yes + + self.vmedia_mo = self.show_dict( + 'show vmedia detail', + start='vMedia Settings:' + ) + + if self.vmedia_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'vmedia', + self.vmedia_mo + ) + + self.log.debug( + 'get_vmedia_mo', + json.dumps(self.vmedia_mo, indent=4) + ) + return self.vmedia_mo + + def get_vmedia_info(self, vmedia_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in vmedia_mo: + info[key] = vmedia_mo[key] + + self.log.debug( + 'get_vmedia_info', + json.dumps(info, indent=4) + ) + return info + + def get_vmedia(self, cache_enabled=True): + vmedia_mo = self.get_vmedia_mo(cache_enabled=cache_enabled) + if vmedia_mo is None: + return None + + vmedia_info = self.get_vmedia_info( + vmedia_mo + ) + + return vmedia_info diff --git a/lib/imc/cli/vmedia/output.py b/lib/imc/cli/vmedia/output.py new file mode 100644 index 00000000..cd860a82 --- /dev/null +++ b/lib/imc/cli/vmedia/output.py @@ -0,0 +1,12 @@ +class ImcCliVmediaOutput(): + def __init__(self): + pass + + def print_imc_vmedia(self, info): + self.print_list_dict( + info, + 'vMedia', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/cli/xml/__init__.py b/lib/imc/cli/xml/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/imc/cli/xml/main.py b/lib/imc/cli/xml/main.py new file mode 100644 index 00000000..5f97065d --- /dev/null +++ b/lib/imc/cli/xml/main.py @@ -0,0 +1,67 @@ +import json + + +class ImcCliXml(): + def __init__(self): + self.xml_mo = None + + def get_xml_mo(self, cache_enabled=True): + if cache_enabled: + if self.xml_mo is not None: + return self.xml_mo + + self.xml_mo = self.get_icm_cli_cache_entry( + 'xml' + ) + if self.xml_mo is not None: + return self.xml_mo + + # comp-7-p2b-eu-spdc-WMP24040061# show xmlapi detail + # XMLAPI Settings: + # Enabled: yes + # Active Sessions: 0 + # Max Sessions: 4 + + self.xml_mo = self.show_dict( + 'show xmlapi detail', + start='XMLAPI Settings:' + ) + + if self.xml_mo is None: + return None + + self.set_imc_cli_cache_entry( + 'xml', + self.xml_mo + ) + + self.log.debug( + 'get_xml_mo', + json.dumps(self.xml_mo, indent=4) + ) + return self.xml_mo + + def get_xml_info(self, xml_mo): + info = {} + info['__Output'] = {} + info['__IP'] = self.endpoint_ip + + for key in xml_mo: + info[key] = xml_mo[key] + + self.log.debug( + 'get_xml_info', + json.dumps(info, indent=4) + ) + return info + + def get_xml(self, cache_enabled=True): + xml_mo = self.get_xml_mo(cache_enabled=cache_enabled) + if xml_mo is None: + return None + + xml_info = self.get_xml_info( + xml_mo + ) + + return xml_info diff --git a/lib/imc/cli/xml/output.py b/lib/imc/cli/xml/output.py new file mode 100644 index 00000000..48808d2a --- /dev/null +++ b/lib/imc/cli/xml/output.py @@ -0,0 +1,12 @@ +class ImcCliXmlOutput(): + def __init__(self): + pass + + def print_imc_xml(self, info): + self.print_list_dict( + info, + 'XML API', + add_endpoint_ip=True, + underline=False, + allow_order_subkeys=False + ) diff --git a/lib/imc/settings.py b/lib/imc/settings.py new file mode 100644 index 00000000..aeb0b2c3 --- /dev/null +++ b/lib/imc/settings.py @@ -0,0 +1,216 @@ +import os +import json +import traceback + +from lib import file_helper +from lib import ip_helper +from lib import log_helper +from lib.settings_helper import Settings + + +class ImcEndpointSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.endpoint_directory = os.path.join( + self.settings_dir, + 'imc-endpoint' + ) + + self.imc_settings_filename = os.path.join( + self.settings_dir, + 'imc' + ) + + if not self.initialize_imc_settings(): + raise ValueError('IMC endpoints initialization failed') + + def get_default_imc_endpoint_settings(self): + imc_settings = {} + imc_settings['CacheEnabled'] = True + imc_settings['CacheTtl'] = 600 + return imc_settings + + def initialize_imc_settings(self): + try: + if not os.path.isdir(self.endpoint_directory): + os.makedirs(self.endpoint_directory) + + if not os.path.isfile(self.imc_settings_filename): + success = file_helper.set_file_json( + self.imc_settings_filename, + self.get_default_imc_endpoint_settings() + ) + if not success: + self.log.error( + 'initialize_imc_settings', + 'Failed to create file: %s' % (self.imc_settings_filename) + ) + return False + + except BaseException: + self.log.error( + 'initialize_imc_settings', + traceback.format_exc() + ) + return False + + return True + + def get_imc_settings(self): + return file_helper.get_file_json(self.imc_settings_filename) + + def get_endpoint_ids(self): + return os.listdir(self.endpoint_directory) + + def get_endpoint_directory(self, endpoint_id): + return os.path.join( + self.endpoint_directory, + endpoint_id + + ) + + def is_endpoint(self, endpoint_id): + if self.get_endpoint_settings(endpoint_id) is None: + return False + return True + + def get_endpoint_settings(self, endpoint_id): + endpoint_directory = os.path.join( + self.endpoint_directory, + endpoint_id + ) + + if not os.path.isdir(endpoint_directory): + return None + + endpoint_settings = {} + endpoint_settings['id'] = endpoint_id + for key in ['cli', 'api']: + endpoint_filename = os.path.join( + endpoint_directory, + key + ) + if not os.path.isfile(endpoint_filename): + endpoint_settings[key] = None + settings = {} + settings['enabled'] = False + else: + try: + with open(endpoint_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + settings['enabled'] = True + + except BaseException: + self.log.error( + 'get_endpoint_settings', + 'File read failed: %s' % (endpoint_filename) + ) + settings = {} + settings['enabled'] = False + + endpoint_settings[key] = settings + + return endpoint_settings + + def get_endpoints(self, ip_address=None, ip_addresses=None, ip_subnet=None): + endpoint_ids = self.get_endpoint_ids() + + endpoints = [] + if endpoint_ids is not None: + for endpoint_id in endpoint_ids: + if ip_address is not None and ip_address != endpoint_id: + continue + + if ip_addresses is not None and endpoint_id not in ip_addresses: + continue + + if ip_subnet is not None and not ip_helper.is_ipv4_in_cidr(endpoint_id, ip_subnet): + continue + + endpoint_settings = self.get_endpoint_settings(endpoint_id) + if endpoint_settings is not None: + endpoints.append( + endpoint_settings + ) + + return endpoints + + def get_cli_endpoint(self, ip_address): + endpoint_settings = self.get_endpoint_settings(ip_address) + if endpoint_settings is None: + return None + + if endpoint_settings['cli']['enabled']: + return endpoint_settings['cli'] + + return None + + def get_cli_endpoints(self, ip_address=None, ip_addresses=None, ip_subnet=None): + all_endpoints = self.get_endpoints( + ip_address=ip_address, + ip_addresses=ip_addresses, + ip_subnet=ip_subnet + ) + if all_endpoints is None: + return None + + cli_endpoints = [] + for endpoint in all_endpoints: + if endpoint['cli']['enabled']: + cli_endpoints.append( + endpoint['cli'] + ) + + return cli_endpoints + + def set_endpoint_settings(self, endpoint_id, filename, settings): + endpoint_directory = os.path.join( + self.endpoint_directory, + endpoint_id + ) + if not os.path.isdir(endpoint_directory): + os.makedirs(endpoint_directory, exist_ok=True) + + endpoint_filename = os.path.join( + endpoint_directory, + filename + ) + + try: + with open(endpoint_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + settings, + indent=4 + ) + ) + + except BaseException: + self.log.error( + 'set_endpoint_settings', + 'File write failed: %s' % (endpoint_filename) + ) + return False + + return True + + def set_imc_ssh_access(self, ip_address, username, password, port=22): + endpoint_settings = {} + endpoint_settings['ip'] = ip_address + endpoint_settings['port'] = port + endpoint_settings['username'] = username + endpoint_settings['password'] = password + + if not self.set_endpoint_settings(ip_address, 'cli', endpoint_settings): + self.log.error( + 'set_imc_ssh_access', + 'Failed: %s' % (ip_address) + ) + return False + + return True diff --git a/lib/info_helper.py b/lib/info_helper.py new file mode 100644 index 00000000..fbd95ba2 --- /dev/null +++ b/lib/info_helper.py @@ -0,0 +1,106 @@ +from lib import log_helper + + +class InfoHelper(): + def __init__(self, log_id=None): + self.log = log_helper.Log(log_id=log_id) + + def is_ancestor(self, managed_object, ancestor_type, ancestor_moid): + if managed_object is None: + return False + + if 'Ancestors' not in managed_object: + return False + + for ancestor in managed_object['Ancestors']: + if ancestor['ObjectType'] == ancestor_type: + if ancestor['Moid'] == ancestor_moid: + return True + + return False + + def get_objects_with_ancestor(self, managed_objects, ancestor_type, ancestor_moid, sort_by=None): + if managed_objects is None: + return None + + selected_objects = [] + for managed_object in managed_objects: + if self.is_ancestor(managed_object, ancestor_type, ancestor_moid): + selected_objects.append( + managed_object + ) + + if sort_by is not None: + selected_objects = sorted(selected_objects, key=lambda i: i[sort_by]) + + return selected_objects + + def convert_cpu_capacity(self, value): + try: + value = '%s [GHz]' % ( + int(value / 1000) + ) + except BaseException: + self.log.error('info_helper.convert_cpu_capacity', value) + return None + return value + + def convert_cpu_usage(self, value): + try: + value = '%s%%' % (int(value)) + except BaseException: + self.log.error('info_helper.convert_cpu_usage', value) + return None + return value + + def convert_pct(self, pct): + try: + value = '%s%%' % (round(pct, 2)) + except BaseException: + self.log.error('info_helper.convert_cpu_capacity', pct) + return None + return value + + def convert_memory(self, value, precision=2): + try: + unit = ['KiB', 'MiB', 'GiB', 'TiB'] + for index in range(0, 4): + value = value / 1024 + if value < 1000: + break + + if precision == 0: + value = '%s [%s]' % ( + int(value), + unit[index] + ) + else: + value = '%s [%s]' % ( + round(value, precision), + unit[index] + ) + + except BaseException: + self.log.error('info_helper.convert_memory', value) + return None + + return value + + def convert_storage(self, value): + try: + unit = ['KB', 'MB', 'GB', 'TB'] + for index in range(0, 4): + value = value / 1000 + if value < 1000: + break + + value = '%s [%s]' % ( + round(value, 2), + unit[index] + ) + + except BaseException: + self.log.error('info_helper.convert_storage', value) + return None + + return value diff --git a/lib/input_validator.py b/lib/input_validator.py new file mode 100644 index 00000000..cef5e105 --- /dev/null +++ b/lib/input_validator.py @@ -0,0 +1,833 @@ +import os + +from lib import file_helper +from lib import ip_helper +from lib import log_helper + + +class InputValidator(): + def __init__(self, log_id=None): + self.log_handler = log_helper.Log(log_id=log_id) + self.base_directory = None + + def get_template_dir(self, template_name, template_category=None): + main_dir = file_helper.get_main_dir() + if main_dir is None: + return None + + templates_dir = os.path.join(main_dir, 'templates') + if template_category is not None: + templates_dir = os.path.join(templates_dir, template_category) + + template_dir = os.path.join( + templates_dir, + template_name + ) + if not os.path.isdir(template_dir): + self.log_handler.error( + 'get_template_dir', + 'Template definition not found: %s' % (template_dir) + ) + return None + + return template_dir + + def get_template_files_dir(self, template_name, template_category=None): + template_dir = self.get_template_dir(template_name, template_category=template_category) + if template_dir is None: + return None + + files_dir = os.path.join( + template_dir, + 'files' + ) + if not os.path.isdir(files_dir): + self.log_handler.error( + 'get_template_files_dir', + 'Template files not found: %s' % (files_dir) + ) + return None + + return files_dir + + def get_template_rules_dir(self, template_name, template_category=None): + template_dir = self.get_template_dir(template_name, template_category=template_category) + if template_dir is None: + return None + + rules_dir = os.path.join( + template_dir, + 'rules' + ) + if not os.path.isdir(rules_dir): + self.log_handler.error( + 'get_template_rules_dir', + 'Template rules not found: %s' % (rules_dir) + ) + return None + + return rules_dir + + def get_section_rules(self, template_name, section_name, template_category=None): + rules_dir = self.get_template_rules_dir(template_name, template_category=template_category) + if rules_dir is None: + return None + + filename = os.path.join(rules_dir, '%s.yaml' % (section_name)) + content = file_helper.get_file_yaml( + filename + ) + if content is None: + self.log_handler.error( + 'get_section_rules', + 'Section %s rules read failed: %s' % (section_name, filename) + ) + return None + + return content + + def get_template_name(self, user_input, template_reference=None, template_name=None): + if template_reference is None and template_name is None: + self.log_handler.error( + 'get_template_name', + 'Define template reference or name' + ) + return None + + if template_name is not None: + return template_name + + # Keep it stupid simple. Template reference has syntax section.key. No need to make it more complicated + try: + (section, key) = template_reference.split('.') + template_name = user_input[section][key] + except BaseException: + self.log_handler.error( + 'get_template_name', + 'Template name expected at %s' % (template_reference) + ) + return None + + return template_name + + def get_template_definition_key_value(self, template_name, key, template_category=None): + template_definition = self.get_template_definition(template_name, template_category=template_category) + if template_definition is None: + return None + + if key not in template_definition['main']: + self.log_handler.error( + 'get_template_definition_key_value', + 'No key %s found in template definition %s' % (key, template_name) + ) + return None + + return template_definition['main'][key] + + def get_template_definition(self, template_name, template_category=None): + rules_dir = self.get_template_rules_dir(template_name, template_category=template_category) + if rules_dir is None: + return None + + filename = os.path.join(rules_dir, 'main.yaml') + content = file_helper.get_file_yaml( + filename + ) + if content is None: + self.log_handler.error( + 'get_template_definition', + 'Template definition read failed: %s' % (filename) + ) + + return content + + def get_template_filename(self, template_name, filename, template_category=None): + files_dir = self.get_template_files_dir(template_name, template_category=template_category) + if files_dir is None: + return None + + template_filename = os.path.join(files_dir, filename) + if not os.path.isfile(template_filename): + self.log_handler.error( + 'get_template_filename', + 'Template file not found: %s' % (template_filename) + ) + return None + + return template_filename + + def get_input(self, location): + if not os.path.isfile(location) and not os.path.isdir(location): + self.log_handler.error( + 'get_input', + 'Specify valid location user input' + ) + return None + + if os.path.isfile(location): + content = file_helper.get_file_yaml( + location + ) + if content is None: + return None + + return content + + content = {} + for filename in os.listdir(location): + if filename in ['.gitignore']: + continue + + fullname = os.path.join(location, filename) + if os.path.isdir(fullname): + continue + + part = file_helper.get_file_yaml( + fullname + ) + if part is None: + continue + + for key in part: + if key in content: + self.log_handler.error( + 'get_input', + 'Sections have to be defined in single file: %s' % (key) + ) + return None + + content[key] = part[key] + + return content + + def is_key_in_section(self, key, section): + try: + value = None + for field in key.split('.'): + if value is None: + value = section[field] + continue + + value = value[field] + + except BaseException: + return False + + return True + + def get_key_value(self, key, section): + try: + value = None + for field in key.split('.'): + if value is None: + value = section[field] + continue + + value = value[field] + + except BaseException: + return None + + return value + + def add_key_value(self, section, key, value): + try: + if len(key.split('.')) == 1: + section[key] = value + return section + + subsection = None + for subdict in key.split('.')[:-1]: + if subsection is None: + if subdict not in section: + section[subdict] = {} + subsection = section[subdict] + continue + + if subdict not in subsection: + subsection[subdict] = {} + subsection = subsection[subdict] + + subsection[key.split('.')[-1]] = value + + except BaseException: + return None + + return section + + def validate_key_value(self, section_name, key, rules, value): + attribute_name = '%s.%s' % (section_name, key) + + if rules['type'] not in ['str', 'int', 'bool']: + self.log_handler.error( + 'validate_key_value', + 'Unsupported attribute type: %s' % (rules['type']) + ) + return False, None + + if rules['type'] == 'str': + if value is None and rules['check'] == 'local-file-null-accepted': + pass + else: + if not isinstance(value, str): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s type is %s' % (attribute_name, rules['type']) + ) + return False, None + + if rules['type'] == 'int': + if not isinstance(value, int): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s type is %s' % (attribute_name, rules['type']) + ) + return False, None + + if rules['type'] == 'bool': + if not isinstance(value, bool): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s type is %s' % (attribute_name, rules['type']) + ) + return False, None + + if rules['check'] is not None: + if rules['type'] == 'bool': + if rules['check'] == 'must-be-true': + if not value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is True: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'must-be-false': + if value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is False: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['type'] == 'str': + if rules['check'] == 'ipv4': + if not ip_helper.is_valid_ipv4_address(value): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid IPv4 address: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'ipv4s': + for item in value.split(','): + if not ip_helper.is_valid_ipv4_address(item): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is list of valid IPv4 addresses: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'ipv6': + if not ip_helper.is_valid_ipv6_address(value): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid IPv6 address: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'cidrv4': + if not ip_helper.is_valid_ipv4_cidr(value): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid IPv4 CIDR: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'cidrv6': + if not ip_helper.is_valid_ipv6_cidr(value): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid IPv6 CIDR: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'url': + if not ip_helper.is_url_valid(value): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid URL: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'dhcp-v4-range': + if len(value.split('-')) != 2: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid IPv4 address ranges: %s' % (attribute_name, value) + ) + return False, None + + (start_ip, end_ip) = value.split('-') + if not ip_helper.is_valid_ipv4_address(start_ip) or not ip_helper.is_valid_ipv4_address(end_ip): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is valid IPv4 address ranges: %s' % (attribute_name, value) + ) + return False, None + + return True, value + + if rules['check'] == 'not-empty-no-spaces': + if value is None: + value = '' + value = value.strip() + + if len(value) == 0: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is non-empty string without spaces: %s' % (attribute_name, value) + ) + return False, None + + if ' ' in value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is non-empty string without spaces: %s' % (attribute_name, value) + ) + return False, None + + return True, value + + if rules['check'] == 'not-empty': + if value is None: + value = '' + value = value.strip() + + if len(value) == 0: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is non-empty string: %s' % (attribute_name, value) + ) + return False, None + + return True, value + + if rules['check'].startswith('values:'): + reference_values = rules['check'].lstrip('values').lstrip(':') + if value not in reference_values.split(','): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is one of %s: %s' % (attribute_name, reference_values, value) + ) + return False, None + return True, value + + if rules['check'] == 'local-file': + if os.path.isabs(value): + filename = value + else: + filename = os.path.join( + self.base_directory, + value + ) + if not os.path.isfile(filename): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is existing local file: %s' % (attribute_name, filename) + ) + return False, None + + return True, value + + if rules['check'] == 'local-file-null-accepted': + if value is None: + return True, None + + if len(value) == 0: + return True, None + + if not os.path.isfile(value): + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is existing local file: %s' % (attribute_name, value) + ) + return False, None + + return True, value + + if rules['check'] == 'must-be-null': + if value is None: + return True, None + + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is null' % (attribute_name) + ) + return False, None + + if rules['type'] == 'int': + if rules['check'] == 'port': + if value < 1 or value > 65535: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is within TCP/UDP port range: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'host-prefix-v4': + if value < 1 or value > 30: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is within <1,30> range: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'] == 'host-prefix-v6': + if value > 127 or value < 64: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is within <64,127> range: %s' % (attribute_name, value) + ) + return False, None + return True, value + + if rules['check'].startswith('ge'): + reference_value = int(rules['check'].lstrip('ge')) + if value < reference_value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is greater or equal %s: %s' % (attribute_name, reference_value, value) + ) + return False, None + return True, value + + if rules['check'].startswith('gt'): + reference_value = int(rules['check'].lstrip('gt')) + if value <= reference_value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is greater than %s: %s' % (attribute_name, reference_value, value) + ) + return False, None + return True, value + + if rules['check'].startswith('le'): + reference_value = int(rules['check'].lstrip('le')) + if value > reference_value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is lower or equal %s: %s' % (attribute_name, reference_value, value) + ) + return False, None + return True, value + + if rules['check'].startswith('lt'): + reference_value = int(rules['check'].lstrip('lt')) + if value >= reference_value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is lower than %s: %s' % (attribute_name, reference_value, value) + ) + return False, None + return True, value + + if rules['check'].startswith('eq'): + reference_value = int(rules['check'].lstrip('eq')) + if value != reference_value: + self.log_handler.error( + 'validate_key_value', + 'Expected attribute %s value is %s: %s' % (attribute_name, reference_value, value) + ) + return False, None + return True, value + + self.log_handler.error( + 'validate_key_value', + 'Unsupported check: %s' % (rules['check']) + ) + return False, None + + return True, value + + def validate_section(self, section_name, section_rules, user_input): + if section_rules['value'] == 'dict': + if not isinstance(user_input, dict): + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be dictionary' % (section_name) + ) + return None + + if not section_rules['validate']: + validated_input = {} + for key in user_input: + validated_input[key] = user_input[key] + + if section_rules['validate']: + validated_input = {} + for key in section_rules['properties']: + if section_rules['properties'][key]['mandatory']: + if not self.is_key_in_section(key, user_input): + self.log_handler.error( + 'validate_section', + 'Required property %s.%s' % (section_name, key) + ) + return None + + success, value = self.validate_key_value( + section_name, + key, + section_rules['properties'][key], + self.get_key_value(key, user_input) + ) + if not success: + return None + + validated_input = self.add_key_value( + validated_input, + key, + value + ) + + if not section_rules['properties'][key]['mandatory']: + if self.is_key_in_section(key, user_input): + success, value = self.validate_key_value( + section_name, + key, + section_rules['properties'][key], + self.get_key_value(key, user_input) + ) + if not success: + return None + + validated_input = self.add_key_value( + validated_input, + key, + value + ) + else: + validated_input = self.add_key_value( + validated_input, + key, + section_rules['properties'][key]['default'] + ) + + if section_rules['value'] == 'list_of_dict': + if not isinstance(user_input, list): + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list' % (section_name) + ) + return None + + if 'min_length' in section_rules: + if len(user_input) < section_rules['min_length']: + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list with minimum %s elements: %s' % (section_name, section_rules['min_length'], len(user_input)) + ) + return None + + if 'max_length' in section_rules: + if len(user_input) > section_rules['max_length']: + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list with maximum %s elements: %s' % (section_name, section_rules['max_length'], len(user_input)) + ) + return None + + if not section_rules['validate']: + validated_input = [] + for item in user_input: + validated_input.append(item) + + if section_rules['validate']: + validated_input = [] + for item in user_input: + if not isinstance(item, dict): + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list of dict' % (section_name) + ) + return None + + validated_item = {} + for key in section_rules['properties']: + if section_rules['properties'][key]['mandatory']: + if not self.is_key_in_section(key, item): + self.log_handler.error( + 'validate_section', + 'Required property %s.%s' % (section_name, key) + ) + return None + + success, value = self.validate_key_value( + section_name, + key, + section_rules['properties'][key], + self.get_key_value(key, item) + ) + if not success: + return None + + validated_item = self.add_key_value( + validated_item, + key, + value + ) + + if not section_rules['properties'][key]['mandatory']: + if self.is_key_in_section(key, user_input): + success, value = self.validate_key_value( + section_name, + key, + section_rules['properties'][key], + self.get_key_value(key, item) + ) + if not success: + return None + + validated_item = self.add_key_value( + validated_item, + key, + value + ) + else: + validated_item = self.add_key_value( + validated_item, + key, + section_rules['properties'][key]['default'] + ) + + validated_input.append(validated_item) + + if section_rules['value'] == 'list_of_str': + if not isinstance(user_input, list): + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list' % (section_name) + ) + return None + + if not section_rules['validate']: + validated_input = [] + for item in user_input: + validated_input.append(item) + + if section_rules['validate']: + validated_input = [] + for value in user_input: + if not isinstance(value, str): + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list of strings' % (section_name) + ) + return None + + if section_rules['check'] is None: + validated_input.append(value) + continue + + if section_rules['check'] is not None: + if section_rules['check'] == 'ssh-public-key': + if not ip_helper.is_public_key_valid(value): + self.log_handler.error( + 'validate_section', + 'Section %s is expected to be list of ssh public keys' % (section_name) + ) + return None + validated_input.append(value) + continue + + if section_rules['check'] == 'tasks-yaml': + filename = os.path.join(self.base_directory, value) + if not os.path.isfile(filename): + self.log_handler.error( + 'validate_section', + 'Expected attribute %s value is existing local file: %s' % (section_name, value) + ) + return None + + content = file_helper.get_file_yaml(filename) + if content is None: + self.log_handler.error( + 'validate_section', + 'Expected attribute %s value is existing local file with yaml formatted content: %s' % (section_name, value) + ) + return None + + validated_input.append(filename) + continue + + self.log_handler.error( + 'validate_section', + 'Unsupported check: %s' % (section_rules['check']) + ) + return None + + return validated_input + + def validate(self, user_input_location, operation, template_reference=None, template_category=None, template_name=None): + user_input = self.get_input(user_input_location) + if user_input is None: + return None + + template_name = self.get_template_name( + user_input, + template_reference=template_reference, + template_name=template_name + ) + if template_name is None: + return None + + template_definition = self.get_template_definition(template_name, template_category=template_category) + if template_definition is None: + return None + + mandatory_sections = template_definition['main']['operation'][operation]['mandatory'] + if mandatory_sections is None: + mandatory_sections = [] + + optional_sections = template_definition['main']['operation'][operation]['optional'] + if optional_sections is None: + optional_sections = [] + + for key in mandatory_sections: + if key not in user_input: + user_input[key] = {} + + validated_input = {} + validated_input['template_name'] = template_name + + if os.path.isfile(user_input_location): + self.base_directory = os.path.dirname(user_input_location) + else: + self.base_directory = user_input_location + validated_input['base_directory'] = self.base_directory + + for section_name in user_input: + if section_name in mandatory_sections or section_name in optional_sections: + section_rules = self.get_section_rules(template_name, section_name, template_category=template_category) + if section_rules is None: + return None + + validated_input[section_name] = self.validate_section( + section_name, + section_rules, + user_input[section_name] + ) + if validated_input[section_name] is None: + return None + + return validated_input diff --git a/lib/intersight/__init__.py b/lib/intersight/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/__pycache__/__init__.cpython-310.pyc b/lib/intersight/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..99e354ad Binary files /dev/null and b/lib/intersight/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/adapter_ext_eth_interface.cpython-310.pyc b/lib/intersight/__pycache__/adapter_ext_eth_interface.cpython-310.pyc new file mode 100644 index 00000000..87451955 Binary files /dev/null and b/lib/intersight/__pycache__/adapter_ext_eth_interface.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/adapter_host_eth_interface.cpython-310.pyc b/lib/intersight/__pycache__/adapter_host_eth_interface.cpython-310.pyc new file mode 100644 index 00000000..381bc164 Binary files /dev/null and b/lib/intersight/__pycache__/adapter_host_eth_interface.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/adapter_host_fc_interface.cpython-310.pyc b/lib/intersight/__pycache__/adapter_host_fc_interface.cpython-310.pyc new file mode 100644 index 00000000..c4738d5e Binary files /dev/null and b/lib/intersight/__pycache__/adapter_host_fc_interface.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/adapter_unit.cpython-310.pyc b/lib/intersight/__pycache__/adapter_unit.cpython-310.pyc new file mode 100644 index 00000000..a2999ade Binary files /dev/null and b/lib/intersight/__pycache__/adapter_unit.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/asset_device_contract_information.cpython-310.pyc b/lib/intersight/__pycache__/asset_device_contract_information.cpython-310.pyc new file mode 100644 index 00000000..b1156afe Binary files /dev/null and b/lib/intersight/__pycache__/asset_device_contract_information.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/asset_device_registration.cpython-310.pyc b/lib/intersight/__pycache__/asset_device_registration.cpython-310.pyc new file mode 100644 index 00000000..194e365f Binary files /dev/null and b/lib/intersight/__pycache__/asset_device_registration.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/bios_boot_mode.cpython-310.pyc b/lib/intersight/__pycache__/bios_boot_mode.cpython-310.pyc new file mode 100644 index 00000000..cf758023 Binary files /dev/null and b/lib/intersight/__pycache__/bios_boot_mode.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_cdd_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_cdd_device.cpython-310.pyc new file mode 100644 index 00000000..f4d98736 Binary files /dev/null and b/lib/intersight/__pycache__/boot_cdd_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_device_boot_mode.cpython-310.pyc b/lib/intersight/__pycache__/boot_device_boot_mode.cpython-310.pyc new file mode 100644 index 00000000..1ca10ad7 Binary files /dev/null and b/lib/intersight/__pycache__/boot_device_boot_mode.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_device_boot_security.cpython-310.pyc b/lib/intersight/__pycache__/boot_device_boot_security.cpython-310.pyc new file mode 100644 index 00000000..20226dce Binary files /dev/null and b/lib/intersight/__pycache__/boot_device_boot_security.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_hdd_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_hdd_device.cpython-310.pyc new file mode 100644 index 00000000..240ef3ef Binary files /dev/null and b/lib/intersight/__pycache__/boot_hdd_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_iscsi_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_iscsi_device.cpython-310.pyc new file mode 100644 index 00000000..57857a6a Binary files /dev/null and b/lib/intersight/__pycache__/boot_iscsi_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_nvme_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_nvme_device.cpython-310.pyc new file mode 100644 index 00000000..f8a89b1f Binary files /dev/null and b/lib/intersight/__pycache__/boot_nvme_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_pxe_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_pxe_device.cpython-310.pyc new file mode 100644 index 00000000..b45a5867 Binary files /dev/null and b/lib/intersight/__pycache__/boot_pxe_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_san_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_san_device.cpython-310.pyc new file mode 100644 index 00000000..e1ff8055 Binary files /dev/null and b/lib/intersight/__pycache__/boot_san_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_sd_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_sd_device.cpython-310.pyc new file mode 100644 index 00000000..3a0aa85b Binary files /dev/null and b/lib/intersight/__pycache__/boot_sd_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_uefi_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_uefi_device.cpython-310.pyc new file mode 100644 index 00000000..de43becd Binary files /dev/null and b/lib/intersight/__pycache__/boot_uefi_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_usb_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_usb_device.cpython-310.pyc new file mode 100644 index 00000000..19396a1e Binary files /dev/null and b/lib/intersight/__pycache__/boot_usb_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/boot_vmedia_device.cpython-310.pyc b/lib/intersight/__pycache__/boot_vmedia_device.cpython-310.pyc new file mode 100644 index 00000000..5cdeb739 Binary files /dev/null and b/lib/intersight/__pycache__/boot_vmedia_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/cache.cpython-310.pyc b/lib/intersight/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..d921c3c4 Binary files /dev/null and b/lib/intersight/__pycache__/cache.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/chassis_extra_attributes.cpython-310.pyc b/lib/intersight/__pycache__/chassis_extra_attributes.cpython-310.pyc new file mode 100644 index 00000000..a4b8f61d Binary files /dev/null and b/lib/intersight/__pycache__/chassis_extra_attributes.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/chassis_info.cpython-310.pyc b/lib/intersight/__pycache__/chassis_info.cpython-310.pyc new file mode 100644 index 00000000..722c42f9 Binary files /dev/null and b/lib/intersight/__pycache__/chassis_info.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/chassis_profile.cpython-310.pyc b/lib/intersight/__pycache__/chassis_profile.cpython-310.pyc new file mode 100644 index 00000000..4ad35ba8 Binary files /dev/null and b/lib/intersight/__pycache__/chassis_profile.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/chassiz_info.cpython-310.pyc b/lib/intersight/__pycache__/chassiz_info.cpython-310.pyc new file mode 100644 index 00000000..3aa4a843 Binary files /dev/null and b/lib/intersight/__pycache__/chassiz_info.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_blade.cpython-310.pyc b/lib/intersight/__pycache__/compute_blade.cpython-310.pyc new file mode 100644 index 00000000..3413e62b Binary files /dev/null and b/lib/intersight/__pycache__/compute_blade.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_board.cpython-310.pyc b/lib/intersight/__pycache__/compute_board.cpython-310.pyc new file mode 100644 index 00000000..a655e15d Binary files /dev/null and b/lib/intersight/__pycache__/compute_board.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_extra_attributes.cpython-310.pyc b/lib/intersight/__pycache__/compute_extra_attributes.cpython-310.pyc new file mode 100644 index 00000000..1423db61 Binary files /dev/null and b/lib/intersight/__pycache__/compute_extra_attributes.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_filter.cpython-310.pyc b/lib/intersight/__pycache__/compute_filter.cpython-310.pyc new file mode 100644 index 00000000..41013efe Binary files /dev/null and b/lib/intersight/__pycache__/compute_filter.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_info.cpython-310.pyc b/lib/intersight/__pycache__/compute_info.cpython-310.pyc new file mode 100644 index 00000000..76926095 Binary files /dev/null and b/lib/intersight/__pycache__/compute_info.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_rack.cpython-310.pyc b/lib/intersight/__pycache__/compute_rack.cpython-310.pyc new file mode 100644 index 00000000..6ea38c26 Binary files /dev/null and b/lib/intersight/__pycache__/compute_rack.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_redfish.cpython-310.pyc b/lib/intersight/__pycache__/compute_redfish.cpython-310.pyc new file mode 100644 index 00000000..571c4604 Binary files /dev/null and b/lib/intersight/__pycache__/compute_redfish.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/compute_server_setting.cpython-310.pyc b/lib/intersight/__pycache__/compute_server_setting.cpython-310.pyc new file mode 100644 index 00000000..5cc3c292 Binary files /dev/null and b/lib/intersight/__pycache__/compute_server_setting.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/computes_info.cpython-310.pyc b/lib/intersight/__pycache__/computes_info.cpython-310.pyc new file mode 100644 index 00000000..dcc11304 Binary files /dev/null and b/lib/intersight/__pycache__/computes_info.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/computes_summary.cpython-310.pyc b/lib/intersight/__pycache__/computes_summary.cpython-310.pyc new file mode 100644 index 00000000..b8e4fbd8 Binary files /dev/null and b/lib/intersight/__pycache__/computes_summary.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/computes_worfklow.cpython-310.pyc b/lib/intersight/__pycache__/computes_worfklow.cpython-310.pyc new file mode 100644 index 00000000..3d45f2e2 Binary files /dev/null and b/lib/intersight/__pycache__/computes_worfklow.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/cond_alarm.cpython-310.pyc b/lib/intersight/__pycache__/cond_alarm.cpython-310.pyc new file mode 100644 index 00000000..88222d37 Binary files /dev/null and b/lib/intersight/__pycache__/cond_alarm.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/cond_hclstatus.cpython-310.pyc b/lib/intersight/__pycache__/cond_hclstatus.cpython-310.pyc new file mode 100644 index 00000000..260fd570 Binary files /dev/null and b/lib/intersight/__pycache__/cond_hclstatus.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/cond_hclstatus_detail.cpython-310.pyc b/lib/intersight/__pycache__/cond_hclstatus_detail.cpython-310.pyc new file mode 100644 index 00000000..613b7066 Binary files /dev/null and b/lib/intersight/__pycache__/cond_hclstatus_detail.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_chassis.cpython-310.pyc b/lib/intersight/__pycache__/equipment_chassis.cpython-310.pyc new file mode 100644 index 00000000..aeeb5032 Binary files /dev/null and b/lib/intersight/__pycache__/equipment_chassis.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_fan.cpython-310.pyc b/lib/intersight/__pycache__/equipment_fan.cpython-310.pyc new file mode 100644 index 00000000..bc6c8f91 Binary files /dev/null and b/lib/intersight/__pycache__/equipment_fan.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_fan_control.cpython-310.pyc b/lib/intersight/__pycache__/equipment_fan_control.cpython-310.pyc new file mode 100644 index 00000000..b31fad3b Binary files /dev/null and b/lib/intersight/__pycache__/equipment_fan_control.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_fan_module.cpython-310.pyc b/lib/intersight/__pycache__/equipment_fan_module.cpython-310.pyc new file mode 100644 index 00000000..e991252f Binary files /dev/null and b/lib/intersight/__pycache__/equipment_fan_module.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_iocard.cpython-310.pyc b/lib/intersight/__pycache__/equipment_iocard.cpython-310.pyc new file mode 100644 index 00000000..d38f0d9b Binary files /dev/null and b/lib/intersight/__pycache__/equipment_iocard.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_led.cpython-310.pyc b/lib/intersight/__pycache__/equipment_led.cpython-310.pyc new file mode 100644 index 00000000..14013b3e Binary files /dev/null and b/lib/intersight/__pycache__/equipment_led.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_psu.cpython-310.pyc b/lib/intersight/__pycache__/equipment_psu.cpython-310.pyc new file mode 100644 index 00000000..e54f185b Binary files /dev/null and b/lib/intersight/__pycache__/equipment_psu.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_psu_control.cpython-310.pyc b/lib/intersight/__pycache__/equipment_psu_control.cpython-310.pyc new file mode 100644 index 00000000..f8650dc0 Binary files /dev/null and b/lib/intersight/__pycache__/equipment_psu_control.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/equipment_tpm.cpython-310.pyc b/lib/intersight/__pycache__/equipment_tpm.cpython-310.pyc new file mode 100644 index 00000000..0b1387d2 Binary files /dev/null and b/lib/intersight/__pycache__/equipment_tpm.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/ethernet_host_port.cpython-310.pyc b/lib/intersight/__pycache__/ethernet_host_port.cpython-310.pyc new file mode 100644 index 00000000..644102cc Binary files /dev/null and b/lib/intersight/__pycache__/ethernet_host_port.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/ethernet_network_port.cpython-310.pyc b/lib/intersight/__pycache__/ethernet_network_port.cpython-310.pyc new file mode 100644 index 00000000..5e089d46 Binary files /dev/null and b/lib/intersight/__pycache__/ethernet_network_port.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/ethernet_physical_port.cpython-310.pyc b/lib/intersight/__pycache__/ethernet_physical_port.cpython-310.pyc new file mode 100644 index 00000000..0d7e2f06 Binary files /dev/null and b/lib/intersight/__pycache__/ethernet_physical_port.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/hcl_operating_system.cpython-310.pyc b/lib/intersight/__pycache__/hcl_operating_system.cpython-310.pyc new file mode 100644 index 00000000..ba1bb22b Binary files /dev/null and b/lib/intersight/__pycache__/hcl_operating_system.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/hcl_operating_system_vendor.cpython-310.pyc b/lib/intersight/__pycache__/hcl_operating_system_vendor.cpython-310.pyc new file mode 100644 index 00000000..10b7f61c Binary files /dev/null and b/lib/intersight/__pycache__/hcl_operating_system_vendor.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/intersight_common.cpython-310.pyc b/lib/intersight/__pycache__/intersight_common.cpython-310.pyc new file mode 100644 index 00000000..d5606414 Binary files /dev/null and b/lib/intersight/__pycache__/intersight_common.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/memory_unit.cpython-310.pyc b/lib/intersight/__pycache__/memory_unit.cpython-310.pyc new file mode 100644 index 00000000..b4586eab Binary files /dev/null and b/lib/intersight/__pycache__/memory_unit.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/network_element_summary.cpython-310.pyc b/lib/intersight/__pycache__/network_element_summary.cpython-310.pyc new file mode 100644 index 00000000..36c23346 Binary files /dev/null and b/lib/intersight/__pycache__/network_element_summary.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/organization.cpython-310.pyc b/lib/intersight/__pycache__/organization.cpython-310.pyc new file mode 100644 index 00000000..313c3055 Binary files /dev/null and b/lib/intersight/__pycache__/organization.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/os_configuration_file.cpython-310.pyc b/lib/intersight/__pycache__/os_configuration_file.cpython-310.pyc new file mode 100644 index 00000000..16689f39 Binary files /dev/null and b/lib/intersight/__pycache__/os_configuration_file.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/os_image.cpython-310.pyc b/lib/intersight/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..2170bf80 Binary files /dev/null and b/lib/intersight/__pycache__/os_image.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/os_install.cpython-310.pyc b/lib/intersight/__pycache__/os_install.cpython-310.pyc new file mode 100644 index 00000000..3d9a39e2 Binary files /dev/null and b/lib/intersight/__pycache__/os_install.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/pci_device.cpython-310.pyc b/lib/intersight/__pycache__/pci_device.cpython-310.pyc new file mode 100644 index 00000000..39c24cff Binary files /dev/null and b/lib/intersight/__pycache__/pci_device.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/power_control_state.cpython-310.pyc b/lib/intersight/__pycache__/power_control_state.cpython-310.pyc new file mode 100644 index 00000000..dad3a94b Binary files /dev/null and b/lib/intersight/__pycache__/power_control_state.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/processor_unit.cpython-310.pyc b/lib/intersight/__pycache__/processor_unit.cpython-310.pyc new file mode 100644 index 00000000..5ac97d62 Binary files /dev/null and b/lib/intersight/__pycache__/processor_unit.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/running_firmware.cpython-310.pyc b/lib/intersight/__pycache__/running_firmware.cpython-310.pyc new file mode 100644 index 00000000..22d64618 Binary files /dev/null and b/lib/intersight/__pycache__/running_firmware.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/scu.cpython-310.pyc b/lib/intersight/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..13c77a31 Binary files /dev/null and b/lib/intersight/__pycache__/scu.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/search_item.cpython-310.pyc b/lib/intersight/__pycache__/search_item.cpython-310.pyc new file mode 100644 index 00000000..d05359fd Binary files /dev/null and b/lib/intersight/__pycache__/search_item.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/server_profile.cpython-310.pyc b/lib/intersight/__pycache__/server_profile.cpython-310.pyc new file mode 100644 index 00000000..79f32bdd Binary files /dev/null and b/lib/intersight/__pycache__/server_profile.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/settings.cpython-310.pyc b/lib/intersight/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..09c371d4 Binary files /dev/null and b/lib/intersight/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/software_repository_catalog.cpython-310.pyc b/lib/intersight/__pycache__/software_repository_catalog.cpython-310.pyc new file mode 100644 index 00000000..3cdfb2d1 Binary files /dev/null and b/lib/intersight/__pycache__/software_repository_catalog.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/storage_controller.cpython-310.pyc b/lib/intersight/__pycache__/storage_controller.cpython-310.pyc new file mode 100644 index 00000000..a21185f2 Binary files /dev/null and b/lib/intersight/__pycache__/storage_controller.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/storage_physical_disk.cpython-310.pyc b/lib/intersight/__pycache__/storage_physical_disk.cpython-310.pyc new file mode 100644 index 00000000..fc394592 Binary files /dev/null and b/lib/intersight/__pycache__/storage_physical_disk.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/storage_physical_disk_usage.cpython-310.pyc b/lib/intersight/__pycache__/storage_physical_disk_usage.cpython-310.pyc new file mode 100644 index 00000000..ab9e6afd Binary files /dev/null and b/lib/intersight/__pycache__/storage_physical_disk_usage.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/storage_virtual_drive.cpython-310.pyc b/lib/intersight/__pycache__/storage_virtual_drive.cpython-310.pyc new file mode 100644 index 00000000..c0ea95f3 Binary files /dev/null and b/lib/intersight/__pycache__/storage_virtual_drive.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/tam_advisory_instance.cpython-310.pyc b/lib/intersight/__pycache__/tam_advisory_instance.cpython-310.pyc new file mode 100644 index 00000000..132634c5 Binary files /dev/null and b/lib/intersight/__pycache__/tam_advisory_instance.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/tam_security_advisory.cpython-310.pyc b/lib/intersight/__pycache__/tam_security_advisory.cpython-310.pyc new file mode 100644 index 00000000..726e1f74 Binary files /dev/null and b/lib/intersight/__pycache__/tam_security_advisory.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/workflow.cpython-310.pyc b/lib/intersight/__pycache__/workflow.cpython-310.pyc new file mode 100644 index 00000000..a9eebe24 Binary files /dev/null and b/lib/intersight/__pycache__/workflow.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/workflow_info.cpython-310.pyc b/lib/intersight/__pycache__/workflow_info.cpython-310.pyc new file mode 100644 index 00000000..25b16c6c Binary files /dev/null and b/lib/intersight/__pycache__/workflow_info.cpython-310.pyc differ diff --git a/lib/intersight/__pycache__/workflow_task_info.cpython-310.pyc b/lib/intersight/__pycache__/workflow_task_info.cpython-310.pyc new file mode 100644 index 00000000..8273f134 Binary files /dev/null and b/lib/intersight/__pycache__/workflow_task_info.cpython-310.pyc differ diff --git a/lib/intersight/adapter_ext_eth_interface/__init__.py b/lib/intersight/adapter_ext_eth_interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/adapter_ext_eth_interface/class.md b/lib/intersight/adapter_ext_eth_interface/class.md new file mode 100644 index 00000000..b6891124 --- /dev/null +++ b/lib/intersight/adapter_ext_eth_interface/class.md @@ -0,0 +1,97 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AcknowledgedPeerInterface": { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac2", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac2" + }, + "AdapterUnit": { + "ClassId": "mo.MoRef", + "Moid": "632b188376752d3236311708", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/632b188376752d3236311708" + }, + "AdminState": "Enabled", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b188376752d3236311708", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/632b188376752d3236311708" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b163d76752d323630734f", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b163d76752d323630734f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + } + ], + "ClassId": "adapter.ExtEthInterface", + "CreateTime": "2022-09-21T13:58:35.052Z", + "DeviceMoId": "632b16036f72612d39c67825", + "Dn": "/redfish/v1/Chassis/FCH26167L94/NetworkAdapters/UCSX-V4-Q25GML_FCH26217EZ0/iom-id-2/ext-eth-1", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EpDn": "", + "ExtEthInterfaceId": "1", + "InterfaceType": "", + "InventoryDeviceInfo": null, + "MacAddress": "48:2E:72:E4:50:29", + "ModTime": "2022-11-07T18:32:32.651Z", + "Moid": "632b188b76752d3236311bb7", + "ObjectType": "adapter.ExtEthInterface", + "OperState": "", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942", + "632b16036f72612d39c67825" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b188376752d3236311708", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/632b188376752d3236311708" + }, + "PeerAggrPortId": 0, + "PeerDn": "chassis-1-ioc-2-muxhostport-port-5", + "PeerInterface": { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac2", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac2" + }, + "PeerPortId": 5, + "PeerSlotId": 1, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632b16036f72612d39c67825", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632b16036f72612d39c67825" + }, + "Rn": "", + "SharedScope": "", + "SwitchId": "A", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/adapter_ext_eth_interface/info.py b/lib/intersight/adapter_ext_eth_interface/info.py new file mode 100644 index 00000000..85dc51a0 --- /dev/null +++ b/lib/intersight/adapter_ext_eth_interface/info.py @@ -0,0 +1,24 @@ +class AdapterExtEthInterfaceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['AdapterUnitId'] = managed_object['AdapterUnit']['Moid'] + info['AdminState'] = managed_object['AdminState'] + info['InterfaceId'] = managed_object['ExtEthInterfaceId'] + info['MacAddress'] = managed_object['MacAddress'].lower() + info['SwitchId'] = managed_object['SwitchId'] + + info['PeerHostPortId'] = None + if managed_object['AcknowledgedPeerInterface'] is not None: + if managed_object['AcknowledgedPeerInterface']['ObjectType'] == 'ether.HostPort': + info['PeerHostPortId'] = managed_object['AcknowledgedPeerInterface']['Moid'] + info['PeerAggrPortId'] = managed_object['PeerAggrPortId'] + info['PeerDn'] = managed_object['PeerDn'] + info['PeerPortId'] = managed_object['PeerPortId'] + info['PeerSlotId'] = managed_object['PeerSlotId'] + + return info diff --git a/lib/intersight/adapter_ext_eth_interface/main.py b/lib/intersight/adapter_ext_eth_interface/main.py new file mode 100644 index 00000000..f2872d8d --- /dev/null +++ b/lib/intersight/adapter_ext_eth_interface/main.py @@ -0,0 +1,8 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.adapter_ext_eth_interface.info import AdapterExtEthInterfaceInfo + +class AdapterExtEthInterface(IntersightCommon, AdapterExtEthInterfaceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'adapter extethinterface' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + AdapterExtEthInterfaceInfo.__init__(self) diff --git a/lib/intersight/adapter_host_eth_interface/__init__.py b/lib/intersight/adapter_host_eth_interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/adapter_host_eth_interface/class.md b/lib/intersight/adapter_host_eth_interface/class.md new file mode 100644 index 00000000..93fac18a --- /dev/null +++ b/lib/intersight/adapter_host_eth_interface/class.md @@ -0,0 +1,91 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "AcknowledgedPeerInterface": null, + "AdapterUnit": { + "ClassId": "mo.MoRef", + "Moid": "5e8c50046176752d32d64486", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/5e8c50046176752d32d64486" + }, + "AdminState": "", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5e8c50046176752d32d64486", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/5e8c50046176752d32d64486" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed26176752d32d51c40", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5e8c4ed26176752d32d51c40" + } + ], + "ClassId": "adapter.HostEthInterface", + "CreateTime": "2020-04-07T10:03:45.983Z", + "DeviceMoId": "5e8c4ecd6f72612d302b11a6", + "Dn": "sys/rack-unit-1/network-adapter-1/eth-3", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EpDn": "", + "HostEthInterfaceId": 3, + "InterfaceType": "", + "InventoryDeviceInfo": null, + "MacAddress": "3c:fd:fe:cb:eb:02", + "ModTime": "2022-05-09T13:36:01.032Z", + "Moid": "5e8c50016176752d32d64236", + "Name": "eth-3", + "ObjectType": "adapter.HostEthInterface", + "OperReason": [], + "OperState": "", + "Operability": "", + "OriginalMacAddress": "", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5e8c4ecd6f72612d302b11a6" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5e8c50046176752d32d64486", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/5e8c50046176752d32d64486" + }, + "PciAddr": "", + "PeerDn": "", + "PeerInterface": null, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PinGroupName": "", + "PinnedInterface": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ecd6f72612d302b11a6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5e8c4ecd6f72612d302b11a6" + }, + "Rn": "", + "SharedScope": "", + "Tags": [], + "VirtualizationPreference": "", + "VnicDn": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/adapter_host_eth_interface/info.py b/lib/intersight/adapter_host_eth_interface/info.py new file mode 100644 index 00000000..4f95c79c --- /dev/null +++ b/lib/intersight/adapter_host_eth_interface/info.py @@ -0,0 +1,22 @@ +class AdapterHostEthInterfaceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Type'] = 'HostEth' + info['Dn'] = managed_object['Dn'] + info['AdapterUnitId'] = managed_object['AdapterUnit']['Moid'] + info['AdminState'] = managed_object['AdminState'] + info['HostEthInterfaceId'] = managed_object['HostEthInterfaceId'] + info['InterfaceType'] = managed_object['InterfaceType'] + info['MacAddress'] = managed_object['MacAddress'] + info['Name'] = managed_object['Name'] + info['OperState'] = managed_object['OperState'] + info['Operability'] = managed_object['Operability'] + info['PciAddr'] = managed_object['PciAddr'] + info['PeerDn'] = managed_object['PeerDn'] + info['PeerInterface'] = managed_object['PeerInterface'] + + return info diff --git a/lib/intersight/adapter_host_eth_interface/main.py b/lib/intersight/adapter_host_eth_interface/main.py new file mode 100644 index 00000000..e516cec2 --- /dev/null +++ b/lib/intersight/adapter_host_eth_interface/main.py @@ -0,0 +1,8 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.adapter_host_eth_interface.info import AdapterHostEthInterfaceInfo + +class AdapterHostEthInterface(IntersightCommon, AdapterHostEthInterfaceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'adapter hostethinterface' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + AdapterHostEthInterfaceInfo.__init__(self) diff --git a/lib/intersight/adapter_host_fc_interface/__init__.py b/lib/intersight/adapter_host_fc_interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/adapter_host_fc_interface/class.md b/lib/intersight/adapter_host_fc_interface/class.md new file mode 100644 index 00000000..8390c731 --- /dev/null +++ b/lib/intersight/adapter_host_fc_interface/class.md @@ -0,0 +1,93 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "AdapterUnit": { + "ClassId": "mo.MoRef", + "Moid": "6098fe5c6176752d35a6d757", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/6098fe5c6176752d35a6d757" + }, + "AdminState": "", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6098fe5c6176752d35a6d757", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/6098fe5c6176752d35a6d757" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6098fe686176752d35a6dbc8", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6098fe686176752d35a6dbc8" + } + ], + "ClassId": "adapter.HostFcInterface", + "CreateTime": "2021-09-09T14:18:06.829Z", + "DeviceMoId": "6098fe506f72612d30e78ffb", + "Dn": "sys/rack-unit-1/adaptor-MLOM/host-fc-fc0", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EpDn": "", + "HostFcInterfaceId": 0, + "InventoryDeviceInfo": null, + "ModTime": "2022-07-25T08:07:30.83Z", + "Model": "", + "Moid": "613a179e76752d31372d2bc9", + "Name": "fc0", + "ObjectType": "adapter.HostFcInterface", + "OperReason": [], + "OperState": "", + "Operability": "", + "OriginalWwnn": "", + "OriginalWwpn": "", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "6098fe506f72612d30e78ffb" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6098fe5c6176752d35a6d757", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/6098fe5c6176752d35a6d757" + }, + "PeerDn": "", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PinGroupName": "", + "PinnedInterface": null, + "Presence": "", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "6098fe506f72612d30e78ffb", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/6098fe506f72612d30e78ffb" + }, + "Revision": "", + "Rn": "", + "Serial": "", + "SharedScope": "", + "Tags": [], + "Vendor": "", + "Wwnn": "10:00:3C:57:31:CC:17:DA", + "Wwpn": "20:00:3C:57:31:CC:17:DA" + } +``` \ No newline at end of file diff --git a/lib/intersight/adapter_host_fc_interface/info.py b/lib/intersight/adapter_host_fc_interface/info.py new file mode 100644 index 00000000..74f4a3b1 --- /dev/null +++ b/lib/intersight/adapter_host_fc_interface/info.py @@ -0,0 +1,19 @@ +class AdapterHostFcInterfaceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Type'] = 'HostFc' + info['Dn'] = managed_object['Dn'] + info['AdapterUnitId'] = managed_object['AdapterUnit']['Moid'] + info['AdminState'] = managed_object['AdminState'] + info['HostFcInterfaceId'] = managed_object['HostFcInterfaceId'] + info['Name'] = managed_object['Name'] + info['OperState'] = managed_object['OperState'] + info['Operability'] = managed_object['Operability'] + info['Wwnn'] = managed_object['Wwnn'] + info['Wwpn'] = managed_object['Wwpn'] + + return info diff --git a/lib/intersight/adapter_host_fc_interface/main.py b/lib/intersight/adapter_host_fc_interface/main.py new file mode 100644 index 00000000..eaeea0a8 --- /dev/null +++ b/lib/intersight/adapter_host_fc_interface/main.py @@ -0,0 +1,8 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.adapter_host_fc_interface.info import AdapterHostFcInterfaceInfo + +class AdapterHostFcInterface(IntersightCommon, AdapterHostFcInterfaceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'adapter hostfcinterface' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + AdapterHostFcInterfaceInfo.__init__(self) diff --git a/lib/intersight/adapter_unit/__init__.py b/lib/intersight/adapter_unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/adapter_unit/class.md b/lib/intersight/adapter_unit/class.md new file mode 100644 index 00000000..ed4099ee --- /dev/null +++ b/lib/intersight/adapter_unit/class.md @@ -0,0 +1,130 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AdapterId": "UCSX-V4-Q25GML_FCH26217FVU", + "AdapterUnitExpander": null, + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b174e76752d323630bb47", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b174e76752d323630bb47" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + } + ], + "BaseMacAddress": "48:2E:72:E4:50:40", + "ClassId": "adapter.Unit", + "ComputeBlade": { + "ClassId": "mo.MoRef", + "Moid": "632b174e76752d323630bb47", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b174e76752d323630bb47" + }, + "ComputeRackUnit": null, + "ConnectionStatus": "", + "Controller": { + "ClassId": "mo.MoRef", + "Moid": "632b19a876752d3236316cb7", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/632b19a876752d3236316cb7" + }, + "CreateTime": "2022-09-21T14:03:20.004Z", + "DeviceMoId": "632b165e6f72612d39c67cd5", + "DisplayNames": { + "hierarchical": [ + "adapter-UCSX-V4-Q25GML_FCH26217FVU" + ], + "short": [ + "Adapter-UCSX-V4-Q25GML_FCH26217FVU" + ] + }, + "Dn": "/redfish/v1/Chassis/FCH26167MMZ/NetworkAdapters/UCSX-V4-Q25GML_FCH26217FVU", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "ExtEthIfs": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b19af76752d3236316ea9", + "ObjectType": "adapter.ExtEthInterface", + "link": "https://www.intersight.com/api/v1/adapter/ExtEthInterfaces/632b19af76752d3236316ea9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b19af76752d3236316eaa", + "ObjectType": "adapter.ExtEthInterface", + "link": "https://www.intersight.com/api/v1/adapter/ExtEthInterfaces/632b19af76752d3236316eaa" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b19af76752d3236316eab", + "ObjectType": "adapter.ExtEthInterface", + "link": "https://www.intersight.com/api/v1/adapter/ExtEthInterfaces/632b19af76752d3236316eab" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b19af76752d3236316eac", + "ObjectType": "adapter.ExtEthInterface", + "link": "https://www.intersight.com/api/v1/adapter/ExtEthInterfaces/632b19af76752d3236316eac" + } + ], + "HostEthIfs": [], + "HostFcIfs": [], + "HostIscsiIfs": [], + "Integrated": "", + "InventoryDeviceInfo": null, + "ModTime": "2022-10-14T10:35:56.755Z", + "Model": "UCSX-V4-Q25GML", + "Moid": "632b19a776752d3236316cb1", + "ObjectType": "adapter.Unit", + "OperState": "OK", + "Operability": "", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942", + "632b165e6f72612d39c67cd5" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b174e76752d323630bb47", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b174e76752d323630bb47" + }, + "PartNumber": "73-20185-03", + "PciSlot": "SlotID:0-MLOM", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "Power": "", + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632b165e6f72612d39c67cd5", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632b165e6f72612d39c67cd5" + }, + "Revision": "", + "Rn": "", + "Serial": "FCH26217FVU", + "SharedScope": "", + "Tags": [], + "Thermal": "", + "Vendor": "Cisco Systems Inc", + "Vid": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/adapter_unit/info.py b/lib/intersight/adapter_unit/info.py new file mode 100644 index 00000000..9a62e00d --- /dev/null +++ b/lib/intersight/adapter_unit/info.py @@ -0,0 +1,49 @@ +class AdapterUnitInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['AdapterId'] = managed_object['AdapterId'] + info['Name'] = 'Adapter %s' % (info['AdapterId']) + info['BaseMacAddress'] = managed_object['BaseMacAddress'] + if managed_object['ComputeBlade'] is not None: + info['ComputeNodeMoid'] = managed_object['ComputeBlade']['Moid'] + if managed_object['ComputeRackUnit'] is not None: + info['ComputeNodeMoid'] = managed_object['ComputeRackUnit']['Moid'] + + info['ExtEthIfsIds'] = [] + for interface in managed_object['ExtEthIfs']: + info['ExtEthIfsIds'].append(interface['Moid']) + info['ExtEthIfsCount'] = len(info['ExtEthIfsIds']) + + info['HostEthIfsIds'] = [] + for interface in managed_object['HostEthIfs']: + info['HostEthIfsIds'].append(interface['Moid']) + info['HostEthIfsCount'] = len(info['HostEthIfsIds']) + + info['HostFcIfsIds'] = [] + for interface in managed_object['HostFcIfs']: + info['HostFcIfsIds'].append(interface['Moid']) + info['HostFcIfsCount'] = len(info['HostFcIfsIds']) + + info['HostIscsiIfsIds'] = [] + for interface in managed_object['HostIscsiIfs']: + info['HostIscsiIfsIds'].append(interface['Moid']) + info['HostIscsiIfsCount'] = len(info['HostIscsiIfsIds']) + + info['Model'] = managed_object['Model'] + info['OperState'] = managed_object['OperState'] + info['PartNumber'] = managed_object['PartNumber'] + info['Presence'] = managed_object['Presence'] + info['Healthy'] = False + if info['Presence'] == 'equipped' and info['OperState'] == 'OK': + info['Healthy'] = True + info['PciSlot'] = managed_object['PciSlot'] + info['Thermal'] = managed_object['Thermal'] + info['Serial'] = managed_object['Serial'] + info['Vendor'] = managed_object['Vendor'] + + return info diff --git a/lib/intersight/adapter_unit/main.py b/lib/intersight/adapter_unit/main.py new file mode 100644 index 00000000..85d83524 --- /dev/null +++ b/lib/intersight/adapter_unit/main.py @@ -0,0 +1,8 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.adapter_unit.info import AdapterUnitInfo + +class AdapterUnit(IntersightCommon, AdapterUnitInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'adapter unit' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + AdapterUnitInfo.__init__(self) diff --git a/lib/intersight/asset_device_contract_information/__init__.py b/lib/intersight/asset_device_contract_information/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/asset_device_contract_information/class.md b/lib/intersight/asset_device_contract_information/class.md new file mode 100644 index 00000000..3fc14677 --- /dev/null +++ b/lib/intersight/asset_device_contract_information/class.md @@ -0,0 +1,171 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [], + "ClassId": "asset.DeviceContractInformation", + "Contract": { + "BillTo": { + "Address1": "", + "Address2": "", + "Address3": "", + "City": "", + "ClassId": "asset.AddressInformation", + "Country": "", + "County": "", + "Location": "", + "Name": "", + "ObjectType": "asset.AddressInformation", + "PostalCode": "", + "Province": "", + "State": "" + }, + "BillToGlobalUltimate": { + "ClassId": "asset.GlobalUltimate", + "Id": "", + "Name": "", + "ObjectType": "asset.GlobalUltimate" + }, + "ClassId": "asset.ContractInformation", + "ContractNumber": "", + "LineStatus": "NEVER COVERED", + "ObjectType": "asset.ContractInformation" + }, + "ContractStatus": "Not Covered", + "ContractStatusReason": "", + "ContractUnavailableRetryCount": 0, + "ContractUpdatedTime": "2022-11-15T22:03:14.439Z", + "CoveredProductLineEndDate": "", + "CreateTime": "2022-02-04T07:29:30.967Z", + "DeviceId": "FDO25500ZVK", + "DeviceType": "CiscoNexusSwitch", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EndCustomer": { + "Address": { + "Address1": "VIA SANTA MARIA MOLGORA 48 C", + "Address2": "", + "Address3": "", + "City": "VIMERCATE", + "ClassId": "asset.AddressInformation", + "Country": "IT", + "County": "", + "Location": "", + "Name": "", + "ObjectType": "asset.AddressInformation", + "PostalCode": "20871", + "Province": "", + "State": "LOMBARDIA" + }, + "ClassId": "asset.CustomerInformation", + "Id": "1001745576", + "Name": "CISCO PHOTONICS ITALY SRL", + "ObjectType": "asset.CustomerInformation" + }, + "EndUserGlobalUltimate": { + "ClassId": "asset.GlobalUltimate", + "Id": "52428", + "Name": "CISCO SYSTEMS INC", + "ObjectType": "asset.GlobalUltimate" + }, + "IsValid": true, + "managed_objectType": "CHASSIS", + "MaintenancePurchaseOrderNumber": "", + "MaintenanceSalesOrderNumber": "", + "ModTime": "2022-11-15T22:03:15.018Z", + "Moid": "61fcd5da6265722d3016f18a", + "ObjectType": "asset.DeviceContractInformation", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fe1ddc96f72612d304f7531" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PlatformType": "APIC", + "Product": { + "BillTo": { + "Address1": "PALAZZO ACERO", + "Address2": "VIA TORRI BIANCHE 8", + "Address3": "", + "City": "VIMERCATE", + "ClassId": "asset.AddressInformation", + "Country": "IT", + "County": "", + "Location": "405085", + "Name": "CISCO SYSTEMS ITALY SRL", + "ObjectType": "asset.AddressInformation", + "PostalCode": "20871", + "Province": "", + "State": "" + }, + "ClassId": "asset.ProductInformation", + "Description": "Nexus 9300 Series, 32p 400G QSFP-DD", + "Family": "N9300", + "Group": "SWITCH", + "Number": "N9K-C9332D-GX2B", + "ObjectType": "asset.ProductInformation", + "ShipTo": { + "Address1": "VIA SANTA MARIA MOLGORA 48 C", + "Address2": "", + "Address3": "", + "City": "VIMERCATE", + "ClassId": "asset.AddressInformation", + "Country": "IT", + "County": "", + "Location": "1001745576", + "Name": "CISCO PHOTONICS ITALY SRL", + "ObjectType": "asset.AddressInformation", + "PostalCode": "20871", + "Province": "", + "State": "LOMBARDIA" + }, + "SubType": "N9300 SERIES" + }, + "PurchaseOrderNumber": "PR555627", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fe1ddc96f72612d304f7531", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fe1ddc96f72612d304f7531" + }, + "ResellerGlobalUltimate": { + "ClassId": "asset.GlobalUltimate", + "Id": "", + "Name": "", + "ObjectType": "asset.GlobalUltimate" + }, + "SalesOrderNumber": "113581639", + "ServiceDescription": "Nexus 9300 Series, 32p 400G QSFP-DD", + "ServiceEndDate": "0001-01-01T00:00:00Z", + "ServiceLevel": "", + "ServiceSku": "", + "ServiceStartDate": "0001-01-01T00:00:00Z", + "SharedScope": "", + "Source": { + "ClassId": "mo.MoRef", + "Moid": "61fcd5da77616e2d31925d37", + "ObjectType": "niatelemetry.NiaInventory", + "link": "https://www.intersight.com/api/v1/niatelemetry/NiaInventories/61fcd5da77616e2d31925d37" + }, + "StateContract": "OK", + "Tags": [], + "WarrantyEndDate": "2023-04-14T00:00:00Z", + "WarrantyType": "WARR-1YR-LTD-HW" + } +``` \ No newline at end of file diff --git a/lib/intersight/asset_device_contract_information/info.py b/lib/intersight/asset_device_contract_information/info.py new file mode 100644 index 00000000..7057d3ef --- /dev/null +++ b/lib/intersight/asset_device_contract_information/info.py @@ -0,0 +1,27 @@ +class AssetDeviceContractInformationInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['Moid'] = managed_object['Moid'] + info['PurchaseOrderNumber'] = managed_object['PurchaseOrderNumber'] + info['SalesOrderNumber'] = managed_object['SalesOrderNumber'] + info['ContractStatus'] = managed_object['ContractStatus'] + info['ContractNumber'] = managed_object['Contract']['ContractNumber'] + info['ContractUpdatedTime'] = managed_object['ContractUpdatedTime'] + info['ServiceDescription'] = managed_object['ServiceDescription'] + info['ServiceLevel'] = managed_object['ServiceLevel'] + info['ServiceSku'] = managed_object['ServiceSku'] + info['ServiceStartDate'] = managed_object['ServiceStartDate'] + info['ServiceEndDate'] = managed_object['ServiceEndDate'] + info['IsValid'] = managed_object['IsValid'] + + if info['ContractStatus'] == 'Active': + info['__Output']['ContractStatus'] = 'Green' + else: + info['__Output']['ContractStatus'] = 'Red' + + return info diff --git a/lib/intersight/asset_device_contract_information/main.py b/lib/intersight/asset_device_contract_information/main.py new file mode 100644 index 00000000..473bbe4d --- /dev/null +++ b/lib/intersight/asset_device_contract_information/main.py @@ -0,0 +1,8 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.asset_device_contract_information.info import AssetDeviceContractInformationInfo + +class AssetDeviceContractInformation(IntersightCommon, AssetDeviceContractInformationInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'asset devicecontractinformation' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + AssetDeviceContractInformationInfo.__init__(self) diff --git a/lib/intersight/asset_device_registration/__init__.py b/lib/intersight/asset_device_registration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/asset_device_registration/class.md b/lib/intersight/asset_device_registration/class.md new file mode 100644 index 00000000..4d47312b --- /dev/null +++ b/lib/intersight/asset_device_registration/class.md @@ -0,0 +1,122 @@ +``` + { + "Account": { + "ClassId": "mo.MoRef", + "Moid": "5a58c3ba3768393836cb0f1b", + "ObjectType": "iam.Account", + "link": "https://www.intersight.com/api/v1/iam/Accounts/5a58c3ba3768393836cb0f1b" + }, + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "Ancestors": [], + "ApiVersion": 11, + "AppPartitionNumber": 125, + "ClaimedByUser": { + "ClassId": "mo.MoRef", + "Moid": "5a58c41a3768393836cb10bc", + "ObjectType": "iam.User", + "link": "https://www.intersight.com/api/v1/iam/Users/5a58c41a3768393836cb10bc" + }, + "ClaimedByUserName": "******", + "ClaimedTime": "2022-09-20T10:43:18.327Z", + "ClassId": "asset.DeviceRegistration", + "ClusterMembers": [ + { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26945", + "ObjectType": "asset.ClusterMember", + "link": "https://www.intersight.com/api/v1/asset/ClusterMembers/632999466f72612d39b26945" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26946", + "ObjectType": "asset.ClusterMember", + "link": "https://www.intersight.com/api/v1/asset/ClusterMembers/632999466f72612d39b26946" + } + ], + "ConnectionId": "e53fb7c94631f12a96832ed63dcdb8d4:8e008439-dc1d-4f25-89b9-8471e6262801", + "ConnectionReason": "", + "ConnectionStatus": "Connected", + "ConnectionStatusLastChangeTime": "2022-11-13T03:27:22.596Z", + "ConnectorVersion": "1.0.11-2396", + "CreateTime": "2022-09-20T10:43:18.301Z", + "DeviceClaim": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26939", + "ObjectType": "asset.DeviceClaim", + "link": "https://www.intersight.com/api/v1/asset/DeviceClaims/632999466f72612d39b26939" + }, + "DeviceConfiguration": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26943", + "ObjectType": "asset.DeviceConfiguration", + "link": "https://www.intersight.com/api/v1/asset/DeviceConfigurations/632999466f72612d39b26943" + }, + "DeviceExternalIpAddress": "", + "DeviceHostname": [ + "ucsX" + ], + "DeviceIpAddress": [ + "", + "" + ], + "DisplayNames": { + "hierarchical": [ + "[ucsX]" + ], + "short": [ + "[ucsX]" + ] + }, + "DomainGroup": { + "ClassId": "mo.MoRef", + "Moid": "5b2541957a7662743465d06d", + "ObjectType": "iam.DomainGroup", + "link": "https://www.intersight.com/api/v1/iam/DomainGroups/5b2541957a7662743465d06d" + }, + "DomainGroupMoid": "5b2541957a7662743465d06d", + "ExecutionMode": "Normal", + "ModTime": "2022-11-13T03:27:22.648Z", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "ParentConnection": null, + "ParentSignature": null, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "Pid": [ + "UCS-FI-6454" + ], + "PlatformType": "UCSFIISM", + "ProxyApp": "astro", + "PublicAccessKey": "", + "ReadOnly": false, + "SecurityToken": null, + "Serial": [ + "FDO26340DE3", + "FDO26340CVC" + ], + "SharedScope": "", + "Tags": [ + { + "Key": "cisco.meta.ManagementMode", + "Value": "Intersight" + } + ], + "Vendor": "Cisco Systems, Inc." + } +``` \ No newline at end of file diff --git a/lib/intersight/asset_device_registration/info.py b/lib/intersight/asset_device_registration/info.py new file mode 100644 index 00000000..98bf78b1 --- /dev/null +++ b/lib/intersight/asset_device_registration/info.py @@ -0,0 +1,23 @@ +class AssetDeviceRegistrationInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + info['Moid'] = managed_object['Moid'] + info['ClaimedByUserName'] = managed_object['ClaimedByUserName'] + info['ClaimedTime'] = managed_object['ClaimedTime'] + info['PlatformType'] = managed_object['PlatformType'] + info['ConnectorVersion'] = managed_object['ConnectorVersion'] + info['ConnectionStatus'] = managed_object['ConnectionStatus'] + info['DeviceExternalIpAddress'] = managed_object['DeviceExternalIpAddress'] + info['ConnectionStatusLastChangeTime'] = managed_object['ConnectionStatusLastChangeTime'] + if info['ConnectionStatus'] == 'Connected': + info['__Output']['ConnectionStatus'] = 'Green' + info['Connected'] = True + else: + info['__Output']['ConnectionStatus'] = 'Red' + info['Connected'] = False + + return info diff --git a/lib/intersight/asset_device_registration/main.py b/lib/intersight/asset_device_registration/main.py new file mode 100644 index 00000000..dff5bf42 --- /dev/null +++ b/lib/intersight/asset_device_registration/main.py @@ -0,0 +1,26 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.asset_device_registration.info import AssetDeviceRegistrationInfo + + +class AssetDeviceRegistration(IntersightCommon, AssetDeviceRegistrationInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'asset deviceregistration' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + AssetDeviceRegistrationInfo.__init__(self) + + def create_target(self, serial_number, security_token): + self.iobject = 'asset deviceclaim' + create_attributes = '' + create_attributes = '%s --SerialNumber %s' % (create_attributes, serial_number) + create_attributes = '%s --SecurityToken %s' % (create_attributes, security_token) + + response = self.create( + create_attributes, + get_response=True, + json_conversion=True + ) + return response + + def delete_target(self, moid): + self.iobject = 'asset deviceclaim' + return self.delete(moid) diff --git a/lib/intersight/bios_boot_mode/__init__.py b/lib/intersight/bios_boot_mode/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/bios_boot_mode/class.md b/lib/intersight/bios_boot_mode/class.md new file mode 100644 index 00000000..5fa1dc9d --- /dev/null +++ b/lib/intersight/bios_boot_mode/class.md @@ -0,0 +1,69 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "ActualBootMode": "Legacy", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + } + ], + "ClassId": "bios.BootMode", + "ComputeBlade": null, + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "CreateTime": "2020-12-20T18:46:23.454Z", + "DeviceMoId": "5fdf9be76f72612d300a8d81", + "Dn": "sys/rack-unit-1/bios/bdgep/boot-mode", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InventoryDeviceInfo": null, + "ModTime": "2022-10-25T16:16:22.589Z", + "Moid": "5fdf9bff6176752d35e4471c", + "ObjectType": "bios.BootMode", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fdf9be76f72612d300a8d81" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9be76f72612d300a8d81", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fdf9be76f72612d300a8d81" + }, + "Rn": "", + "SharedScope": "", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/bios_boot_mode/info.py b/lib/intersight/bios_boot_mode/info.py new file mode 100644 index 00000000..8ea3f4a3 --- /dev/null +++ b/lib/intersight/bios_boot_mode/info.py @@ -0,0 +1,11 @@ +class BiosBootModeInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['ActualBootMode'] = managed_object['ActualBootMode'] + info['Moid'] = managed_object['Moid'] + + return info diff --git a/lib/intersight/bios_boot_mode/main.py b/lib/intersight/bios_boot_mode/main.py new file mode 100644 index 00000000..78dfdd54 --- /dev/null +++ b/lib/intersight/bios_boot_mode/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.bios_boot_mode.info import BiosBootModeInfo + + +class BiosBootMode(IntersightCommon, BiosBootModeInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'bios bootmode' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BiosBootModeInfo.__init__(self) diff --git a/lib/intersight/bios_unit/__init__.py b/lib/intersight/bios_unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/bios_unit/bios_unit.py b/lib/intersight/bios_unit/bios_unit.py new file mode 100644 index 00000000..11199f2b --- /dev/null +++ b/lib/intersight/bios_unit/bios_unit.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class BiosUnit(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'bios unit' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) diff --git a/lib/intersight/bios_unit/class.md b/lib/intersight/bios_unit/class.md new file mode 100644 index 00000000..a81587f1 --- /dev/null +++ b/lib/intersight/bios_unit/class.md @@ -0,0 +1,85 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "ClassId": "bios.Unit", + "ComputeBlade": null, + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + }, + "CreateTime": "2022-09-02T07:09:58.416Z", + "DeviceMoId": "61c35fa36f72612d3005590c", + "Dn": "sys/rack-unit-3/bios", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InitSeq": "0xb1:0xad:0xb2:0x92:0xa2:0xa2:0xa2:0xa2:0xa2:0xa2:0xa0:0x99:0xa2:0xa2:0xa2:0xa2:0xa0:0x92:0xb4:0xb4", + "InitTs": "2022-09-02T07:33:38.461", + "InventoryDeviceInfo": null, + "ModTime": "2022-09-02T07:33:38.549Z", + "Model": "UCSC-C220-M4S", + "Moid": "6311ac4676752d31398e5336", + "ObjectType": "bios.Unit", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "RunningFirmware": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5338", + "ObjectType": "firmware.RunningFirmware", + "link": "https://www.intersight.com/api/v1/firmware/RunningFirmwares/6311ac4676752d31398e5338" + } + ], + "Serial": "", + "SharedScope": "", + "SystemBootOrder": null, + "Tags": [], + "Vendor": "Cisco Systems, Inc." + } +``` \ No newline at end of file diff --git a/lib/intersight/boot_cdd_device/__init__.py b/lib/intersight/boot_cdd_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_cdd_device/info.py b/lib/intersight/boot_cdd_device/info.py new file mode 100644 index 00000000..ef8502a3 --- /dev/null +++ b/lib/intersight/boot_cdd_device/info.py @@ -0,0 +1,14 @@ +class BootCddDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_cdd_device/main.py b/lib/intersight/boot_cdd_device/main.py new file mode 100644 index 00000000..a4d055ed --- /dev/null +++ b/lib/intersight/boot_cdd_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_cdd_device.info import BootCddDeviceInfo + + +class BootCddDevice(IntersightCommon, BootCddDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot cdddevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootCddDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_device_boot_mode/__init__.py b/lib/intersight/boot_device_boot_mode/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_device_boot_mode/class.md b/lib/intersight/boot_device_boot_mode/class.md new file mode 100644 index 00000000..5a993e89 --- /dev/null +++ b/lib/intersight/boot_device_boot_mode/class.md @@ -0,0 +1,69 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + } + ], + "ClassId": "boot.DeviceBootMode", + "ComputeBlade": null, + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "ConfiguredBootMode": "Legacy", + "CreateTime": "2020-12-20T18:47:09.114Z", + "DeviceMoId": "5fdf9be76f72612d300a8d81", + "Dn": "sys/rack-unit-1/boot-precision", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InventoryDeviceInfo": null, + "ModTime": "2022-10-25T20:00:14.716Z", + "Moid": "5fdf9c2d6176752d35e457e2", + "ObjectType": "boot.DeviceBootMode", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fdf9be76f72612d300a8d81" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9be76f72612d300a8d81", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fdf9be76f72612d300a8d81" + }, + "Rn": "", + "SharedScope": "", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/boot_device_boot_mode/info.py b/lib/intersight/boot_device_boot_mode/info.py new file mode 100644 index 00000000..1ad11bb1 --- /dev/null +++ b/lib/intersight/boot_device_boot_mode/info.py @@ -0,0 +1,11 @@ +class BootDeviceBootModeInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['ConfiguredBootMode'] = managed_object['ConfiguredBootMode'] + info['Moid'] = managed_object['Moid'] + + return info diff --git a/lib/intersight/boot_device_boot_mode/main.py b/lib/intersight/boot_device_boot_mode/main.py new file mode 100644 index 00000000..448bf4c6 --- /dev/null +++ b/lib/intersight/boot_device_boot_mode/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_device_boot_mode.info import BootDeviceBootModeInfo + + +class BootDeviceBootMode(IntersightCommon, BootDeviceBootModeInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot devicebootmode' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootDeviceBootModeInfo.__init__(self) diff --git a/lib/intersight/boot_device_boot_security/__init__.py b/lib/intersight/boot_device_boot_security/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_device_boot_security/class.md b/lib/intersight/boot_device_boot_security/class.md new file mode 100644 index 00000000..9e44ada5 --- /dev/null +++ b/lib/intersight/boot_device_boot_security/class.md @@ -0,0 +1,68 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + } + ], + "ClassId": "boot.DeviceBootSecurity", + "ComputePhysical": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "CreateTime": "2020-12-20T18:47:09.811Z", + "DeviceMoId": "5fdf9be76f72612d300a8d81", + "Dn": "sys/rack-unit-1/boot-policy/boot-security", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InventoryDeviceInfo": null, + "ModTime": "2022-10-25T16:13:55.344Z", + "Moid": "5fdf9c2d6176752d35e45801", + "ObjectType": "boot.DeviceBootSecurity", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fdf9be76f72612d300a8d81" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9be76f72612d300a8d81", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fdf9be76f72612d300a8d81" + }, + "Rn": "", + "SecureBoot": "disabled", + "SharedScope": "", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/boot_device_boot_security/info.py b/lib/intersight/boot_device_boot_security/info.py new file mode 100644 index 00000000..00164087 --- /dev/null +++ b/lib/intersight/boot_device_boot_security/info.py @@ -0,0 +1,11 @@ +class BootDeviceBootSecurityInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['SecureBoot'] = managed_object['SecureBoot'] + info['Moid'] = managed_object['Moid'] + + return info diff --git a/lib/intersight/boot_device_boot_security/main.py b/lib/intersight/boot_device_boot_security/main.py new file mode 100644 index 00000000..1515adf8 --- /dev/null +++ b/lib/intersight/boot_device_boot_security/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_device_boot_security.info import BootDeviceBootSecurityInfo + + +class BootDeviceBootSecurity(IntersightCommon, BootDeviceBootSecurityInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot devicebootsecurity' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootDeviceBootSecurityInfo.__init__(self) diff --git a/lib/intersight/boot_hdd_device/__init__.py b/lib/intersight/boot_hdd_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_hdd_device/class.md b/lib/intersight/boot_hdd_device/class.md new file mode 100644 index 00000000..e2773b8a --- /dev/null +++ b/lib/intersight/boot_hdd_device/class.md @@ -0,0 +1,77 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + } + ], + "ClassId": "boot.HddDevice", + "ComputePhysical": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "CreateTime": "2021-01-14T09:16:59.989Z", + "DeviceMoId": "5fdf9be76f72612d300a8d81", + "Dn": "sys/rack-unit-1/boot-precision/hdd-localhdd", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InventoryDeviceInfo": null, + "ModTime": "2022-12-06T17:23:08.954Z", + "Model": "", + "Moid": "60000c0b6176752d35b76e3e", + "Name": "localhdd", + "ObjectType": "boot.HddDevice", + "Order": 1, + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fdf9be76f72612d300a8d81" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9be76f72612d300a8d81", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fdf9be76f72612d300a8d81" + }, + "Revision": "", + "Rn": "", + "Serial": "", + "SharedScope": "", + "State": "Disabled", + "Tags": [], + "Type": "LOCALHDD", + "Vendor": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/boot_hdd_device/info.py b/lib/intersight/boot_hdd_device/info.py new file mode 100644 index 00000000..5509c39c --- /dev/null +++ b/lib/intersight/boot_hdd_device/info.py @@ -0,0 +1,14 @@ +class BootHddDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_hdd_device/main.py b/lib/intersight/boot_hdd_device/main.py new file mode 100644 index 00000000..a5a8d9a6 --- /dev/null +++ b/lib/intersight/boot_hdd_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_hdd_device.info import BootHddDeviceInfo + + +class BootHddDevice(IntersightCommon, BootHddDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot hdddevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootHddDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_iscsi_device/__init__.py b/lib/intersight/boot_iscsi_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_iscsi_device/info.py b/lib/intersight/boot_iscsi_device/info.py new file mode 100644 index 00000000..920b3662 --- /dev/null +++ b/lib/intersight/boot_iscsi_device/info.py @@ -0,0 +1,14 @@ +class BootIscsiDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_iscsi_device/main.py b/lib/intersight/boot_iscsi_device/main.py new file mode 100644 index 00000000..657df765 --- /dev/null +++ b/lib/intersight/boot_iscsi_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_iscsi_device.info import BootIscsiDeviceInfo + + +class BootIscsiDevice(IntersightCommon, BootIscsiDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot iscsidevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootIscsiDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_nvme_device/__init__.py b/lib/intersight/boot_nvme_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_nvme_device/info.py b/lib/intersight/boot_nvme_device/info.py new file mode 100644 index 00000000..9dcbc9c7 --- /dev/null +++ b/lib/intersight/boot_nvme_device/info.py @@ -0,0 +1,14 @@ +class BootNvmeDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_nvme_device/main.py b/lib/intersight/boot_nvme_device/main.py new file mode 100644 index 00000000..d3768bf2 --- /dev/null +++ b/lib/intersight/boot_nvme_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_nvme_device.info import BootNvmeDeviceInfo + + +class BootNvmeDevice(IntersightCommon, BootNvmeDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot nvmedevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootNvmeDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_pxe_device/__init__.py b/lib/intersight/boot_pxe_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_pxe_device/info.py b/lib/intersight/boot_pxe_device/info.py new file mode 100644 index 00000000..1f8b3d33 --- /dev/null +++ b/lib/intersight/boot_pxe_device/info.py @@ -0,0 +1,14 @@ +class BootPxeDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_pxe_device/main.py b/lib/intersight/boot_pxe_device/main.py new file mode 100644 index 00000000..aff45191 --- /dev/null +++ b/lib/intersight/boot_pxe_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_pxe_device.info import BootPxeDeviceInfo + + +class BootPxeDevice(IntersightCommon, BootPxeDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot pxedevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootPxeDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_san_device/__init__.py b/lib/intersight/boot_san_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_san_device/info.py b/lib/intersight/boot_san_device/info.py new file mode 100644 index 00000000..71581548 --- /dev/null +++ b/lib/intersight/boot_san_device/info.py @@ -0,0 +1,14 @@ +class BootSanDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_san_device/main.py b/lib/intersight/boot_san_device/main.py new file mode 100644 index 00000000..56e68a4b --- /dev/null +++ b/lib/intersight/boot_san_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_san_device.info import BootSanDeviceInfo + + +class BootSanDevice(IntersightCommon, BootSanDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot sandevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootSanDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_sd_device/__init__.py b/lib/intersight/boot_sd_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_sd_device/info.py b/lib/intersight/boot_sd_device/info.py new file mode 100644 index 00000000..8d049363 --- /dev/null +++ b/lib/intersight/boot_sd_device/info.py @@ -0,0 +1,14 @@ +class BootSdDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_sd_device/main.py b/lib/intersight/boot_sd_device/main.py new file mode 100644 index 00000000..abab49eb --- /dev/null +++ b/lib/intersight/boot_sd_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_sd_device.info import BootSdDeviceInfo + + +class BootSdDevice(IntersightCommon, BootSdDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot sddevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootSdDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_uefi_device/__init__.py b/lib/intersight/boot_uefi_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_uefi_device/info.py b/lib/intersight/boot_uefi_device/info.py new file mode 100644 index 00000000..92414402 --- /dev/null +++ b/lib/intersight/boot_uefi_device/info.py @@ -0,0 +1,14 @@ +class BootUefiDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_uefi_device/main.py b/lib/intersight/boot_uefi_device/main.py new file mode 100644 index 00000000..6eeb6650 --- /dev/null +++ b/lib/intersight/boot_uefi_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_uefi_device.info import BootUefiDeviceInfo + + +class BootUefiDevice(IntersightCommon, BootUefiDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot uefishelldevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootUefiDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_usb_device/__init__.py b/lib/intersight/boot_usb_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_usb_device/info.py b/lib/intersight/boot_usb_device/info.py new file mode 100644 index 00000000..b930fd80 --- /dev/null +++ b/lib/intersight/boot_usb_device/info.py @@ -0,0 +1,14 @@ +class BootUsbDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_usb_device/main.py b/lib/intersight/boot_usb_device/main.py new file mode 100644 index 00000000..e3a11ac5 --- /dev/null +++ b/lib/intersight/boot_usb_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_usb_device.info import BootUsbDeviceInfo + + +class BootUsbDevice(IntersightCommon, BootUsbDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot usbdevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootUsbDeviceInfo.__init__(self) diff --git a/lib/intersight/boot_vmedia_device/__init__.py b/lib/intersight/boot_vmedia_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/boot_vmedia_device/info.py b/lib/intersight/boot_vmedia_device/info.py new file mode 100644 index 00000000..f6990c33 --- /dev/null +++ b/lib/intersight/boot_vmedia_device/info.py @@ -0,0 +1,14 @@ +class BootVmediaDeviceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Order'] = managed_object['Order'] + info['State'] = managed_object['State'] + info['Type'] = managed_object['Type'] + + return info diff --git a/lib/intersight/boot_vmedia_device/main.py b/lib/intersight/boot_vmedia_device/main.py new file mode 100644 index 00000000..b51ecdb2 --- /dev/null +++ b/lib/intersight/boot_vmedia_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.boot_vmedia_device.info import BootVmediaDeviceInfo + + +class BootVmediaDevice(IntersightCommon, BootVmediaDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'boot vmediadevice' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + BootVmediaDeviceInfo.__init__(self) diff --git a/lib/intersight/bot_output.py b/lib/intersight/bot_output.py new file mode 100644 index 00000000..2e5d99c1 --- /dev/null +++ b/lib/intersight/bot_output.py @@ -0,0 +1,3308 @@ +from lib import filter_helper +from lib import output_helper +from lib import log_helper + + +class ComputeBotOutput(): + def __init__(self, log_id=None): + self.my_output = output_helper.OutputHelper(log_id=log_id) + self.log_handler = log_helper.Log(log_id=log_id) + + def print_summary_table(self, servers, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Server Summary [#%s]' % (len(servers)), + underline=True, + before_newline=True + ) + + if len(servers) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [] + headers = [] + + if servers[0]['StateEnabled']: + order = order + [ + 'FlagState', + 'FlagManagement' + ] + + headers = headers + [ + 'SF', + 'MF' + ] + + if 'Workflow' in servers[0]: + order = order + [ + 'FlagWorkflow' + ] + + headers = headers + [ + 'WF (%sd)' % (servers[0]['Workflow']['Days']) + ] + + for server in servers: + if 'Workflow' in server: + if len(server['FlagWorkflow']) == 0: + server['FlagWorkflow'] = '--' + + row_separator = False + for server in servers: + server['TagT'] = [] + for item in server['Tags']: + server['TagT'].append( + '%s:%s' % ( + item['Key'], + item['Value'] + ) + ) + + if len(server['TagT']) == 0: + server['TagT'].append('--') + + if len(server['TagT']) > 1: + row_separator = True + + order = order + [ + 'Name', + 'TagT', + 'TypeModel', + 'Serial', + 'ManagementIp', + 'Cpu', + 'TotalMemoryUnit' + ] + + headers = headers + [ + 'Name', + 'Tag', + 'Model', + 'Serial', + 'IP', + 'CPU', + 'Memory' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + servers, + order, + ['TagT'] + ), + order=order, + headers=headers, + row_separator=row_separator, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + servers, + order, + headers, + title='Server' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in servers: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('Server', order, rows) + + return output, html_output + + def print_board(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'BoardInfo' in server: + item = server['BoardInfo'] + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Motherboard Hardware Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'BoardId', + 'Vendor', + 'ProcessorsCount', + 'MemoryArraysCount', + 'PciSwitchCount', + 'PciCoprocessorCardsCount', + 'GraphicsCardsCount', + 'StorageControllersCount', + 'StorageFlexFlashControllersCount', + 'StorageFlexUtilControllersCount', + 'SecurityUnitsCount', + 'EquipmentTpmsCount' + ] + + headers = [ + 'Server', + 'Board Id', + 'Vendor', + 'CPU', + 'MemArr', + 'PCI Switch', + 'PCI Cooprocessor', + 'Graphics', + 'Storage Ctrl', + 'FlexFlash Ctrl', + 'FlexUtil Ctrl', + 'Sec', + 'TPM' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Board' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('Board', order, rows) + + return output, html_output + + def print_cpu(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'CpuInfo' in server: + for item in server['CpuInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'CPU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'StateTick', + 'ProcessorId', + 'SocketDesignation', + 'Vendor', + 'Architecture', + 'Model', + 'NumCores', + 'NumCoresEnabled', + 'NumThreads', + 'Speed', + 'Stepping', + 'Presence', + 'OperState', + 'Thermal' + ] + + headers = [ + 'Server', + 'State', + 'CPU Id', + 'Socket', + 'Vendor', + 'Arch', + 'Model', + 'Cores', + 'Enabled', + 'Threads', + 'Speed [GHz]', + 'Stepping', + 'Presence', + 'OperState', + 'Thermal' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='CPU' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('CPU', order, rows) + + return output, html_output + + def print_gpu(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'GpuInfo' in server: + for item in server['GpuInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'GPU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Model', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'FirmwareVersion' + ] + + headers = [ + 'Server', + 'GPU Device Model', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'Firmware' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='GPU' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('GPU', order, rows) + + return output, html_output + + def print_memory(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'MemoryInfo' in server: + for item in server['MemoryInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Memory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'StateTick', + 'MemoryId', + 'ArrayId', + 'Bank', + 'Location', + 'CapacityUnit', + 'Clock', + 'LatencyUnit', + 'FormFactor', + 'Type', + 'Model', + 'Serial', + 'OperState', + 'Presence', + 'Thermal' + ] + + headers = [ + 'Server', + 'State', + 'Memory Id', + 'Array', + 'Bank', + 'Location', + 'Capacity', + 'Clock', + 'Latency', + 'Form Factor', + 'Type', + 'Model', + 'Serial', + 'Oper State', + 'Presence', + 'Thermal' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Memory' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('Memory', order, rows) + + return output, html_output + + def print_cimc(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'CimcInfo' in server: + for item in server['CimcInfo']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'IMC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + for item in info: + if len(item['FabricDomain']) == 0: + item['Fabric'] = '--' + else: + item['Fabric'] = '%s:%s %s (%s)' % ( + item['FabricDomain'], + item['FabricDevice'], + item['FabricInterface'], + item['FabricSource'] + ) + + order = [ + 'ServerName', + 'IpAddress', + 'Mask', + 'Gateway', + 'MacAddress', + 'Fabric' + ] + + headers = [ + 'Server', + 'IP', + 'Mask', + 'Gateway', + 'MAC', + 'Fabric' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='IMC' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('IMC', order, rows) + + return output, html_output + + def print_adapters(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'AdaptersInfo' in server: + for item in server['AdaptersInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Network Adapters [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'PciSlot', + 'Model', + 'Serial', + 'Vendor', + 'HostEthIfsCount', + 'HostFcIfsCount', + 'ExtEthIfsCount' + ] + + headers = [ + 'Server', + 'Name', + 'PciSlot', + 'Model', + 'Serial', + 'Vendor', + 'Eth', + 'HBA', + 'DCE' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Network Adapters' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('NetworkAdapter', order, rows) + + return output, html_output + + def print_ext_eth(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'ExtEthInfo' in server: + for item in server['ExtEthInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'External Ethernet (MLOM) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + for item in info: + if len(item['FabricDomain']) == 0: + item['Fabric'] = '--' + else: + item['Fabric'] = '%s:%s %s (%s)' % ( + item['FabricDomain'], + item['FabricDevice'], + item['FabricInterface'], + item['FabricSource'] + ) + + order = [ + 'ServerName', + 'InterfaceId', + 'MacAddress', + 'Fabric' + ] + + headers = [ + 'Server', + 'Interface ID', + 'MAC Address', + 'Fabric' + ] + + self.my_output.my_table( + server['ExtEthInfo'], + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='External Ethernet (MLOM)' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('MLOM', order, rows) + + return output, html_output + + def print_host_eth(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'HostEthInfo' in server: + for item in server['HostEthInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Host Ethernet [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'AdapterName', + 'Name', + 'MacAddress' + ] + + headers = [ + 'Server', + 'Adapter Name', + 'Interface Name', + 'MAC Address' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + for item in info: + if len(item['FabricDomain']) == 0: + item['Fabric'] = '--' + else: + item['Fabric'] = '%s:%s %s (%s)' % ( + item['FabricDomain'], + item['FabricDevice'], + item['FabricInterface'], + item['FabricSource'] + ) + + order = [ + 'ServerName', + 'AdapterName', + 'Name', + 'MacAddress', + 'Fabric' + ] + + headers = [ + 'Server', + 'Adapter Name', + 'Interface Name', + 'MAC Address', + 'Fabric' + ] + self.my_output.my_table_html( + info, + order, + headers, + title='Host Ethernet' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('HostEthernet', order, rows) + + return output, html_output + + def print_host_fc(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'HostFcInfo' in server: + for item in server['HostFcInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Host FC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'AdapterName', + 'Name', + 'Wwnn', + 'Wwpn' + ] + + headers = [ + 'Server', + 'Adapter Name', + 'Interface Name', + 'WWNN', + 'WWPN' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Host FC' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('HostFC', order, rows) + + return output, html_output + + def print_storage_controllers(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'StorageControllerInfo' in server: + for item in server['StorageControllerInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Storage Controller [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + for item in info: + item['ModelT'] = filter_helper.get_string_chunks( + item['Model'], + 30 + ) + + order = [ + 'ServerName', + 'ControllerId', + 'Model', + 'Vendor', + 'Serial', + 'Presence', + 'PciSlot', + 'RaidSupport', + 'PhysicalDiskCount', + 'VirtualDriveCount' + ] + + headers = [ + 'Server', + 'Controller', + 'Model', + 'Vendor', + 'Serial', + 'Presence', + 'PCI Slot', + 'Raid Support', + 'PD', + 'VD' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + row_separator=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Storage Controller' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('StorageController', order, rows) + + return output, html_output + + def print_physical_disks_state(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'PhysicalDiskInfo' in server: + for item in server['PhysicalDiskInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Physical Disk - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'StorageControllerId', + 'DiskId', + 'VirtualDriveId', + 'SizeUnit', + 'Type', + 'Protocol', + 'BootableTick', + 'LinkSpeed', + 'DriveFirmware', + 'DiskState', + 'Presence' + ] + + headers = [ + 'Server', + 'Controller', + 'Disk Id', + 'VD', + 'Size', + 'Type', + 'Protocol', + 'Bootable', + 'Link Speed', + 'Fw', + 'State', + 'Presence' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + order = [ + 'ServerName', + 'StorageControllerId', + 'DiskId', + 'VirtualDriveId', + 'SizeUnit', + 'Type', + 'Protocol', + 'BootableTick', + 'LinkSpeed', + 'DriveFirmware', + 'DiskState', + 'Presence', + 'Pid', + 'Model', + 'Vendor', + 'Serial' + ] + + headers = [ + 'Server', + 'Controller', + 'Disk Id', + 'VD', + 'Size', + 'Type', + 'Protocol', + 'Bootable', + 'Link Speed', + 'Fw', + 'State', + 'Presence', + 'Pid', + 'Model', + 'Vendor', + 'Serial' + ] + + self.my_output.my_table_html( + info, + order, + headers, + title='Physical Disk' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('PhysicalDisk', order, rows) + + return output, html_output + + def print_physical_disks_inventory(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'PhysicalDiskInfo' in server: + for item in server['PhysicalDiskInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Physical Disk - Inventory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'DiskId', + 'Pid', + 'Model', + 'Vendor', + 'Serial' + ] + + headers = [ + 'Server', + 'Disk Id', + 'Pid', + 'Model', + 'Vendor', + 'Serial' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + return output, None + + def print_virtual_drives(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'VirtualDisks' in server: + for item in server['VirtualDisks']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Virtual Drive [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'StateTick', + 'StorageControllerId', + 'VirtualDriveId', + 'SizeUnit', + 'PhysicalDiskCount', + 'Type', + 'Name', + 'BootableTick', + 'ActualWriteCachePolicy', + 'DriveState' + ] + + headers = [ + 'Server', + 'State', + 'Controller', + 'Drive Id', + 'Size', + 'Disks', + 'Type', + 'Name', + 'Bootable', + 'Write Cache', + 'Drive State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Virtual Drive' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('VirtualDrive', order, rows) + + return output, html_output + + def print_tpm(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'TpmInfo' in server: + for item in server['TpmInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Trusted Platform Module (TPM) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Presence', + 'ActivationStatus', + 'AdminState', + 'Version', + 'Model', + 'Vendor', + 'Serial', + 'FirmwareVersion' + ] + + headers = [ + 'Server', + 'TPM', + 'Activation Status', + 'Admin State', + 'Version', + 'Model', + 'Vendor', + 'Serial', + 'Firmware Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Trusted Platform Module (TPM)' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('TPM', order, rows) + + return output, html_output + + def print_pci(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'PciDevicesInfo' in server: + for item in server['PciDevicesInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'PCI [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + for item in info: + item['ModelT'] = filter_helper.get_string_chunks( + item['Model'], + 40 + ) + + order = [ + 'ServerName', + 'ModelT', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'FirmwareVersion' + ] + + headers = [ + 'Server', + 'PCI Device Model', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'Firmware' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ModelT'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='PCI' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('PCI', order, rows) + + return output, html_output + + def print_fan_module(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'FanModuleInfo' in server: + for item in server['FanModuleInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Fan Module [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'StateTick', + 'Name', + 'OperState', + 'Presence' + ] + + headers = [ + 'Server', + 'State', + 'Fan Module', + 'OperState', + 'Presence' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Fan Module' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('FanModule', order, rows) + + return output, html_output + + def print_fan(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'FanInfo' in server: + for item in server['FanInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Fan [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'StateTick', + 'Name', + 'OperState', + 'Presence' + ] + + headers = [ + 'Server', + 'State', + 'Fan', + 'OperState', + 'Presence' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Fan' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('Fan', order, rows) + + return output, html_output + + def print_psu(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'PsuInfo' in server: + for item in server['PsuInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'PSU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'StateTick', + 'PresenceTick', + 'Voltage', + 'Model', + 'Serial', + 'Vendor' + ] + + headers = [ + 'Server', + 'Name', + 'State', + 'Present', + 'Voltage', + 'Model', + 'Serial', + 'Vendor' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='PSU' + ) + + html_output = self.my_output.get_output() + + rows = [] + for server in info: + row = [] + for key in order: + row.append(server[key]) + rows.append(row) + + self.log_handler.bot_csv('PSU', order, rows) + + return output, html_output + + def print_boot(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'BootInfo' in server: + item = server['BootInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Boot [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'ConfiguredBootMode', + 'ActualBootMode', + 'SecureBoot', + 'Order.Order', + 'Order.Name', + 'Order.Type', + 'Order.State' + ] + + headers = [ + 'Server', + 'Configured Boot Mode', + 'Actual Boot Mode', + 'Secure Boot', + 'Order', + 'Name', + 'Type', + 'State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Order'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Boot' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_connector(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'ConnectorInfo' in server: + item = server['ConnectorInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Connector [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'ConnectionStatus', + 'ConnectorVersion', + 'ClaimedByUserName', + 'ClaimedTime', + 'ConnectionStatusLastChangeTime', + 'PlatformType', + 'DeviceExternalIpAddress' + ] + + headers = [ + 'Server', + 'Connection Status', + 'Connector Version', + 'Claimed By', + 'Claimed Time', + 'Connection Status Last Update', + 'Platform Type', + 'Device External IP Address' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Connector' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_contract(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'ContractInfo' in server: + item = server['ContractInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Contract [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'ContractStatus', + 'ContractNumber', + 'ServiceStartDate', + 'ServiceEndDate', + 'ContractUpdatedTime', + 'ServiceDescription', + 'ServiceLevel', + 'ServiceSku', + 'PurchaseOrderNumber', + 'SalesOrderNumber' + ] + + headers = [ + 'Server', + 'Contract Status', + 'Contract Number', + 'Start Date', + 'End Date', + 'Last Updated', + 'Service Description', + 'Service Level', + 'Service Sku', + 'Purchase Order Number', + 'Sales Order Number' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Contract' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_firmware(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'FirmwarewComponents' in server: + for item in server['FirmwarewComponents']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Firmware [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'Component', + 'Type', + 'PackageVersion', + 'Version' + ] + + headers = [ + 'Server', + 'Name', + 'Component', + 'Type', + 'PackageVersion', + 'Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Firmware' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_hcl_summary(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'HCL Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Status' + ] + + headers = [ + 'Server', + 'Overall' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='HCL Summary' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_hcl_hardware(self, servers, title=False): + self.my_output.clear_output() + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'HCL Server Hardware Compliance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'HardwareStatus', + 'HclModel', + 'HclProcessor', + 'HclFirmwareVersion' + ] + + headers = [ + 'Server', + 'Status', + 'Model', + 'CPU', + 'Firmware' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='HCL Server Hardware Compliance' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_hcl_software(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'HCL Server Software Compliance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'SoftwareStatus', + 'Reason', + 'HclOsVendor', + 'HclOsVersion' + ] + + headers = [ + 'Server', + 'Status', + 'Reason', + 'OS Vendor', + 'OS Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='HCL Server Software Compliance' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_hcl_component(self, servers, title=False): + self.my_output.clear_output() + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'HCL Server Adapter Compliance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'ComponentStatus', + 'Details.Status', + 'Details.HardwareStatus', + 'Details.SoftwareStatus', + 'Details.Reason', + 'Details.HclModel', + 'Details.HclCimcVersion', + 'Details.HclDriverName', + 'Details.HclDriverVersion', + 'Details.HclFirmwareVersion' + ] + + headers = [ + 'Server', + 'Status', + 'Component', + 'Hardware', + 'Software', + 'Reason', + 'Model', + 'Cimc Version', + 'Driver Name', + 'Driver Version', + 'Firmware Version' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Details'] + ), + order=order, + headers=headers, + underline=True, + table=True, + allow_order_subkeys=True, + row_separator=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='HCL Server Adapter Compliance' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_kvm(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'KvmInfo' in server: + item = server['KvmInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'KVM [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'KvmServerStateEnabled', + 'KvmVendor', + 'TunneledKvm', + 'KvmIpAddresses.Name', + 'KvmIpAddresses.Address', + 'KvmIpAddresses.Subnet', + 'KvmIpAddresses.DefaultGateway', + 'KvmIpAddresses.HttpPort', + 'KvmIpAddresses.HttpsPort', + 'KvmIpAddresses.KvmPort', + 'KvmIpAddresses.KvmVlan' + ] + + headers = [ + 'Server', + 'Kvm Server Enabled', + 'Kvm Vendor', + 'Tunneled Kvm', + 'Address Name', + 'Address', + 'Subnet', + 'Gateway', + 'Http Port', + 'Https Port', + 'Kvm Port', + 'Kvm Vlan' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['KvmIpAddresses'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='KVM' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_license(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'LicenseInfo' in server: + item = server['LicenseInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'License [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'Name', + 'Tier' + ] + + headers = [ + 'Server', + 'License' + ] + + self.my_output.my_table( + servers, + order=order, + headers=headers, + table=True, + allow_order_subkeys=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='License' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_power_consumption(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'Power' in server and server['Power'] is not None: + item = server['Power']['Data']['PowerControl'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Power Consumption [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'PowerConsumedWatts', + 'MinConsumedWatts', + 'AverageConsumedWatts', + 'MaxConsumedWatts', + 'LimitException' + ] + + headers = [ + 'Server', + 'Current', + 'Min', + 'Average', + 'Max', + 'Limit action' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Power Consumption' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_power_voltage(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'Power' in server and server['Power'] is not None: + for item in server['Power']['Data']['Voltage']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Power Sensor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'ReadingVolts', + 'UpperThresholdCritical' + ] + + headers = [ + 'Server', + 'Sensor Name', + 'State', + 'Health', + 'Volts', + 'Upper Threshold' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Power Sensor' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_power_supply(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'Power' in server and server['Power'] is not None: + for item in server['Power']['Data']['PowerSupply']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Power Supply [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'SerialNumber', + 'FirmwareVersion', + 'PowerOutputWatts', + 'PowerInputWatts', + 'MaximumVoltage', + 'MinimumVoltage', + 'MaximumFrequencyHz', + 'MinimumFrequencyHz' + ] + + headers = [ + 'Server', + 'PSU Name', + 'State', + 'Health', + 'Serial', + 'Firmware', + 'Output (Watt)', + 'Input (Watt)', + 'Max (V)', + 'Min (V)', + 'Max (Hz)', + 'Min (Hz)' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Power Supply' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_profile(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'ProfileInfo' in server: + if server['ProfileInfo'] is not None: + item = server['ProfileInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Profile [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'ConfigState', + 'ModTime', + 'TargetPlatform', + 'Policies.Name', + 'Policies.ClassId', + 'Policies.ModTime', + 'Policies.Shared', + 'Policies.InSync' + ] + + headers = [ + 'Server', + 'Profile', + 'State', + 'Last Modified', + 'Target Platform', + 'Policy Name', + 'Class Id', + 'Modification Time', + 'Shared', + 'In Sync' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Policies'] + ), + order=order, + headers=headers, + underline=True, + table=True, + allow_order_subkeys=True, + row_separator=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Profile' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_thermal_summary(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'Thermal' in server: + item = server['Thermal']['Summary'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Thermal Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'SensorHealth', + 'HighestTemperature', + 'SmallestGap', + 'OverThreshold', + 'FanHealth' + ] + + headers = [ + 'Server', + 'Sensors Health', + 'Highest (C)', + 'Smallest Gap (C)', + 'Over Threshold', + 'Fans Health' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Thermal Summary' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_thermal_sensor(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'Thermal' in server: + for item in server['Thermal']['Data']['Temperature']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Thermal Sensor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + + headers = [ + 'Server', + 'Sensor Name', + 'State', + 'Health', + 'Location', + 'Value (Celcius)', + 'Upper Threshold (Celcius)' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Thermal Sensor' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_thermal_fan(self, servers, title=False): + self.my_output.clear_output() + + info = [] + for server in servers: + if 'Thermal' in server: + for item in server['Thermal']['Data']['Fan']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Thermal Fan [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'Value' + ] + + headers = [ + 'Server', + 'Fan Name', + 'State', + 'Health', + 'Value' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Thermal Fan' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_inventory_rack(self, server_info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.default( + 'Server Inventory (R): %s' % (server_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + server_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_inventory_chassis(self, chassis_info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.default( + 'Chassis Inventory: %s' % (chassis_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + chassis_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_inventory_blade(self, server_info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.default( + 'Server Inventory (B): %s' % (server_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + server_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_inventory(self, servers, chassiz_info, title=False): + self.my_output.clear_output() + + for server in servers: + if server['Type'] == 'Rack': + self.print_inventory_rack( + server, + title=title + ) + + chassis_moid = [] + for server in servers: + if server['Type'] == 'Blade': + if server['ChassisMoid'] not in chassis_moid: + chassis_moid.append( + server['ChassisMoid'] + ) + + for chassis_info in chassiz_info: + if chassis_info['Moid'] in chassis_moid: + self.print_inventory_chassis( + chassis_info, + title=title + ) + + for server in servers: + if server['Type'] == 'Blade': + if server['ChassisMoid'] == chassis_info['Moid']: + self.print_inventory_blade( + server, + title=title + ) + + def print_advisory(self, servers, title=False): + self.my_output.clear_output() + + advisories = {} + for server in servers: + for server_advisory in server['AdvisoryInfo']: + if server_advisory['Name'] not in advisories: + advisories[server_advisory['Name']] = server_advisory + advisories[server_advisory['Name']]['Server'] = [] + + advisories[server_advisory['Name']]['Server'].append( + server['Name'] + ) + + info = [] + for advisory_name in advisories: + item = advisories[advisory_name] + item['NameT'] = filter_helper.get_string_chunks( + item['Name'], + 40, + separator=' ' + ) + item['DescriptionT'] = filter_helper.get_string_chunks( + item['Description'].replace('\n', ''), + 40, + separator=' ' + ) + item['Server'] = sorted( + item['Server'], + key=lambda i: i.lower() + ) + info.append( + item + ) + + if title: + self.my_output.my_print( + 'Advisory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'Server', + 'Severity', + 'BaseScore', + 'NameT', + 'DescriptionT', + 'CveIds', + 'DatePublished', + 'DateUpdated' + ] + + headers = [ + 'Server', + 'Severity', + 'Score', + 'Name', + 'Description', + 'CveIds', + 'DatePublished', + 'DateUpdated' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Server', 'DescriptionT', 'NameT', 'CveIds'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Thermal Fan' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + # if len(info) > 0: + # if title: + # self.my_output.default( + # 'Advisory Url [#%s]' % (len(info)), + # underline=True, + # before_newline=True + # ) + + # order = [ + # 'Server', + # 'NameT', + # 'Urls' + # ] + + # headers = [ + # 'Server', + # 'Name', + # 'Urls' + # ] + + # self.my_output.my_table( + # self.my_output.expand_lists( + # info, + # order, + # ['Server', 'NameT', 'Urls'] + # ), + # order=order, + # headers=headers, + # remove_empty_columns=True, + # allow_order_subkeys=True, + # row_separator=True, + # underline=True, + # table=True + # ) + + def print_tag(self, servers, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Server Tags', + underline=True, + before_newline=True + ) + + if len(servers) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + tags = {} + for server in servers: + for tag in server['Tags']: + if tag['Key'] == 'Intersight.LicenseTier': + continue + + tag_kv = '%s:%s' % ( + tag['Key'], + tag['Value'] + ) + + if tag_kv not in tags: + tags[tag_kv] = {} + tags[tag_kv]['count'] = 0 + tags[tag_kv]['server'] = [] + + tags[tag_kv]['count'] = tags[tag_kv]['count'] + 1 + tags[tag_kv]['server'].append(server['Name']) + + info = [] + for tag in tags: + item = {} + item['tag'] = tag + item['count'] = tags[tag]['count'] + info.append(item) + + info = sorted( + info, + key=lambda i: i['tag'] + ) + + order = [ + 'tag', + 'count' + ] + + headers = [ + 'Tag', + 'Count' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=False, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Server Tags' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_alarm(self, alarms, title=False): + self.my_output.clear_output() + + info = [] + for alarm in alarms: + alarm['DescriptionT'] = filter_helper.get_string_chunks( + alarm['Description'], + 40, + separator=' ' + ) + alarm['AffectedTypeT'] = alarm['AffectedType'].split('.') + alarm['AffectedNameT'] = alarm['AffectedName'].split('/') + alarm['NameCodeT'] = [] + alarm['NameCodeT'].append(alarm['Name']) + if alarm['Name'] != alarm['Code']: + alarm['NameCodeT'].append('Code: %s' % (alarm['Code'])) + + alarm['TimeT'] = [] + alarm['TimeT'].append('(C) %s' % (alarm['CreateTime'])) + alarm['TimeT'].append('(U) %s' % (alarm['LastTransitionTime'])) + + info.append( + alarm + ) + + if title: + self.my_output.my_print( + 'Alarm [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'Severity', + 'AffectedTypeT', + 'AffectedNameT', + 'TimeT', + 'NameCodeT', + 'DescriptionT' + ] + + headers = [ + 'Severity', + 'Affected Type', + 'Affected Name', + 'When', + 'Alarm', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['AffectedTypeT', 'DescriptionT', 'AffectedNameT', 'NameCodeT', 'TimeT'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Alarm' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/intersight/cache.py b/lib/intersight/cache.py new file mode 100644 index 00000000..25493316 --- /dev/null +++ b/lib/intersight/cache.py @@ -0,0 +1,112 @@ +import os +import json +import time + +from lib import log_helper + +from lib.intersight.settings import IntersightSettings + + +class IntersightCache(IntersightSettings): + def __init__(self, iaccount, log_id=None): + IntersightSettings.__init__(self, log_id=log_id) + + self.iaccount = iaccount + self.log = log_helper.Log(log_id=log_id) + + self.intersight_settings = self.get_intersight_settings() + if self.intersight_settings is None: + raise ValueError('Intersight settings read failed') + + self.intersight_cache_directory = self.intersight_settings['ComputeCacheDirectory'] + self.intersight_cache_ttl = self.intersight_settings['CacheTtl'] + + def is_intersight_cache(self, cache_entry_name, subdirectory=None, cache_ttl=None): + if self.get_intersight_cache_entry(cache_entry_name, subdirectory=subdirectory, cache_ttl=cache_ttl) is None: + return False + return True + + def get_intersight_cache_entry(self, cache_entry_name, subdirectory=None, check_ttl=True, cache_ttl=None): + directory_name = self.intersight_cache_directory + if subdirectory is not None: + directory_name = os.path.join( + directory_name, + subdirectory + ) + + filename = os.path.join( + directory_name, + cache_entry_name + ) + + if not os.path.isfile(filename): + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + cache_entry = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_intersight_cache_entry', 'Cache read failed: %s' % (filename)) + return None + + for key in ['data', 'timestamp']: + if key not in cache_entry: + self.log.error('get_intersight_cache_entry', 'Invalid cache content: %s' % (filename)) + return None + + if check_ttl: + if cache_ttl is None: + if self.intersight_cache_ttl > 0: + entry_ttl = int(time.time()) - cache_entry['timestamp'] + if entry_ttl > self.intersight_cache_ttl: + return None + + if cache_ttl is not None: + if cache_ttl > 0: + entry_ttl = int(time.time()) - cache_entry['timestamp'] + if entry_ttl > cache_ttl: + return None + + return cache_entry['data'] + + def set_intersight_cache_entry(self, cache_entry_name, data, subdirectory=None): + directory_name = self.intersight_cache_directory + if subdirectory is not None: + directory_name = os.path.join( + directory_name, + subdirectory + ) + + if os.path.isfile(directory_name): + os.remove(directory_name) + + if not os.path.isdir(directory_name): + os.makedirs( + directory_name, + exist_ok=True + ) + + filename = os.path.join( + directory_name, + cache_entry_name + ) + + content = {} + content['timestamp'] = int(time.time()) + content['data'] = data + + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + content, + indent=4 + ) + ) + + except BaseException: + self.log.error('set_intersight_cache_entry', 'Cache set failed: %s' % (filename)) + return False + + return True diff --git a/lib/intersight/chassis.py b/lib/intersight/chassis.py new file mode 100644 index 00000000..070c37a2 --- /dev/null +++ b/lib/intersight/chassis.py @@ -0,0 +1,70 @@ +from lib import log_helper + +from lib.intersight import cache as intersight_cache +from lib.intersight.chassis_mo import ChassisMo +from lib.intersight.chassis_info import ChassisInfo + +from lib.intersight.adapter_unit import main as adapter_unit +from lib.intersight.adapter_ext_eth_interface import main as adapter_ext_eth_interface +from lib.intersight.asset_device_contract_information import main as asset_device_contract_information +from lib.intersight.chassis_profile import main as chassis_profile +from lib.intersight.compute_blade import main as compute_blade +from lib.intersight.cond_alarm import main as cond_alarm +from lib.intersight.equipment_chassis import main as equipment_chassis +from lib.intersight.equipment_expander_module import main as equipment_expander_module +from lib.intersight.equipment_fan_module import main as equipment_fan_module +from lib.intersight.equipment_fan import main as equipment_fan +from lib.intersight.equipment_fan_control import main as equipment_fan_control +from lib.intersight.equipment_iocard import main as equipment_iocard +from lib.intersight.equipment_psu import main as equipment_psu +from lib.intersight.equipment_psu_control import main as equipment_psu_control +from lib.intersight.ethernet_host_port import main as ethernet_host_port +from lib.intersight.ethernet_network_port import main as ethernet_network_port +from lib.intersight.ethernet_physical_port import main as ethernet_physical_port +from lib.intersight.network_element_summary import main as network_element_summary +from lib.intersight.power_control_state import main as power_control_state +from lib.intersight.tam_advisory_instance import main as tam_advisory_instance + + +class Chassis(ChassisMo, ChassisInfo): + def __init__(self, iaccount, log_id=None): + ChassisMo.__init__(self) + ChassisInfo.__init__(self) + + self.log_handler = log_helper.Log(log_id=log_id) + self.log_id = log_id + + self.chassis_handler = equipment_chassis.EquipmentChassis(iaccount, log_id=log_id) + self.chassis_handler.set_get_expand('RegisteredDevice') + self.blade_handler = compute_blade.ComputeBlade(iaccount, log_id=log_id) + + self.cache_handler = intersight_cache.IntersightCache( + iaccount, + log_id=log_id + ) + self.iaccount = iaccount + + self.cache_handler = intersight_cache.IntersightCache( + iaccount, + log_id=log_id + ) + + self.iocard_handler = equipment_iocard.EquipmentIoCard(iaccount, log_id=log_id) + self.expander_module_handler = equipment_expander_module.EquipmentExpanderModule(iaccount, log_id=log_id) + self.ether_host_port_handler = ethernet_host_port.EthernetHostPort(iaccount, log_id=log_id) + self.ether_network_port_handler = ethernet_network_port.EthernetNetworkPort(iaccount, log_id=log_id) + self.ether_physical_port_handler = ethernet_physical_port.EthernetPhysicalPort(iaccount, log_id=log_id) + self.fan_module_handler = equipment_fan_module.EquipmentFanModule(iaccount, log_id=log_id) + self.fan_handler = equipment_fan.EquipmentFan(iaccount, log_id=log_id) + self.fan_control_handler = equipment_fan_control.EquipmentFanControl(iaccount, log_id=log_id) + self.psu_handler = equipment_psu.EquipmentPsu(iaccount, log_id=log_id) + self.psu_control_handler = equipment_psu_control.EquipmentPsuControl(iaccount, log_id=log_id) + self.power_control_state_handler = power_control_state.PowerControlState(iaccount, log_id=log_id) + self.compute_blade_handler = compute_blade.ComputeBlade(iaccount, log_id=log_id) + self.adapter_unit_handler = adapter_unit.AdapterUnit(iaccount, log_id=log_id) + self.adapter_ext_eth_interface_handler = adapter_ext_eth_interface.AdapterExtEthInterface(iaccount, log_id=log_id) + self.cond_alarm_handler = cond_alarm.CondAlarm(iaccount, log_id=log_id) + self.tam_advisory_instance_handler = tam_advisory_instance.TamAdvisoryInstance(iaccount, log_id=log_id) + self.asset_device_contract_information_handler = asset_device_contract_information.AssetDeviceContractInformation(iaccount, log_id=log_id) + self.chassis_profile_handler = chassis_profile.ChassisProfile(iaccount, log_id=log_id) + self.network_element_summary_handler = network_element_summary.NetworkElementSummary(iaccount, log_id=log_id) diff --git a/lib/intersight/chassis_cache.py b/lib/intersight/chassis_cache.py new file mode 100644 index 00000000..475f72e7 --- /dev/null +++ b/lib/intersight/chassis_cache.py @@ -0,0 +1,2391 @@ +import time + + +class ChassisCache(): + def __init__(self): + self.fan_module_moids = {} + + def set_intersight_cache(self, key, chassis_moids, device_moids, serial, filter_length_threshold=20, cache_ttl=None): + if key == 'fan_control': + cache_hits = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('fan_control', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'fan control cache hit: %s' % (cache_hits) + ) + + if len(target_chassis_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_chassis_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_chassis_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.fan_control_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'fan control miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.fan_control_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'fan control failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['Parent']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'fan_control', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'fan_module': + cache_hits = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('fan_module', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_chassis_moids.append( + chassis_moid + ) + else: + fan_modules_mo = self.cache_handler.get_intersight_cache_entry( + 'fan_module', + subdirectory=chassis_moid, + cache_ttl=cache_ttl + ) + if fan_modules_mo is None: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'fan module cache failed: %s' % (chassis_moid) + ) + else: + self.fan_module_moids[chassis_moid] = [] + for chassis_fan_module_mo in fan_modules_mo: + self.fan_module_moids[chassis_moid].append( + chassis_fan_module_mo['Moid'] + ) + + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'fan module cache hit: %s' % (cache_hits) + ) + + if len(target_chassis_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_chassis_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_chassis_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.fan_module_handler.set_get_filter( + "EquipmentChassis/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'fan module miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.fan_module_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'fan module failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'fan_module', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + self.fan_module_moids[target_moid] = [] + for managed_object in chassis_managed_objects[target_moid]: + self.fan_module_moids[target_moid].append( + managed_object['Moid'] + ) + + return + + # if len(target_chassis_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_chassis_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.fan_module_handler.set_get_filter( + # "EquipmentChassis/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'fan module miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'fan module miss wout filter' + # ) + + # managed_objects = self.fan_module_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'fan module failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'fan_module', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # self.fan_module_moids[chassis_moid] = [] + # for managed_object in chassis_managed_objects: + # self.fan_module_moids[chassis_moid].append( + # managed_object['Moid'] + # ) + + # return + + if key == 'fan': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('fan', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'fan cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_chassis_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_chassis_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for chunk_target_moid in chunk_target_moids: + for fan_module_moid in self.fan_module_moids[chunk_target_moid]: + moids_list.append('\'%s\'' % (fan_module_moid)) + moids_filter = ', '.join(moids_list) + + self.fan_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'fan miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.fan_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'fan failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['Parent']['Moid'] in self.fan_module_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'fan', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for target_chassis_moid in target_chassis_moids: + # for fan_module_moid in self.fan_module_moids[target_chassis_moid]: + # moids_list.append('\'%s\'' % (fan_module_moid)) + # moids_filter = ', '.join(moids_list) + + # self.fan_handler.set_get_filter( + # "Parent/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'fan miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'fan miss wout filter' + # ) + + # managed_objects = self.fan_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'fan failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['Parent']['Moid'] in self.fan_module_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'fan', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'power_control': + cache_hits = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('power_control', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'power control cache hit: %s' % (cache_hits) + ) + + if len(target_chassis_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_chassis_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_chassis_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.power_control_state_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'power control miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.power_control_state_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'power control failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['Parent']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'power_control', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'psu_control': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('psu_control', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + chassis_moid + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'psu control cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_chassis_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_chassis_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.psu_control_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'psu control miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.psu_control_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'psu control failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['Parent']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'psu_control', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'psu': + cache_hits = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('psu', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'psu cache hit: %s' % (cache_hits) + ) + + if len(target_chassis_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_chassis_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_chassis_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.psu_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'psu miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.psu_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'psu failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['Parent']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'psu', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'iocard': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('iocard', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + chassis_moid + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'iocard cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.iocard_handler.set_get_filter( + "EquipmentChassis/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'iocard miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.iocard_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'iocard failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'iocard', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.iocard_handler.set_get_filter( + # "EquipmentChassis/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'iocard miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'iocard miss wout filter' + # ) + + # managed_objects = self.iocard_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'iocard failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'iocard', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'expander_module': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('expander_module', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + chassis_moid + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'expander module cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.expander_module_handler.set_get_filter( + "EquipmentChassis/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'expander module miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.expander_module_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'iocard failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'expander_module', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.iocard_handler.set_get_filter( + # "EquipmentChassis/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'iocard miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'iocard miss wout filter' + # ) + + # managed_objects = self.iocard_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'iocard failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'iocard', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'ether_host_port': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('ether_host_port', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'host port cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.ether_host_port_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'host port miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.ether_host_port_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'host port failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'ether_host_port', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.ether_host_port_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'ether host port miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'ether host port miss wout filter' + # ) + + # managed_objects = self.ether_host_port_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'ether host port failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'ether_host_port', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'ether_network_port': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('ether_network_port', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'network port cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.ether_network_port_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'network port miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.ether_network_port_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'network port failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'ether_network_port', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.ether_network_port_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'ether network port miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'ether network port miss wout filter' + # ) + + # managed_objects = self.ether_network_port_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'ether network port failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'ether_network_port', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'ether_physical_port': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('ether_physical_port', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'phy port cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.ether_physical_port_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'phy port miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.ether_physical_port_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'phy port failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'ether_physical_port', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.ether_physical_port_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'ether phy port miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'ether phy port miss wout filter' + # ) + + # managed_objects = self.ether_physical_port_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'ether phy port failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'ether_physical_port', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'blade': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('blade', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + chassis_moid + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'blade cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.blade_handler.set_get_filter( + "EquipmentChassis/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'blade miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.blade_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'blade failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'blade', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.blade_handler.set_get_filter( + # "EquipmentChassis/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'blade miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'blade miss wout filter' + # ) + + # managed_objects = self.blade_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'blade failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['EquipmentChassis']['Moid'] == chassis_moid: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'blade', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'adapter': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('adapter', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'adapter cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.adapter_unit_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'adapter miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.adapter_unit_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'adapter failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'adapter', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.adapter_unit_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'adapter miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'adapter miss wout filter' + # ) + + # managed_objects = self.adapter_unit_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'adapter failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'adapter', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'interface': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('interface', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'interface cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.adapter_ext_eth_interface_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'interface miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.adapter_ext_eth_interface_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'interface failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'interface', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.adapter_ext_eth_interface_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'interface miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'interface miss wout filter' + # ) + + # managed_objects = self.adapter_ext_eth_interface_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'interface failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'interface', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'alarm': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('alarm', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'alarm cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.cond_alarm_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'alarm miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.cond_alarm_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'alarm failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'alarm', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.cond_alarm_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'alarm miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'alarm miss wout filter' + # ) + + # managed_objects = self.cond_alarm_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'alarm failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'alarm', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'advisory': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('advisory', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'advisory cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.tam_advisory_instance_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'advisory miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.tam_advisory_instance_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'advisory failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'advisory', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.tam_advisory_instance_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'advisory miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'advisory miss wout filter' + # ) + + # managed_objects = self.tam_advisory_instance_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'advisory failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'advisory', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'contract': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in serial: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('contract', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + serial[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'contract cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.asset_device_contract_information_handler.set_get_filter( + "DeviceId in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'contract miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.asset_device_contract_information_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'contract failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if serial[chassis_moid] == managed_object['DeviceId']: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'contract', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.asset_device_contract_information_handler.set_get_filter( + # "DeviceId in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'compute_info.set_intersight_cache', + # 'contract cache miss w/filter: %s' % (target_moids) + # ) + # else: + # self.log_handler.debug( + # 'compute_info.set_intersight_cache', + # 'contract cache miss wout filter' + # ) + + # managed_objects = self.asset_device_contract_information_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'compute.set_intersight_cache', + # 'contract failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if serial[chassis_moid] == managed_object['DeviceId']: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'contract', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'fi': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('fi', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[chassis_moid] + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'chassis.set_intersight_cache', + 'fi cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.network_element_summary_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'fi miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.network_element_summary_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'fi failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'fi', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.network_element_summary_handler.set_get_filter( + # "RegisteredDevice/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'fi miss w/filter: %s' % (target_chassis_moids) + # ) + # else: + # self.log_handler.debug( + # 'chassis_info.set_intersight_cache', + # 'fi miss wout filter' + # ) + + # managed_objects = self.network_element_summary_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'chassis_info.set_intersight_cache', + # 'fi failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if managed_object['RegisteredDevice']['Moid'] == device_moids[chassis_moid]: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'fi', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + if key == 'profile': + cache_hits = [] + target_moids = [] + target_chassis_moids = [] + for chassis_moid in chassis_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('profile', subdirectory=chassis_moid, cache_ttl=cache_ttl): + target_moids.append( + chassis_moid + ) + target_chassis_moids.append( + chassis_moid + ) + else: + cache_hits.append( + chassis_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'profile cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + self.chassis_profile_handler.set_get_expand('ConfigResult') + + chassis_managed_objects = {} + for target_moid in target_chassis_moids: + chassis_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.chassis_profile_handler.set_get_filter( + "AssignedChassis/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'chassis_info.set_intersight_cache', + 'profile miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.chassis_profile_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'chassis_info.set_intersight_cache', + 'profile failed' + ) + return + + for chassis_moid in target_chassis_moids: + for managed_object in managed_objects: + if 'AssignedChassis' in managed_object and managed_object['AssignedChassis'] is not None: + if managed_object['AssignedChassis']['Moid'] == device_moids[chassis_moid]: + chassis_managed_objects[chassis_moid].append( + managed_object + ) + + for target_moid in target_chassis_moids: + self.cache_handler.set_intersight_cache_entry( + 'profile', + chassis_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + # if len(target_moids) < filter_length_threshold: + # moids_list = [] + # for moid in target_moids: + # moids_list.append('\'%s\'' % (moid)) + # moids_filter = ', '.join(moids_list) + + # self.chassis_profile_handler.set_get_filter( + # "AssignedChassis/Moid in (%s)" % (moids_filter) + # ) + + # self.log_handler.debug( + # 'compute_info.set_intersight_cache', + # 'profile cache miss w/filter: %s' % (target_moids) + # ) + # else: + # self.log_handler.debug( + # 'compute_info.set_intersight_cache', + # 'profile cache miss wout filter' + # ) + + # managed_objects = self.chassis_profile_handler.get_all() + # if managed_objects is None: + # self.log_handler.error( + # 'compute.set_intersight_cache', + # 'profile failed' + # ) + # return + + # for chassis_moid in target_chassis_moids: + # chassis_managed_objects = [] + # for managed_object in managed_objects: + # if 'AssignedChassis' in managed_object and managed_object['AssignedChassis'] is not None: + # if chassis_moid == managed_object['AssignedChassis']['Moid']: + # chassis_managed_objects.append( + # managed_object + # ) + + # self.cache_handler.set_intersight_cache_entry( + # 'profile', + # chassis_managed_objects, + # subdirectory=chassis_moid + # ) + + # return + + self.log_handler.error( + 'set_intersight_cache', + 'Unsupported key: %s' % (key) + ) + return + + def set_cache(self, chassiz_mo, cache_settings, cache_ttl, ctx=None): + start_time = int(time.time() * 1000) + self.log_handler.debug( + 'chassis.set_cache', + 'Start cache population' + ) + + moids = [] + device_moids = {} + serial = {} + + for chassis_mo in chassiz_mo: + moids.append(chassis_mo['Moid']) + device_moids[chassis_mo['Moid']] = chassis_mo['DeviceMoId'] + serial[chassis_mo['Moid']] = chassis_mo['Serial'] + + keys = [] + + if 'advisory' in cache_settings and cache_settings['advisory']: + keys.append('advisory') + + if 'alarm' in cache_settings and cache_settings['alarm']: + keys.append('alarm') + + if 'contract' in cache_settings and cache_settings['contract']: + keys.append('contract') + + if 'profile' in cache_settings and cache_settings['profile']: + keys.append('profile') + + if 'node' in cache_settings and cache_settings['node']: + keys.append('blade') + + if 'io' in cache_settings and cache_settings['io']: + keys.append('iocard') + + if 'expander_module' in cache_settings and cache_settings['expander_module']: + keys.append('expander_module') + + if 'port' in cache_settings and cache_settings['port']: + keys.append('ether_host_port') + keys.append('ether_network_port') + + if 'eth' in cache_settings and cache_settings['eth']: + keys.append('ether_physical_port') + keys.append('adapter') + keys.append('interface') + + if 'fi' in cache_settings and cache_settings['fi']: + keys.append('fi') + + if 'fan' in cache_settings and cache_settings['fan']: + keys.append('fan_control') + keys.append('fan_module') + keys.append('fan') + + if 'psu' in cache_settings and cache_settings['psu']: + keys.append('psu') + + if 'psu_control' in cache_settings and cache_settings['psu_control']: + keys.append('psu_control') + + if 'power_control' in cache_settings and cache_settings['power_control']: + keys.append('power_control') + + if len(keys) > 0: + for key in keys: + if ctx is not None: + ctx.my_output.debug('- %s' % (key)) + + self.set_intersight_cache( + key, + moids, + device_moids, + serial, + cache_ttl=cache_ttl + ) + + duration = int(time.time() * 1000) - start_time + self.log_handler.debug( + 'chassis.set_cache', + 'Cache populated in %s ms' % (duration) + ) diff --git a/lib/intersight/chassis_extra_attributes.py b/lib/intersight/chassis_extra_attributes.py new file mode 100644 index 00000000..f33a145b --- /dev/null +++ b/lib/intersight/chassis_extra_attributes.py @@ -0,0 +1,1011 @@ +from lib import log_helper +from lib.intersight import cache as intersight_cache +from lib.intersight.adapter_unit import main as adapter_unit +from lib.intersight.adapter_ext_eth_interface import main as adapter_ext_eth_interface +from lib.intersight.asset_device_contract_information import main as asset_device_contract_information +from lib.intersight.chassis_profile import main as chassis_profile +from lib.intersight.compute_blade import main as compute_blade +from lib.intersight.cond_alarm import main as cond_alarm +from lib.intersight.equipment_expander_module import main as equipment_expander_module +from lib.intersight.equipment_fan_module import main as equipment_fan_module +from lib.intersight.equipment_fan import main as equipment_fan +from lib.intersight.equipment_fan_control import main as equipment_fan_control +from lib.intersight.equipment_iocard import main as equipment_iocard +from lib.intersight.equipment_psu import main as equipment_psu +from lib.intersight.equipment_psu_control import main as equipment_psu_control +from lib.intersight.ethernet_host_port import main as ethernet_host_port +from lib.intersight.ethernet_network_port import main as ethernet_network_port +from lib.intersight.ethernet_physical_port import main as ethernet_physical_port +from lib.intersight.network_element_summary import main as network_element_summary +from lib.intersight.power_control_state import main as power_control_state +from lib.intersight.tam_advisory_instance import main as tam_advisory_instance + + +class ChassisExtraAttributes(): + """Class for chassis object extra attributes + """ + def __init__(self, iaccount, log_id=None): + self.chassis_info = {} + self.chassis_helper = {} + + self.log_handler = log_helper.Log(log_id=log_id) + + self.cache_handler = intersight_cache.IntersightCache( + iaccount, + log_id=log_id + ) + + self.iocard_handler = equipment_iocard.EquipmentIoCard(iaccount, log_id=log_id) + self.expander_module_handler = equipment_expander_module.EquipmentExpanderModule(iaccount, log_id=log_id) + self.ether_host_port_handler = ethernet_host_port.EthernetHostPort(iaccount, log_id=log_id) + self.ether_network_port_handler = ethernet_network_port.EthernetNetworkPort(iaccount, log_id=log_id) + self.ether_physical_port_handler = ethernet_physical_port.EthernetPhysicalPort(iaccount, log_id=log_id) + + self.fan_module_handler = equipment_fan_module.EquipmentFanModule(iaccount, log_id=log_id) + self.fan_handler = equipment_fan.EquipmentFan(iaccount, log_id=log_id) + self.fan_control_handler = equipment_fan_control.EquipmentFanControl(iaccount, log_id=log_id) + self.psu_handler = equipment_psu.EquipmentPsu(iaccount, log_id=log_id) + self.psu_control_handler = equipment_psu_control.EquipmentPsuControl(iaccount, log_id=log_id) + self.power_control_state_handler = power_control_state.PowerControlState(iaccount, log_id=log_id) + + self.compute_blade_handler = compute_blade.ComputeBlade(iaccount, log_id=log_id) + self.adapter_unit_handler = adapter_unit.AdapterUnit(iaccount, log_id=log_id) + self.adapter_ext_eth_interface_handler = adapter_ext_eth_interface.AdapterExtEthInterface(iaccount, log_id=log_id) + self.cond_alarm_handler = cond_alarm.CondAlarm(iaccount, log_id=log_id) + self.tam_advisory_instance_handler = tam_advisory_instance.TamAdvisoryInstance(iaccount, log_id=log_id) + self.asset_device_contract_information_handler = asset_device_contract_information.AssetDeviceContractInformation(iaccount, log_id=log_id) + self.chassis_profile_handler = chassis_profile.ChassisProfile(iaccount, log_id=log_id) + self.network_element_summary_handler = network_element_summary.NetworkElementSummary(iaccount, log_id=log_id) + + def add_common_attributes(self, chassis_mo): + keys = [ + 'ConnectionPath', + 'ConnectionStatus', + 'Description', + 'Dn', + 'DeviceMoId', + 'Moid', + 'Model', + 'Name', + 'OperState', + 'PartNumber', + 'Pid', + 'ProductName', + 'Serial', + 'Sku', + 'Vendor' + ] + + for key in keys: + if isinstance(chassis_mo[key], str): + self.chassis_info[key] = chassis_mo[key].strip() + continue + + self.chassis_info[key] = chassis_mo[key] + + self.chassis_info['AlarmSummary'] = {} + self.chassis_info['AlarmSummary']['__Output'] = {} + self.chassis_info['AlarmSummary']['__Output']['Critical'] = 'Red' + self.chassis_info['AlarmSummary']['__Output']['Warning'] = 'Yellow' + self.chassis_info['AlarmSummary']['__Output']['Info'] = 'Blue' + self.chassis_info['AlarmSummary']['__Output']['Cleared'] = 'Green' + + for key in ['Critical', 'Warning', 'Info', 'Cleared']: + if key in chassis_mo['AlarmSummary']: + self.chassis_info['AlarmSummary'][key] = chassis_mo['AlarmSummary'][key] + + self.chassis_info['Health'] = 'Healthy' + self.chassis_info['__Output']['Health'] = 'Green' + + if self.chassis_info['AlarmSummary']['Warning'] == 0 and self.chassis_info['AlarmSummary']['Critical'] == 0: + if 'Info' in self.chassis_info['AlarmSummary'] and self.chassis_info['AlarmSummary']['Info'] > 0: + self.chassis_info['Health'] = 'Healthy (%s)' % ( + self.chassis_info['AlarmSummary']['Info'] + ) + self.chassis_info['__Output']['Health'] = 'Blue' + + if self.chassis_info['AlarmSummary']['Warning'] > 0 and self.chassis_info['AlarmSummary']['Critical'] == 0: + self.chassis_info['Health'] = 'Warnings (%s)' % ( + self.chassis_info['AlarmSummary']['Warning'] + ) + self.chassis_info['__Output']['Health'] = 'Yellow' + + if self.chassis_info['AlarmSummary']['Critical'] > 0: + self.chassis_info['Health'] = 'Critical (%s)' % ( + self.chassis_info['AlarmSummary']['Critical'] + ) + self.chassis_info['__Output']['Health'] = 'Red' + + if self.chassis_info['OperState'] == '': + self.chassis_info['OperStateTick'] = '--' + else: + if self.chassis_info['OperState'].lower() in ['ok', 'operable']: + self.chassis_info['OperStateTick'] = '\u2713' + self.chassis_info['__Output']['OperStateTick'] = 'Green' + else: + self.chassis_info['OperStateTick'] = '\u2717' + self.chassis_info['__Output']['OperStateTick'] = 'Red' + + self.chassis_info['NodeCount'] = len( + chassis_mo['Blades'] + ) + + self.chassis_info['FanModuleCount'] = len( + chassis_mo['Fanmodules'] + ) + + self.chassis_info['IoCount'] = len( + chassis_mo['Ioms'] + ) + + self.chassis_info['ExpanderModuleCount'] = len( + chassis_mo['ExpanderModules'] + ) + + self.chassis_info['PsuCount'] = len( + chassis_mo['Psus'] + ) + + def add_alarm_info(self, include_cleared=False, include_acknowledged=False): + self.chassis_info['AlarmInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'alarm', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_alarm_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + critical_count = 0 + warning_count = 0 + info_count = 0 + + for managed_object in managed_objects: + alarm_info = self.cond_alarm_handler.get_info( + managed_object + ) + if alarm_info['Severity'] == 'Cleared' and not include_cleared: + continue + + if alarm_info['Acknowledge'] == 'Acknowledge' and not include_acknowledged: + continue + + if alarm_info['AncestorMoId'] != self.chassis_info['Moid']: + continue + + if alarm_info['Severity'] == 'Critical': + critical_count = critical_count + 1 + + if alarm_info['Severity'] == 'Warning': + warning_count = warning_count + 1 + + if alarm_info['Severity'] == 'Info': + info_count = info_count + 1 + + self.chassis_info['AlarmInfo'].append( + alarm_info + ) + + if critical_count != self.chassis_info['AlarmSummary']['Critical']: + self.log.error( + 'add_alarm_info', + 'Critical alarms do not match count: %s' % (self.chassis_info['Moid']) + ) + + if warning_count != self.chassis_info['AlarmSummary']['Warning']: + self.log.error( + 'add_alarm_info', + 'Warning alarms do not match count: %s' % (self.chassis_info['Moid']) + ) + + if info_count != self.chassis_info['AlarmSummary']['Info']: + self.log.error( + 'add_alarm_info', + 'Info alarms do not match count: %s' % (self.chassis_info['Moid']) + ) + + def add_advisory_info(self): + self.chassis_info['AdvisoryInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'advisory', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_advisory_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['AdvisoryInfo'].append( + self.tam_advisory_instance_handler.get_info( + managed_object + ) + ) + + def add_contract_info(self): + self.chassis_info['ContractInfo'] = None + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'contract', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_contract_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + if len(managed_objects) == 0: + return + + if len(managed_objects) > 1: + self.log_handler.error( + 'add_contract_info', + 'Unexpected contract count: %s' % (self.chassis['Moid']) + ) + return + + self.chassis_info['ContractInfo'] = self.asset_device_contract_information_handler.get_info( + managed_objects[0] + ) + + def add_profile_info(self): + self.chassis_info['ProfileInfo'] = None + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'profile', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_profile_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + if len(managed_objects) == 0: + return + + if len(managed_objects) > 1: + self.log_handler.error( + 'add_profile_info', + 'Unexpected profile count: %s' % (self.chassis['Moid']) + ) + return + + self.chassis_info['ProfileInfo'] = self.chassis_profile_handler.get_info( + managed_objects[0] + ) + + def add_domain_info(self, chassis_mo): + self.chassis_info['Domain'] = {} + self.chassis_info['Domain']['Name'] = chassis_mo['RegisteredDevice']['DeviceHostname'][0] + + self.chassis_info['Domain']['Switch'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'network', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_domain_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['Domain']['Switch'].append( + self.network_element_summary_handler.get_info( + managed_object + ) + ) + + self.chassis_info['Domain']['Switch'] = sorted( + self.chassis_info['Domain']['Switch'], + key=lambda k: (k['Name']) + ) + + def add_node_info(self): + self.chassis_info['NodeInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'blade', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_node_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['NodeInfo'].append( + self.compute_blade_handler.get_info( + managed_object + ) + ) + + # Sort for nice display + self.chassis_info['NodeInfo'] = sorted( + self.chassis_info['NodeInfo'], + key=lambda i: ( + i['SlotId'] + ) + ) + + for node_info in self.chassis_info['NodeInfo']: + if node_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 2 + inventory_info['SubOrder'] = node_info['SlotId'] + inventory_info['Type'] = 'Node' + inventory_info['Name'] = node_info['ServerName'] + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in node_info: + inventory_info[key] = node_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.chassis_info['Moid'] + inventory_info['ServerType'] = 'N/A' + inventory_info['ServerPid'] = 'N/A' + inventory_info['ServerSerial'] = 'N/A' + + self.chassis_info['Inventory'].append( + inventory_info + ) + + def add_adapter_unit_attributes(self): + self.chassis_helper['AdapterUnitIds'] = [] + self.chassis_info['AdapterUnitInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'adapter', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_adapter_unit_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + for managed_object in managed_objects: + self.chassis_helper['AdapterUnitIds'].append( + managed_object['Moid'] + ) + + adapter_unit_info = self.adapter_unit_handler.get_info( + managed_object + ) + self.chassis_info['AdapterUnitInfo'].append( + adapter_unit_info + ) + + adapter_unit_info['ComputeNodeId'] = None + adapter_unit_info['ComputeNodePowerOn'] = None + for node_info in self.chassis_info['NodeInfo']: + if adapter_unit_info['ComputeNodeMoid'] == node_info['Moid']: + adapter_unit_info['ComputeNodeId'] = node_info['SlotId'] + adapter_unit_info['ComputeNodePowerOn'] = node_info['PowerOn'] + + def add_adapter_ext_eth_interface_attributes(self): + self.chassis_info['AdapterExtEthInterfaceInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'interface', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_adapter_ext_eth_interface_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + for managed_object in managed_objects: + adapter_ext_eth_interface_info = self.adapter_ext_eth_interface_handler.get_info( + managed_object + ) + + for adapter_unit_info in self.chassis_info['AdapterUnitInfo']: + if adapter_ext_eth_interface_info['AdapterUnitId'] == adapter_unit_info['Moid']: + adapter_ext_eth_interface_info['ComputeNodeMoid'] = adapter_unit_info['ComputeNodeMoid'] + adapter_ext_eth_interface_info['ComputeNodeId'] = adapter_unit_info['ComputeNodeId'] + adapter_ext_eth_interface_info['ComputeNodePowerOn'] = adapter_unit_info['ComputeNodePowerOn'] + adapter_ext_eth_interface_info['ComputeNodeSlot'] = adapter_unit_info['PciSlot'] + adapter_ext_eth_interface_info['AdepterModel'] = adapter_unit_info['Model'] + adapter_ext_eth_interface_info['AdepterOperState'] = adapter_unit_info['OperState'] + adapter_ext_eth_interface_info['AdepterPresence'] = adapter_unit_info['Presence'] + adapter_ext_eth_interface_info['AdepterSerial'] = adapter_unit_info['Serial'] + + if adapter_ext_eth_interface_info['ComputeNodePowerOn']: + adapter_ext_eth_interface_info['PeerInfo'] = 'Node #%s (P+) %s %s' % ( + adapter_ext_eth_interface_info['ComputeNodeId'], + adapter_ext_eth_interface_info['ComputeNodeSlot'], + adapter_ext_eth_interface_info['AdepterModel'] + ) + + if not adapter_ext_eth_interface_info['ComputeNodePowerOn']: + adapter_ext_eth_interface_info['PeerInfo'] = 'Node #%s (P-) %s %s' % ( + adapter_ext_eth_interface_info['ComputeNodeId'], + adapter_ext_eth_interface_info['ComputeNodeSlot'], + adapter_ext_eth_interface_info['AdepterModel'] + ) + + self.chassis_info['AdapterExtEthInterfaceInfo'].append( + adapter_ext_eth_interface_info + ) + + for host_port in self.chassis_info['HostPortInfo']: + host_port['PeerInfo'] = '' + host_port['PeerNodeId'] = None + + if host_port['PeerInterfaceType'] is not None: + if host_port['PeerInterfaceType'] == 'adapter.ExtEthInterface': + for ext_eth_interface_info in self.chassis_info['AdapterExtEthInterfaceInfo']: + if host_port['PeerInterfaceId'] == ext_eth_interface_info['Moid']: + host_port['PeerNodeId'] = ext_eth_interface_info['ComputeNodeId'] + host_port['PeerInfo'] = ext_eth_interface_info['PeerInfo'] + + def add_io_info(self): + self.chassis_info['IfmInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'iocard', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_io_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['IfmInfo'].append( + self.iocard_handler.get_info( + managed_object + ) + ) + + self.chassis_info['IfmInfo'] = sorted( + self.chassis_info['IfmInfo'], + key=lambda i: ( + i['ModuleId'] + ) + ) + + # Inventory + + for ifm_info in self.chassis_info['IfmInfo']: + if ifm_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 3 + inventory_info['SubOrder'] = ifm_info['ModuleId'] + inventory_info['Type'] = 'IO' + inventory_info['Name'] = ifm_info['Name'] + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in ifm_info: + inventory_info[key] = ifm_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.chassis_info['Moid'] + inventory_info['ServerType'] = 'N/A' + inventory_info['ServerPid'] = 'N/A' + inventory_info['ServerSerial'] = 'N/A' + + self.chassis_info['Inventory'].append( + inventory_info + ) + + def add_expander_module_info(self): + self.chassis_info['ExpanderModuleInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'expander_module', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_expander_module_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['ExpanderModuleInfo'].append( + self.expander_module_handler.get_info( + managed_object + ) + ) + + self.chassis_info['ExpanderModuleInfo'] = sorted( + self.chassis_info['ExpanderModuleInfo'], + key=lambda i: ( + i['ModuleId'] + ) + ) + + # Inventory + + for expander_info in self.chassis_info['ExpanderModuleInfo']: + if expander_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 4 + inventory_info['SubOrder'] = expander_info['ModuleId'] + inventory_info['Type'] = 'Expander' + inventory_info['Name'] = expander_info['Name'] + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in expander_info: + inventory_info[key] = expander_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.chassis_info['Moid'] + inventory_info['ServerType'] = 'N/A' + inventory_info['ServerPid'] = 'N/A' + inventory_info['ServerSerial'] = 'N/A' + + self.chassis_info['Inventory'].append( + inventory_info + ) + + def add_host_port_attributes(self): + self.chassis_info['HostPortInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'ether_host_port', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_host_port_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + host_port_info = self.ether_host_port_handler.get_info( + managed_object + ) + + # Enrich with module info + for io_module in self.chassis_info['IfmInfo']: + if io_module['Moid'] == host_port_info['IoModuleId']: + host_port_info['IfmDn'] = io_module['Dn'] + host_port_info['IfmName'] = io_module['Name'] + host_port_info['IfmId'] = io_module['ModuleId'] + + self.chassis_info['HostPortInfo'].append( + host_port_info + ) + + # Sort for nice display + self.chassis_info['HostPortInfo'] = sorted( + self.chassis_info['HostPortInfo'], + key=lambda k: ( + k['IfmName'], + k['ModuleId'], + k['SlotId'], + k['PortId'] + ) + ) + + def add_network_port_attributes(self): + self.chassis_helper['PhysicalPortIds'] = [] + self.chassis_info['NetworkPortInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'ether_network_port', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_network_port_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + network_port_info = self.ether_network_port_handler.get_info( + managed_object + ) + + # Enrich with module info + for io_module in self.chassis_info['IfmInfo']: + if io_module['Moid'] == network_port_info['IoModuleId']: + network_port_info['IfmDn'] = io_module['Dn'] + network_port_info['IfmName'] = io_module['Name'] + network_port_info['IfmId'] = io_module['ModuleId'] + + self.chassis_info['NetworkPortInfo'].append( + network_port_info + ) + + # Populate physical port ids for later use + if network_port_info['PeerInterfaceType'] is not None: + if network_port_info['PeerInterfaceType'] == 'ether.PhysicalPort': + self.chassis_helper['PhysicalPortIds'].append( + network_port_info['PeerInterfaceId'] + ) + + # Sort for nice display + self.chassis_info['NetworkPortInfo'] = sorted( + self.chassis_info['NetworkPortInfo'], + key=lambda k: ( + k['IfmDn'], + k['PortId'] + ) + ) + + def add_physical_port_attributes(self): + self.chassis_info['PhysicalPortInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'ether_physical_port', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_physical_port_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['PhysicalPortInfo'].append( + self.ether_physical_port_handler.get_info( + managed_object + ) + ) + + for network_port in self.chassis_info['NetworkPortInfo']: + if network_port['PeerInterfaceType'] is not None: + if network_port['PeerInterfaceType'] == 'ether.PhysicalPort': + for physical_port_info in self.chassis_info['PhysicalPortInfo']: + if network_port['PeerInterfaceId'] == physical_port_info['Moid']: + network_port['PeerSwitchId'] = physical_port_info['SwitchId'] + network_port['PeerPortName'] = physical_port_info['Name'] + network_port['PeerPortChannelId'] = physical_port_info['PortChannelId'] + network_port['PeerPortTransceiverType'] = physical_port_info['TransceiverType'] + network_port['PeerOperSpeed'] = physical_port_info['OperSpeed'] + + def add_fan_control_info(self): + self.chassis_info['FanControlInfo'] = None + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'fan_control', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_fan_control_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + if len(managed_objects) == 0: + return + + if len(managed_objects) > 1: + self.log_handler.error( + 'add_fan_control_info', + 'Unexpected fan control count: %s' % (self.chassis['Moid']) + ) + return + + self.chassis_info['FanControlInfo'] = self.fan_control_handler.get_info( + managed_objects[0] + ) + + def add_fan_module_info(self): + self.chassis_helper['FanModuleIds'] = [] + self.chassis_info['FanModuleInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'fan_module', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_fan_module_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['FanModuleInfo'].append( + self.fan_module_handler.get_info( + managed_object + ) + ) + + # Sort for nice display + self.chassis_info['FanModuleInfo'] = sorted( + self.chassis_info['FanModuleInfo'], + key=lambda i: i['ModuleId'] + ) + + def add_fan_info(self): + self.chassis_info['FanInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'fan', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_fan_info', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['FanInfo'].append( + self.fan_handler.get_info( + managed_object + ) + ) + + # Sort for nice display + self.chassis_info['FanInfo'] = sorted( + self.chassis_info['FanInfo'], + key=lambda i: ( + i['FanModuleId'], + i['FanId'] + ) + ) + + # Inventory + + for fan_info in self.chassis_info['FanInfo']: + if fan_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 5 + inventory_info['SubOrder'] = (fan_info['FanModuleId'] + 1) * 10 + fan_info['FanId'] + inventory_info['Type'] = 'Fan' + inventory_info['Name'] = fan_info['Name'] + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in fan_info: + inventory_info[key] = fan_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.chassis_info['Moid'] + inventory_info['ServerType'] = 'N/A' + inventory_info['ServerPid'] = 'N/A' + inventory_info['ServerSerial'] = 'N/A' + + self.chassis_info['Inventory'].append( + inventory_info + ) + + def add_psu_control_attributes(self): + self.chassis_info['PsuControlStateInfo'] = None + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'psu_control', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_psu_control_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + if len(managed_objects) == 0: + return + + if len(managed_objects) > 1: + self.log_handler.error( + 'add_psu_control_attributes', + 'Unexpected psu control count: %s' % (self.chassis['Moid']) + ) + return + + self.chassis_info['PsuControlStateInfo'] = self.psu_control_handler.get_info( + managed_objects[0] + ) + + def add_power_control_attributes(self): + self.chassis_info['PowerControlStateInfo'] = None + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'power_control', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_power_control_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + return + + if len(managed_objects) == 0: + return + + if len(managed_objects) > 1: + self.log_handler.error( + 'add_power_control_attributes', + 'Unexpected psu control count: %s' % (self.chassis['Moid']) + ) + return + + self.chassis_info['PowerControlStateInfo'] = self.power_control_state_handler.get_info( + managed_objects[0] + ) + + def add_psu_attributes(self): + self.chassis_info['PsuInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'psu', + subdirectory=self.chassis_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log_handler.error( + 'add_psu_attributes', + 'No cache:%s' % (self.chassis['Moid']) + ) + else: + for managed_object in managed_objects: + self.chassis_info['PsuInfo'].append( + self.psu_handler.get_info( + managed_object + ) + ) + + # Sort psu info for nice display + self.chassis_info['PsuInfo'] = sorted( + self.chassis_info['PsuInfo'], + key=lambda i: i['Dn'] + ) + + # Inventory + + for psu_info in self.chassis_info['PsuInfo']: + inventory_info = {} + inventory_info['Order'] = 6 + inventory_info['SubOrder'] = psu_info['Id'] + inventory_info['Type'] = 'PSU' + inventory_info['Id'] = psu_info['Id'] + inventory_info['Name'] = 'PSU #%s' % (psu_info['Id']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in psu_info: + inventory_info[key] = psu_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.chassis_info['Moid'] + inventory_info['ServerType'] = 'N/A' + inventory_info['ServerPid'] = 'N/A' + inventory_info['ServerSerial'] = 'N/A' + + self.chassis_info['Inventory'].append( + inventory_info + ) + + def add_chassis_attributes(self, chassis_mo, settings): + self.chassis_info = {} + self.chassis_info['__Output'] = {} + + self.add_common_attributes(chassis_mo) + + self.chassis_info['Inventory'] = [] + inventory_info = {} + inventory_info['Order'] = 1 + inventory_info['SubOrder'] = 1 + inventory_info['Type'] = 'Chassis' + inventory_info['Name'] = self.chassis_info['Name'] + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in self.chassis_info: + inventory_info[key] = self.chassis_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + if len(inventory_info['Pid']) == 0: + inventory_info['Pid'] = inventory_info['Model'] + + inventory_info['ChassisMoid'] = self.chassis_info['Moid'] + self.chassis_info['ChassisPid'] = inventory_info['Pid'] + self.chassis_info['ChassisSerial'] = inventory_info['Serial'] + + inventory_info['ServerType'] = 'N/A' + inventory_info['ServerPid'] = 'N/A' + inventory_info['ServerSerial'] = 'N/A' + + self.chassis_info['Inventory'].append( + inventory_info + ) + + if 'alarm' in settings and settings['alarm']: + self.add_alarm_info() + + if 'advisory' in settings and settings['advisory']: + self.add_advisory_info() + + if 'contract' in settings and settings['contract']: + self.add_contract_info() + + if 'profile' in settings and settings['profile']: + self.add_profile_info() + + if 'node' in settings and settings['node']: + self.add_node_info() + + if 'io' in settings and settings['io']: + self.add_io_info() + + if 'expander_module' in settings and settings['expander_module']: + self.add_expander_module_info() + + if 'eth' in settings and settings['eth']: + self.add_adapter_unit_attributes() + + if 'port' in settings and settings['port']: + self.add_adapter_unit_attributes() + self.add_host_port_attributes() + self.add_network_port_attributes() + self.add_physical_port_attributes() + self.add_adapter_ext_eth_interface_attributes() + + if 'fi' in settings and settings['fi']: + self.add_domain_info(chassis_mo) + + if 'fan' in settings and settings['fan']: + self.add_fan_module_info() + self.add_fan_info() + + if 'fan_control' in settings and settings['fan_control']: + self.add_fan_control_info() + + if 'psu_control' in settings and settings['psu_control']: + self.add_power_control_attributes() + self.add_psu_control_attributes() + + if 'psu' in settings and settings['psu']: + self.add_psu_attributes() + + self.chassis_info['Inventory'] = sorted( + self.chassis_info['Inventory'], + key=lambda i: ( + i['Order'], + i['SubOrder'] + ) + ) + + self.log_handler.set_log( + 'chassis_info.%s' % (chassis_mo['Moid']), + self.chassis_info, + json_conversion=True + ) + + return self.chassis_info diff --git a/lib/intersight/chassis_filter.py b/lib/intersight/chassis_filter.py new file mode 100644 index 00000000..548dd72e --- /dev/null +++ b/lib/intersight/chassis_filter.py @@ -0,0 +1,84 @@ +from lib import filter_helper + + +class ChassisFilter(): + def __init__(self): + pass + + def moid_filter_match_mo(self, chassis, moids): + if chassis['Moid'] in moids.split(','): + return True + return False + + def name_filter_match_mo(self, chassis_mo, name_filter): + for item in name_filter: + if '*' in item: + if filter_helper.match_string(item, chassis_mo['Name']): + return True + if '*' not in item: + if item.lower() in chassis_mo['Name'].lower(): + return True + return False + + def model_filter_match_mo(self, chassis_mo, model_filter): + for item in model_filter: + if '*' in item: + if filter_helper.match_string(item, chassis_mo['Model']): + return True + if '*' not in model_filter: + if item.lower() in chassis_mo['Model'].lower(): + return True + return False + + def serial_filter_match_mo(self, chassis_mo, serials): + for item in serials: + if '*' in item: + if filter_helper.match_string(item, chassis_mo['Serial']): + return True + if '*' not in item: + if chassis_mo['Serial'] == item: + return True + return False + + def match_chassis_mo(self, chassis_mo, match_rules): + if match_rules is None: + return True + + if 'moid' in match_rules and len(match_rules['moid']) > 0: + if not self.moid_filter_match_mo(chassis_mo, match_rules['moid']): + return False + + if 'name' in match_rules and len(match_rules['name']) > 0: + if not self.name_filter_match_mo(chassis_mo, match_rules['name']): + return False + + if 'model' in match_rules and len(match_rules['model']) > 0: + if not self.model_filter_match_mo(chassis_mo, match_rules['model']): + return False + + if 'serial' in match_rules and len(match_rules['serial']) > 0: + if not self.serial_filter_match_mo(chassis_mo, match_rules['serial']): + return False + + return True + + def get_mo_match_rules(self, moid_filter=None, name_filter=None, serial_filter=None, model_filter=None): + match_rules = {} + match_rules['moid'] = [] + match_rules['name'] = [] + match_rules['serial'] = [] + match_rules['model'] = [] + + if moid_filter is not None and len(moid_filter) > 0: + match_rules['moid'] = moid_filter + + if name_filter is not None and len(name_filter) > 0: + match_rules['name'] = name_filter + + if serial_filter is not None and len(serial_filter) > 0: + match_rules['serial'] = serial_filter + + if model_filter is not None and len(model_filter) > 0: + match_rules['model'] = model_filter + + return match_rules diff --git a/lib/intersight/chassis_info.py b/lib/intersight/chassis_info.py new file mode 100644 index 00000000..77d8d220 --- /dev/null +++ b/lib/intersight/chassis_info.py @@ -0,0 +1,45 @@ +import json + +from lib.intersight import chassis_extra_attributes +from lib.intersight.chassis_filter import ChassisFilter +from lib.intersight.chassis_cache import ChassisCache + + +class ChassisInfo(ChassisCache, ChassisFilter): + """Class for intersight chassis objects + """ + def __init__(self): + ChassisFilter.__init__(self) + ChassisCache.__init__(self) + + def get_default_settings(self): + settings = {} + settings['power'] = False + settings['fan'] = False + settings['fan_control'] = False + settings['module'] = False + settings['port'] = False + settings['node'] = False + return settings + + def get_info(self, chassiz_mo, settings, match_rules, cache_ttl, prepare_cache=True, bar_handler=None): + if prepare_cache: + self.set_cache(chassiz_mo, settings, cache_ttl) + + chassiz_info = [] + + for chassis_mo in chassiz_mo: + chassis_info_handler = chassis_extra_attributes.ChassisExtraAttributes(self.iaccount, log_id=self.log_id) + chassis_info = chassis_info_handler.add_chassis_attributes( + chassis_mo, + settings + ) + + chassiz_info.append( + chassis_info + ) + + if bar_handler is not None: + bar_handler.next() + + return chassiz_info diff --git a/lib/intersight/chassis_mo.py b/lib/intersight/chassis_mo.py new file mode 100644 index 00000000..6e64ef4c --- /dev/null +++ b/lib/intersight/chassis_mo.py @@ -0,0 +1,26 @@ +class ChassisMo(): + def __init__(self): + pass + + def get_mo(self, match_rules=None, cache_ttl=None): + chassiz_mo = None + + if cache_ttl is not None: + chassiz_mo = self.cache_handler.get_intersight_cache_entry( + 'inventory.chassis.%s' % (self.iaccount), + cache_ttl=cache_ttl + ) + + if chassiz_mo is None: + chassiz_mo = self.chassis_handler.get_all() + self.cache_handler.set_intersight_cache_entry( + 'inventory.chassis.%s' % (self.iaccount), + chassiz_mo + ) + + selected_chassiz_mo = [] + for chassis_mo in chassiz_mo: + if self.match_chassis_mo(chassis_mo, match_rules): + selected_chassiz_mo.append(chassis_mo) + + return selected_chassiz_mo diff --git a/lib/intersight/chassis_output.py b/lib/intersight/chassis_output.py new file mode 100644 index 00000000..23f81db7 --- /dev/null +++ b/lib/intersight/chassis_output.py @@ -0,0 +1,956 @@ +from lib import filter_helper +from lib import output_helper + + +class ChassisOutput(): + def __init__(self, log_id): + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def print_state(self, chassiz, title=False): + if title: + self.my_output.default( + 'Chassis State Summary [#%s]' % (len(chassiz)), + underline=True, + before_newline=True + ) + + if len(chassiz) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'Name', + 'Health', + 'OperStateTick', + 'ProfileInfo.Name', + 'Model', + 'Serial', + 'ConnectionPath', + 'ConnectionStatus', + 'NodeCount', + 'IoCount', + 'ExpanderModuleCount', + 'FanModuleCount', + 'PsuCount' + ] + + headers = [ + 'Chassis', + 'Health', + 'State', + 'Profile', + 'Model', + 'Serial', + 'ConnPath', + 'ConnStatus', + 'Node', + 'I/O', + 'Expander', + 'FanModule', + 'PSU' + ] + + self.my_output.my_table( + chassiz, + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_advisory(self, chassiz, title=False): + info = [] + for chassis in chassiz: + if 'AdvisorySummary' in chassis: + item = chassis['AdvisorySummary'] + item['ChassisName'] = chassis['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Advisory Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'High', + 'Info' + ] + + headers = [ + 'Chassis', + 'High', + 'Info' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + advisories = {} + for chassis in chassiz: + for chassis_advisory in chassis['AdvisoryInfo']: + if chassis_advisory['Name'] not in advisories: + advisories[chassis_advisory['Name']] = chassis_advisory + advisories[chassis_advisory['Name']]['Chassis'] = [] + + advisories[chassis_advisory['Name']]['Chassis'].append( + chassis['Name'] + ) + + info = [] + for advisory_name in advisories: + item = advisories[advisory_name] + item['NameT'] = filter_helper.get_string_chunks( + item['Name'], + 40, + separator=' ' + ) + item['DescriptionT'] = filter_helper.get_string_chunks( + item['Description'].replace('\n', ''), + 40, + separator=' ' + ) + item['chassis'] = sorted( + item['Chassis'], + key=lambda i: i.lower() + ) + info.append( + item + ) + + if len(info) > 0: + if title: + self.my_output.default( + 'Advisory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'Chassis', + 'Severity', + 'BaseScore', + 'NameT', + 'DescriptionT', + 'CveIds', + 'DatePublished', + 'DateUpdated' + ] + + headers = [ + 'Chassis', + 'Severity', + 'Score', + 'Name', + 'Description', + 'CveIds', + 'DatePublished', + 'DateUpdated' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Chassis', 'DescriptionT', 'NameT', 'CveIds'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + if len(info) > 0: + if title: + self.my_output.default( + 'Advisory Url [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'Chassis', + 'NameT', + 'Urls' + ] + + headers = [ + 'Chassis', + 'Name', + 'Urls' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Chassis', 'NameT', 'Urls'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_domain(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for switch_info in chassis['Domain']['Switch']: + item = switch_info + switch_info['DomainName'] = chassis['Domain']['Name'] + switch_info['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'UCS Domain Switch [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'DomainName', + 'Name', + 'HealthSummary', + 'SwitchId', + 'Model', + 'Serial', + 'OutOfBandIpAddress', + 'NumEtherPortsSummary', + 'Version' + ] + + headers = [ + 'Chassis', + 'Domain', + 'Switch', + 'Health', + 'Id', + 'Model', + 'Serial', + 'Management IP', + 'Ports', + 'Version' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassis_alarm(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for alarm in chassis['AlarmInfo']: + item = alarm + item['ChassisName'] = chassis['Name'] + item['DescriptionT'] = filter_helper.get_string_chunks( + item['Description'], + 40, + separator=' ' + ) + items.append( + item + ) + + if title: + self.my_output.default( + 'Alarm [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'Severity', + 'CreateTime', + 'Name', + 'DescriptionT' + ] + + headers = [ + 'Chassis', + 'Severity', + 'CreateTime', + 'Name', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + items, + order, + ['DescriptionT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_contract(self, chassiz, title=False): + info = [] + for chassis in chassiz: + if chassis['ContractInfo'] is None: + continue + item = chassis['ContractInfo'] + item['ChassisName'] = chassis['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Contract [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + if item['ServiceStartDate'] == '0001-01-01T00:00:00Z': + item['ServiceStartDate'] = '--' + + if item['ServiceEndDate'] == '0001-01-01T00:00:00Z': + item['ServiceEndDate'] = '--' + + order = [ + 'ChassisName', + 'ContractStatus', + 'ContractNumber', + 'ServiceStartDate', + 'ServiceEndDate', + 'ContractUpdatedTime', + 'ServiceDescription', + 'ServiceLevel', + 'ServiceSku', + 'PurchaseOrderNumber', + 'SalesOrderNumber' + ] + + headers = [ + 'Chassis', + 'Status', + 'Number', + 'Start Date', + 'End Date', + 'Last Updated', + 'Service Description', + 'Service Level', + 'Service Sku', + 'Purchase Order', + 'Sales Order' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_node(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for alarm in chassis['NodeInfo']: + item = alarm + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'Node [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'SlotId', + 'Name', + 'Health', + 'OperPowerState', + 'Model', + 'Serial', + 'CpuSummary', + 'TotalMemoryUnit' + ] + + headers = [ + 'Chassis', + 'Slot', + 'Name', + 'Health', + 'Power', + 'Model', + 'Serial', + 'CPU', + 'Memory' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_io_module(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for ifm in chassis['IfmInfo']: + item = ifm + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'I/O Module [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'Name', + 'ConnectionPath', + 'Presence', + 'OperTick', + 'Model', + 'Serial', + 'PartNumber', + 'Version', + 'Vendor', + 'HostPortsCount', + 'NetworkPortsCount', + 'FansCount' + ] + + headers = [ + 'Chassis', + 'I/O Module', + 'Path', + 'Presence', + 'OperState', + 'Model', + 'Serial', + 'P/N', + 'Version', + 'Vendor', + 'Host Ports', + 'Network Ports', + 'Fans' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_expander_module(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for exp in chassis['ExpanderModuleInfo']: + item = exp + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'Expander Module [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'Name', + 'Presence', + 'OperTick', + 'Model', + 'Serial', + 'PartNumber', + 'Vendor', + 'FansCount' + ] + + headers = [ + 'Chassis', + 'I/O Module', + 'Presence', + 'OperState', + 'Model', + 'Serial', + 'P/N', + 'Vendor', + 'Fans' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_network_port(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for item in chassis['NetworkPortInfo']: + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'Network Port [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'IfmName', + 'Name', + 'Speed', + 'PeerSwitchId', + 'PeerPortName', + 'PeerPortChannelId', + 'PeerPortTransceiverType', + 'PeerOperSpeed' + ] + + headers = [ + 'Chassis', + 'I/O Module', + 'Network Port', + 'Speed', + 'Switch ID', + 'Switch Port', + 'Switch Port Channel', + 'Switch Transceiver', + 'Switch Port Speed' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_host_port(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for item in chassis['HostPortInfo']: + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'Host Port [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'IfmName', + 'SwitchId', + 'Name', + 'Mode', + 'OperSpeed', + 'OperState', + 'OperStateQual', + 'PortChannelId' + ] + + headers = [ + 'Chassis', + 'I/O Module', + 'Path', + 'Host Port', + 'Mode', + 'Speed', + 'State', + 'State Qual', + 'Port Channel' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_fan_control(self, chassiz, title=False): + if title: + self.my_output.default( + 'Fan Control [#%s]' % (len(chassiz)), + underline=True, + before_newline=True + ) + + if len(chassiz) == 0: + self.my_output.default('None') + return + + order = [ + 'Name', + 'FanModuleSummary', + 'FanSummary', + 'FanControlInfo.Mode' + ] + + headers = [ + 'Chassis', + 'Fan Module', + 'Fan', + 'Fan Control Mode' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + chassiz, + order, + ['FanModuleInfo'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_fan(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for item in chassis['FanInfo']: + item['ChassisName'] = chassis['Name'] + item['Control'] = None + if 'FanControlInfo' in chassis and chassis['FanControlInfo'] is not None: + item['Control'] = chassis['FanControlInfo']['Mode'] + if item['Control'] is None or len(item['Control']) == 0: + item['Control'] = '--' + items.append( + item + ) + + if title: + self.my_output.default( + 'Fan [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'Name', + 'Control', + 'Presence', + 'OperState', + 'Model', + 'Serial', + 'PartNumber' + ] + + headers = [ + 'Chassis', + 'Fan', + 'Control', + 'Presence', + 'State', + 'Model', + 'Serial', + 'Part Number' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_power_control_state_info(self, chassiz, title=False): + items = [] + for chassis in chassiz: + item = chassis['PowerControlStateInfo'] + if item is None: + item = {} + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'Power Control [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'PowerSaveMode', + 'ExtendedPowerCapacity', + 'PowerRebalancing', + 'AllocatedBudget', + 'MaxRequiredPowerUnit', + 'MinRequiredPowerUnit', + 'NonRedundantMaxPowerUnit', + 'GridMaxPowerUnit', + 'N1MaxPowerUnit', + 'N2MaxPowerUnit' + ] + + for item in items: + for key in order: + if key not in item or item[key] is None or len(item[key]) == 0: + item[key] = '--' + + headers = [ + 'Chassis', + 'Save Mode', + 'Ext Capacity', + 'Dyn Rebalancing', + 'Alloc Budget', + 'Max Req', + 'Min Req', + 'Max Avail Non-Redundant (N)', + 'Max Avail Grid (N+N)', + 'Max Avail (N+1)', + 'Max Avail (N+2)' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + table=True + ) + + def print_psu_control_state_info(self, chassiz, title=False): + items = [] + for chassis in chassiz: + item = chassis['PsuControlStateInfo'] + if item is None: + item = {} + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'PSU Control [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'InputPowerStateTick', + 'OutputPowerStateTick', + 'OperStateTick', + 'Redundancy' + ] + + for item in items: + for key in order: + if key not in item or item[key] is None or len(item[key]) == 0: + item[key] = '--' + + headers = [ + 'Chassis', + 'Input Power Health', + 'Output Power Health', + 'Redundancy Health', + 'Redundancy Mode' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + table=True + ) + + def print_psu(self, chassiz, title=False): + items = [] + for chassis in chassiz: + for item in chassis['PsuInfo']: + item['ChassisName'] = chassis['Name'] + items.append( + item + ) + + if title: + self.my_output.default( + 'PSU [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(chassiz) == 0: + self.my_output.default('None') + return + + order = [ + 'ChassisName', + 'Name', + 'StateTick', + 'Voltage', + 'Model', + 'Serial' + ] + + headers = [ + 'Chassis', + 'PSU', + 'State', + 'Voltage', + 'Model', + 'Serial' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + underline=True, + row_separator=True, + allow_order_subkeys=True, + table=True + ) + + def print_inventory(self, chassiz_info, title=False): + for chassis_info in chassiz_info: + if title: + self.my_output.default( + 'Chassis Inventory: %s' % (chassis_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + chassis_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/intersight/chassis_profile/__init__.py b/lib/intersight/chassis_profile/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/chassis_profile/class.md b/lib/intersight/chassis_profile/class.md new file mode 100644 index 00000000..cd02747e --- /dev/null +++ b/lib/intersight/chassis_profile/class.md @@ -0,0 +1,78 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "Action": "No-op", + "ActionParams": [], + "Ancestors": [], + "AssignedChassis": null, + "AssociatedChassis": null, + "ClassId": "chassis.Profile", + "ConfigChangeDetails": [], + "ConfigChanges": { + "Changes": [], + "ClassId": "policy.ConfigChange", + "Disruptions": [], + "ObjectType": "policy.ConfigChange" + }, + "ConfigContext": { + "ClassId": "policy.ConfigContext", + "ConfigState": "Not-assigned", + "ConfigType": "", + "ControlAction": "No-op", + "ErrorState": "", + "ObjectType": "policy.ConfigContext", + "OperState": "" + }, + "ConfigResult": { + "ClassId": "mo.MoRef", + "Moid": "6373a88d77696e2d32fe5db3", + "ObjectType": "chassis.ConfigResult", + "link": "https://www.intersight.com/api/v1/chassis/ConfigResults/6373a88d77696e2d32fe5db3" + }, + "CreateTime": "2022-11-15T14:56:13.129Z", + "Description": "", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "IomProfiles": [ + { + "ClassId": "mo.MoRef", + "Moid": "6373a88d77696e2d32fe5db7", + "ObjectType": "chassis.IomProfile", + "link": "https://www.intersight.com/api/v1/chassis/IomProfiles/6373a88d77696e2d32fe5db7" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6373a88d77696e2d32fe5dbc", + "ObjectType": "chassis.IomProfile", + "link": "https://www.intersight.com/api/v1/chassis/IomProfiles/6373a88d77696e2d32fe5dbc" + } + ], + "ModTime": "2022-11-16T09:54:30.6Z", + "Moid": "6373a88d77696e2d32fe5db0", + "Name": "demo_chassis_policy", + "ObjectType": "chassis.Profile", + "Organization": { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + }, + "Owners": [ + "5a58c3ba3768393836cb0f1b" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "PolicyBucket": [], + "RunningWorkflows": [], + "SharedScope": "", + "SrcTemplate": null, + "Tags": [], + "TargetPlatform": "FIAttached", + "Type": "instance" + } +``` \ No newline at end of file diff --git a/lib/intersight/chassis_profile/info.py b/lib/intersight/chassis_profile/info.py new file mode 100644 index 00000000..6a298956 --- /dev/null +++ b/lib/intersight/chassis_profile/info.py @@ -0,0 +1,10 @@ +class ChassisProfileInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + + return info diff --git a/lib/intersight/chassis_profile/main.py b/lib/intersight/chassis_profile/main.py new file mode 100644 index 00000000..a74d0a70 --- /dev/null +++ b/lib/intersight/chassis_profile/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.chassis_profile.info import ChassisProfileInfo + + +class ChassisProfile(IntersightCommon, ChassisProfileInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'chassis profile' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + ChassisProfileInfo.__init__(self) diff --git a/lib/intersight/compute.py b/lib/intersight/compute.py new file mode 100644 index 00000000..be785948 --- /dev/null +++ b/lib/intersight/compute.py @@ -0,0 +1,291 @@ +from lib import log_helper + +from lib.intersight import cache as intersight_cache + +from lib.intersight.adapter_unit import main as adapter_unit +from lib.intersight.adapter_ext_eth_interface import main as adapter_ext_eth_interface +from lib.intersight.adapter_host_eth_interface import main as adapter_host_eth_interface +from lib.intersight.adapter_host_fc_interface import main as adapter_host_fc_interface +from lib.intersight.asset_device_registration import main as asset_device_registration +from lib.intersight.asset_device_contract_information import main as asset_device_contract_information +from lib.intersight.bios_boot_mode import main as bios_boot_mode +from lib.intersight.boot_cdd_device import main as boot_cdd_device +from lib.intersight.boot_device_boot_mode import main as boot_device_boot_mode +from lib.intersight.boot_device_boot_security import main as boot_device_boot_security +from lib.intersight.boot_hdd_device import main as boot_hdd_device +from lib.intersight.boot_iscsi_device import main as boot_iscsi_device +from lib.intersight.boot_nvme_device import main as boot_nvme_device +from lib.intersight.boot_pxe_device import main as boot_pxe_device +from lib.intersight.boot_san_device import main as boot_san_device +from lib.intersight.boot_sd_device import main as boot_sd_device +from lib.intersight.boot_uefi_device import main as boot_uefi_device +from lib.intersight.boot_usb_device import main as boot_usb_device +from lib.intersight.boot_vmedia_device import main as boot_vmedia_device +from lib.intersight.compute_blade import main as compute_blade +from lib.intersight.compute_rack import main as compute_rack +from lib.intersight.cond_alarm import main as cond_alarm +from lib.intersight.cond_hclstatus import main as cond_hclstatus +from lib.intersight.cond_hclstatus_detail import main as cond_hclstatus_detail +from lib.intersight.compute_board import main as compute_board +from lib.intersight.compute_server_setting import main as compute_server_setting +from lib.intersight.equipment_chassis import main as equipment_chassis +from lib.intersight.equipment_fan_module import main as equipment_fan_module +from lib.intersight.equipment_fan import main as equipment_fan +from lib.intersight.equipment_led import main as equipment_led +from lib.intersight.equipment_psu import main as equipment_psu +from lib.intersight.equipment_tpm import main as equipment_tpm +from lib.intersight.graphics_card import main as graphics_card +from lib.intersight.graphics_controller import main as graphics_controller +from lib.intersight.management_interface import main as management_interface +from lib.intersight.memory_unit import main as memory_unit +from lib.intersight.pci_device import main as pci_device +from lib.intersight.pci_node import main as pci_node +from lib.intersight.processor_unit import main as processor_unit +from lib.intersight.running_firmware import main as running_firmware +from lib.intersight.search_item import main as search_item +from lib.intersight.server_profile import main as server_profile +from lib.intersight.storage_disk_group import main as storage_disk_group +from lib.intersight.storage_physical_disk import main as storage_physical_disk +from lib.intersight.storage_physical_disk_usage import main as storage_physical_disk_usage +from lib.intersight.storage_virtual_drive import main as storage_virtual_drive +from lib.intersight.storage_controller import main as storage_controller +from lib.intersight.tam_advisory_definition import main as tam_advisory_definition +from lib.intersight.tam_advisory_instance import main as tam_advisory_instance +from lib.intersight.tam_security_advisory import main as tam_security_advisory +from lib.intersight.workflow import main as workflow + +from lib.redfish import endpoint_settings as redfish_endpoint_settings +from lib.ucsm import endpoint_settings as ucsm_endpoint_settings + +from lib.intersight.compute_mo import ComputeMo +from lib.intersight.compute_info import ComputeInfo +from lib.intersight.compute_context import ComputeContext + + +class Compute(ComputeMo, ComputeInfo, ComputeContext): + def __init__(self, iaccount, log_id=None): + ComputeMo.__init__(self) + ComputeInfo.__init__(self) + ComputeContext.__init__(self) + + self.log_handler = log_helper.Log(log_id=log_id) + self.log_id = log_id + + self.rack_handler = compute_rack.ComputeRack(iaccount, log_id=log_id) + self.blade_handler = compute_blade.ComputeBlade(iaccount, log_id=log_id) + self.cache_handler = intersight_cache.IntersightCache( + iaccount, + log_id=log_id + ) + self.iaccount = iaccount + + self.cache_handler = intersight_cache.IntersightCache( + iaccount, + log_id=log_id + ) + + self.adapter_ext_eth_interface_handler = adapter_ext_eth_interface.AdapterExtEthInterface( + iaccount, + log_id=log_id + ) + self.adapter_host_eth_interface_handler = adapter_host_eth_interface.AdapterHostEthInterface( + iaccount, + log_id=log_id + ) + self.adapter_host_fc_interface_handler = adapter_host_fc_interface.AdapterHostFcInterface( + iaccount, + log_id=log_id + ) + self.adapter_unit_handler = adapter_unit.AdapterUnit( + iaccount, + log_id=log_id + ) + self.asset_device_contract_information_handler = asset_device_contract_information.AssetDeviceContractInformation( + iaccount, + log_id=log_id + ) + self.asset_device_registration_handler = asset_device_registration.AssetDeviceRegistration( + iaccount, + log_id=log_id + ) + self.bios_boot_mode_handler = bios_boot_mode.BiosBootMode( + iaccount, + log_id=log_id + ) + self.boot_cdd_device_handler = boot_cdd_device.BootCddDevice( + iaccount, + log_id=log_id + ) + self.boot_device_boot_mode_handler = boot_device_boot_mode.BootDeviceBootMode( + iaccount, + log_id=log_id + ) + self.boot_device_boot_security_handler = boot_device_boot_security.BootDeviceBootSecurity( + iaccount, + log_id=log_id + ) + self.boot_hdd_device_handler = boot_hdd_device.BootHddDevice( + iaccount, + log_id=log_id + ) + self.boot_iscsi_device_handler = boot_iscsi_device.BootIscsiDevice( + iaccount, + log_id=log_id + ) + self.boot_nvme_device_handler = boot_nvme_device.BootNvmeDevice( + iaccount, + log_id=log_id + ) + self.boot_pxe_device_handler = boot_pxe_device.BootPxeDevice( + iaccount, + log_id=log_id + ) + self.boot_san_device_handler = boot_san_device.BootSanDevice( + iaccount, + log_id=log_id + ) + self.boot_sd_device_handler = boot_sd_device.BootSdDevice( + iaccount, + log_id=log_id + ) + self.boot_uefi_device_handler = boot_uefi_device.BootUefiDevice( + iaccount, + log_id=log_id + ) + self.boot_usb_device_handler = boot_usb_device.BootUsbDevice( + iaccount, + log_id=log_id + ) + self.boot_vmedia_device_handler = boot_vmedia_device.BootVmediaDevice( + iaccount, + log_id=log_id + ) + self.cond_alarm_handler = cond_alarm.CondAlarm( + iaccount, + log_id=log_id + ) + self.cond_hclstatus_handler = cond_hclstatus.CondHclStatus( + iaccount, + log_id=log_id + ) + self.cond_hclstatus_detail_handler = cond_hclstatus_detail.CondHclStatusDetail( + iaccount, + log_id=log_id + ) + self.compute_board_handler = compute_board.ComputeBoard( + iaccount, + log_id=log_id + ) + self.compute_server_setting_handler = compute_server_setting.ComputeServerSetting( + iaccount, + log_id=log_id + ) + self.equipment_chassis_handler = equipment_chassis.EquipmentChassis( + iaccount, + log_id=log_id + ) + self.equipment_tpm_handler = equipment_tpm.EquipmentTpm( + iaccount, + log_id=log_id + ) + self.fan_module_handler = equipment_fan_module.EquipmentFanModule( + iaccount, + log_id=log_id + ) + self.fan_handler = equipment_fan.EquipmentFan( + iaccount, + log_id=log_id + ) + self.graphics_card_handler = graphics_card.GraphicsCard( + iaccount, + log_id=log_id + ) + self.graphics_controller_handler = graphics_controller.GraphicsController( + iaccount, + log_id=log_id + ) + self.locator_handler = equipment_led.EquipmentLed( + iaccount, + log_id=log_id + ) + self.management_interface_handler = management_interface.ManagementInterface( + iaccount, + log_id=log_id + ) + self.memory_unit_handler = memory_unit.MemoryUnit( + iaccount, + log_id=log_id + ) + self.processor_unit_handler = processor_unit.ProcessorUnit( + iaccount, + log_id=log_id + ) + self.psu_handler = equipment_psu.EquipmentPsu( + iaccount, + log_id=log_id + ) + self.pci_handler = pci_device.PciDevice( + iaccount, + log_id=log_id + ) + self.pci_node_handler = pci_node.PciNode( + iaccount, + log_id=log_id + ) + running_firmware_filter = '"Component eq \'system\' and Type eq \'blade-controller\'"' + self.running_firmware_handler = running_firmware.RunningFirmware( + iaccount, + get_filter=running_firmware_filter, + log_id=log_id + ) + self.search_item_handler = search_item.SearchItem( + iaccount, + log_id=log_id + ) + self.server_profile_handler = server_profile.ServerProfile( + iaccount, + log_id=log_id + ) + self.server_profile_handler.set_get_expand('ConfigChangeDetails') + self.storage_controller_handler = storage_controller.StorageController( + iaccount, + log_id=log_id + ) + self.storage_disk_group_handler = storage_disk_group.StorageDiskGroup( + iaccount, + log_id=log_id + ) + self.storage_physical_disk_handler = storage_physical_disk.StoragePhysicalDisk( + iaccount, + log_id=log_id + ) + self.storage_physical_disk_usage_handler = storage_physical_disk_usage.StoragePhysicalDiskUsage( + iaccount, + log_id=log_id + ) + self.storage_virtual_drive_handler = storage_virtual_drive.StorageVirtualDrive( + iaccount, + log_id=log_id + ) + self.tam_advisory_definition_handler = tam_advisory_definition.TamAdvisoryDefinition( + iaccount, + log_id=log_id + ) + self.tam_advisory_instance_handler = tam_advisory_instance.TamAdvisoryInstance( + iaccount, + log_id=log_id + ) + self.tam_security_advisory_handler = tam_security_advisory.TamSecurityAdvisory( + iaccount, + log_id=log_id + ) + self.workflow_handler = workflow.Workflow( + iaccount, + log_id=log_id + ) + self.redfish_endpoint_settings_handler = redfish_endpoint_settings.RedfishEndpointSettings( + log_id=log_id + ) + self.ucsm_endpoint_settings_handler = ucsm_endpoint_settings.UcsmEndpointSettings( + log_id=log_id + ) diff --git a/lib/intersight/compute_aci_output.py b/lib/intersight/compute_aci_output.py new file mode 100644 index 00000000..3016b8cd --- /dev/null +++ b/lib/intersight/compute_aci_output.py @@ -0,0 +1,328 @@ +class ComputeAciOutput(): + def __init__(self): + pass + + def print_aci(self, server, title=False): + self.print_aci_summary(server, title=title) + self.print_aci_endpoint(server, title=title) + self.print_aci_lacp(server, title=title) + self.print_aci_lldp(server, title=title) + + def print_aci_summary(self, server, title=False): + if title: + self.my_output.default( + 'Interface - ACI Summary [#%s]' % (len(server['MacAddressInfo'])), + underline=True, + before_newline=True + ) + + if len(server['MacAddressInfo']) == 0: + self.my_output.default('None') + return + + for item in server['MacAddressInfo']: + item['__Output'] = {} + in_aci = False + if item['endpoint'] is not None: + in_aci = True + item['epTick'] = '\u2713' + item['__Output']['epTick'] = 'Green' + else: + item['epTick'] = '\u2717' + item['__Output']['epTick'] = 'Red' + + if len(item['lacp']) > 0: + in_aci = True + item['lacpTick'] = '\u2713' + item['__Output']['lacpTick'] = 'Green' + else: + item['lacpTick'] = '\u2717' + item['__Output']['lacpTick'] = 'Red' + + if item['adjacency'] is not None: + in_aci = True + item['lldpTick'] = '\u2713' + item['__Output']['lldpTick'] = 'Green' + else: + item['lldpTick'] = '\u2717' + item['__Output']['lldpTick'] = 'Red' + + if in_aci: + item['aciTick'] = '\u2713' + item['__Output']['aciTick'] = 'Green' + else: + item['aciTick'] = '\u2717' + item['__Output']['aciTick'] = 'Red' + + server['MacAddressInfo'] = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'aciTick', + 'epTick', + 'lacpTick', + 'lldpTick', + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'ACI', + 'Endpoint', + 'LACP', + 'LLDP' + ] + + self.my_output.my_table( + server['MacAddressInfo'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_aci_endpoint(self, server, skip_empty=True, title=False): + macs = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + info = [] + + for mac in macs: + if mac['endpoint'] is None: + if skip_empty: + continue + mac['endpoint'] = {} + mac['endpoint']['ip'] = '--' + mac['endpoint']['epgNameApTenant'] = '--' + mac['endpoint']['encapT'] = '--' + mac['endpoint']['bdNameTenant'] = '--' + mac['endpoint']['vrfNameTenant'] = '--' + mac['fabric'] = [dict(ep='--')] + else: + mac['fabric'] = mac['endpoint']['fabric'] + + info.append(mac) + + if len(info) == 0: + return + + if title: + self.my_output.default( + 'Endpoint [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'endpoint.ip', + 'endpoint.epgNameApTenant', + 'endpoint.encapT', + 'endpoint.bdNameTenant', + 'endpoint.vrfNameTenant', + 'fabric.ep' + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'IP Address', + 'EPG', + 'Encap', + 'BD', + 'VRF', + 'Fabric' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fabric'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_aci_lacp(self, server, skip_empty=True, title=False): + macs = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + info = [] + + for mac in macs: + if mac['lacp'] is None or len(mac['lacp']) == 0: + if skip_empty: + continue + + empty_lacp = {} + empty_lacp['pod_node_name'] = '--' + empty_lacp['id'] = '--' + empty_lacp['key'] = '--' + empty_lacp['adjacency'] = {} + empty_lacp['adjacency']['sysId'] = '--' + empty_lacp['adjacency']['sysPrio'] = '--' + empty_lacp['adjacency']['key'] = '--' + empty_lacp['adjacency']['port'] = '--' + empty_lacp['adjacency']['portPrio'] = '--' + mac['lacp'].append( + empty_lacp + ) + + info.append( + mac + ) + + if len(info) == 0: + return + + if title: + self.my_output.default( + 'LACP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'lacp.pod_node_name', + 'lacp.id', + 'lacp.key', + 'lacp.adjacency.sysId', + 'lacp.adjacency.sysPrio', + 'lacp.adjacency.key', + 'lacp.adjacency.port', + 'lacp.adjacency.portPrio' + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'ACI Node', + 'Member', + 'Oper Key', + 'Nbr System MAC', + 'Nbr System Prio', + 'Nbr Oper Key', + 'Nbr Port', + 'Nbr Port Prio' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['lacp'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_aci_lldp(self, server, skip_empty=True, title=False): + macs = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + info = [] + + for mac in macs: + if mac['adjacency'] is None: + if skip_empty: + continue + + mac['adjacency'] = {} + mac['adjacency']['pod_node_name'] = '--' + mac['adjacency']['interface_id'] = '--' + mac['adjacency']['health'] = '--' + mac['adjacency']['faults'] = '--' + + info.append( + mac + ) + + if len(info) == 0: + return + + if title: + self.my_output.default( + 'LLDP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'adjacency.pod_node_name', + 'adjacency.interface_id', + 'adjacency.health', + 'adjacency.faults', + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'ACI Node', + 'Interface', + 'Nei Health', + 'Nei Faults' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) diff --git a/lib/intersight/compute_blade/__init__.py b/lib/intersight/compute_blade/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/compute_blade/class.md b/lib/intersight/compute_blade/class.md new file mode 100644 index 00000000..18e05324 --- /dev/null +++ b/lib/intersight/compute_blade/class.md @@ -0,0 +1,184 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Adapters": [], + "AdminPowerState": "policy", + "AlarmSummary": { + "ClassId": "compute.AlarmSummary", + "Critical": 0, + "ObjectType": "compute.AlarmSummary", + "Warning": 0 + }, + "Alerts": [], + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "619d05ae76752d313994a00a", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/619d05ae76752d313994a00a" + } + ], + "AssetTag": "", + "AvailableMemory": 393216, + "BiosBootmode": null, + "BiosPostComplete": false, + "BiosTokenSettings": null, + "BiosUnits": [], + "BiosVfSelectMemoryRasConfiguration": null, + "Bmc": { + "ClassId": "mo.MoRef", + "Moid": "63347c2776752d3139813840", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/63347c2776752d3139813840" + }, + "Board": null, + "BootCddDevices": [], + "BootDeviceBootSecurity": null, + "BootDeviceBootmode": null, + "BootHddDevices": [], + "BootIscsiDevices": [], + "BootNvmeDevices": [], + "BootPchStorageDevices": [], + "BootPxeDevices": [], + "BootSanDevices": [], + "BootSdDevices": [], + "BootUefiShellDevices": [], + "BootUsbDevices": [], + "BootVmediaDevices": [], + "ChassisId": "2", + "ClassId": "compute.Blade", + "CreateTime": "2022-09-28T16:52:10.992Z", + "DeviceMoId": "618942976f72612d309dfbe1", + "Dn": "sys/chassis-2/blade-1", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "619d05ae76752d313994a00a", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/619d05ae76752d313994a00a" + }, + "EquipmentIoExpanders": [], + "FaultSummary": 0, + "GenericInventoryHolders": [ + { + "ClassId": "mo.MoRef", + "Moid": "6334904f76752d313984d14b", + "ObjectType": "inventory.GenericInventoryHolder", + "link": "https://www.intersight.com/api/v1/inventory/GenericInventoryHolders/6334904f76752d313984d14b" + } + ], + "GraphicsCards": [], + "HardwareUuid": "", + "InventoryDeviceInfo": null, + "KvmIpAddresses": [ + { + "Address": "", + "Category": "Equipment", + "ClassId": "compute.IpAddress", + "DefaultGateway": "", + "Dn": "sys/chassis-2/blade-1/mgmt/ipv4-static-addr", + "HttpPort": 80, + "HttpsPort": 443, + "KvmPort": 2068, + "KvmVlan": 0, + "Name": "Outband", + "ObjectType": "compute.IpAddress", + "Subnet": "", + "Type": "VnicIpV4StaticAddr" + } + ], + "KvmServerStateEnabled": false, + "KvmVendor": "", + "LocatorLed": null, + "ManagementMode": "UCSM", + "MemoryArrays": [], + "MemorySpeed": "2666", + "MgmtIdentity": null, + "MgmtIpAddress": "", + "ModTime": "2022-09-28T18:19:59.019Z", + "Model": "UCSB-B200-M5", + "Moid": "63347bba76752d313981268f", + "Name": "FI-ucsb1-eu-spdc-2-1", + "NumAdaptors": 2, + "NumCpuCores": 40, + "NumCpuCoresEnabled": 40, + "NumCpus": 2, + "NumEthHostInterfaces": 8, + "NumFcHostInterfaces": 0, + "NumThreads": 80, + "ObjectType": "compute.Blade", + "OperPowerState": "on", + "OperReason": [], + "OperState": "ok", + "Operability": "operable", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "618942976f72612d309dfbe1" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "619d05ae76752d313994a00a", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/619d05ae76752d313994a00a" + }, + "PciDevices": [], + "PciNodes": [], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PlatformType": "UCSFI", + "Presence": "equipped", + "PreviousFru": null, + "Processors": [], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "618942976f72612d309dfbe1", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/618942976f72612d309dfbe1" + }, + "Revision": "0", + "Rn": "", + "ScaledMode": "none", + "Serial": "FLM241501FB", + "ServiceProfile": "org-root/org-EU-SPN/ls-esx51-eu-spdc", + "SharedScope": "", + "SlotId": 1, + "StorageControllers": [], + "StorageEnclosures": [], + "Tags": [ + { + "Key": "Intersight.LicenseTier", + "Value": "Premier" + } + ], + "TopSystem": { + "ClassId": "mo.MoRef", + "Moid": "618942be76752d3139ace73b", + "ObjectType": "top.System", + "link": "https://www.intersight.com/api/v1/top/Systems/618942be76752d3139ace73b" + }, + "TotalMemory": 393216, + "TunneledKvm": false, + "UserLabel": "", + "Uuid": "315220a5-2121-4e5b-0101-e1dc0000010f", + "Vendor": "Cisco Systems Inc", + "Vmedia": null + } +``` \ No newline at end of file diff --git a/lib/intersight/compute_blade/info.py b/lib/intersight/compute_blade/info.py new file mode 100644 index 00000000..f267526b --- /dev/null +++ b/lib/intersight/compute_blade/info.py @@ -0,0 +1,77 @@ +class ComputeBladeInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'Dn', + 'HardwareUuid', + 'Model', + 'Moid', + 'Name', + 'NumAdaptors', + 'NumCpuCores', + 'NumCpuCoresEnabled', + 'NumCpus', + 'NumEthHostInterfaces', + 'NumFcHostInterfaces', + 'NumThreads', + 'OperPowerState', + 'Pid', + 'Presence', + 'Serial', + 'ServiceProfile', + 'SlotId', + 'TotalMemory', + 'Vendor' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['Pid'] is None or len(info['Pid']) == 0: + info['Pid'] = info['Model'] + + info['ServerName'] = 'Server #%s' % ( + managed_object['SlotId'] + ) + + info['AlarmCritical'] = managed_object['AlarmSummary']['Critical'] + info['AlarmWarning'] = managed_object['AlarmSummary']['Warning'] + if managed_object['AlarmSummary']['Warning'] == 0 and managed_object['AlarmSummary']['Critical'] == 0: + info['Health'] = 'Healthy' + info['HealthSummary'] = 'Healthy' + info['__Output']['Health'] = 'Green' + info['__Output']['HealthSummary'] = 'Green' + if managed_object['AlarmSummary']['Warning'] > 0 and managed_object['AlarmSummary']['Critical'] == 0: + info['Health'] = 'Warnings' + info['HealthSummary'] = 'Warnings (%s)' % (managed_object['AlarmSummary']['Warning']) + info['__Output']['Health'] = 'Yellow' + info['__Output']['HealthSummary'] = 'Yellow' + if managed_object['AlarmSummary']['Critical'] > 0: + info['Health'] = 'Critical' + info['HealthSummary'] = 'Critical (%s)' % (managed_object['AlarmSummary']['Critical']) + info['__Output']['Health'] = 'Red' + info['__Output']['HealthSummary'] = 'Red' + + info['PowerOn'] = False + if managed_object['OperPowerState'] == 'on': + info['PowerOn'] = True + info['__Output']['OperPowerState'] = 'Green' + else: + info['__Output']['OperPowerState'] = 'Red' + + info['CpuSummary'] = '%sS %sC %sT' % ( + info['NumCpus'], + info['NumCpuCores'], + info['NumThreads'] + ) + info['TotalMemoryUnit'] = self.info_helper.convert_memory( + info['TotalMemory'] * 1024 * 1024 + ) + + return info diff --git a/lib/intersight/compute_blade/main.py b/lib/intersight/compute_blade/main.py new file mode 100644 index 00000000..b8d4ae05 --- /dev/null +++ b/lib/intersight/compute_blade/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.compute_blade.info import ComputeBladeInfo + + +class ComputeBlade(IntersightCommon, ComputeBladeInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'compute blade' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + ComputeBladeInfo.__init__(self) diff --git a/lib/intersight/compute_board/__init__.py b/lib/intersight/compute_board/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/compute_board/class.md b/lib/intersight/compute_board/class.md new file mode 100644 index 00000000..48b46940 --- /dev/null +++ b/lib/intersight/compute_board/class.md @@ -0,0 +1,137 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "BoardId": 0, + "ClassId": "compute.Board", + "ComputeBlade": null, + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + }, + "CpuTypeController": "other", + "CreateTime": "2022-09-02T07:09:58.414Z", + "DeviceMoId": "61c35fa36f72612d3005590c", + "DisplayNames": { + "hierarchical": [ + "board" + ], + "short": [ + "Board" + ] + }, + "Dn": "sys/rack-unit-3/board", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentTpms": [], + "GraphicsCards": [], + "InventoryDeviceInfo": null, + "MemoryArrays": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c4d", + "ObjectType": "memory.Array", + "link": "https://www.intersight.com/api/v1/memory/Arrays/6311ac8376752d31398e5c4d" + } + ], + "ModTime": "2022-09-02T07:26:18.425Z", + "Model": "UCSC-C220-M4S", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "OperPowerState": "ok", + "OperReason": [], + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + }, + "PciCoprocessorCards": [], + "PciSwitch": [], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PersistentMemoryConfiguration": null, + "Presence": "not-supported", + "PreviousFru": null, + "Processors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c49", + "ObjectType": "processor.Unit", + "link": "https://www.intersight.com/api/v1/processor/Units/6311ac8376752d31398e5c49" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c4b", + "ObjectType": "processor.Unit", + "link": "https://www.intersight.com/api/v1/processor/Units/6311ac8376752d31398e5c4b" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "SecurityUnits": [], + "Serial": "FCH2031V0YM", + "SharedScope": "", + "StorageControllers": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c1", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c1" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + } + ], + "StorageFlexFlashControllers": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c43", + "ObjectType": "storage.FlexFlashController", + "link": "https://www.intersight.com/api/v1/storage/FlexFlashControllers/6311ac8376752d31398e5c43" + } + ], + "StorageFlexUtilControllers": [], + "Tags": [], + "Vendor": "Cisco Systems Inc" + } +``` \ No newline at end of file diff --git a/lib/intersight/compute_board/info.py b/lib/intersight/compute_board/info.py new file mode 100644 index 00000000..750b7f0e --- /dev/null +++ b/lib/intersight/compute_board/info.py @@ -0,0 +1,40 @@ +class ComputeBoardInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + info['BoardId'] = managed_object['BoardId'] + info['CpuTypeController'] = managed_object['CpuTypeController'] + info['Dn'] = managed_object['Dn'] + info['Model'] = managed_object['Model'] + info['Moid'] = managed_object['Moid'] + info['OperPowerState'] = managed_object['OperPowerState'] + info['Serial'] = managed_object['Serial'] + info['Vendor'] = managed_object['Vendor'] + + keys = [ + 'EquipmentTpms', + 'GraphicsCards', + 'MemoryArrays', + 'PciCoprocessorCards', + 'PciSwitch', + 'Processors', + 'SecurityUnits', + 'StorageControllers', + 'StorageFlexFlashControllers', + 'StorageFlexUtilControllers' + ] + for key in keys: + name_ids = '%sIds' % (key) + info[name_ids] = [] + for item in managed_object[key]: + info[name_ids].append( + item['Moid'] + ) + + name_count = '%sCount' % (key) + info[name_count] = len(info[name_ids]) + + return info diff --git a/lib/intersight/compute_board/main.py b/lib/intersight/compute_board/main.py new file mode 100644 index 00000000..fe19aabc --- /dev/null +++ b/lib/intersight/compute_board/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.compute_board.info import ComputeBoardInfo + + +class ComputeBoard(IntersightCommon, ComputeBoardInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'compute board' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + ComputeBoardInfo.__init__(self) diff --git a/lib/intersight/compute_cache.py b/lib/intersight/compute_cache.py new file mode 100644 index 00000000..c09e660b --- /dev/null +++ b/lib/intersight/compute_cache.py @@ -0,0 +1,4486 @@ +import time + +from lib.imc.cli import endpoint as imc_endpoint +from lib.redfish import endpoint as redfish_endpoint + + +class ComputeCache(): + def __init__(self): + self.memory_array_moids = {} + + def get_redfish_endpoint_template(self, endpoint_id, template_name): + endpoint_settings = self.redfish_endpoint_settings_handler.get_redfish_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return None + + redfish_handler = redfish_endpoint.RedfishEndpoint( + endpoint_settings['endpoint']['type'], + endpoint_settings['endpoint']['ip'], + endpoint_settings['endpoint']['port'], + endpoint_settings['endpoint']['username'], + endpoint_settings['endpoint']['password'], + log_id=self.log_id + ) + + if not redfish_handler.is_connected(): + return None + + if endpoint_settings['endpoint']['type'] == 'fi': + redfish_handler.endpoint_handler.set_inventory( + endpoint_settings['endpoint']['inventory_type'], + endpoint_settings['endpoint']['inventory_id'] + ) + + return redfish_handler.endpoint_handler.get_template_properties(template_name) + + def get_imc_endpoint_template(self, endpoint_id, template_name): + endpoint_settings = self.redfish_endpoint_settings_handler.get_redfish_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return None + + imc_handler = imc_endpoint.ImcCliEndpoint( + endpoint_settings['endpoint']['ip'], + 22, + endpoint_settings['endpoint']['username'], + endpoint_settings['endpoint']['password'], + log_id=self.log_id + ) + + if template_name == 'psu': + return imc_handler.get_psu() + + return None + + def set_redfish_cache(self, key, server_moids, server_serial, cache_ttl=None): + if key == 'psu-imc': + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('psu-imc', subdirectory=server_moid, cache_ttl=cache_ttl): + psu_info = self.get_imc_endpoint_template( + server_serial[server_moid], + 'psu' + ) + + if psu_info is not None: + self.cache_handler.set_intersight_cache_entry( + 'psu-imc', + psu_info, + subdirectory=server_moid + ) + + if key == 'power': + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('power', subdirectory=server_moid, cache_ttl=cache_ttl): + power_info = self.get_redfish_endpoint_template( + server_serial[server_moid], + 'power' + ) + + if power_info is not None: + self.cache_handler.set_intersight_cache_entry( + 'power', + power_info, + subdirectory=server_moid + ) + + if key == 'power-ucsm': + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('power', subdirectory=server_moid, cache_ttl=cache_ttl): + power_info = power_info = self.ucsm_endpoint_settings_handler.get_ucsm_endpoint_template( + server_serial[server_moid], + 'power' + ) + + if power_info is not None: + self.cache_handler.set_intersight_cache_entry( + 'power', + power_info, + subdirectory=server_moid + ) + + if key == 'thermal': + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('thermal', subdirectory=server_moid, cache_ttl=cache_ttl): + power_info = self.get_redfish_endpoint_template( + server_serial[server_moid], + 'thermal' + ) + + if power_info is not None: + self.cache_handler.set_intersight_cache_entry( + 'thermal', + power_info, + subdirectory=server_moid + ) + + if key == 'thermal-ucsm': + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('thermal', subdirectory=server_moid, cache_ttl=cache_ttl): + power_info = power_info = self.ucsm_endpoint_settings_handler.get_ucsm_endpoint_template( + server_serial[server_moid], + 'thermal' + ) + + if power_info is not None: + self.cache_handler.set_intersight_cache_entry( + 'thermal', + power_info, + subdirectory=server_moid + ) + + def set_intersight_cache( + self, + key, + expand, + server_moids, + rack_moids, + blade_moids, + registration_moids, + board_moids, + adapter_moids, + boot_moids, + device_moids, + gcard_moids, + serial, + workflow_seconds, + filter_length_threshold=20, + cache_ttl=None + ): + if key == 'adapter': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in adapter_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('adapter', subdirectory=server_moid, cache_ttl=cache_ttl): + for adapter_moid in adapter_moids[server_moid]: + target_moids.append( + adapter_moid + ) + if server_moid not in target_server_moids: + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if 'adapter' in expand and len(expand['adapter']) > 0: + self.adapter_unit_handler.set_get_expand( + ','.join(expand['adapter']) + ) + + server_managed_objects = {} + for target_moid in target_server_moids: + server_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.adapter_unit_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.adapter_unit_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'adapter failed' + ) + return + + self.log_handler.set_log( + 'intersight.adapter_unit', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + for managed_object in managed_objects: + if managed_object['Moid'] in adapter_moids[server_moid]: + server_managed_objects[server_moid].append( + managed_object + ) + + for target_moid in target_server_moids: + self.cache_handler.set_intersight_cache_entry( + 'adapter', + server_managed_objects[target_moid], + subdirectory=target_moid + ) + + if 'adapter' in expand: + for expanded_item in expand['adapter']: + if expanded_item not in ['ExtEthIfs', 'HostEthIfs', 'HostFcIfs']: + self.log_handler.error( + 'compute.set_intersight_cache', + 'unsupported adapter expand: %s' % (expanded_item) + ) + continue + + if expanded_item == 'ExtEthIfs': + server_expanded_managed_objects = [] + for server_managed_object in server_managed_objects[target_moid]: + for server_expanded_managed_object in server_managed_object['ExtEthIfs']: + server_expanded_managed_objects.append( + server_expanded_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'adapter_ext_eth_interface', + server_expanded_managed_objects, + subdirectory=target_moid + ) + + if expanded_item == 'HostEthIfs': + server_expanded_managed_objects = [] + for server_managed_object in server_managed_objects[target_moid]: + for server_expanded_managed_object in server_managed_object['HostEthIfs']: + server_expanded_managed_objects.append( + server_expanded_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'adapter_host_eth_interface', + server_expanded_managed_objects, + subdirectory=target_moid + ) + + if expanded_item == 'HostFcIfs': + server_expanded_managed_objects = [] + for server_managed_object in server_managed_objects[target_moid]: + for server_expanded_managed_object in server_managed_object['HostFcIfs']: + server_expanded_managed_objects.append( + server_expanded_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'adapter_host_fc_interface', + server_expanded_managed_objects, + subdirectory=target_moid + ) + + return + + if key == 'adapter_ext_eth_interface': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in adapter_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('adapter_ext_eth_interface', subdirectory=server_moid, cache_ttl=cache_ttl): + for adapter_moid in adapter_moids[server_moid]: + target_moids.append( + adapter_moid + ) + if server_moid not in target_server_moids: + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter ext eth interface cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.adapter_ext_eth_interface_handler.set_get_filter( + "AdapterUnit/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter ext eth interface miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter ext eth interface miss wout filter' + ) + + managed_objects = self.adapter_ext_eth_interface_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'adapter ext eth interface failed' + ) + return + + self.log_handler.set_log( + 'intersight.adapter_ext_eth_interface', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'AdapterUnit' in managed_object and managed_object['AdapterUnit'] is not None: + if managed_object['AdapterUnit']['Moid'] in adapter_moids[server_moid]: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'adapter_ext_eth_interface', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'adapter_host_eth_interface': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in adapter_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('adapter_host_eth_interface', subdirectory=server_moid, cache_ttl=cache_ttl): + for adapter_moid in adapter_moids[server_moid]: + target_moids.append( + adapter_moid + ) + if server_moid not in target_server_moids: + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter host eth interface cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.adapter_host_eth_interface_handler.set_get_filter( + "AdapterUnit/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter host eth interface miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter host eth interface miss wout filter' + ) + + managed_objects = self.adapter_host_eth_interface_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'adapter host eth interface failed' + ) + return + + self.log_handler.set_log( + 'intersight.adapter_host_eth_interface', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'AdapterUnit' in managed_object and managed_object['AdapterUnit'] is not None: + if managed_object['AdapterUnit']['Moid'] in adapter_moids[server_moid]: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'adapter_host_eth_interface', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'adapter_host_fc_interface': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in adapter_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('adapter_host_fc_interface', subdirectory=server_moid, cache_ttl=cache_ttl): + for adapter_moid in adapter_moids[server_moid]: + target_moids.append( + adapter_moid + ) + if server_moid not in target_server_moids: + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter fc eth interface cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.adapter_host_fc_interface_handler.set_get_filter( + "AdapterUnit/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter fc eth interface miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'adapter fc eth interface miss wout filter' + ) + + managed_objects = self.adapter_host_fc_interface_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'adapter fc eth interface failed' + ) + return + + self.log_handler.set_log( + 'intersight.adapter_host_fc_interface', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'AdapterUnit' in managed_object and managed_object['AdapterUnit'] is not None: + if managed_object['AdapterUnit']['Moid'] in adapter_moids[server_moid]: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'adapter_host_fc_interface', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'advisories': + if cache_ttl is None or not self.cache_handler.is_intersight_cache('advisory_security', cache_ttl=cache_ttl): + managed_objects = self.tam_security_advisory_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'security advisory failed' + ) + return + + self.cache_handler.set_intersight_cache_entry( + 'advisory_security', + managed_objects + ) + + if cache_ttl is None or not self.cache_handler.is_intersight_cache('advisory_definition', cache_ttl=cache_ttl): + managed_objects = self.tam_advisory_definition_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'advisory definition failed' + ) + return + + self.log_handler.set_log( + 'intersight.advisory_definition', + managed_objects, + json_conversion=True + ) + + self.cache_handler.set_intersight_cache_entry( + 'advisory_definition', + managed_objects + ) + + return + + if key == 'advisory': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('advisory', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'advirosy cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.tam_advisory_instance_handler.set_get_filter( + "AffectedObject/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'advisory cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'advisory cache miss wout filter' + ) + + managed_objects = self.tam_advisory_instance_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'advisory failed' + ) + return + + self.log_handler.set_log( + 'intersight.advisory', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'AffectedObject' in managed_object and managed_object['AffectedObject'] is not None: + if server_moid == managed_object['AffectedObject']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'advisory', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'alarm': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in registration_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('alarm', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + registration_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'alarm cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.cond_alarm_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'alarm cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'alarm cache miss wout filter' + ) + + managed_objects = self.cond_alarm_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'alarm failed' + ) + return + + self.log_handler.set_log( + 'intersight.cond_alarm', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'RegisteredDevice' in managed_object and managed_object['RegisteredDevice'] is not None: + if registration_moids[server_moid] == managed_object['RegisteredDevice']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'alarm', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'board': + cache_hits = [] + target_moids = [] + target_rack_moids = [] + target_blade_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('board', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + if server_moid in blade_moids: + target_blade_moids.append( + server_moid + ) + if server_moid in rack_moids: + target_rack_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + server_boards_mo = self.cache_handler.get_intersight_cache_entry( + 'board', + subdirectory=server_moid, + cache_ttl=cache_ttl + ) + if server_boards_mo is None: + self.log_handler.error( + 'set_intersight_cache', + 'board cache read failed: %s' % (server_moid) + ) + else: + self.memory_array_moids[server_moid] = [] + for server_board_mo in server_boards_mo: + for memory_array_mo in server_board_mo['MemoryArrays']: + self.memory_array_moids[server_moid].append( + memory_array_mo['Moid'] + ) + + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'board cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if 'board' in expand and len(expand['board']) > 0: + self.compute_board_handler.set_get_expand( + ','.join(expand['board']) + ) + + server_managed_objects = {} + for target_moid in target_moids: + server_managed_objects[target_moid] = [] + self.memory_array_moids[target_moid] = [] + + if len(target_rack_moids) > 0: + chunk_id = 0 + while True: + if chunk_id >= len(target_rack_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_rack_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.compute_board_handler.set_get_filter( + "ComputeRackUnit/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'board cache miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.compute_board_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'board failed' + ) + return + + self.log_handler.set_log( + 'intersight.compute_board', + managed_objects, + json_conversion=True + ) + + for server_moid in target_rack_moids: + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + if server_moid == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + + for memory_array_mo in managed_object['MemoryArrays']: + self.memory_array_moids[server_moid].append( + memory_array_mo['Moid'] + ) + + for server_moid in target_rack_moids: + self.cache_handler.set_intersight_cache_entry( + 'board', + server_managed_objects[server_moid], + subdirectory=server_moid + ) + + if 'board' in expand: + for expanded_item in expand['board']: + if expanded_item not in ['Processors']: + self.log_handler.error( + 'compute.set_intersight_cache', + 'unsupported board expand: %s' % (expanded_item) + ) + continue + + if expanded_item == 'Processors': + server_cpu_managed_objects = [] + for server_managed_object in server_managed_objects[server_moid]: + for server_cpu_managed_object in server_managed_object['Processors']: + server_cpu_managed_objects.append( + server_cpu_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'cpu', + server_cpu_managed_objects, + subdirectory=server_moid + ) + + if len(target_blade_moids) > 0: + chunk_id = 0 + while True: + if chunk_id >= len(target_blade_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_blade_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.compute_board_handler.set_get_filter( + "ComputeBlade/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'board cache miss w/filter: %s' % (target_blade_moids) + ) + + managed_objects = self.compute_board_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'board failed' + ) + return + + for server_moid in target_blade_moids: + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + if server_moid == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + + for memory_array_mo in managed_object['MemoryArrays']: + self.memory_array_moids[server_moid].append( + memory_array_mo['Moid'] + ) + + for server_moid in target_blade_moids: + self.cache_handler.set_intersight_cache_entry( + 'board', + server_managed_objects[server_moid], + subdirectory=server_moid + ) + + if 'board' in expand: + for expanded_item in expand['board']: + if expanded_item not in ['Processors']: + self.log_handler.error( + 'compute.set_intersight_cache', + 'unsupported board expand: %s' % (expanded_item) + ) + continue + + if expanded_item == 'Processors': + server_cpu_managed_objects = [] + for server_managed_object in server_managed_objects[server_moid]: + for server_cpu_managed_object in server_managed_object['Processors']: + server_cpu_managed_objects.append( + server_cpu_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'cpu', + server_cpu_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_bios': + cache_hits = [] + target_moids = [] + target_rack_moids = [] + target_blade_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_bios', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + if server_moid in blade_moids: + target_blade_moids.append( + server_moid + ) + if server_moid in rack_moids: + target_rack_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot bios cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_rack_moids) > 0: + if len(target_rack_moids) < filter_length_threshold: + moids_list = [] + for moid in target_rack_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.bios_boot_mode_handler.set_get_filter( + "ComputeRackUnit/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot bios cache miss w/filter: %s' % (target_rack_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache miss wout filter' + ) + + managed_objects = self.bios_boot_mode_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot bios failed' + ) + return + + self.log_handler.set_log( + 'intersight.bios_boot_mode', + managed_objects, + json_conversion=True + ) + + for server_moid in target_rack_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputeRackUnit' in managed_object and managed_object['ComputeRackUnit'] is not None: + if server_moid == managed_object['ComputeRackUnit']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_bios', + server_managed_objects, + subdirectory=server_moid + ) + + if len(target_blade_moids) > 0: + if len(target_blade_moids) < filter_length_threshold: + moids_list = [] + for moid in target_blade_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.bios_boot_mode_handler.set_get_filter( + "ComputeBlade/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot bios cache miss w/filter: %s' % (target_blade_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache miss wout filter' + ) + + managed_objects = self.bios_boot_mode_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot bios failed' + ) + return + + self.log_handler.set_log( + 'intersight.bios_boot_mode', + managed_objects, + json_conversion=True + ) + + for server_moid in target_blade_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputeBlade' in managed_object and managed_object['ComputeBlade'] is not None: + if server_moid == managed_object['ComputeBlade']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_bios', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_mode': + cache_hits = [] + target_moids = [] + target_rack_moids = [] + target_blade_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_mode', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + if server_moid in blade_moids: + target_blade_moids.append( + server_moid + ) + if server_moid in rack_moids: + target_rack_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_rack_moids) > 0: + if len(target_rack_moids) < filter_length_threshold: + moids_list = [] + for moid in target_rack_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_device_boot_mode_handler.set_get_filter( + "ComputeRackUnit/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache miss w/filter: %s' % (target_rack_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache miss wout filter' + ) + + managed_objects = self.boot_device_boot_mode_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot mode failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_device_boot_mode', + managed_objects, + json_conversion=True + ) + for server_moid in target_rack_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputeRackUnit' in managed_object and managed_object['ComputeRackUnit'] is not None: + if server_moid == managed_object['ComputeRackUnit']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_mode', + server_managed_objects, + subdirectory=server_moid + ) + + if len(target_blade_moids) > 0: + if len(target_blade_moids) < filter_length_threshold: + moids_list = [] + for moid in target_blade_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_device_boot_mode_handler.set_get_filter( + "ComputeBlade/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache miss w/filter: %s' % (target_blade_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot mode cache miss wout filter' + ) + + managed_objects = self.boot_device_boot_mode_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot mode failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_device_boot_mode', + managed_objects, + json_conversion=True + ) + + for server_moid in target_blade_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputeBlade' in managed_object and managed_object['ComputeBlade'] is not None: + if server_moid == managed_object['ComputeBlade']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_mode', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_security': + cache_hits = [] + target_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_security', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot security cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_device_boot_security_handler.set_get_filter( + "ComputePhysical/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot security cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot security cache miss wout filter' + ) + + managed_objects = self.boot_device_boot_security_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot security failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_device_boot_security', + managed_objects, + json_conversion=True + ) + + for server_moid in target_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_security', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_cdd': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_cdd', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['cdd']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_cdd', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['cdd']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot cdd cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_cdd_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot cdd cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot cdd cache miss wout filter' + ) + + managed_objects = self.boot_cdd_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot cdd failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_cdd_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_cdd', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_hdd': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_hdd', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['hdd']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_hdd', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['hdd']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot hdd cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_hdd_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot hdd cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot hdd cache miss wout filter' + ) + + managed_objects = self.boot_hdd_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot hdd failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_hdd_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_hdd', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_iscsi': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_iscsi', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['iscsi']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_iscsi', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['iscsi']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot iscsi cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_iscsi_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot iscsi cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot iscsi cache miss wout filter' + ) + + managed_objects = self.boot_iscsi_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot iscsi failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_iscsi_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_iscsi', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_nvme': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_nvme', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['nvme']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_nvme', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['nvme']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot nvme cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_nvme_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot nvme cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot nvme cache miss wout filter' + ) + + managed_objects = self.boot_nvme_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot nvme failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_nvme_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_nvme', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_pxe': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_pxe', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['pxe']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_pxe', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['pxe']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot pxe cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_pxe_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot pxe cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot pxe cache miss wout filter' + ) + + managed_objects = self.boot_pxe_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot pxe failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_pxe_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_pxe', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_san': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_san', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['san']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_san', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['san']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot san cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_san_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot san cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot san cache miss wout filter' + ) + + managed_objects = self.boot_san_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot san failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_san_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_san', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_sd': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_sd', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['sd']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_sd', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['sd']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot sd cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_sd_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot sd cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot sd cache miss wout filter' + ) + + managed_objects = self.boot_sd_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot sd failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_sd_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_sd', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_uefi': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_uefi', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['uefi']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_uefi', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['uefi']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot uefi cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_uefi_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot uefi cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot uefi cache miss wout filter' + ) + + managed_objects = self.boot_uefi_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot uefi failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_uefi_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_uefi', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_usb': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_usb', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['usb']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_usb', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['usb']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot usb cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_usb_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot usb cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot usb cache miss wout filter' + ) + + managed_objects = self.boot_usb_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot usb failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_usb_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_usb', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'boot_vmedia': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in boot_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('boot_vmedia', subdirectory=server_moid, cache_ttl=cache_ttl): + if len(boot_moids[server_moid]['vmedia']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'boot_vmedia', + [], + subdirectory=server_moid + ) + cache_hits.append( + server_moid + ) + continue + + target_server_moids.append( + server_moid + ) + for boot_id in boot_moids[server_moid]['vmedia']: + target_moids.append( + boot_id + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot vmedia cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.boot_vmedia_device_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot vmedia cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'boot vmedia cache miss wout filter' + ) + + managed_objects = self.boot_vmedia_device_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'boot vmedia failed' + ) + return + + self.log_handler.set_log( + 'intersight.boot_vmedia_device', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputePhysical' in managed_object and managed_object['ComputePhysical'] is not None: + if server_moid == managed_object['ComputePhysical']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'boot_vmedia', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'cimc': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in rack_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('cimc', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + device_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'cimc cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + server_managed_objects = {} + for target_moid in target_server_moids: + server_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.management_interface_handler.set_get_filter( + "DeviceMoId in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'cimc miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.management_interface_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'cimc failed' + ) + return + + self.log_handler.set_log( + 'intersight.management_interface', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + for managed_object in managed_objects: + if managed_object['DeviceMoId'] == device_moids[server_moid]: + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['ObjectType'] == 'compute.RackUnit': + if ancestor_mo['Moid'] == server_moid: + server_managed_objects[server_moid].append( + managed_object + ) + + for target_moid in target_server_moids: + self.cache_handler.set_intersight_cache_entry( + 'cimc', + server_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'connector': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in registration_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('connector', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + registration_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'connector cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.asset_device_registration_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'connector cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'connector cache miss wout filter' + ) + + managed_objects = self.asset_device_registration_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'connector failed' + ) + return + + self.log_handler.set_log( + 'intersight.asset_device_registration', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if registration_moids[server_moid] == managed_object['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'connector', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'contract': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in serial: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('contract', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + serial[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'contract cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.asset_device_contract_information_handler.set_get_filter( + "DeviceId in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'contract cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'contract cache miss wout filter' + ) + + managed_objects = self.asset_device_contract_information_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'contract failed' + ) + return + + self.log_handler.set_log( + 'intersight.asset_device_contract_information', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if serial[server_moid] == managed_object['DeviceId']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'contract', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'cpu': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in board_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('cpu', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + board_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'cpu cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.processor_unit_handler.set_get_filter( + "ComputeBoard/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'cpu cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'cpu cache miss wout filter' + ) + + managed_objects = self.processor_unit_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'cpu failed' + ) + return + + self.log_handler.set_log( + 'intersight.processor_unit', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'ComputeBoard' in managed_object and managed_object['ComputeBoard'] is not None: + if board_moids[server_moid] == managed_object['ComputeBoard']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'cpu', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'disk_group': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('disk_group', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'disk group cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + server_storage_controller_map = {} + storage_controller_moids = [] + for server_moid in target_moids: + storage_controller_mos = self.cache_handler.get_intersight_cache_entry( + 'storage_controller', + subdirectory=server_moid + ) + if storage_controller_mos is None: + continue + + for storage_controller_mo in storage_controller_mos: + server_storage_controller_map[storage_controller_mo['Moid']] = server_moid + storage_controller_moids.append( + storage_controller_mo['Moid'] + ) + + if len(storage_controller_moids) > 0: + if len(storage_controller_moids) < filter_length_threshold: + storage_controller_moids_list = [] + for storage_controller_moid in storage_controller_moids: + storage_controller_moids_list.append('\'%s\'' % (storage_controller_moid)) + storage_controller_moids_filter = ', '.join(storage_controller_moids_list) + self.storage_disk_group_handler.set_get_filter( + "StorageController/Moid in (%s)" % (storage_controller_moids_filter) + ) + + self.storage_disk_group_handler.set_get_expand( + 'Spans' + ) + managed_objects = self.storage_disk_group_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute_extra_attributes.set_cache', + 'storage disk group failed' + ) + return + + self.log_handler.set_log( + 'intersight.storage_disk_group', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'StorageController' in managed_object and managed_object['StorageController'] is not None: + if managed_object['StorageController']['Moid'] in server_storage_controller_map: + if server_storage_controller_map[managed_object['StorageController']['Moid']] == server_moid: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'disk_group', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'fanmodule': + # Server rack only + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in rack_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('fanmodule', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'fan module cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + server_managed_objects = {} + for target_moid in target_moids: + server_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.fan_module_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'fan module cache miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.fan_module_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'Fanmodule failed' + ) + return + + self.log_handler.set_log( + 'intersight.fan_module', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + if server_moid == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + + for target_moid in target_moids: + self.cache_handler.set_intersight_cache_entry( + 'fanmodule', + server_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'fan': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in rack_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('fan', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'fan cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + detail_moids = [] + server_detail_moids = {} + + for server_moid in target_server_moids: + server_detail_moids[server_moid] = [] + fan_module_mos = self.cache_handler.get_intersight_cache_entry( + 'fanmodule', + subdirectory=server_moid + ) + if fan_module_mos is None: + self.log_handler.error( + 'compute_info.set_intersight_cache', + 'fan module cache miss: %s' % (server_moid) + ) + return + + for fan_module_mo in fan_module_mos: + server_detail_moids[server_moid].append( + fan_module_mo['Moid'] + ) + if fan_module_mo['Moid'] not in detail_moids: + detail_moids.append( + fan_module_mo['Moid'] + ) + + server_managed_objects = {} + for target_moid in target_moids: + server_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(detail_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in detail_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.fan_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'fan cache miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.fan_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'Fan failed' + ) + return + + self.log_handler.set_log( + 'intersight.fan', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + for module_id in server_detail_moids[server_moid]: + if module_id == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + + for target_moid in target_moids: + self.cache_handler.set_intersight_cache_entry( + 'fan', + server_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'firmware': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('firmware', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'firmware cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + managed_objects = self.running_firmware_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'firmware failed' + ) + return + + self.log_handler.set_log( + 'intersight.running_firmware', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'Ancestors' in managed_object and managed_object['Ancestors'] is not None: + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['Moid'] == server_moid: + server_managed_objects.append( + managed_object + ) + break + + self.cache_handler.set_intersight_cache_entry( + 'firmware', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'gcard': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in blade_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('gcard', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids = target_moids + gcard_moids[server_moid] + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'gcard cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.graphics_card_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'gcard cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'gcard cache miss wout filter' + ) + + self.graphics_card_handler.set_get_expand( + 'GraphicsControllers,PciNode' + ) + managed_objects = self.graphics_card_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'gcard failed' + ) + return + + self.log_handler.set_log( + 'intersight.graphics_card', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'PciNode' in managed_object and managed_object['PciNode'] is not None: + if 'ComputeBlade' in managed_object['PciNode'] and managed_object['PciNode']['ComputeBlade'] is not None: + if server_moid == managed_object['PciNode']['ComputeBlade']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'gcard', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'gpu': + return + + if key == 'hcl': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('hcl', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'hcl cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.cond_hclstatus_handler.set_get_filter( + "ManagedObject/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'hcl cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'hcl cache miss wout filter' + ) + + managed_objects = self.cond_hclstatus_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'hcl failed' + ) + return + + self.log_handler.set_log( + 'intersight.cond_hclstatus', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if server_moid == managed_object['ManagedObject']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'hcl', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'hcl_detail': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('hcl_detail', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'hcl status cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + detail_moids = [] + server_detail_moids = {} + + for server_moid in target_server_moids: + server_detail_moids[server_moid] = [] + hcl_mos = self.cache_handler.get_intersight_cache_entry( + 'hcl', + subdirectory=server_moid + ) + if hcl_mos is None: + self.log_handler.error( + 'compute_info.set_intersight_cache', + 'hcl cache miss: %s' % (server_moid) + ) + return + + for hcl_mo in hcl_mos: + for detail_mo in hcl_mo['Details']: + server_detail_moids[server_moid].append( + detail_mo['Moid'] + ) + if detail_mo not in detail_moids: + detail_moids.append( + detail_mo['Moid'] + ) + + if len(detail_moids) < filter_length_threshold: + moids_list = [] + for moid in detail_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.cond_hclstatus_detail_handler.set_get_filter( + "Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'hcl detail cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'hcl detail cache miss wout filter' + ) + + managed_objects = self.cond_hclstatus_detail_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'hcl detail failed' + ) + return + + self.log_handler.set_log( + 'intersight.cond_hclstatus_detail', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if managed_object['Moid'] in server_detail_moids[server_moid]: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'hcl_detail', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'memory': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in registration_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('memory', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'memory cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + server_managed_objects = {} + for target_moid in target_moids: + server_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for target_server_moid in chunk_target_moids: + for moid in self.memory_array_moids[target_server_moid]: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.memory_unit_handler.set_get_filter( + "MemoryArray/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'memory cache miss w/filter for memory array: %s' % (moids_filter) + ) + + managed_objects = self.memory_unit_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'memory failed' + ) + return + + self.log_handler.set_log( + 'intersight.memory_unit', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + for managed_object in managed_objects: + if managed_object['MemoryArray']['Moid'] in self.memory_array_moids[server_moid]: + server_managed_objects[server_moid].append( + managed_object + ) + + for target_moid in target_moids: + self.cache_handler.set_intersight_cache_entry( + 'memory', + server_managed_objects[target_moid], + subdirectory=target_moid + ) + + return + + if key == 'pci': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('pci', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'pci cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.pci_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'pci cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'pci cache miss wout filter' + ) + + managed_objects = self.pci_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'pci failed' + ) + return + + self.log_handler.set_log( + 'intersight.pci_handler', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + if server_moid == managed_object['Parent']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'pci', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'physical_disk': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in registration_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('physical_disk', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + registration_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'physical disk cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.storage_physical_disk_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'physical disk cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'physical disk cache miss wout filter' + ) + + managed_objects = self.storage_physical_disk_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'physical disk failed' + ) + return + + self.log_handler.set_log( + 'intersight.storage_physical_disk', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + if server_moid in rack_moids: + for managed_object in managed_objects: + if 'RegisteredDevice' in managed_object and managed_object['RegisteredDevice'] is not None: + if registration_moids[server_moid] == managed_object['RegisteredDevice']['Moid']: + server_managed_objects.append( + managed_object + ) + + if server_moid in blade_moids: + for managed_object in managed_objects: + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['ObjectType'] == 'compute.Blade' and ancestor_mo['Moid'] == server_moid: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'physical_disk', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'physical_disk_usage': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('physical_disk_usage', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'physical disk usage cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + server_virtual_drive_map = {} + virtual_drive_moids = [] + for server_moid in target_moids: + virtual_drive_mos = self.cache_handler.get_intersight_cache_entry( + 'virtual_drive', + subdirectory=server_moid + ) + if virtual_drive_mos is None: + continue + + for virtual_drive_mo in virtual_drive_mos: + server_virtual_drive_map[virtual_drive_mo['Moid']] = server_moid + virtual_drive_moids.append( + virtual_drive_mo['Moid'] + ) + + if len(virtual_drive_moids) > 0: + if len(virtual_drive_moids) < filter_length_threshold: + virtual_drive_moids_list = [] + for virtual_drive_moid in virtual_drive_moids: + virtual_drive_moids_list.append('\'%s\'' % (virtual_drive_moid)) + virtual_drive_moids_filter = ', '.join(virtual_drive_moids_list) + self.storage_physical_disk_usage_handler.set_get_filter( + "StorageVirtualDrive/Moid in (%s)" % (virtual_drive_moids_filter) + ) + + managed_objects = self.storage_physical_disk_usage_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute_extra_attributes.set_cache', + 'physical disk usage failed' + ) + return + + self.log_handler.set_log( + 'intersight.storage_physical_disk_usage', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'StorageVirtualDrive' in managed_object and managed_object['StorageVirtualDrive'] is not None: + if managed_object['StorageVirtualDrive']['Moid'] in server_virtual_drive_map: + if server_virtual_drive_map[managed_object['StorageVirtualDrive']['Moid']] == server_moid: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'physical_disk_usage', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'profile': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('profile', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'profile cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.server_profile_handler.set_get_filter( + "AssignedServer/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'profile cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'profile cache miss wout filter' + ) + + managed_objects = self.server_profile_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'profile failed' + ) + return + + self.log_handler.set_log( + 'intersight.server_profile', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'AssignedServer' in managed_object and managed_object['AssignedServer'] is not None: + if server_moid == managed_object['AssignedServer']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'profile', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'psu': + # Rack servers only + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in rack_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('psu', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'psu cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.psu_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'psu cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'psu cache miss wout filter' + ) + + managed_objects = self.psu_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'psu failed' + ) + return + + self.log_handler.set_log( + 'intersight.psu', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + if server_moid == managed_object['Parent']['Moid']: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'psu', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'storage_controller': + cache_hits = [] + target_moids = [] + target_server_moids = [] + + # Rack server links to board + for server_moid in rack_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('storage_controller', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + board_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + # Blade server links to moid or board + for server_moid in blade_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('storage_controller', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + board_moids[server_moid] + ) + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'storage controller cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if 'storage' in expand and len(expand['storage']) > 0: + self.storage_controller_handler.set_get_expand( + ','.join(expand['storage']) + ) + + server_managed_objects = {} + for target_moid in target_server_moids: + server_managed_objects[target_moid] = [] + + chunk_id = 0 + while True: + if chunk_id >= len(target_moids): + break + + chunk_target_moids = [] + index = 0 + for target_moid in target_moids: + if index >= chunk_id and len(chunk_target_moids) < filter_length_threshold: + chunk_target_moids.append( + target_moid + ) + + index = index + 1 + + chunk_id = chunk_id + len(chunk_target_moids) + + moids_list = [] + for moid in chunk_target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.storage_controller_handler.set_get_filter( + "Parent/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'storage controller cache miss w/filter: %s' % (chunk_target_moids) + ) + + managed_objects = self.storage_controller_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'cpu failed' + ) + return + + self.log_handler.set_log( + 'intersight.storage_controller', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + for managed_object in managed_objects: + if 'Parent' in managed_object and managed_object['Parent'] is not None: + if server_moid in rack_moids: + if board_moids[server_moid] == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + + if server_moid in blade_moids: + if server_moid == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + if board_moids[server_moid] == managed_object['Parent']['Moid']: + server_managed_objects[server_moid].append( + managed_object + ) + + for target_moid in target_server_moids: + self.cache_handler.set_intersight_cache_entry( + 'storage_controller', + server_managed_objects[target_moid], + subdirectory=target_moid + ) + + if 'storage' in expand: + for expanded_item in expand['storage']: + if expanded_item not in ['PhysicalDisks', 'VirtualDrives']: + self.log_handler.error( + 'compute.set_intersight_cache', + 'unsupported storage controller expand: %s' % (expanded_item) + ) + continue + + if expanded_item == 'PhysicalDisks': + server_expanded_managed_objects = [] + for server_managed_object in server_managed_objects[target_moid]: + for server_expanded_managed_object in server_managed_object['PhysicalDisks']: + server_expanded_managed_objects.append( + server_expanded_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'physical_disk', + server_expanded_managed_objects, + subdirectory=target_moid + ) + + if expanded_item == 'VirtualDrives': + server_expanded_managed_objects = [] + for server_managed_object in server_managed_objects[target_moid]: + for server_expanded_managed_object in server_managed_object['VirtualDrives']: + server_expanded_managed_objects.append( + server_expanded_managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'virtual_drive', + server_expanded_managed_objects, + subdirectory=target_moid + ) + + return + + if key == 'tpm': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('tpm', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'tpm cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + tpm_server_map = {} + tpm_moids = [] + for server_moid in target_moids: + self.cache_handler.set_intersight_cache_entry( + 'tpm', + [], + subdirectory=server_moid + ) + board_mos = self.cache_handler.get_intersight_cache_entry( + 'board', + subdirectory=server_moid + ) + if board_mos is None: + continue + + for board_mo in board_mos: + for tpm_mo in board_mo['EquipmentTpms']: + tpm_moids.append( + tpm_mo['Moid'] + ) + tpm_server_map[tpm_mo['Moid']] = server_moid + + if len(tpm_moids) == 0: + return + + if len(tpm_moids) > 0: + if len(tpm_moids) < filter_length_threshold: + tpm_moids_list = [] + for tpm_moid in tpm_moids: + tpm_moids_list.append('\'%s\'' % (tpm_moid)) + tpm_moids_filter = ', '.join(tpm_moids_list) + self.equipment_tpm_handler.set_get_filter( + "Moid in (%s)" % (tpm_moids_filter) + ) + + managed_objects = self.equipment_tpm_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute_extra_attributes.set_cache', + 'tpm usage failed' + ) + return + + self.log_handler.set_log( + 'intersight.equipment_tpm', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + for managed_object in managed_objects: + if managed_object['Moid'] in tpm_server_map: + if tpm_server_map[managed_object['Moid']] == server_moid: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'tpm', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'virtual_drive': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in registration_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('virtual_drive', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + registration_moids[server_moid] + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'virtual drive cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + if len(target_moids) < filter_length_threshold: + moids_list = [] + for moid in target_moids: + moids_list.append('\'%s\'' % (moid)) + moids_filter = ', '.join(moids_list) + + self.storage_virtual_drive_handler.set_get_filter( + "RegisteredDevice/Moid in (%s)" % (moids_filter) + ) + + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'virtual drive cache miss w/filter: %s' % (target_moids) + ) + else: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'virtual drive cache miss wout filter' + ) + + managed_objects = self.storage_virtual_drive_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'virtual drive failed' + ) + return + + self.log_handler.set_log( + 'intersight.storage_virtual_drive', + managed_objects, + json_conversion=True + ) + + for server_moid in target_server_moids: + server_managed_objects = [] + if server_moid in rack_moids: + for managed_object in managed_objects: + if 'RegisteredDevice' in managed_object and managed_object['RegisteredDevice'] is not None: + if registration_moids[server_moid] == managed_object['RegisteredDevice']['Moid']: + server_managed_objects.append( + managed_object + ) + + if server_moid in blade_moids: + for managed_object in managed_objects: + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['ObjectType'] == 'compute.Blade' and ancestor_mo['Moid'] == server_moid: + server_managed_objects.append( + managed_object + ) + + self.cache_handler.set_intersight_cache_entry( + 'virtual_drive', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'workflow': + cache_hits = [] + target_moids = [] + target_server_moids = [] + for server_moid in server_moids: + if cache_ttl is None or not self.cache_handler.is_intersight_cache('workflow', subdirectory=server_moid, cache_ttl=cache_ttl): + target_moids.append( + server_moid + ) + target_server_moids.append( + server_moid + ) + else: + cache_hits.append( + server_moid + ) + + if len(cache_hits) > 0: + self.log_handler.debug( + 'compute_info.set_intersight_cache', + 'fan cache hit: %s' % (cache_hits) + ) + + if len(target_moids) == 0: + return + + workflows_mo = self.cache_handler.get_intersight_cache_entry( + 'workflows', + check_ttl=False + ) + if workflows_mo is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'workflows cache not found' + ) + return + + for server_moid in target_server_moids: + server_managed_objects = [] + for workflow_mo in workflows_mo: + if self.workflow_handler.is_server_workflow(server_moid, workflow_mo): + server_managed_objects.append( + workflow_mo + ) + + self.cache_handler.set_intersight_cache_entry( + 'workflow', + server_managed_objects, + subdirectory=server_moid + ) + + return + + if key == 'workflows': + if cache_ttl is None or not self.cache_handler.is_intersight_cache('workflows'): + start_time = int(time.time()) - workflow_seconds + reference_time = '%s.000Z' % ( + time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime(int(start_time))) + ) + self.workflow_handler.set_get_filter('CreateTime gt %s' % (reference_time)) + + managed_objects = self.workflow_handler.get_all() + if managed_objects is None: + self.log_handler.error( + 'compute.set_intersight_cache', + 'workflows' + ) + return + + self.log_handler.set_log( + 'intersight.workflow', + managed_objects, + json_conversion=True + ) + + self.cache_handler.set_intersight_cache_entry( + 'workflows', + managed_objects + ) + + return + + self.log_handler.error( + 'set_intersight_cache', + 'Unsupported key: %s' % (key) + ) + return + + def set_cache(self, servers_mo, cache_settings, cache_ttl, ctx=None): + start_time = int(time.time() * 1000) + self.log_handler.debug( + 'compute.set_cache', + 'Start cache population' + ) + + # Expanded data in servers_mo is always 'fresh' + + expanded = [] + for server_mo in servers_mo: + self.cache_handler.set_intersight_cache_entry( + 'server', + server_mo, + subdirectory=server_mo['Moid'] + ) + + if 'PciDevices' in server_mo: + if len(server_mo['PciDevices']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'pci', + [], + subdirectory=server_mo['Moid'] + ) + + if len(server_mo['PciDevices']) > 0: + if 'link' not in server_mo['PciDevices'][0]: + if 'pci' not in expanded: + expanded.append('pci') + + self.cache_handler.set_intersight_cache_entry( + 'pci', + server_mo['PciDevices'], + subdirectory=server_mo['Moid'] + ) + + if 'PciNodes' in server_mo: + if len(server_mo['PciNodes']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'pci_nodes', + [], + subdirectory=server_mo['Moid'] + ) + + if len(server_mo['PciNodes']) > 0: + if 'link' not in server_mo['PciNodes'][0]: + if 'pci_node' not in expanded: + expanded.append('pci_node') + + self.cache_handler.set_intersight_cache_entry( + 'pci_node', + server_mo['PciNodes'], + subdirectory=server_mo['Moid'] + ) + + if 'Fanmodules' in server_mo: + if len(server_mo['Fanmodules']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'fanmodule', + [], + subdirectory=server_mo['Moid'] + ) + + if len(server_mo['Fanmodules']) > 0: + if 'link' not in server_mo['Fanmodules'][0]: + if 'fanmodule' not in expanded: + expanded.append('fanmodule') + + self.cache_handler.set_intersight_cache_entry( + 'fanmodule', + server_mo['Fanmodules'], + subdirectory=server_mo['Moid'] + ) + + if 'Psus' in server_mo: + if len(server_mo['Psus']) == 0: + self.cache_handler.set_intersight_cache_entry( + 'psu', + [], + subdirectory=server_mo['Moid'] + ) + + if len(server_mo['Psus']) > 0: + if 'link' not in server_mo['Psus'][0]: + if 'psu' not in expanded: + expanded.append('psu') + + self.cache_handler.set_intersight_cache_entry( + 'psu', + server_mo['Psus'], + subdirectory=server_mo['Moid'] + ) + + if 'RegisteredDevice' in server_mo: + if 'link' not in server_mo['RegisteredDevice']: + expanded.append('connector') + self.cache_handler.set_intersight_cache_entry( + 'connector', + [server_mo['RegisteredDevice']], + subdirectory=server_mo['Moid'] + ) + + # Collect identifiers + + moids = [] + rack = [] + blade = [] + serial = {} + registration_moids = {} + board_moids = {} + adapter_moids = {} + boot_moids = {} + device_moids = {} + gcard_moids = {} + + for server_mo in servers_mo: + moids.append(server_mo['Moid']) + if server_mo['ObjectType'] == 'compute.RackUnit': + rack.append(server_mo['Moid']) + device_moids[server_mo['Moid']] = server_mo['DeviceMoId'] + if server_mo['ObjectType'] == 'compute.Blade': + blade.append(server_mo['Moid']) + serial[server_mo['Moid']] = server_mo['Serial'] + registration_moids[server_mo['Moid']] = server_mo['RegisteredDevice']['Moid'] + board_moids[server_mo['Moid']] = server_mo['Board']['Moid'] + + adapter_moids[server_mo['Moid']] = [] + for adapter_mo in server_mo['Adapters']: + adapter_moids[server_mo['Moid']].append( + adapter_mo['Moid'] + ) + + boot_moids[server_mo['Moid']] = {} + + boot_moids[server_mo['Moid']]['cdd'] = [] + for item in server_mo['BootCddDevices']: + boot_moids[server_mo['Moid']]['cdd'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['cdd'] = [] + for item in server_mo['BootCddDevices']: + boot_moids[server_mo['Moid']]['cdd'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['cdd'] = [] + for item in server_mo['BootCddDevices']: + boot_moids[server_mo['Moid']]['cdd'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['hdd'] = [] + for item in server_mo['BootHddDevices']: + boot_moids[server_mo['Moid']]['hdd'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['iscsi'] = [] + for item in server_mo['BootIscsiDevices']: + boot_moids[server_mo['Moid']]['iscsi'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['nvme'] = [] + for item in server_mo['BootNvmeDevices']: + boot_moids[server_mo['Moid']]['nvme'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['pxe'] = [] + for item in server_mo['BootPxeDevices']: + boot_moids[server_mo['Moid']]['pxe'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['san'] = [] + for item in server_mo['BootSanDevices']: + boot_moids[server_mo['Moid']]['san'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['sd'] = [] + for item in server_mo['BootSdDevices']: + boot_moids[server_mo['Moid']]['sd'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['uefi'] = [] + for item in server_mo['BootUefiShellDevices']: + boot_moids[server_mo['Moid']]['uefi'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['usb'] = [] + for item in server_mo['BootUsbDevices']: + boot_moids[server_mo['Moid']]['usb'].append( + item['Moid'] + ) + + boot_moids[server_mo['Moid']]['vmedia'] = [] + for item in server_mo['BootVmediaDevices']: + boot_moids[server_mo['Moid']]['vmedia'].append( + item['Moid'] + ) + + gcard_moids[server_mo['Moid']] = [] + if 'PciNodes' in server_mo: + for pci_node_mo in server_mo['PciNodes']: + if 'GraphicsCards' in pci_node_mo: + for gcard_mo in pci_node_mo['GraphicsCards']: + gcard_moids[server_mo['Moid']].append( + gcard_mo['Moid'] + ) + + # Set cache keys and expansion rules + + keys = [] + expand = {} + + if 'board' in cache_settings and cache_settings['board']: + keys.append('board') + expand['board'] = [] + + if 'cpu' in cache_settings and cache_settings['cpu']: + if 'board' in keys: + expand['board'].append('Processors') + else: + keys.append('cpu') + + if 'gpu' in cache_settings and cache_settings['gpu']: + keys.append('gpu') + keys.append('gcard') + + if 'fan' in cache_settings and cache_settings['fan']: + if 'fanmodule' not in expanded: + keys.append('fanmodule') + keys.append('fan') + + if 'memory' in cache_settings and cache_settings['memory']: + if 'board' not in keys: + keys.append('board') + keys.append('memory') + + if 'pci' in cache_settings and cache_settings['pci'] and 'pci' not in expanded: + keys.append('pci') + + if 'net' in cache_settings and cache_settings['net']: + keys.append('cimc') + keys.append('adapter') + expand['adapter'] = [] + expand['adapter'].append( + 'ExtEthIfs' + ) + expand['adapter'].append( + 'HostEthIfs' + ) + expand['adapter'].append( + 'HostFcIfs' + ) + + if 'psu' in cache_settings and cache_settings['psu'] and 'psu' not in expanded: + keys.append('psu') + + if 'storage' in cache_settings and cache_settings['storage']: + keys.append('storage_controller') + expand['storage'] = [] + expand['storage'].append( + 'PhysicalDisks' + ) + expand['storage'].append( + 'VirtualDrives' + ) + keys.append('physical_disk_usage') + keys.append('disk_group') + + if 'fw' in cache_settings and cache_settings['fw']: + keys.append('firmware') + + if 'boot' in cache_settings and cache_settings['boot']: + keys.append('boot_bios') + keys.append('boot_mode') + keys.append('boot_security') + keys.append('boot_hdd') + keys.append('boot_cdd') + keys.append('boot_iscsi') + keys.append('boot_nvme') + keys.append('boot_pxe') + keys.append('boot_san') + keys.append('boot_sd') + keys.append('boot_uefi') + keys.append('boot_usb') + keys.append('boot_vmedia') + + if 'advisory' in cache_settings and cache_settings['advisory']: + keys.append('advisories') + keys.append('advisory') + + if 'alarm' in cache_settings and cache_settings['alarm']: + keys.append('alarm') + + if 'connector' in cache_settings and cache_settings['connector'] and 'connector' not in expanded: + keys.append('connector') + + if 'contract' in cache_settings and cache_settings['contract']: + keys.append('contract') + + if 'hcl' in cache_settings and cache_settings['hcl']: + keys.append('hcl') + keys.append('hcl_detail') + + if 'profile' in cache_settings and cache_settings['profile']: + keys.append('profile') + + if 'workflow' not in cache_settings: + cache_settings['workflow'] = None + + if cache_settings['workflow'] is not None: + keys.append('workflows') + keys.append('workflow') + + if 'tpm' in cache_settings and cache_settings['tpm']: + keys.append('tpm') + + # Collect cache data + + if len(keys) > 0: + for key in keys: + if ctx is not None: + ctx.my_output.debug('- %s' % (key)) + + self.set_intersight_cache( + key, + expand, + moids, + rack, + blade, + registration_moids, + board_moids, + adapter_moids, + boot_moids, + device_moids, + gcard_moids, + serial, + cache_settings['workflow'], + cache_ttl=cache_ttl + ) + + if 'power' in cache_settings and cache_settings['power']: + if ctx is not None: + ctx.my_output.debug('- power') + + for server_mo in servers_mo: + if server_mo['ManagementMode'] == 'UCSM': + if self.ucsm_endpoint_settings_handler.is_ucsm_endpoint(server_mo['Serial']): + server_serial = {} + server_serial[server_mo['Moid']] = server_mo['Serial'] + self.set_redfish_cache( + 'power-ucsm', + [server_mo['Moid']], + server_serial, + cache_ttl=cache_ttl + ) + else: + self.log_handler.error( + 'set_cache', + 'Server in ucsm mode is not ucsm-enabled endpoint: %s' % (server_mo['Moid']) + ) + + if server_mo['ManagementMode'] != 'UCSM': + if self.redfish_endpoint_settings_handler.is_redfish_endpoint(server_mo['Serial']): + server_serial = {} + server_serial[server_mo['Moid']] = server_mo['Serial'] + self.set_redfish_cache( + 'power', + [server_mo['Moid']], + server_serial, + cache_ttl=cache_ttl + ) + else: + self.log_handler.error( + 'set_cache', + 'Server in IMM mode is not redfish-enabled endpoint: %s' % (server_mo['Moid']) + ) + + if 'thermal' in cache_settings and cache_settings['thermal']: + if ctx is not None: + ctx.my_output.debug('- thermal') + + for server_mo in servers_mo: + if server_mo['OperPowerState'] == 'on': + if server_mo['ManagementMode'] == 'UCSM': + if self.ucsm_endpoint_settings_handler.is_ucsm_endpoint(server_mo['Serial']): + server_serial = {} + server_serial[server_mo['Moid']] = server_mo['Serial'] + self.set_redfish_cache( + 'thernal-ucsm', + [server_mo['Moid']], + server_serial, + cache_ttl=cache_ttl + ) + else: + self.log_handler.error( + 'set_cache', + 'Server in ucsm mode is not ucsm-enabled endpoint: %s' % (server_mo['Moid']) + ) + + if server_mo['ManagementMode'] != 'UCSM': + if self.redfish_endpoint_settings_handler.is_redfish_endpoint(server_mo['Serial']): + server_serial = {} + server_serial[server_mo['Moid']] = server_mo['Serial'] + self.set_redfish_cache( + 'thermal', + [server_mo['Moid']], + server_serial, + cache_ttl=cache_ttl + ) + else: + self.log_handler.error( + 'set_cache', + 'Server in IMM mode is not redfish-enabled endpoint: %s' % (server_mo['Moid']) + ) + + duration = int(time.time() * 1000) - start_time + self.log_handler.debug( + 'compute.set_cache', + 'Cache populated in %s ms' % (duration) + ) diff --git a/lib/intersight/compute_context.py b/lib/intersight/compute_context.py new file mode 100644 index 00000000..3155cdb8 --- /dev/null +++ b/lib/intersight/compute_context.py @@ -0,0 +1,38 @@ +class ComputeContext(): + def __init__(self): + pass + + def get_context_ip(self, servers_info): + ips = [] + for server_info in servers_info: + if 'ManagementIp' in server_info and server_info['ManagementIp'] is not None: + ips.append( + server_info['ManagementIp'] + ) + + return ips + + def get_context_mac(self, servers_info): + mac = [] + + for server_info in servers_info: + if 'HostEthInfo' in server_info and server_info['HostEthInfo'] is not None: + for item in server_info['HostEthInfo']: + if '__show' not in item or item['__show']: + if item['MacAddress'] not in mac: + mac.append(item['MacAddress']) + + if 'ExtEthInfo' in server_info and server_info['ExtEthInfo'] is not None: + for item in server_info['ExtEthInfo']: + if '__show' not in item or item['__show']: + if item['MacAddress'] not in mac: + mac.append(item['MacAddress']) + + + if 'CimcInfo' in server_info and server_info['CimcInfo'] is not None: + for item in server_info['CimcInfo']: + if '__show' not in item or item['__show']: + if item['MacAddress'] not in mac: + mac.append(item['MacAddress']) + + return mac diff --git a/lib/intersight/compute_extra_attributes.py b/lib/intersight/compute_extra_attributes.py new file mode 100644 index 00000000..87de842c --- /dev/null +++ b/lib/intersight/compute_extra_attributes.py @@ -0,0 +1,2751 @@ +import time + +from lib import info_helper + +from lib.intersight import cache as intersight_cache +from lib.intersight.adapter_unit import main as adapter_unit +from lib.intersight.adapter_ext_eth_interface import main as adapter_ext_eth_interface +from lib.intersight.adapter_host_eth_interface import main as adapter_host_eth_interface +from lib.intersight.adapter_host_fc_interface import main as adapter_host_fc_interface +from lib.intersight.asset_device_registration import main as asset_device_registration +from lib.intersight.asset_device_contract_information import main as asset_device_contract_information +from lib.intersight.bios_boot_mode import main as bios_boot_mode +from lib.intersight.boot_cdd_device import main as boot_cdd_device +from lib.intersight.boot_device_boot_mode import main as boot_device_boot_mode +from lib.intersight.boot_device_boot_security import main as boot_device_boot_security +from lib.intersight.boot_hdd_device import main as boot_hdd_device +from lib.intersight.boot_iscsi_device import main as boot_iscsi_device +from lib.intersight.boot_nvme_device import main as boot_nvme_device +from lib.intersight.boot_pxe_device import main as boot_pxe_device +from lib.intersight.boot_san_device import main as boot_san_device +from lib.intersight.boot_sd_device import main as boot_sd_device +from lib.intersight.boot_uefi_device import main as boot_uefi_device +from lib.intersight.boot_usb_device import main as boot_usb_device +from lib.intersight.boot_vmedia_device import main as boot_vmedia_device +from lib.intersight.cond_alarm import main as cond_alarm +from lib.intersight.cond_hclstatus import main as cond_hclstatus +from lib.intersight.cond_hclstatus_detail import main as cond_hclstatus_detail +from lib.intersight.compute_board import main as compute_board +from lib.intersight.compute_server_setting import main as compute_server_setting +from lib.intersight.equipment_fan_module import main as equipment_fan_module +from lib.intersight.equipment_fan import main as equipment_fan +from lib.intersight.equipment_led import main as equipment_led +from lib.intersight.equipment_psu import main as equipment_psu +from lib.intersight.equipment_tpm import main as equipment_tpm +from lib.intersight.graphics_card import main as graphics_card +from lib.intersight.graphics_controller import main as graphics_controller +from lib.intersight.management_interface import main as management_interface +from lib.intersight.memory_unit import main as memory_unit +from lib.intersight.pci_device import main as pci_device +from lib.intersight.pci_node import main as pci_node +from lib.intersight.processor_unit import main as processor_unit +from lib.intersight.running_firmware import main as running_firmware +from lib.intersight.search_item import main as search_item +from lib.intersight.server_profile import main as server_profile +from lib.intersight.storage_disk_group import main as storage_disk_group +from lib.intersight.storage_physical_disk import main as storage_physical_disk +from lib.intersight.storage_physical_disk_usage import main as storage_physical_disk_usage +from lib.intersight.storage_virtual_drive import main as storage_virtual_drive +from lib.intersight.storage_controller import main as storage_controller +from lib.intersight.tam_advisory_definition import main as tam_advisory_definition +from lib.intersight.tam_advisory_instance import main as tam_advisory_instance +from lib.intersight.tam_security_advisory import main as tam_security_advisory +from lib.intersight.workflow import main as workflow + +from lib.redfish import endpoint_settings as redfish_endpoint_settings +from lib.ucsm import endpoint_settings as ucsm_endpoint_settings +from lib import my_servers_helper +from lib import log_helper + + +class ComputeExtraAttributes(): + """Class for rack/blade compute object extra attributes + """ + def __init__(self, iaccount, log_id=None): + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.my_servers_handler = my_servers_helper.MyServers() + self.my_servers_serials = self.my_servers_handler.get_serials() + self.info_handler = info_helper.InfoHelper( + log_id=log_id + ) + + self.cache_handler = intersight_cache.IntersightCache( + iaccount, + log_id=log_id + ) + + self.adapter_ext_eth_interface_handler = adapter_ext_eth_interface.AdapterExtEthInterface( + iaccount, + log_id=log_id + ) + self.adapter_host_eth_interface_handler = adapter_host_eth_interface.AdapterHostEthInterface( + iaccount, + log_id=log_id + ) + self.adapter_host_fc_interface_handler = adapter_host_fc_interface.AdapterHostFcInterface( + iaccount, + log_id=log_id + ) + self.adapter_unit_handler = adapter_unit.AdapterUnit( + iaccount, + log_id=log_id + ) + self.asset_device_contract_information_handler = asset_device_contract_information.AssetDeviceContractInformation( + iaccount, + log_id=log_id + ) + self.asset_device_registration_handler = asset_device_registration.AssetDeviceRegistration( + iaccount, + log_id=log_id + ) + self.bios_boot_mode_handler = bios_boot_mode.BiosBootMode( + iaccount, + log_id=log_id + ) + self.boot_cdd_device_handler = boot_cdd_device.BootCddDevice( + iaccount, + log_id=log_id + ) + self.boot_device_boot_mode_handler = boot_device_boot_mode.BootDeviceBootMode( + iaccount, + log_id=log_id + ) + self.boot_device_boot_security_handler = boot_device_boot_security.BootDeviceBootSecurity( + iaccount, + log_id=log_id + ) + self.boot_hdd_device_handler = boot_hdd_device.BootHddDevice( + iaccount, + log_id=log_id + ) + self.boot_iscsi_device_handler = boot_iscsi_device.BootIscsiDevice( + iaccount, + log_id=log_id + ) + self.boot_nvme_device_handler = boot_nvme_device.BootNvmeDevice( + iaccount, + log_id=log_id + ) + self.boot_pxe_device_handler = boot_pxe_device.BootPxeDevice( + iaccount, + log_id=log_id + ) + self.boot_san_device_handler = boot_san_device.BootSanDevice( + iaccount, + log_id=log_id + ) + self.boot_sd_device_handler = boot_sd_device.BootSdDevice( + iaccount, + log_id=log_id + ) + self.boot_uefi_device_handler = boot_uefi_device.BootUefiDevice( + iaccount, + log_id=log_id + ) + self.boot_usb_device_handler = boot_usb_device.BootUsbDevice( + iaccount, + log_id=log_id + ) + self.boot_vmedia_device_handler = boot_vmedia_device.BootVmediaDevice( + iaccount, + log_id=log_id + ) + self.cond_alarm_handler = cond_alarm.CondAlarm( + iaccount, + log_id=log_id + ) + self.cond_hclstatus_handler = cond_hclstatus.CondHclStatus( + iaccount, + log_id=log_id + ) + self.cond_hclstatus_detail_handler = cond_hclstatus_detail.CondHclStatusDetail( + iaccount, + log_id=log_id + ) + self.compute_board_handler = compute_board.ComputeBoard( + iaccount, + log_id=log_id + ) + self.compute_server_setting_handler = compute_server_setting.ComputeServerSetting( + iaccount, + log_id=log_id + ) + self.equipment_tpm_handler = equipment_tpm.EquipmentTpm( + iaccount, + log_id=log_id + ) + self.fan_module_handler = equipment_fan_module.EquipmentFanModule( + iaccount, + log_id=log_id + ) + self.fan_handler = equipment_fan.EquipmentFan( + iaccount, + log_id=log_id + ) + self.graphics_card_handler = graphics_card.GraphicsCard( + iaccount, + log_id=log_id + ) + self.graphics_controller_handler = graphics_controller.GraphicsController( + iaccount, + log_id=log_id + ) + self.locator_handler = equipment_led.EquipmentLed( + iaccount, + log_id=log_id + ) + self.management_interface_handler = management_interface.ManagementInterface( + iaccount, + log_id=log_id + ) + self.memory_unit_handler = memory_unit.MemoryUnit( + iaccount, + log_id=log_id + ) + self.processor_unit_handler = processor_unit.ProcessorUnit( + iaccount, + log_id=log_id + ) + self.psu_handler = equipment_psu.EquipmentPsu( + iaccount, + log_id=log_id + ) + self.pci_handler = pci_device.PciDevice( + iaccount, + log_id=log_id + ) + self.pci_node_handler = pci_node.PciNode( + iaccount, + log_id=log_id + ) + running_firmware_filter = '"Component eq \'system\' and Type eq \'blade-controller\'"' + self.running_firmware_handler = running_firmware.RunningFirmware( + iaccount, + get_filter=running_firmware_filter, + log_id=log_id + ) + self.search_item_handler = search_item.SearchItem( + iaccount, + log_id=log_id + ) + self.server_profile_handler = server_profile.ServerProfile( + iaccount, + log_id=log_id + ) + self.server_profile_handler.set_get_expand('ConfigChangeDetails') + self.storage_controller_handler = storage_controller.StorageController( + iaccount, + log_id=log_id + ) + self.storage_disk_group_handler = storage_disk_group.StorageDiskGroup( + iaccount, + log_id=log_id + ) + self.storage_physical_disk_handler = storage_physical_disk.StoragePhysicalDisk( + iaccount, + log_id=log_id + ) + self.storage_physical_disk_usage_handler = storage_physical_disk_usage.StoragePhysicalDiskUsage( + iaccount, + log_id=log_id + ) + self.storage_virtual_drive_handler = storage_virtual_drive.StorageVirtualDrive( + iaccount, + log_id=log_id + ) + self.tam_advisory_definition_handler = tam_advisory_definition.TamAdvisoryDefinition( + iaccount, + log_id=log_id + ) + self.tam_advisory_instance_handler = tam_advisory_instance.TamAdvisoryInstance( + iaccount, + log_id=log_id + ) + self.tam_security_advisory_handler = tam_security_advisory.TamSecurityAdvisory( + iaccount, + log_id=log_id + ) + self.workflow_handler = workflow.Workflow( + iaccount, + log_id=log_id + ) + self.redfish_endpoint_settings_handler = redfish_endpoint_settings.RedfishEndpointSettings( + log_id=log_id + ) + self.ucsm_endpoint_settings_handler = ucsm_endpoint_settings.UcsmEndpointSettings( + log_id=log_id + ) + + self.server_info = {} + + def add_advisory_info(self): + self.server_info['AdvisorySummary'] = {} + self.server_info['AdvisorySummary']['__Output'] = {} + self.server_info['AdvisorySummary']['__Output']['High'] = 'Red' + self.server_info['AdvisorySummary']['__Output']['Info'] = 'Blue' + self.server_info['AdvisorySummary']['High'] = 0 + self.server_info['AdvisorySummary']['Info'] = 0 + + self.server_info['AdvisoryInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'advisory', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_advisory_info', + 'No cache' + ) + return + + security_advisories = self.cache_handler.get_intersight_cache_entry( + 'advisory_security', + check_ttl=False + ) + if security_advisories is None: + self.log.error( + 'add_advisory_info', + 'No main security advisory cache' + ) + return + + advisory_definitions = self.cache_handler.get_intersight_cache_entry( + 'advisory_definition', + check_ttl=False + ) + if advisory_definitions is None: + self.log.error( + 'add_advisory_info', + 'No main advisory definitions cache' + ) + return + + for managed_object in managed_objects: + if managed_object['Advisory']['ObjectType'] == 'tam.SecurityAdvisory': + for advisory_mo in security_advisories: + if managed_object['Advisory']['Moid'] == advisory_mo['Moid']: + advisory_info = self.tam_security_advisory_handler.get_info( + advisory_mo + ) + self.server_info['AdvisoryInfo'].append( + advisory_info + ) + if advisory_info['Severity'] == 'high': + self.server_info['AdvisorySummary']['High'] = self.server_info['AdvisorySummary']['High'] + 1 + else: + self.server_info['AdvisorySummary']['Info'] = self.server_info['AdvisorySummary']['Info'] + 1 + + break + + continue + + if managed_object['Advisory']['ObjectType'] == 'tam.AdvisoryDefinition': + for advisory_mo in advisory_definitions: + if managed_object['Advisory']['Moid'] == advisory_mo['Moid']: + advisory_info = self.tam_advisory_definition_handler.get_info( + advisory_mo + ) + self.server_info['AdvisoryInfo'].append( + advisory_info + ) + if advisory_info['Severity'] == 'high': + self.server_info['AdvisorySummary']['High'] = self.server_info['AdvisorySummary']['High'] + 1 + else: + self.server_info['AdvisorySummary']['Info'] = self.server_info['AdvisorySummary']['Info'] + 1 + + break + + continue + + self.log.error( + 'add_advisory_info', + 'Unsupported advisory: %s' % (managed_object['Advisory']['ObjectType']) + ) + + def add_alarm_info(self, include_cleared=False, include_acknowledged=False): + self.server_info['AlarmInfo'] = [] + self.server_info['AlarmExcludedInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'alarm', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_alarm_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + critical_count = 0 + warning_count = 0 + info_count = 0 + + for managed_object in managed_objects: + alarm_info = self.cond_alarm_handler.get_info( + managed_object + ) + if alarm_info['Severity'] == 'Cleared' and not include_cleared: + continue + + if alarm_info['Acknowledge'] == 'Acknowledge' and not include_acknowledged: + continue + + if alarm_info['AncestorMoId'] != self.server_info['Moid']: + continue + + if alarm_info['Severity'] == 'Critical': + critical_count = critical_count + 1 + + if alarm_info['Severity'] == 'Warning': + warning_count = warning_count + 1 + + if alarm_info['Severity'] == 'Info': + info_count = info_count + 1 + + self.server_info['AlarmInfo'].append( + alarm_info + ) + + if critical_count != self.server_info['AlarmSummary']['Critical']: + self.log.error( + 'add_alarm_info', + 'Critical alarms do not match count: %s' % (self.server_info['Moid']) + ) + + if warning_count != self.server_info['AlarmSummary']['Warning']: + self.log.error( + 'add_alarm_info', + 'Warning alarms do not match count: %s' % (self.server_info['Moid']) + ) + + if info_count != self.server_info['AlarmSummary']['Info']: + self.log.error( + 'add_alarm_info', + 'Info alarms do not match count: %s' % (self.server_info['Moid']) + ) + + def add_cimc_info(self): + self.server_info['CimcInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'cimc', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_cimc_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['CimcInfo'].append( + self.management_interface_handler.get_info( + managed_object + ) + ) + + def add_adapters_info(self): + self.server_info['AdaptersInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'adapter', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_adapters_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['AdaptersInfo'].append( + self.adapter_unit_handler.get_info( + managed_object + ) + ) + self.server_info['AdaptersInfo'] = sorted( + self.server_info['AdaptersInfo'], + key=lambda i: i['Name'] + ) + + # create inventory if not yet created via associated pci device + + for adapter_info in self.server_info['AdaptersInfo']: + found = False + for inventory_info in self.server_info['Inventory']: + if inventory_info['Type'] == 'PCI Adapter': + if inventory_info['Name'] == 'PCI Slot %s' % (adapter_info['PciSlot']): + found = True + break + + if not found: + # assume it is mlom or mezz + + inventory_info = {} + inventory_info['Order'] = 10 + inventory_info['SubOrder'] = 0 + inventory_info['Type'] = 'PCI Adapter' + if adapter_info['PciSlot'].lower() in ['n/a', 'unknown', 'none', '']: + inventory_info['Name'] = 'PCI Slot MLOM' + else: + inventory_info['Name'] = 'PCI Slot %s' % (adapter_info['PciSlot']) + + for key in ['Model', 'Vendor', 'Serial']: + inventory_info[key] = '' + if key in adapter_info: + inventory_info[key] = adapter_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['Pid'] = inventory_info['Model'] + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + # sync adapter to inventory + + for adapter_info in self.server_info['AdaptersInfo']: + for inventory_info in self.server_info['Inventory']: + if inventory_info['Type'] == 'PCI Adapter': + if inventory_info['Name'] == 'PCI Slot %s' % (adapter_info['PciSlot']): + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + if inventory_info[key] is None or len(inventory_info[key]) == 0: + if key in adapter_info: + inventory_info[key] = adapter_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + # sync inventory to adapter + + for adapter_info in self.server_info['AdaptersInfo']: + for inventory_info in self.server_info['Inventory']: + if inventory_info['Type'] == 'PCI Adapter': + if inventory_info['Name'] == 'PCI Slot %s' % (adapter_info['PciSlot']): + adapter_info['Pid'] = inventory_info['Pid'] + + def add_board_info(self): + self.server_info['BoardInfo'] = None + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'board', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_board_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + if len(managed_objects) == 0: + return + + if len(managed_objects) > 1: + self.log.error( + 'add_board_info', + 'Multiple board info objects found' + ) + return + + self.server_info['BoardInfo'] = self.compute_board_handler.get_info( + managed_objects[0] + ) + + inventory_info = {} + inventory_info['Order'] = 2 + inventory_info['SubOrder'] = 1 + inventory_info['Type'] = 'Board' + inventory_info['Name'] = 'Mother Board' + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in self.server_info['BoardInfo']: + inventory_info[key] = self.server_info['BoardInfo'][key] + if inventory_info[key] is None: + inventory_info[key] = '' + + if len(inventory_info['Pid']) == 0: + inventory_info['Pid'] = inventory_info['Model'] + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_boot_info(self): + self.server_info['BootInfo'] = {} + self.server_info['BootInfo']['ConfiguredBootMode'] = None + self.server_info['BootInfo']['ActualBootMode'] = None + self.server_info['BootInfo']['SecureBoot'] = None + self.server_info['BootInfo']['Order'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_mode', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot mode cache' + ) + return + + if len(managed_objects) == 0: + self.log.debug( + 'add_boot_info', + 'No boot info: %s' % (self.server_info['Moid']) + ) + return + + if len(managed_objects) > 1: + self.log.error( + 'add_boot_info', + 'Unexpected number of boot device boot mode objects: %s' % (self.server_info['Moid']) + ) + self.log.error( + 'add_boot_info', + managed_objects + ) + return + + self.server_info['BootInfo']['ConfiguredBootMode'] = self.boot_device_boot_mode_handler.get_info( + managed_objects[0] + )['ConfiguredBootMode'] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_bios', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot bios cache' + ) + return + + if len(managed_objects) != 1: + self.log.error( + 'add_boot_info', + 'Unexpected number of boot bios mode objects' + ) + return + + self.server_info['BootInfo']['ActualBootMode'] = self.bios_boot_mode_handler.get_info( + managed_objects[0] + )['ActualBootMode'] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_security', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot security cache' + ) + return + + if len(managed_objects) != 1: + self.log.error( + 'add_boot_info', + 'Unexpected number of boot security mode objects' + ) + return + + self.server_info['BootInfo']['SecureBoot'] = self.boot_device_boot_security_handler.get_info( + managed_objects[0] + )['SecureBoot'] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_cdd', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot cdd cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_cdd_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_hdd', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot hdd cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_hdd_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_iscsi', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot iscsi cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_iscsi_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_nvme', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot nvme cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_nvme_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_pxe', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot pxe cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_pxe_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_san', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot san cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_san_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_sd', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot sd cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_sd_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_uefi', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot uefi cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_uefi_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_usb', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot usb cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_usb_device_handler.get_info( + managed_object + ) + ) + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'boot_vmedia', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_boot_info', + 'No boot vmedia cache' + ) + return + + for managed_object in managed_objects: + self.server_info['BootInfo']['Order'].append( + self.boot_vmedia_device_handler.get_info( + managed_object + ) + ) + + self.server_info['BootInfo']['Order'] = sorted( + self.server_info['BootInfo']['Order'], + key=lambda i: i['Order'] + ) + + def add_connector_info(self): + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'connector', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_connector_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + if len(managed_objects) > 1: + self.log.error( + 'add_connector_info', + 'Unexpected number of device connector objects: %s' % (self.server_info['Moid']) + ) + return + + self.server_info['ConnectorInfo'] = None + if len(managed_objects) == 1: + self.server_info['ConnectorInfo'] = self.asset_device_registration_handler.get_info( + managed_objects[0] + ) + self.server_info['Connected'] = self.server_info['ConnectorInfo']['Connected'] + + def add_contract_info(self): + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'contract', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_contract_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + if len(managed_objects) != 1: + self.log.error( + 'add_contract_info', + 'Unexpected number of device contract objects: %s' % (self.server_info['Moid']) + ) + return + + self.server_info['ContractInfo'] = self.asset_device_contract_information_handler.get_info( + managed_objects[0] + ) + + def add_cpu_info(self): + self.server_info['CpuInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'cpu', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_cpu_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + cpu_info = self.processor_unit_handler.get_processor_unit_info( + managed_object + ) + if cpu_info['Presence'] == 'equipped': + self.server_info['CpuInfo'].append( + cpu_info + ) + + self.server_info['CpuInfo'] = sorted( + self.server_info['CpuInfo'], + key=lambda i: i['ProcessorId'] + ) + + for cpu_info in self.server_info['CpuInfo']: + inventory_info = {} + inventory_info['Order'] = 3 + inventory_info['SubOrder'] = cpu_info['ProcessorId'] + inventory_info['Type'] = 'CPU' + inventory_info['Name'] = 'CPU #%s' % (cpu_info['ProcessorId']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in cpu_info: + inventory_info[key] = cpu_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_ext_eth_info(self): + self.server_info['MacAddressInfo'] = [] + self.server_info['ExtEthInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'adapter_ext_eth_interface', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_ext_eth_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + for managed_object in managed_objects: + interface_info = self.adapter_ext_eth_interface_handler.get_info( + managed_object + ) + + mac_info = {} + mac_info['InterfaceDn'] = interface_info['Dn'] + mac_info['InterfaceName'] = interface_info['Dn'].split('/')[-1] + mac_info['MacAddress'] = interface_info['MacAddress'].lower() + mac_info['AdapterModel'] = None + mac_info['AdapterPciSlot'] = None + + interface_info['AdapterName'] = None + interface_info['AdapterPciSlot'] = None + interface_info['AdapterModel'] = None + interface_info['AdapterPid'] = None + for adapter_info in self.server_info['AdaptersInfo']: + if managed_object['Moid'] in adapter_info['ExtEthIfsIds']: + if 'Name' in adapter_info: + interface_info['AdapterName'] = adapter_info['Name'] + if 'PciSlot' in adapter_info: + interface_info['AdapterPciSlot'] = adapter_info['PciSlot'] + mac_info['AdapterPciSlot'] = adapter_info['PciSlot'] + if 'Model' in adapter_info: + interface_info['AdapterModel'] = adapter_info['Model'] + mac_info['AdapterModel'] = adapter_info['Model'] + if 'Pid' in adapter_info: + interface_info['Pid'] = adapter_info['Pid'] + + self.server_info['ExtEthInfo'].append( + interface_info + ) + + self.server_info['MacAddressInfo'].append( + mac_info + ) + + self.server_info['ExtEthInfo'] = sorted( + self.server_info['ExtEthInfo'], + key=lambda i: ( + i['Dn'], + i['InterfaceId'] + ) + ) + + def add_fan_module_info(self): + if self.server_info['Type'] == 'Blade': + return + + if self.server_info['Type'] == 'Rack': + self.server_info['FanModuleInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'fanmodule', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_fan_module_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['FanModuleInfo'].append( + self.fan_module_handler.get_info( + managed_object + ) + ) + + self.server_info['FanModuleInfo'] = sorted( + self.server_info['FanModuleInfo'], + key=lambda i: i['Dn'] + ) + + self.server_info['FanModuleOn'] = 0 + for fan_module_info in self.server_info['FanModuleInfo']: + if fan_module_info['On']: + self.server_info['FanModuleOn'] = self.server_info['FanModuleOn'] + 1 + + self.server_info['FanModuleCount'] = len(self.server_info['FanModuleInfo']) + self.server_info['FanModuleSummary'] = '%s/%s' % ( + self.server_info['FanModuleOn'], + self.server_info['FanModuleCount'] + ) + self.server_info['FanModuleHealthy'] = True + if self.server_info['FanModuleOn'] < self.server_info['FanModuleCount']: + self.server_info['FanModuleHealthy'] = False + + def add_fan_info(self): + if self.server_info['Type'] == 'Blade': + return + + if self.server_info['Type'] == 'Rack': + self.server_info['FanInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'fan', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_fan_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['FanInfo'].append( + self.fan_handler.get_info( + managed_object + ) + ) + + self.server_info['FanInfo'] = sorted( + self.server_info['FanInfo'], + key=lambda i: i['Dn'] + ) + + self.server_info['FanOn'] = 0 + for fan_info in self.server_info['FanInfo']: + if fan_info['On']: + self.server_info['FanOn'] = self.server_info['FanOn'] + 1 + + self.server_info['FanCount'] = len(self.server_info['FanInfo']) + self.server_info['FanSummary'] = '%s/%s' % ( + self.server_info['FanOn'], + self.server_info['FanCount'] + ) + self.server_info['FanHealthy'] = True + if self.server_info['FanOn'] < self.server_info['FanCount']: + self.server_info['FanHealthy'] = False + + for fan_info in self.server_info['FanInfo']: + if fan_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 11 + inventory_info['SubOrder'] = (fan_info['FanModuleId'] + 1) * 10 + fan_info['FanId'] + inventory_info['Type'] = 'Fan' + inventory_info['Name'] = fan_info['Name'] + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in fan_info: + inventory_info[key] = fan_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_firmware_info(self): + self.server_info['FirmwarewComponents'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'firmware', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_firmware_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + for managed_object in managed_objects: + self.server_info['FirmwarewComponents'].append( + self.running_firmware_handler.get_info( + managed_object + ) + ) + + self.server_info['FirmwareVersion'] = self.running_firmware_handler.get_version( + managed_objects + ) + + self.server_info['FirmwarewComponents'] = sorted( + self.server_info['FirmwarewComponents'], + key=lambda i: i['Dn'] + ) + + def add_flags(self, workflow_days): + self.add_state_flag() + self.add_management_flag() + self.add_workflow_flag(workflow_days) + + def add_gcard_info(self): + self.server_info['GraphicsCardInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'gcard', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is not None: + for managed_object in managed_objects: + gcard_info = self.graphics_card_handler.get_info( + managed_object + ) + + gcard_info['PciNodeSlotId'] = None + for pci_node_info in self.server_info['PciNodesInfo']: + if gcard_info['PciNodeId'] == pci_node_info['Moid']: + gcard_info['PciNodeSlotId'] = int(pci_node_info['SlotId']) + + gcard_info['GraphicsControllersInfo'] = [] + for gcontroller_mo in managed_object['GraphicsControllers']: + gcontroller_info = self.graphics_controller_handler.get_info( + gcontroller_mo + ) + + for key in ['GpuId', 'FirmwareVersion', 'PartNumber', 'SlotId']: + gcontroller_info[key] = gcard_info[key] + + + gcard_info['GraphicsControllersInfo'].append( + gcontroller_info + ) + + self.server_info['GpuInfo'].append( + gcontroller_info + ) + + gcard_info['GraphicsControllersInfo'] = sorted( + gcard_info['GraphicsControllersInfo'], + key=lambda i: i['ControllerId'] + ) + + if gcard_info['Presence'] == 'equipped': + self.server_info['GraphicsCardInfo'].append( + gcard_info + ) + + self.server_info['GraphicsCardInfo'] = sorted( + self.server_info['GraphicsCardInfo'], + key=lambda i: i['CardId'] + ) + + for pci_node_info in self.server_info['PciNodesInfo']: + pci_node_info['GpuInfo'] = [] + for gcard_info in self.server_info['GraphicsCardInfo']: + if gcard_info['PciNodeId'] == pci_node_info['Moid']: + for gpu_info in gcard_info['GraphicsControllersInfo']: + pci_node_info['GpuInfo'].append( + gpu_info + ) + + for gcard_info in self.server_info['GraphicsCardInfo']: + for gpu_info in gcard_info['GraphicsControllersInfo']: + inventory_info = {} + inventory_info['Order'] = 4 + inventory_info['SubOrder'] = gcard_info['PciNodeSlotId'] * 10 + gpu_info['ControllerId'] + inventory_info['Type'] = 'GPU @ Pci Node' + inventory_info['Name'] = 'GPU #%s @ Pci Node #%s' % (gpu_info['ControllerId'], gcard_info['PciNodeSlotId']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in gpu_info: + inventory_info[key] = gpu_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_gpu_info(self): + self.server_info['GpuInfo'] = [] + for pci_device_info in self.server_info['PciDevicesInfo']: + if pci_device_info['Pid'] is not None and '-GPU-' in pci_device_info['Pid']: + self.server_info['GpuInfo'].append( + pci_device_info + ) + + for gpu_info in self.server_info['GpuInfo']: + inventory_info = {} + inventory_info['Order'] = 4 + inventory_info['SubOrder'] = gpu_info['SlotId'] + inventory_info['Type'] = 'GPU' + inventory_info['Name'] = 'GPU #%s' % (gpu_info['SlotId']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in gpu_info: + inventory_info[key] = gpu_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_group_info(self): + self.server_info['Groups'] = '' + if self.my_servers_serials is not None: + if self.server_info['Serial'] in self.my_servers_serials: + self.server_info['Groups'] = ','.join( + self.my_servers_serials[self.server_info['Serial']] + ) + + def add_hcl_info(self): + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'hcl', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_hcl_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + if len(managed_objects) == 0: + self.server_info['HclInfo'] = None + return + + if len(managed_objects) > 1: + self.log.error( + 'add_hcl_info', + 'Multiple hcl info objects found: %s' % (self.server_info['Moid']) + ) + return + + self.server_info['HclInfo'] = self.cond_hclstatus_handler.get_info( + managed_objects[0] + ) + self.server_info['HclInfo']['Details'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'hcl_detail', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_hcl_info', + 'No hcl detail cache' + ) + return + + for managed_object in managed_objects: + self.server_info['HclInfo']['Details'].append( + self.cond_hclstatus_detail_handler.get_info( + managed_object + ) + ) + + return + + def add_health_info(self, server_mo): + self.server_info['AlarmSummary'] = {} + self.server_info['AlarmSummary']['__Output'] = {} + self.server_info['AlarmSummary']['__Output']['Critical'] = 'Red' + self.server_info['AlarmSummary']['__Output']['Warning'] = 'Yellow' + self.server_info['AlarmSummary']['__Output']['Info'] = 'Blue' + self.server_info['AlarmSummary']['__Output']['Cleared'] = 'Green' + + for key in ['Critical', 'Warning', 'Info', 'Cleared']: + if key in server_mo['AlarmSummary']: + self.server_info['AlarmSummary'][key] = server_mo['AlarmSummary'][key] + + self.server_info['Health'] = 'Healthy' + + if self.server_info['AlarmSummary']['Warning'] == 0 and self.server_info['AlarmSummary']['Critical'] == 0: + if 'Info' in self.server_info['AlarmSummary'] and self.server_info['AlarmSummary']['Info'] > 0: + self.server_info['Health'] = 'Healthy (%s)' % ( + self.server_info['AlarmSummary']['Info'] + ) + + if self.server_info['AlarmSummary']['Warning'] > 0 and self.server_info['AlarmSummary']['Critical'] == 0: + self.server_info['Health'] = 'Warnings (%s)' % ( + self.server_info['AlarmSummary']['Warning'] + ) + + if self.server_info['AlarmSummary']['Critical'] > 0: + self.server_info['Health'] = 'Critical (%s)' % ( + self.server_info['AlarmSummary']['Critical'] + ) + + def add_host_eth_info(self): + self.server_info['HostEthInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'adapter_host_eth_interface', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_host_eth_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + for managed_object in managed_objects: + interface_info = self.adapter_host_eth_interface_handler.get_info( + managed_object + ) + + mac_info = {} + mac_info['InterfaceDn'] = interface_info['Dn'] + mac_info['InterfaceName'] = interface_info['Dn'].split('/')[-1] + mac_info['MacAddress'] = interface_info['MacAddress'].lower() + mac_info['AdapterModel'] = None + mac_info['AdapterPciSlot'] = None + + interface_info['AdapterName'] = None + interface_info['AdapterPciSlot'] = None + interface_info['AdapterModel'] = None + interface_info['AdapterPid'] = None + for adapter_info in self.server_info['AdaptersInfo']: + if managed_object['Moid'] in adapter_info['HostEthIfsIds']: + if 'Name' in adapter_info: + interface_info['AdapterName'] = adapter_info['Name'] + if 'PciSlot' in adapter_info: + interface_info['AdapterPciSlot'] = adapter_info['PciSlot'] + mac_info['AdapterPciSlot'] = adapter_info['PciSlot'] + if 'Model' in adapter_info: + interface_info['AdapterModel'] = adapter_info['Model'] + mac_info['AdapterModel'] = adapter_info['Model'] + if 'Pid' in adapter_info: + interface_info['Pid'] = adapter_info['Pid'] + + self.server_info['HostEthInfo'].append( + interface_info + ) + + self.server_info['MacAddressInfo'].append( + mac_info + ) + + self.server_info['HostEthInfo'] = sorted( + self.server_info['HostEthInfo'], + key=lambda i: ( + i['AdapterName'], + i['Name'] + ) + ) + + def add_host_fc_info(self): + self.server_info['HostFcInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'adapter_host_fc_interface', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_host_fc_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + return + + for managed_object in managed_objects: + interface_info = self.adapter_host_fc_interface_handler.get_info( + managed_object + ) + + interface_info['AdapterName'] = None + interface_info['AdapterPciSlot'] = None + interface_info['AdapterModel'] = None + interface_info['AdapterPid'] = None + for adapter_info in self.server_info['AdaptersInfo']: + if managed_object['Moid'] in adapter_info['HostFcIfsIds']: + if 'Name' in adapter_info: + interface_info['AdapterName'] = adapter_info['Name'] + if 'PciSlot' in adapter_info: + interface_info['AdapterPciSlot'] = adapter_info['PciSlot'] + if 'Model' in adapter_info: + interface_info['AdapterModel'] = adapter_info['Model'] + if 'Pid' in adapter_info: + interface_info['Pid'] = adapter_info['Pid'] + + self.server_info['HostFcInfo'].append( + interface_info + ) + + self.server_info['HostFcInfo'] = sorted( + self.server_info['HostFcInfo'], + key=lambda i: ( + i['AdapterName'], + i['Name'] + ) + ) + + def add_kvm_info(self, server_mo): + self.server_info['KvmInfo'] = {} + self.server_info['KvmInfo']['KvmIpAddresses'] = server_mo['KvmIpAddresses'] + self.server_info['KvmInfo']['KvmServerStateEnabled'] = server_mo['KvmServerStateEnabled'] + self.server_info['KvmInfo']['KvmVendor'] = server_mo['KvmVendor'] + self.server_info['KvmInfo']['TunneledKvm'] = server_mo['TunneledKvm'] + + def add_license_info(self, server_mo): + for tag in server_mo['Tags']: + if tag['Key'] == 'Intersight.LicenseTier': + self.server_info['LicenseInfo'] = {} + self.server_info['LicenseInfo']['Tier'] = tag['Value'] + + def add_tags_info(self, server_mo): + self.server_info['Tags'] = [] + for tag in server_mo['Tags']: + if tag['Key'] == 'Intersight.LicenseTier': + continue + self.server_info['Tags'].append( + tag + ) + + self.server_info['Tags'] = sorted( + self.server_info['Tags'], + key=lambda i: ( + i['Key'].lower(), + i['Value'].lower() + ) + ) + + def add_locator_info(self, server_mo): + self.server_info['LocatorLedOn'] = self.locator_handler.is_locator_led_on( + server_mo['LocatorLed'] + ) + + def get_management_ip(self, server_mo): + if 'KvmIpAddresses' in server_mo: + for kvm_ip in server_mo['KvmIpAddresses']: + if kvm_ip['ClassId'] == 'compute.IpAddress': + return kvm_ip['Address'] + return None + + def add_management_flag(self): + color = ':' + state = '' + + if self.server_info['Connected']: + state = '%sC' % (state) + color = '%sG' % (color) + else: + state = '%sc' % (state) + color = '%sR' % (color) + + if self.server_info['UCSM']['Capable']: + if self.server_info['UCSM']['Enabled']: + state = '%sU' % (state) + color = '%sG' % (color) + else: + state = '%su' % (state) + color = '%sY' % (color) + + if self.server_info['Redfish']['Capable']: + if self.server_info['Redfish']['Enabled']: + state = '%sR' % (state) + color = '%sG' % (color) + else: + state = '%sr' % (state) + color = '%sY' % (color) + + if self.server_info['IMC']['Capable']: + if self.server_info['IMC']['Enabled']: + state = '%sI' % (state) + color = '%sG' % (color) + else: + state = '%si' % (state) + color = '%sY' % (color) + + self.server_info['FlagManagement'] = state + self.server_info['__Output']['FlagManagement'] = color + + def add_management_options(self): + self.server_info['Redfish'] = {} + self.server_info['UCSM'] = {} + self.server_info['IMC'] = {} + + if self.server_info['ManagementMode'] == 'UCSM': + self.server_info['Redfish']['Capable'] = False + self.server_info['Redfish']['Enabled'] = False + self.server_info['UCSM']['Capable'] = True + self.server_info['UCSM']['Enabled'] = self.ucsm_endpoint_settings_handler.is_ucsm_endpoint( + self.server_info['Serial'] + ) + self.server_info['IMC']['Capable'] = False + self.server_info['IMC']['Enabled'] = False + + else: + self.server_info['Redfish']['Capable'] = True + self.server_info['Redfish']['Enabled'] = self.redfish_endpoint_settings_handler.is_redfish_endpoint( + self.server_info['Serial'] + ) + self.server_info['UCSM']['Capable'] = False + self.server_info['UCSM']['Enabled'] = False + self.server_info['IMC']['Capable'] = True + self.server_info['IMC']['Enabled'] = False + + def add_memory_info(self): + self.server_info['MemoryInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'memory', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_memory_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['MemoryInfo'].append( + self.memory_unit_handler.get_memory_unit_info( + managed_object + ) + ) + + self.server_info['MemoryInfo'] = sorted( + self.server_info['MemoryInfo'], + key=lambda i: i['MemoryId'] + ) + + for memory_info in self.server_info['MemoryInfo']: + if memory_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 5 + inventory_info['SubOrder'] = memory_info['MemoryId'] + inventory_info['Type'] = 'Memory' + inventory_info['Name'] = 'Memory #%s' % (memory_info['MemoryId']) + for key in ['Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in memory_info: + inventory_info[key] = memory_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + if len(memory_info['Description']) > 0: + inventory_info['Model'] = '%s (%s)' % ( + memory_info['Description'], + memory_info['Model'].strip() + ) + else: + inventory_info['Model'] = memory_info['Model'].strip() + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_pci_info(self): + self.server_info['PciDevicesInfo'] = [] + self.server_info['PciModels'] = [] + self.server_info['PciSearch'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'pci', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_pci_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['PciDevicesInfo'].append( + self.pci_handler.get_info( + managed_object + ) + ) + + model = self.pci_handler.get_model( + managed_object + ) + if model is not None: + if model not in self.server_info['PciSearch']: + self.server_info['PciSearch'].append( + model + ) + + pid = self.pci_handler.get_pid( + managed_object + ) + if pid is not None: + if pid not in self.server_info['PciSearch']: + self.server_info['PciSearch'].append( + pid + ) + + if pid not in self.server_info['PciModels']: + self.server_info['PciModels'].append( + pid + ) + + if pid is None and model is not None: + if model not in self.server_info['PciModels']: + self.server_info['PciModels'].append( + model + ) + + self.server_info['PciDevicesInfo'] = sorted( + self.server_info['PciDevicesInfo'], + key=lambda i: i['Dn'] + ) + + for pci_info in self.server_info['PciDevicesInfo']: + inventory_info = {} + inventory_info['Order'] = 8 + inventory_info['SubOrder'] = pci_info['SlotId'] + inventory_info['Type'] = 'PCI Adapter' + inventory_info['Name'] = 'PCI Slot %s' % (pci_info['SlotId']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in pci_info: + inventory_info[key] = pci_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_pci_node_info(self): + self.server_info['PciNodesInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'pci_node', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + return + + for managed_object in managed_objects: + pci_node_info = self.pci_node_handler.get_info( + managed_object + ) + + self.server_info['PciNodesInfo'].append( + pci_node_info + ) + + if pci_node_info['Model'] not in self.server_info['PciModels']: + self.server_info['PciModels'].append( + pci_node_info['Model'] + ) + + if pci_node_info['Model'] not in self.server_info['PciSearch']: + self.server_info['PciSearch'].append( + pci_node_info['Model'] + ) + + for pci_node_info in self.server_info['PciNodesInfo']: + inventory_info = {} + inventory_info['Order'] = 9 + inventory_info['SubOrder'] = pci_node_info['SlotId'] + inventory_info['Type'] = 'PCI Node' + inventory_info['Name'] = 'Slot %s' % (pci_node_info['SlotId']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in pci_node_info: + inventory_info[key] = pci_node_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_pci_node_gpu_info(self): + for pci_node_info in self.server_info['PciNodesInfo']: + pci_node_info['NumGpus'] = 0 + + for gcard_moid in pci_node_info['GraphicsCardsMoids']: + for gcard_info in self.server_info['GraphicsCardInfo']: + if gcard_info['Moid'] == gcard_moid: + pci_node_info['NumGpus'] = pci_node_info['NumGpus'] + int(gcard_info['NumGpus']) + + def add_power_info(self): + self.server_info['Power'] = self.cache_handler.get_intersight_cache_entry( + 'power', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if self.server_info['Power'] is None: + self.log.error( + 'add_power_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + + def add_profile_info(self): + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'profile', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_profile_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + + if len(managed_objects) == 0: + self.server_info['ProfileInfo'] = None + return + + if len(managed_objects) > 1: + self.log.error( + 'add_profile_info', + 'Unexpected count of profile objects: %s' % (self.server_info['Moid']) + ) + return + + self.server_info['ProfileInfo'] = self.server_profile_handler.get_info( + managed_objects[0] + ) + + self.search_item_handler.set_get_filter( + "IndexMotypes eq 'policy.AbstractPolicy' and Profiles/any(a:a/Moid eq '%s')" % (self.server_info['ProfileInfo']['Moid']) + ) + policies = self.search_item_handler.get_all() + self.server_info['ProfileInfo']['Policies'] = [] + for policy in policies: + policy_info = {} + policy_info['__Output'] = {} + policy_info['Moid'] = policy['Moid'] + policy_info['Name'] = policy['Name'] + policy_info['ModTime'] = policy['ModTime'] + policy_info['ClassId'] = policy['ClassId'] + policy_info['Shared'] = False + if len(policy['Profiles']) > 1: + policy_info['Shared'] = True + + policy_info['InSync'] = True + policy_info['__Output']['InSync'] = 'Green' + for config_change_info in self.server_info['ProfileInfo']['ConfigChangeDetails']: + if config_change_info['EntityMoid'] == policy_info['Moid']: + if config_change_info['EntityType'] == policy_info['ClassId']: + policy_info['InSync'] = False + policy_info['__Output']['InSync'] = 'Red' + + self.server_info['ProfileInfo']['Policies'].append( + policy_info + ) + + return + + def add_psu_info(self, server_mo, imc_enabled): + if self.server_info['Type'] == 'Blade': + return + + if self.server_info['Type'] == 'Rack': + self.server_info['PsuInfo'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'psu', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_psu_info', + 'No cache: %s' % (server_mo['Moid']) + ) + else: + for managed_object in managed_objects: + self.server_info['PsuInfo'].append( + self.psu_handler.get_info( + managed_object + ) + ) + + self.server_info['PsuInfo'] = sorted( + self.server_info['PsuInfo'], + key=lambda i: i['Dn'] + ) + + self.server_info['PsuOn'] = 0 + for psu_info in self.server_info['PsuInfo']: + if psu_info['On']: + self.server_info['PsuOn'] = self.server_info['PsuOn'] + 1 + + self.server_info['PsuCount'] = len(server_mo['Psus']) + self.server_info['PsuSummary'] = '%s/%s' % ( + self.server_info['PsuOn'], + self.server_info['PsuCount'] + ) + self.server_info['PsuHealthy'] = True + if self.server_info['PsuOn'] < self.server_info['PsuCount']: + self.server_info['PsuHealthy'] = False + + for psu_info in self.server_info['PsuInfo']: + if psu_info['On']: + inventory_info = {} + inventory_info['Order'] = 12 + inventory_info['SubOrder'] = psu_info['Id'] + inventory_info['Type'] = 'PSU' + inventory_info['Id'] = psu_info['Id'] + inventory_info['Name'] = 'PSU #%s' % (psu_info['Id']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in psu_info: + inventory_info[key] = psu_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + if imc_enabled: + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'psu-imc', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is not None: + for managed_object in managed_objects: + for inventory_info in self.server_info['Inventory']: + if inventory_info['Type'] == 'PSU': + if managed_object['Name'] == 'PSU%s' % (inventory_info['Id']): + inventory_info['Pid'] = managed_object['Product ID'] + + def add_setting_id(self): + self.server_info['ServerSettingId'] = self.compute_server_setting_handler.get_id_by_device_moid( + self.server_info['DeviceMoId'] + ) + + def add_state_flag(self): + color = ':' + if self.server_info['OperPowerState'] == 'on': + state = 'P+' + color = '%sGG' % (color) + else: + state = 'P-' + color = '%sRR' % (color) + + if self.server_info['AlarmSummary']['Warning'] == 0 and self.server_info['AlarmSummary']['Critical'] == 0 and self.server_info['AlarmSummary']['Info'] == 0: + alarm_state = 'H' + alarm_color = 'G'.rjust(len(alarm_state), 'G') + state = '%s %s' % (state, alarm_state) + color = '%s.%s' % (color, alarm_color) + if self.server_info['AlarmSummary']['Warning'] == 0 and self.server_info['AlarmSummary']['Critical'] == 0 and self.server_info['AlarmSummary']['Info'] > 0: + alarm_state = 'I(%s)' % (self.server_info['AlarmSummary']['Info']) + alarm_color = 'B'.rjust(len(alarm_state), 'B') + state = '%s %s' % (state, alarm_state) + color = '%s.%s' % (color, alarm_color) + if self.server_info['AlarmSummary']['Warning'] > 0 and self.server_info['AlarmSummary']['Critical'] == 0: + alarm_state = 'W(%s)' % (self.server_info['AlarmSummary']['Warning']) + alarm_color = 'Y'.rjust(len(alarm_state), 'Y') + state = '%s %s' % (state, alarm_state) + color = '%s.%s' % (color, alarm_color) + if self.server_info['AlarmSummary']['Critical'] > 0: + alarm_state = 'C(%s)' % (self.server_info['AlarmSummary']['Critical']) + alarm_color = 'R'.rjust(len(alarm_state), 'R') + state = '%s %s' % (state, alarm_state) + color = '%s.%s' % (color, alarm_color) + + if 'LocatorLedOn' in self.server_info: + if self.server_info['LocatorLedOn']: + state = '%s L' % (state) + color = '%s..' % (color) + + self.server_info['FlagState'] = state + self.server_info['__Output']['FlagState'] = color + + def add_storage_virtual_disk_info(self, virtual_drives_mo, physical_disks_usage_mo, disk_groups_mo): + self.server_info['VirtualDisks'] = self.storage_virtual_drive_handler.get_info( + virtual_drives_mo, + storage_controllers_info=self.server_info['StorageControllerInfo'] + ) + + for virtual_disk_info in self.server_info['VirtualDisks']: + virtual_disk_info['PhysicalDiskIds'] = [] + virtual_disk_info['PhysicalDiskMoids'] = [] + + if virtual_disk_info['PhysicalDiskCount'] > 0: + if physical_disks_usage_mo is not None: + for physical_disk_usage_mo in physical_disks_usage_mo: + if physical_disk_usage_mo['StorageVirtualDrive']['Moid'] == virtual_disk_info['Moid']: + virtual_disk_info['PhysicalDiskIds'].append( + physical_disk_usage_mo['PhysicalDrive'] + ) + + if virtual_disk_info['PhysicalDiskCount'] == 0: + if disk_groups_mo is not None: + for disk_group_mo in disk_groups_mo: + for disk_group_vd_mo in disk_group_mo['VirtualDrives']: + if disk_group_vd_mo['Moid'] == virtual_disk_info['Moid']: + for disk_group_span_mo in disk_group_mo['Spans']: + for physical_disk_mo in disk_group_span_mo['PhysicalDisks']: + virtual_disk_info['PhysicalDiskMoids'].append( + physical_disk_mo['Moid'] + ) + virtual_disk_info['PhysicalDiskCount'] = virtual_disk_info['PhysicalDiskCount'] + 1 + + self.server_info['VirtualDiskCount'] = len( + self.server_info['VirtualDisks'] + ) + + self.server_info['VirtualDiskCapacity'] = self.storage_virtual_drive_handler.get_virtual_drives_size( + self.server_info['VirtualDisks'] + ) + self.server_info['VirtualDiskCapacityUnit'] = self.info_handler.convert_storage( + self.server_info['VirtualDiskCapacity'] + ) + + def add_storage_physical_disk_info(self, physical_disks_mo): + self.server_info['PhysicalDiskInfo'] = self.storage_physical_disk_handler.get_info( + physical_disks_mo, + virtual_drives_info=self.server_info['VirtualDisks'], + storage_controllers_info=self.server_info['StorageControllerInfo'] + ) + self.server_info['PhysicalDiskCount'] = len( + self.server_info['PhysicalDiskInfo'] + ) + self.server_info['PhysicalDiskCapacity'] = self.storage_physical_disk_handler.get_compute_disks_size( + self.server_info['PhysicalDiskInfo'] + ) + self.server_info['PhysicalDiskCapacityUnit'] = self.info_handler.convert_storage( + self.server_info['PhysicalDiskCapacity'] + ) + + for disk_info in self.server_info['PhysicalDiskInfo']: + if disk_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 7 + inventory_info['SubOrder'] = disk_info['DiskId'] + inventory_info['Type'] = 'Disk' + inventory_info['Name'] = 'Disk #%s' % (disk_info['DiskId']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in disk_info: + inventory_info[key] = disk_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + def add_storage_info(self, server): + start_time = int(time.time() * 1000) + + storage_controllers_mo = self.cache_handler.get_intersight_cache_entry( + 'storage_controller', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if storage_controllers_mo is None: + self.log.error( + 'add_storage_info', + 'No storage controller cache: %s' % (self.server_info['Moid']) + ) + return + + virtual_drives_mo = self.cache_handler.get_intersight_cache_entry( + 'virtual_drive', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if virtual_drives_mo is None: + self.log.error( + 'add_storage_info', + 'No virtual drive cache: %s' % (self.server_info['Moid']) + ) + return + + physical_disks_mo = self.cache_handler.get_intersight_cache_entry( + 'physical_disk', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if physical_disks_mo is None: + self.log.error( + 'add_storage_info', + 'No physical disk cache: %s' % (self.server_info['Moid']) + ) + return + + physical_disks_usage_mo = self.cache_handler.get_intersight_cache_entry( + 'physical_disk_usage', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if physical_disks_usage_mo is None: + self.log.error( + 'add_storage_info', + 'No physical disk usage cache: %s' % (self.server_info['Moid']) + ) + return + + disk_groups_mo = self.cache_handler.get_intersight_cache_entry( + 'disk_group', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if disk_groups_mo is None: + self.log.error( + 'add_storage_info', + 'No disk group cache: %s' % (self.server_info['Moid']) + ) + return + + self.log.debug( + 'add_storage_info', + 'Storage (disk): %s' % (int(time.time() * 1000) - start_time) + ) + + if self.server_info['Type'] == 'Rack': + self.server_info['StorageControllerInfo'] = self.storage_controller_handler.get_board_info( + storage_controllers_mo, + physical_disks_mo=physical_disks_mo + ) + + if self.server_info['Type'] == 'Blade': + self.server_info['StorageControllerInfo'] = self.storage_controller_handler.get_blade_info( + controllers=storage_controllers_mo + ) + + for controller_info in self.server_info['StorageControllerInfo']: + if controller_info['Presence'] == 'equipped': + inventory_info = {} + inventory_info['Order'] = 6 + inventory_info['SubOrder'] = controller_info['PciSlot'] + inventory_info['Type'] = 'Storage Controller' + inventory_info['Name'] = 'Storage Controller #%s' % (controller_info['PciSlot']) + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in controller_info: + inventory_info[key] = controller_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + for server_inventory_info in self.server_info['Inventory']: + if server_inventory_info['Type'] == 'PCI Adapter': + if server_inventory_info['SubOrder'] == controller_info['PciSlot']: + if len(server_inventory_info['Pid']) > 0 and len(inventory_info['Pid']) == 0: + inventory_info['Pid'] = server_inventory_info['Pid'] + + if len(server_inventory_info['Pid']) == 0 and len(inventory_info['Pid']) > 0: + server_inventory_info['Pid'] = inventory_info['Pid'] + + if len(server_inventory_info['Serial']) > 0 and len(inventory_info['Serial']) == 0: + inventory_info['Serial'] = server_inventory_info['Serial'] + + if len(server_inventory_info['Serial']) == 0 and len(inventory_info['Serial']) > 0: + server_inventory_info['Serial'] = inventory_info['Serial'] + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + if self.server_info['StorageControllerInfo'] is None: + self.server_info['StorageControllerCount'] = 0 + else: + self.server_info['StorageControllerCount'] = len(self.server_info['StorageControllerInfo']) + + self.add_storage_virtual_disk_info(virtual_drives_mo, physical_disks_usage_mo, disk_groups_mo) + self.add_storage_physical_disk_info(physical_disks_mo) + + self.server_info['StorageDrives'] = '%sC %sD %sVD' % ( + self.server_info['StorageControllerCount'], + self.server_info['PhysicalDiskCount'], + self.server_info['VirtualDiskCount'] + ) + + self.server_info['StorageCapacity'] = 'R %s , VD %s' % ( + self.server_info['PhysicalDiskCapacityUnit'], + self.server_info['VirtualDiskCapacityUnit'] + ) + + self.server_info['StorageSummary'] = '%sC %sD %sVD R%s L%s' % ( + self.server_info['StorageControllerCount'], + self.server_info['PhysicalDiskCount'], + self.server_info['VirtualDiskCount'], + self.server_info['PhysicalDiskCapacityUnit'], + self.server_info['VirtualDiskCapacityUnit'] + ) + + def add_thermal_info(self): + self.server_info['Thermal'] = self.cache_handler.get_intersight_cache_entry( + 'thermal', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if self.server_info['Thermal'] is None: + self.log.error( + 'add_thermal_info', + 'No cache: %s' % (self.server_info['Moid']) + ) + + def add_tpm_info(self): + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'tpm', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_tpm_info', + 'No cache' + ) + return + + self.server_info['TpmInfo'] = [] + for managed_object in managed_objects: + self.server_info['TpmInfo'].append( + self.equipment_tpm_handler.get_info( + managed_object + ) + ) + + def add_workflow_info(self, workflow_days): + self.server_info['Workflow'] = {} + self.server_info['Workflow']['Days'] = int(workflow_days / 86400) + self.server_info['Workflow']['Running'] = None + self.server_info['Workflow']['LatestMoid'] = None + self.server_info['Workflow']['Last'] = [] + + managed_objects = self.cache_handler.get_intersight_cache_entry( + 'workflow', + subdirectory=self.server_info['Moid'], + check_ttl=False + ) + if managed_objects is None: + self.log.error( + 'add_workflow_info', + 'No cache' + ) + return + + latest_create_time = None + for managed_object in managed_objects: + workflow_info = self.workflow_handler.get_info( + managed_object + ) + if workflow_info['Running']: + self.server_info['Workflow']['Running'] = workflow_info + continue + + if latest_create_time is None or latest_create_time < workflow_info['CreateTimeEpoch']: + self.server_info['Workflow']['LatestMoid'] = workflow_info['Moid'] + latest_create_time = workflow_info['CreateTimeEpoch'] + + self.server_info['Workflow']['Last'].append( + workflow_info + ) + + self.server_info['Workflow']['Last'] = sorted( + self.server_info['Workflow']['Last'], + key=lambda i: i['CreateTimeEpoch'], reverse=True + ) + + def add_workflow_flag(self, workflow_days): + state = '' + color = ':' + if workflow_days is not None: + if self.server_info['Workflow']['Running'] is not None: + state = '%sR' % (state) + color = '%sY' % (color) + + if len(self.server_info['Workflow']['Last']) > 0: + completed = 0 + failed = 0 + latest_completed = True + + for workflow_info in self.server_info['Workflow']['Last']: + if workflow_info['Moid'] == self.server_info['Workflow']['LatestMoid']: + latest_completed = workflow_info['Completed'] + + if workflow_info['Completed']: + completed = completed + 1 + else: + failed = failed + 1 + + if completed > 0: + completed_color = ''.join(['G' * len(str(completed))]) + if state == '': + state = '%sC%s' % (state, completed) + color = '%sG%s' % (color, completed_color) + else: + state = '%s C%s' % (state, completed) + color = '%s.G%s' % (color, completed_color) + + if failed > 0: + failed_color = ''.join(['R' * len(str(failed))]) + if state == '': + state = '%sF%s' % (state, failed) + color = '%sR%s' % (color, failed_color) + else: + state = '%s F%s' % (state, failed) + color = '%s.R%s' % (color, failed_color) + + if not latest_completed: + state = '%s!' % (state) + color = '%sR' % (color) + + self.server_info['FlagWorkflow'] = state + self.server_info['__Output']['FlagWorkflow'] = color + + def get_server_info(self, server_mo, settings): + self.server_info = {} + self.server_info['__Output'] = {} + if 'state' not in settings: + settings['state'] = False + self.server_info['StateEnabled'] = settings['state'] + self.server_info['IntersightObject'] = server_mo + + imc_enabled = False + if 'imc' in settings: + imc_enabled = settings['imc'] + + redfish_enabled = False + if 'redfish' in settings: + redfish_enabled = settings['redfish'] + + keys = [ + 'Moid', + 'Ancestors', + 'DeviceMoId', + 'Name', + 'Model', + 'Serial', + 'ManagementMode', + 'OperPowerState', + 'NumCpus', + 'NumCpuCores', + 'NumThreads', + 'AvailableMemory', + 'TotalMemory', + 'Vendor' + ] + for key in keys: + self.server_info[key] = server_mo[key] + + self.server_info['Cpu'] = '%sS %sC %sT' % ( + self.server_info['NumCpus'], + self.server_info['NumCpuCores'], + self.server_info['NumThreads'] + ) + + self.server_info['UsedMemory'] = self.server_info['TotalMemory'] - self.server_info['AvailableMemory'] + + self.server_info['TotalMemoryUnit'] = self.info_handler.convert_memory( + self.server_info['TotalMemory'] * 1024 * 1024, + precision=0 + ) + + self.server_info['TotalMemoryGB'] = int( + self.server_info['TotalMemory'] / 1024 + ) + + self.server_info['AvailableMemoryUnit'] = self.info_handler.convert_memory( + self.server_info['AvailableMemory'] * 1024 * 1024, + precision=0 + ) + + self.server_info['AvailableMemoryGB'] = int( + self.server_info['AvailableMemory'] / 1024 + ) + + self.server_info['UsedMemoryUnit'] = self.info_handler.convert_memory( + self.server_info['UsedMemory'] * 1024 * 1024, + precision=0 + ) + + self.server_info['UsedMemoryGB'] = int( + self.server_info['UsedMemory'] / 1024 + ) + + try: + usage = int(self.server_info['UsedMemory'] * 100 / self.server_info['TotalMemory']) + self.server_info['UsedMemoryPct'] = usage + self.server_info['UsedMemoryPctUnit'] = '%s%%' % (usage) + except BaseException: + self.server_info['UsedMemoryPct'] = '--' + self.server_info['UsedMemoryPctUnit'] = '--' + + self.server_info['ChassisMoid'] = None + if server_mo['ObjectType'] == 'compute.RackUnit': + self.server_info['Type'] = 'Rack' + self.server_info['TypeModel'] = '(R) %s' % (self.server_info['Model']) + + if server_mo['ObjectType'] == 'compute.Blade': + self.server_info['Type'] = 'Blade' + self.server_info['TypeModel'] = '(B) %s' % (server_mo['Model']) + self.server_info['ChassisMoid'] = server_mo['EquipmentChassis']['Moid'] + + self.server_info['Connected'] = False + + self.server_info['Inventory'] = [] + inventory_info = {} + inventory_info['Order'] = 1 + inventory_info['SubOrder'] = 1 + inventory_info['Type'] = 'Server' + if server_mo['ObjectType'] == 'compute.RackUnit': + inventory_info['Name'] = 'Rack Server' + if server_mo['ObjectType'] == 'compute.Blade': + inventory_info['Name'] = 'Blade Server' + for key in ['Model', 'Vendor', 'Serial', 'Pid']: + inventory_info[key] = '' + if key in self.server_info: + inventory_info[key] = self.server_info[key] + if inventory_info[key] is None: + inventory_info[key] = '' + + if len(inventory_info['Pid']) == 0: + inventory_info['Pid'] = inventory_info['Model'] + + self.server_info['InventoryServerPid'] = inventory_info['Pid'] + self.server_info['InventoryServerSerial'] = inventory_info['Serial'] + + inventory_info['ChassisMoid'] = self.server_info['ChassisMoid'] + inventory_info['ServerType'] = self.server_info['Type'] + inventory_info['ServerPid'] = self.server_info['InventoryServerPid'] + inventory_info['ServerSerial'] = self.server_info['InventoryServerSerial'] + + self.server_info['Inventory'].append( + inventory_info + ) + + self.add_group_info() + self.add_health_info(server_mo) + self.add_kvm_info(server_mo) + self.add_license_info(server_mo) + self.add_tags_info(server_mo) + self.server_info['ManagementIp'] = self.get_management_ip(server_mo) + self.add_management_options() + + if 'advisory' in settings and settings['advisory']: + start_time = int(time.time() * 1000) + self.add_advisory_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (advisory): %s' % (duration) + ) + + if 'alarm' in settings and settings['alarm']: + start_time = int(time.time() * 1000) + self.add_alarm_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (alarm): %s' % (duration) + ) + + if 'board' in settings and settings['board']: + start_time = int(time.time() * 1000) + self.add_board_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (board): %s' % (duration) + ) + + if 'boot' in settings and settings['boot']: + start_time = int(time.time() * 1000) + self.add_boot_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (boot): %s' % (duration) + ) + + if 'connector' in settings and settings['connector']: + start_time = int(time.time() * 1000) + self.add_connector_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (connector): %s' % (duration) + ) + + if 'contract' in settings and settings['contract']: + start_time = int(time.time() * 1000) + self.add_contract_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (contract): %s' % (duration) + ) + + if 'cpu' in settings and settings['cpu']: + start_time = int(time.time() * 1000) + self.add_cpu_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (cpu): %s' % (duration) + ) + + if 'fan' in settings and settings['fan']: + start_time = int(time.time() * 1000) + self.add_fan_module_info() + self.add_fan_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (fan): %s' % (duration) + ) + + if 'fw' in settings and settings['fw']: + start_time = int(time.time() * 1000) + self.add_firmware_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (fw): %s' % (duration) + ) + + if 'hcl' in settings and settings['hcl']: + start_time = int(time.time() * 1000) + self.add_hcl_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (hcl): %s' % (duration) + ) + + if 'locator' in settings and settings['locator']: + start_time = int(time.time() * 1000) + self.add_locator_info(server_mo) + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (locator): %s' % (duration) + ) + + if 'memory' in settings and settings['memory']: + start_time = int(time.time() * 1000) + self.add_memory_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (memory): %s' % (duration) + ) + + if 'pci' in settings and settings['pci']: + start_time = int(time.time() * 1000) + self.add_pci_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (pci): %s' % (duration) + ) + + start_time = int(time.time() * 1000) + self.add_pci_node_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (pci_node): %s' % (duration) + ) + + if 'gpu' in settings and settings['gpu']: + start_time = int(time.time() * 1000) + self.add_gpu_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (gpu): %s' % (duration) + ) + + start_time = int(time.time() * 1000) + self.add_gcard_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (gcard): %s' % (duration) + ) + + self.add_pci_node_gpu_info() + + if 'pci' not in settings or not settings['pci']: + if 'PciDevicesInfo' in self.server_info: + del self.server_info['PciDevicesInfo'] + + if 'net' in settings and settings['net']: + if server_mo['ObjectType'] == 'compute.RackUnit': + start_time = int(time.time() * 1000) + self.add_cimc_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (cimc): %s' % (duration) + ) + + start_time = int(time.time() * 1000) + self.add_adapters_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (adapters): %s' % (duration) + ) + + start_time = int(time.time() * 1000) + self.add_ext_eth_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (eth): %s' % (duration) + ) + + start_time = int(time.time() * 1000) + self.add_host_eth_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (host-eth): %s' % (duration) + ) + + start_time = int(time.time() * 1000) + self.add_host_fc_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (fc): %s' % (duration) + ) + + if 'power' in settings and settings['power']: + start_time = int(time.time() * 1000) + self.add_power_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (power): %s' % (duration) + ) + + if 'profile' in settings and settings['profile']: + start_time = int(time.time() * 1000) + self.add_profile_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (profile): %s' % (duration) + ) + + if 'psu' in settings and settings['psu']: + start_time = int(time.time() * 1000) + self.add_psu_info(server_mo, imc_enabled) + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (psu): %s' % (duration) + ) + + if 'server_setting_id' in settings and settings['server_setting_id']: + start_time = int(time.time() * 1000) + self.add_setting_id() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (settings): %s' % (duration) + ) + + if 'storage' in settings and settings['storage']: + start_time = int(time.time() * 1000) + self.add_storage_info(server_mo) + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (storage): %s' % (duration) + ) + + if 'thermal' in settings and settings['thermal']: + start_time = int(time.time() * 1000) + self.add_thermal_info() + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (thermal): %s' % (duration) + ) + + if 'workflow' in settings and settings['workflow'] is not None: + start_time = int(time.time() * 1000) + self.add_workflow_info( + settings['workflow'] + ) + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (workflow): %s' % (duration) + ) + + if 'tpm' in settings and settings['tpm']: + start_time = int(time.time() * 1000) + self.add_tpm_info() + if not settings['board']: + del self.server_info['BoardInfo'] + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (tpm): %s' % (duration) + ) + + if 'state' in settings and settings['state']: + start_time = int(time.time() * 1000) + self.add_flags(settings['workflow']) + duration = int(time.time() * 1000) - start_time + self.log.debug( + 'get_server_info', + 'Duration (flags): %s' % (duration) + ) + + self.server_info['Inventory'] = sorted( + self.server_info['Inventory'], + key=lambda i: ( + i['Order'], + i['SubOrder'] + ) + ) + + self.log.set_log( + 'server_info.%s' % (server_mo['Moid']), + self.server_info, + json_conversion=True + ) + + return self.server_info diff --git a/lib/intersight/compute_filter.py b/lib/intersight/compute_filter.py new file mode 100644 index 00000000..4b352c97 --- /dev/null +++ b/lib/intersight/compute_filter.py @@ -0,0 +1,1576 @@ +from lib import ip_helper +from lib import filter_helper + + +class ComputeFilter(): + """Class for server filtering + """ + def __init__(self): + pass + + def int_filter_match(self, value, filter_rule): + if filter_rule.startswith('>='): + if value >= int(filter_rule.lstrip('>=')): + return True + return False + + if filter_rule.startswith('ge'): + if value >= int(filter_rule.lstrip('ge')): + return True + return False + + if filter_rule.startswith('<='): + if value <= int(filter_rule.lstrip('<=')): + return True + return False + + if filter_rule.startswith('le'): + if value <= int(filter_rule.lstrip('le')): + return True + return False + + if filter_rule.startswith('>'): + if value > int(filter_rule.lstrip('>')): + return True + return False + + if filter_rule.startswith('gt'): + if value > int(filter_rule.lstrip('gt')): + return True + return False + + if filter_rule.startswith('<'): + if value < int(filter_rule.lstrip('<')): + return True + return False + + if filter_rule.startswith('lt'): + if value < int(filter_rule.lstrip('lt')): + return True + return False + + if filter_rule.startswith('!='): + if value != int(filter_rule.lstrip('!=')): + return True + return False + + if filter_rule.startswith('ne'): + if value != int(filter_rule.lstrip('ne')): + return True + return False + + if value == int(filter_rule): + return True + + return False + + def ip_filter_match(self, server, ip_filter): + if len(ip_filter) == 0: + return True + + if 'KvmIpAddresses' in server: + for kvm_ip in server['KvmIpAddresses']: + if kvm_ip['ClassId'] == 'compute.IpAddress': + for item in ip_filter: + if item['type'] == 'address': + if kvm_ip['Address'] == item['value']: + return True + + if item['type'] == 'subnet': + if ip_helper.is_ipv4_in_cidr(kvm_ip['Address'], item['value']): + return True + + if 'ManagementIp' in server: + for item in ip_filter: + if item['type'] == 'address': + if server['ManagementIp'] == item['value']: + return True + + if item['type'] == 'subnet': + if ip_helper.is_ipv4_in_cidr(server['ManagementIp'], item['value']): + return True + + return False + + def name_filter_match(self, server, name_filter): + if name_filter == '': + return True + + for item in name_filter.split(','): + if item.lower() in server['Name'].lower(): + return True + + return False + + def model_filter_match(self, server, model_filter): + if model_filter == '': + return True + + for item in model_filter.split(','): + if item.lower() in server['Model'].lower(): + return True + + return False + + def locator_filter_match(self, server, locator_filter): + if locator_filter == 'any': + return True + + if locator_filter == 'on' and server['LocatorLedOn']: + return True + + if locator_filter == 'off' and not server['LocatorLedOn']: + return True + + return False + + def power_filter_match(self, server, power_filter): + if power_filter == 'any': + return True + + if power_filter == 'on' and server['OperPowerState'] == 'on': + return True + + if power_filter == 'off' and server['OperPowerState'] != 'on': + return True + + return False + + def alarms_filter_match(self, server, alarm_severity): + # ['any', 'info', 'warn', 'crit'] + if alarm_severity == 'any': + return True + + if alarm_severity == 'info': + if server['AlarmSummary']['Critical'] > 0 or server['AlarmSummary']['Warning'] > 0 or server['AlarmSummary']['Info'] > 0: + return True + + if alarm_severity == 'warn': + if server['AlarmSummary']['Critical'] > 0 or server['AlarmSummary']['Warning'] > 0: + return True + + if alarm_severity == 'crit': + if server['AlarmSummary']['Critical'] > 0: + return True + + return False + + def ucsm_filter_match(self, server, ucsm): + if not ucsm: + return True + + if server['ManagementMode'] == 'UCSM': + return True + + return False + + def disconnected_filter_match(self, server, disconnected): + if not disconnected: + return True + + if server['Connected']: + return False + + return True + + def imm_filter_match(self, server, imm): + if not imm: + return True + + if server['ManagementMode'] != 'UCSM': + return True + + return False + + def serial_filter_match(self, server, serials): + if len(serials) == 0: + return True + + if server['Serial'] in serials: + return True + + return False + + def ancestor_filter_match(self, server, ancestors): + if len(ancestors) == 0: + return True + + if 'Ancestors' not in server: + return False + + if len(server['Ancestors']) == 0: + return False + + for ancestor in server['Ancestors']: + if ancestor['ObjectType'] == 'equipment.Chassis': + for ancestor_moid in ancestors: + if ancestor_moid == ancestor['Moid']: + return True + + return False + + def cpu_filter_match(self, server, cpu_filter): + for key in cpu_filter: + if key == 'core': + if not self.int_filter_match(server['NumCpuCores'], cpu_filter[key]): + return False + + if key == 'socket': + if not self.int_filter_match(server['NumCpus'], cpu_filter[key]): + return False + + if key == 'thread': + if not self.int_filter_match(server['NumThreads'], cpu_filter[key]): + return False + + if key == 'vendor': + found = False + if 'CpuInfo' not in server: + return False + + for cpu_info in server['CpuInfo']: + if cpu_info['VendorName'] == cpu_filter[key]: + found = True + + if not found: + return False + + if key == 'arch': + found = False + if 'CpuInfo' not in server: + return False + + for cpu_info in server['CpuInfo']: + if cpu_info['Architecture'].lower() == cpu_filter[key].lower(): + found = True + + if not found: + return False + + if key == 'model': + found = False + if 'CpuInfo' not in server: + return False + + for cpu_info in server['CpuInfo']: + if cpu_filter[key].lower() in cpu_info['Model'].lower(): + found = True + + if not found: + return False + + return True + + def cpu_match(self, server, cpu_filter): + if 'CpuInfo' in server: + for cpu_info in server['CpuInfo']: + cpu_info['__show'] = True + if 'model' in cpu_filter: + if cpu_info['Model'] is None: + cpu_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(cpu_filter['model']), cpu_info['Model']): + cpu_info['__show'] = False + continue + + if 'serial' in cpu_filter: + if cpu_info['Serial'] is None: + cpu_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(cpu_filter['serial']), cpu_info['Serial']): + cpu_info['__show'] = False + continue + + if 'arch' in cpu_filter: + if cpu_info['Architecture'] is None: + cpu_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(cpu_filter['arch']), cpu_info['Architecture']): + cpu_info['__show'] = False + continue + + return server + + def gpu_filter_match(self, server, gpu_filter): + for key in gpu_filter: + if key == 'slot': + if not self.int_filter_match(len(server['GpuInfo']), gpu_filter[key]): + return False + + if key == 'model': + found = False + if 'GpuInfo' not in server: + return False + + for gpu_info in server['GpuInfo']: + if gpu_filter[key].lower() in gpu_info['Model'].lower(): + found = True + + if not found: + return False + + return True + + def gpu_match(self, server, gpu_filter): + if 'GpuInfo' in server: + for gpu_info in server['GpuInfo']: + gpu_info['__show'] = True + if 'model' in gpu_filter: + if gpu_info['Model'] is None: + gpu_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(gpu_filter['model']), gpu_info['Model']): + gpu_info['__show'] = False + continue + + return server + + def memory_filter_match(self, server, memory_filter): + for key in memory_filter: + if key == 'size': + if not self.int_filter_match(server['TotalMemoryGB'], memory_filter[key]): + return False + + if key == 'dimm': + if 'MemoryInfo' not in server: + return False + + count = 0 + for memory_info in server['MemoryInfo']: + if memory_info['Presence'] == 'equipped': + count = count + 1 + + if not self.int_filter_match(count, memory_filter[key]): + return False + + if key == 'model': + found = False + if 'MemoryInfo' not in server: + return False + + for memory_info in server['MemoryInfo']: + if memory_info['Model'] is not None: + if memory_filter[key].lower() in memory_info['Model'].lower(): + found = True + + if not found: + return False + + if key == 'serial': + found = False + if 'MemoryInfo' not in server: + return False + + for memory_info in server['MemoryInfo']: + if memory_info['Serial'] is not None: + if memory_filter[key].lower() in memory_info['Serial'].lower(): + found = True + + if not found: + return False + + return True + + def mem_match(self, server, memory_filter): + if 'MemoryInfo' in server: + for memory_info in server['MemoryInfo']: + memory_info['__show'] = True + if 'model' in memory_filter: + if memory_info['Model'] is None: + memory_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(memory_filter['model']), memory_info['Model']): + memory_info['__show'] = False + continue + + if 'serial' in memory_filter: + if memory_info['Serial'] is None: + memory_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(memory_filter['serial']), memory_info['Serial']): + memory_info['__show'] = False + continue + + return server + + def pci_filter_match(self, server, pci_filter): + for key in pci_filter: + if key == 'slot': + if 'PciDevicesInfo' not in server: + return False + + if not self.int_filter_match(len(server['PciDevicesInfo']), pci_filter[key]): + return False + + if key == 'model': + found = False + if 'PciDevicesInfo' not in server: + return False + + for pci_info in server['PciDevicesInfo']: + if pci_info['Model'] is not None: + if pci_filter[key].lower() in pci_info['Model'].lower(): + found = True + + if not found: + return False + + if key == 'pid': + found = False + if 'PciDevicesInfo' not in server: + return False + + for pci_info in server['PciDevicesInfo']: + if pci_info['Pid'] is not None: + if pci_filter[key].lower() in pci_info['Pid'].lower(): + found = True + + if not found: + return False + + return True + + def pci_match(self, server, pci_filter): + for device_info in server['PciDevicesInfo']: + device_info['__show'] = True + if 'model' in pci_filter: + if device_info['Model'] is None: + device_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['model']), device_info['Model']): + device_info['__show'] = False + continue + + if 'pid' in pci_filter: + if device_info['Pid'] is None: + device_info['__show'] = False + continue + + if device_info['Pid'].lower() in ['unknown', 'n/a']: + device_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['pid']), device_info['Pid']): + device_info['__show'] = False + continue + + for device_info in server['PciNodesInfo']: + device_info['__show'] = True + if 'model' in pci_filter: + if device_info['Model'] is None: + device_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['model']), device_info['Model']): + device_info['__show'] = False + continue + + if 'pid' in pci_filter: + if device_info['Pid'] is None: + device_info['__show'] = False + continue + + if device_info['Pid'].lower() in ['unknown', 'n/a']: + device_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['pid']), device_info['Pid']): + device_info['__show'] = False + continue + + if 'CimcInfo' in server: + for interface_info in server['CimcInfo']: + interface_info['__show'] = False + + if 'ExtEthInfo' in server: + for interface_info in server['ExtEthInfo']: + interface_info['__show'] = True + if 'model' in pci_filter: + if interface_info['AdapterModel'] is None: + interface_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['model']), interface_info['AdapterModel']): + interface_info['__show'] = False + continue + + if 'pid' in pci_filter: + if interface_info['Pid'] is None: + interface_info['__show'] = False + continue + + if interface_info['Pid'].lower() in ['unknown', 'n/a']: + interface_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['pid']), interface_info['Pid']): + interface_info['__show'] = False + continue + + if 'HostEthInfo' in server: + for interface_info in server['HostEthInfo']: + interface_info['__show'] = True + if 'model' in pci_filter: + if interface_info['AdapterModel'] is None: + interface_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['model']), interface_info['AdapterModel']): + interface_info['__show'] = False + continue + + if 'pid' in pci_filter: + if interface_info['Pid'] is None: + interface_info['__show'] = False + continue + + if interface_info['Pid'].lower() in ['unknown', 'n/a']: + interface_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['pid']), interface_info['Pid']): + interface_info['__show'] = False + continue + + if 'HostFcInfo' in server: + for interface_info in server['HostFcInfo']: + interface_info['__show'] = True + if 'model' in pci_filter: + if interface_info['AdapterModel'] is None: + interface_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['model']), interface_info['AdapterModel']): + interface_info['__show'] = False + continue + + if 'pid' in pci_filter: + if interface_info['Pid'] is None: + interface_info['__show'] = False + continue + + if interface_info['Pid'].lower() in ['unknown', 'n/a']: + interface_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['pid']), interface_info['Pid']): + interface_info['__show'] = False + continue + + if 'AdaptersInfo' in server: + for adapter_info in server['AdaptersInfo']: + adapter_info['__show'] = True + if 'model' in pci_filter: + if adapter_info['Model'] is None: + adapter_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['model']), adapter_info['Model']): + adapter_info['__show'] = False + continue + + if 'pid' in pci_filter: + if adapter_info['Pid'] is None: + adapter_info['__show'] = False + continue + + if adapter_info['Pid'].lower() in ['unknown', 'n/a']: + adapter_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pci_filter['pid']), adapter_info['Pid']): + adapter_info['__show'] = False + continue + + return server + + def mac_filter_match(self, server, mac_filter): + if isinstance(mac_filter, str): + mac_filter = [mac_filter] + + if len(mac_filter) == 0: + return True + + for mac_item in mac_filter: + for item in mac_item.split(','): + for mac_info in server['MacAddressInfo']: + if filter_helper.match_mac(item, mac_info['MacAddress']): + return True + + return False + + def mac_match(self, server, mac_filter): + if isinstance(mac_filter, str): + mac_filter = [mac_filter] + + if len(mac_filter) == 0: + return server + + if 'ExtEthInfo' in server: + for interface_info in server['ExtEthInfo']: + interface_info['__show'] = True + + found = False + for mac_item in mac_filter: + for item in mac_item.split(','): + if filter_helper.match_mac(item, interface_info['MacAddress']): + found = True + + if not found: + interface_info['__show'] = False + + if 'HostEthInfo' in server: + for interface_info in server['HostEthInfo']: + interface_info['__show'] = True + + found = False + for mac_item in mac_filter: + for item in mac_item.split(','): + if filter_helper.match_mac(item, interface_info['MacAddress']): + found = True + + if not found: + interface_info['__show'] = False + + if 'HostFcInfo' in server: + for interface_info in server['HostFcInfo']: + interface_info['__show'] = True + + found = False + for mac_item in mac_filter: + for item in mac_item.split(','): + if filter_helper.match_wwn(item, interface_info['Wwnn']) and not filter_helper.match_wwn(item, interface_info['Wwpn']): + found = True + + if not found: + interface_info['__show'] = False + + return server + + def sc_filter_match(self, server, sc_filter): + for key in sc_filter: + if key == 'serial': + found = False + if 'StorageControllerInfo' not in server: + return False + + for sc_info in server['StorageControllerInfo']: + if sc_info['Serial'] is not None: + if sc_filter[key].lower() in sc_info['Serial'].lower(): + found = True + + if not found: + return False + + if key == 'vendor': + found = False + if 'StorageControllerInfo' not in server: + return False + + for sc_info in server['StorageControllerInfo']: + if sc_info['Vendor'] is not None: + if sc_filter[key].lower() in sc_info['Vendor'].lower(): + found = True + + if not found: + return False + + return True + + def sc_match(self, server, sc_filter): + for sc_info in server['StorageControllerInfo']: + sc_info['__show'] = True + if 'serial' in sc_filter: + if sc_info['Serial'] is None: + sc_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(sc_filter['serial']), sc_info['Serial']): + sc_info['__show'] = False + continue + + if 'vendor' in sc_filter: + if sc_info['Vendor'] is None: + sc_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(sc_filter['vendor']), sc_info['Vendor']): + sc_info['__show'] = False + continue + + return server + + def pd_filter_match(self, server, pd_filter): + for key in pd_filter: + if key == 'count': + if 'PhysicalDiskInfo' not in server: + return False + + if not self.int_filter_match(len(server['PhysicalDiskInfo']), pd_filter[key]): + return False + + if key == 'type': + found = False + if 'PhysicalDiskInfo' not in server: + return False + + for pd_info in server['PhysicalDiskInfo']: + if pd_info['Type'] is not None: + if pd_filter[key].lower() in pd_info['Type'].lower(): + found = True + + if not found: + return False + + if key == 'proto': + found = False + if 'PhysicalDiskInfo' not in server: + return False + + for pd_info in server['PhysicalDiskInfo']: + if pd_info['Protocol'] is not None: + if pd_filter[key].lower() in pd_info['Protocol'].lower(): + found = True + + if not found: + return False + + if key == 'pid': + found = False + if 'PhysicalDiskInfo' not in server: + return False + + for pd_info in server['PhysicalDiskInfo']: + if pd_info['Pid'] is not None: + if pd_filter[key].lower() in pd_info['Pid'].lower(): + found = True + + if not found: + return False + + if key == 'model': + found = False + if 'PhysicalDiskInfo' not in server: + return False + + for pd_info in server['PhysicalDiskInfo']: + if pd_info['Model'] is not None: + if pd_filter[key].lower() in pd_info['Model'].lower(): + found = True + + if not found: + return False + + if key == 'vendor': + found = False + if 'PhysicalDiskInfo' not in server: + return False + + for pd_info in server['PhysicalDiskInfo']: + if pd_info['Vendor'] is not None: + if pd_filter[key].lower() in pd_info['Vendor'].lower(): + found = True + + if not found: + return False + + if key == 'serial': + found = False + if 'PhysicalDiskInfo' not in server: + return False + + for pd_info in server['PhysicalDiskInfo']: + if pd_info['Serial'] is not None: + if pd_filter[key].lower() in pd_info['Serial'].lower(): + found = True + + if not found: + return False + + return True + + def pd_match(self, server, pd_filter): + for pd_info in server['PhysicalDiskInfo']: + pd_info['__show'] = True + if 'type' in pd_filter: + if pd_info['Type'] is None: + pd_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pd_filter['type']), pd_info['Type']): + pd_info['__show'] = False + continue + + if 'proto' in pd_filter: + if pd_info['Protocol'] is None: + pd_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pd_filter['proto']), pd_info['Protocol']): + pd_info['__show'] = False + continue + + if 'pid' in pd_filter: + if pd_info['Pid'] is None: + pd_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pd_filter['pid']), pd_info['Pid']): + pd_info['__show'] = False + continue + + if 'model' in pd_filter: + if pd_info['Model'] is None: + pd_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pd_filter['model']), pd_info['Model']): + pd_info['__show'] = False + continue + + if 'vendor' in pd_filter: + if pd_info['Vendor'] is None: + pd_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pd_filter['vendor']), pd_info['Vendor']): + pd_info['__show'] = False + continue + + if 'serial' in pd_filter: + if pd_info['Serial'] is None: + pd_info['__show'] = False + continue + + if not filter_helper.match_string(filter_helper.format_subtring_match(pd_filter['serial']), pd_info['Serial']): + pd_info['__show'] = False + continue + + return server + + def vd_filter_match(self, server, vd_filter): + for key in vd_filter: + if key == 'count': + if 'VirtualDisks' not in server: + return False + + if not self.int_filter_match(len(server['VirtualDisks']), vd_filter[key]): + return False + + return True + + def fan_filter_match(self, server, fan_filter): + for key in fan_filter: + if key == 'mod': + if 'FanModuleInfo' not in server: + return False + + count = 0 + for module_info in server['FanModuleInfo']: + if module_info['Presence'] == 'equipped': + count = count + 1 + + if not self.int_filter_match(count, fan_filter[key]): + return False + + if key == 'unit': + if 'FanInfo' not in server: + return False + + count = 0 + for fan_info in server['FanInfo']: + if fan_info['Presence'] == 'equipped': + count = count + 1 + + if not self.int_filter_match(count, fan_filter[key]): + return False + + if key == 'state': + if 'FanHealthy' not in server: + return False + + if fan_filter['state'] == 'ok' and not server['FanHealthy']: + return False + + if fan_filter['state'] == 'nok' and server['FanHealthy']: + return False + + return True + + def fan_match(self, server, fan_filter): + for fan_info in server['FanInfo']: + fan_info['__show'] = True + if 'state' in fan_filter: + if fan_filter['state'] == 'ok' and not fan_info['On']: + fan_info['__show'] = False + continue + + if fan_filter['state'] == 'nok' and fan_info['On']: + fan_info['__show'] = False + continue + + return server + + def psu_filter_match(self, server_info, psu_filter): + for key in psu_filter: + if key == 'state': + if 'PsuHealthy' not in server_info: + return False + + if psu_filter['state'] == 'ok' and not server_info['PsuHealthy']: + return False + + if psu_filter['state'] == 'nok' and server_info['PsuHealthy']: + return False + + if key == 'model': + found = False + if 'PsuInfo' not in server_info: + return False + + for psu_info in server_info['PsuInfo']: + if psu_info['Model'] is not None: + if psu_filter[key].lower() in psu_info['Model'].lower(): + found = True + + if not found: + return False + + if key == 'serial': + found = False + if 'PsuInfo' not in server_info: + return False + + for psu_info in server_info['PsuInfo']: + if psu_info['Serial'] is not None: + if psu_filter[key].lower() in psu_info['Serial'].lower(): + found = True + + if not found: + return False + + if key == 'vendor': + found = False + if 'PsuInfo' not in server_info: + return False + + for psu_info in server_info['PsuInfo']: + if psu_info['Vendor'] is not None: + if psu_filter[key].lower() in psu_info['Vendor'].lower(): + found = True + + if not found: + return False + + return True + + def psu_match(self, server, psu_filter): + for psu_info in server['PsuInfo']: + psu_info['__show'] = True + if 'state' in psu_filter: + if psu_filter['state'] == 'ok' and not psu_info['On']: + psu_info['__show'] = False + continue + + if psu_filter['state'] == 'nok' and psu_info['On']: + psu_info['__show'] = False + continue + + if 'model' in psu_filter: + if psu_info['Model'] is None: + psu_info['__show'] = False + continue + + if psu_info['Model'] is not None and psu_filter['model'].lower() not in psu_info['Model'].lower(): + psu_info['__show'] = False + continue + + if 'serial' in psu_filter: + if psu_info['Serial'] is None: + psu_info['__show'] = False + continue + + if psu_info['Serial'] is not None and psu_filter['serial'].lower() not in psu_info['Serial'].lower(): + psu_info['__show'] = False + continue + + if 'vendor' in psu_filter: + if psu_info['Vendor'] is None: + psu_info['__show'] = False + continue + + if psu_info['Vendor'] is not None and psu_filter['vendor'].lower() not in psu_info['Vendor'].lower(): + psu_info['__show'] = False + continue + + return server + + def match_server(self, server, rules, base_match=False, debug_logs=True): + if rules is None: + return server + + if 'ancestor' in rules: + if not self.ancestor_filter_match(server, rules['ancestor']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on ancestor %s' % ( + server['Moid'], + rules['ancestor'] + ) + ) + return None + + # If match is based on the base server attributes, exit early + if base_match: + return server + + if 'locator' in rules: + if not self.locator_filter_match(server, rules['locator']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on locator %s' % ( + server['Moid'], + rules['locator'] + ) + ) + return None + + if 'power' in rules: + if not self.power_filter_match(server, rules['power']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on power off %s' % ( + server['Moid'], + rules['power'] + ) + ) + return None + + if 'alarms' in rules: + if not self.alarms_filter_match(server, rules['alarms']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on alarms %s' % ( + server['Moid'], + rules['alarms'] + ) + ) + return None + + if 'ucsm' in rules: + if not self.ucsm_filter_match(server, rules['ucsm']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on ucsm %s' % ( + server['Moid'], + rules['ucsm'] + ) + ) + return None + + if 'disconnected' in rules: + if not self.disconnected_filter_match(server, rules['disconnected']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on disconnected %s' % ( + server['Moid'], + rules['disconnected'] + ) + ) + return None + + if 'imm' in rules: + if not self.imm_filter_match(server, rules['imm']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on imm %s' % ( + server['Moid'], + rules['imm'] + ) + ) + return None + + if 'cpu' in rules and rules['cpu']['enabled']: + if not self.cpu_filter_match(server, rules['cpu']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on cpu %s' % ( + server['Moid'], + rules['cpu'] + ) + ) + return None + + server = self.cpu_match(server, rules['cpu']) + + if 'gpu' in rules and rules['gpu']['enabled']: + if not self.gpu_filter_match(server, rules['gpu']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on gpu %s' % ( + server['Moid'], + rules['gpu'] + ) + ) + return None + + server = self.gpu_match(server, rules['gpu']) + + if 'memory' in rules and rules['memory']['enabled']: + if not self.memory_filter_match(server, rules['memory']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on memory %s' % ( + server['Moid'], + rules['memory'] + ) + ) + return None + + server = self.mem_match(server, rules['memory']) + + if 'pci' in rules and rules['pci']['enabled']: + pci_match = self.pci_filter_match(server, rules['pci']) + if not pci_match: + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on pci %s' % ( + server['Moid'], + rules['pci'] + ) + ) + return None + + server = self.pci_match(server, rules['pci']) + + if 'mac' in rules: + if not self.mac_filter_match(server, rules['mac']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on mac %s' % ( + server['Moid'], + rules['mac'] + ) + ) + return None + + server = self.mac_match(server, rules['mac']) + + if 'sc' in rules and rules['sc']['enabled']: + sc_match = self.sc_filter_match(server, rules['sc']) + if not sc_match: + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on storage controller %s' % ( + server['Moid'], + rules['sc'] + ) + ) + return None + + server = self.sc_match(server, rules['sc']) + + if 'pd' in rules and rules['pd']['enabled']: + pd_match = self.pd_filter_match(server, rules['pd']) + if not pd_match: + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on physical disk %s' % ( + server['Moid'], + rules['pd'] + ) + ) + return None + + server = self.pd_match(server, rules['pd']) + + if 'vd' in rules and rules['vd']['enabled']: + vd_match = self.vd_filter_match(server, rules['vd']) + if not vd_match: + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on virtual drive %s' % ( + server['Moid'], + rules['vd'] + ) + ) + return None + + if 'fan' in rules and rules['fan']['enabled']: + if not self.fan_filter_match(server, rules['fan']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on fan %s' % ( + server['Moid'], + rules['fan'] + ) + ) + return None + + server = self.fan_match(server, rules['fan']) + + if 'psu' in rules and rules['psu']['enabled']: + if not self.psu_filter_match(server, rules['psu']): + if debug_logs: + self.log_handler.debug( + 'compute_filter.match_server', + 'Server %s match fails on psu %s' % ( + server['Moid'], + rules['psu'] + ) + ) + return None + + server = self.psu_match(server, rules['psu']) + + return server + + def ip_filter_match_mo(self, server_mo, ip_filter): + if server_mo['ManagementIp'] is None: + return False + + for item in ip_filter: + if item['type'] == 'address': + if server_mo['ManagementIp'] == item['value']: + return True + + if item['type'] == 'subnet': + if ip_helper.is_ipv4_in_cidr(server_mo['ManagementIp'], item['value']): + return True + + return False + + def name_filter_match_mo(self, server_mo, name_rules, logical): + if logical == 'and': + names_match = True + + if logical == 'or': + names_match = False + + for name_rule in name_rules: + name_match = False + + if isinstance(name_rule, dict): + if not name_rule['negative']: + if filter_helper.match_string(name_rule['value'], server_mo['Name']): + name_match = True + + if name_rule['negative']: + name_found = False + if filter_helper.match_string(name_rule['value'], server_mo['Name']): + name_found = True + + name_match = not name_found + + if isinstance(name_rule, str): + if filter_helper.match_string(name_rule, server_mo['Name']): + name_match = True + + if logical == 'and': + names_match = names_match and name_match + + if logical == 'or': + names_match = names_match or name_match + + return names_match + + def model_filter_match_mo(self, server_mo, model_rules, logical): + if logical == 'and': + models_match = True + + if logical == 'or': + models_match = False + + for model_rule in model_rules: + model_match = False + + if isinstance(model_rule, dict): + if not model_rule['negative']: + if filter_helper.match_string(model_rule['value'], server_mo['Model']): + model_match = True + + if model_rule['negative']: + model_found = False + if filter_helper.match_string(model_rule['value'], server_mo['Model']): + model_found = True + + model_match = not model_found + + if isinstance(model_rule, str): + if filter_helper.match_string(model_rule, server_mo['Model']): + model_match = True + + if logical == 'and': + models_match = models_match and model_match + + if logical == 'or': + models_match = models_match or model_match + + return models_match + + def serial_filter_match_mo(self, server_mo, serial_rules, logical): + if logical == 'and': + serials_match = True + + if logical == 'or': + serials_match = False + + for serial_rule in serial_rules: + serial_match = False + + if isinstance(serial_rule, dict): + if not serial_rule['negative']: + if filter_helper.match_string(serial_rule['value'], server_mo['Serial']): + serial_match = True + + if serial_rule['negative']: + serial_found = False + if filter_helper.match_string(serial_rule['value'], server_mo['Serial']): + serial_found = True + + serial_match = not serial_found + + if isinstance(serial_rule, str): + if filter_helper.match_string(serial_rule, server_mo['Serial']): + serial_match = True + + if logical == 'and': + serials_match = serials_match and serial_match + + if logical == 'or': + serials_match = serials_match or serial_match + + return serials_match + + def tag_filter_match_mo(self, server_mo, tag_rules, logical): + if logical == 'and': + tags_match = True + + if logical == 'or': + tags_match = False + + for tag_rule in tag_rules: + tag_match = False + + if isinstance(tag_rule, dict): + if not tag_rule['negative']: + if tag_rule['key'] == '_count_': + if len(server_mo['Tags']) - 1 == int(tag_rule['value']): + tag_match = True + + if tag_rule['key'] != '_count_': + for tag_mo in server_mo['Tags']: + if tag_mo['Key'] == 'Intersight.LicenseTier': + continue + + if filter_helper.match_string(tag_rule['key'], tag_mo['Key']): + if filter_helper.match_string(tag_rule['value'], tag_mo['Value']): + tag_match = True + break + + if tag_rule['negative']: + tag_found = False + + for tag_mo in server_mo['Tags']: + if tag_mo['Key'] == 'Intersight.LicenseTier': + continue + + if filter_helper.match_string(tag_rule['key'], tag_mo['Key']): + if filter_helper.match_string(tag_rule['value'], tag_mo['Value']): + tag_found = True + break + + tag_match = not tag_found + + if isinstance(tag_rule, str): + if tag_rule.split(':')[0] == '_count_': + if len(server_mo['Tags']) - 1 == int(tag_rule.split(':')[1]): + tag_match = True + + if tag_rule.split(':')[0] != '_count_': + if tag_rule.split(':')[0].startswith('!'): + tag_found = False + for tag_mo in server_mo['Tags']: + if tag_mo['Key'] == 'Intersight.LicenseTier': + continue + + if filter_helper.match_string(tag_rule.split(':')[0][1:], tag_mo['Key']): + if filter_helper.match_string(tag_rule.split(':')[1], tag_mo['Value']): + tag_found = True + break + + tag_match = not tag_found + + if not tag_rule.split(':')[0].startswith('!'): + for tag_mo in server_mo['Tags']: + if tag_mo['Key'] == 'Intersight.LicenseTier': + continue + + if filter_helper.match_string(tag_rule.split(':')[0], tag_mo['Key']): + if filter_helper.match_string(tag_rule.split(':')[1], tag_mo['Value']): + tag_match = True + break + + if logical == 'and': + tags_match = tags_match and tag_match + + if logical == 'or': + tags_match = tags_match or tag_match + + return tags_match + + def match_server_mo(self, server_mo, match_rules): + if match_rules is None: + return True + + if 'ip' in match_rules and len(match_rules['ip']) > 0: + if not self.ip_filter_match_mo(server_mo, match_rules['ip']): + return False + + if 'name' in match_rules and len(match_rules['name']) > 0: + if not self.name_filter_match_mo(server_mo, match_rules['name'], match_rules['logical']['name']): + return False + + if 'model' in match_rules and len(match_rules['model']) > 0: + if not self.model_filter_match_mo(server_mo, match_rules['model'], match_rules['logical']['model']): + return False + + if 'serial' in match_rules and len(match_rules['serial']) > 0: + if not self.serial_filter_match_mo(server_mo, match_rules['serial'], match_rules['logical']['serial']): + return False + + if 'tag' in match_rules and len(match_rules['tag']) > 0: + if not self.tag_filter_match_mo(server_mo, match_rules['tag'], match_rules['logical']['tag']): + return False + + return True + + def get_mo_match_rules(self, ip_filter=None, name_filter=None, serial_filter=None, model_filter=None, tag_filter=None): + match_rules = {} + match_rules['logical'] = {} + + for key in ['ip', 'name', 'serial', 'model', 'tag']: + match_rules[key] = [] + match_rules['logical'][key] = 'or' + + if ip_filter is not None and len(ip_filter) > 0: + for ip_filter_entry in ip_filter: + if ip_helper.is_valid_ipv4_address(ip_filter_entry): + match_rules['ip'].append( + dict( + type='address', + value=ip_filter_entry + ) + ) + continue + + if ip_helper.is_valid_ipv4_cidr(ip_filter_entry): + match_rules['ip'].append( + dict( + type='subnet', + value=ip_filter_entry + ) + ) + continue + + if len(ip_filter_entry.split('-')) == 2: + (start_adress, end_address) = ip_filter_entry.split('-') + if len(end_address.split('.')) == 1: + end_address = '%s.%s' % ( + '.'.join(start_adress.split('.')[:3]), + end_address + ) + + ip_addresses = ip_helper.get_ipv4_addresses_in_range( + start_adress, + end_address + ) + for ip_address in ip_addresses: + match_rules['ip'].append( + dict( + type='address', + value=ip_address + ) + ) + + continue + + ip_address = ip_helper.get_ip(ip_filter_entry) + if ip_address is not None: + match_rules['ip'].append( + dict( + type='address', + value=ip_address + ) + ) + continue + + self.log_handler.error( + 'get_mo_match_rules', + 'Invalid ip entry: %s' % (ip_filter_entry) + ) + + if name_filter is not None: + if isinstance(name_filter, dict): + match_rules['logical']['name'] = name_filter['logical'] + for item in name_filter['rule']: + match_rules['name'].append(item) + + if isinstance(name_filter, list): + for item in name_filter: + match_rules['name'].append(item) + + if serial_filter is not None: + if isinstance(serial_filter, dict): + match_rules['logical']['serial'] = serial_filter['logical'] + for item in serial_filter['rule']: + match_rules['serial'].append(item) + + if isinstance(serial_filter, list): + for item in serial_filter: + match_rules['serial'].append(item) + + if model_filter is not None: + if isinstance(model_filter, dict): + match_rules['logical']['model'] = model_filter['logical'] + for item in model_filter['rule']: + match_rules['model'].append(item) + + if isinstance(model_filter, list): + for item in model_filter: + match_rules['model'].append(item) + + if tag_filter is not None: + if isinstance(tag_filter, dict): + match_rules['logical']['tag'] = tag_filter['logical'] + for item in tag_filter['rule']: + match_rules['tag'].append(item) + + if isinstance(tag_filter, list): + for item in tag_filter: + match_rules['tag'].append(item) + + return match_rules diff --git a/lib/intersight/compute_info.py b/lib/intersight/compute_info.py new file mode 100644 index 00000000..b6a75659 --- /dev/null +++ b/lib/intersight/compute_info.py @@ -0,0 +1,177 @@ +import time + +import concurrent.futures +from concurrent.futures import ProcessPoolExecutor + +from lib.intersight.compute_cache import ComputeCache +from lib.intersight.compute_filter import ComputeFilter +from lib.intersight.computes_worfklow import ComputesWorkflow + +from lib.intersight import compute_extra_attributes + + +class ComputeInfo(ComputeCache, ComputeFilter, ComputesWorkflow): + """Class for intersight compute blade and rack objects + """ + def __init__(self): + ComputeCache.__init__(self) + ComputeFilter.__init__(self) + ComputesWorkflow.__init__(self) + + def get_server_info(self, server_mo, settings, log_id=None): + server_info_handler = compute_extra_attributes.ComputeExtraAttributes( + self.iaccount, + log_id=log_id + ) + server_info = server_info_handler.get_server_info( + server_mo, + settings + ) + return server_info + + def get_threaded(self, servers_mo, settings): + start_time = int(time.time() * 1000) + servers_info = [] + + self.log_handler.debug( + 'computes_info.get_threaded', + 'Start %s threads' % (len(servers_mo)) + ) + + with ProcessPoolExecutor() as executor: + pool = [executor.submit(self.get_server_info, server_mo, settings, log_id=self.log_id) for server_mo in servers_mo] + result = concurrent.futures.wait( + pool, + timeout=120, + return_when=concurrent.futures.ALL_COMPLETED + ) + executor.shutdown( + wait=False, + cancel_futures=True + ) + + self.log_handler.debug( + 'computes_info.get', + 'Completed: %s/%s/%s' % ( + len(result[0]), + len(result[1]), + len(servers_mo) + ) + ) + + for server_mo in servers_mo: + server_info = self.log_handler.get_log( + 'server_info.%s' % (server_mo['Moid']), + json_conversion=True + ) + + if server_info is None: + self.log_handler.error( + 'computes_info.get_server_info', + 'No server info: %s' % (server_mo['Moid']) + ) + continue + + servers_info.append( + server_info + ) + + duration = int(time.time() * 1000) - start_time + self.log_handler.debug( + 'computes_info.get_threaded', + 'Finished: %s ms' % (duration) + ) + + return servers_info + + def get_sequential(self, servers_mo, settings, bar_handler=None): + start_time = int(time.time() * 1000) + servers_info = [] + + self.log_handler.debug( + 'compute_info.get_sequential', + 'Start' + ) + + for server_mo in servers_mo: + server_start_time = int(time.time() * 1000) + server_info = self.get_server_info( + server_mo, + settings, + log_id=self.log_id + ) + if server_info is None: + self.log_handler.error( + 'compute_info.get_sequential', + 'No server info: %s' % (server_mo['Moid']) + ) + continue + + servers_info.append(server_info) + + duration = int(time.time() * 1000) - server_start_time + self.log_handler.debug( + 'computes_info.get_sequential', + 'Server %s: %s ms' % ( + server_mo['Serial'], + duration + ) + ) + + if bar_handler is not None: + bar_handler.next() + + duration = int(time.time() * 1000) - start_time + self.log_handler.debug( + 'computes_info.get_sequential', + 'Finished: %s ms' % (duration) + ) + + return servers_info + + def get_info(self, servers_mo, settings, match_rules, cache_ttl, prepare_cache=True, parallel=False, bar_handler=None): + if prepare_cache: + self.set_cache(servers_mo, settings, cache_ttl) + + start_time = int(time.time() * 1000) + + if parallel: + all_servers_info = self.get_threaded( + servers_mo, + settings + ) + + if not parallel: + all_servers_info = self.get_sequential( + servers_mo, + settings, + bar_handler=bar_handler + ) + + self.log_handler.debug( + 'compute_info.get_info', + 'Match rules: %s' % (match_rules) + ) + + servers_info = [] + for server_info in all_servers_info: + matching_server_info = self.match_server(server_info, match_rules) + if matching_server_info is not None: + servers_info.append( + matching_server_info + ) + + servers_info = sorted( + servers_info, + key=lambda i: i['Name'].lower() + ) + + end_time = int(time.time() * 1000) + duration = end_time - start_time + + self.log_handler.debug( + 'compute_info.get_info', + 'Selected %s/%s/%s servers in %s ms' % (len(servers_info), len(all_servers_info), len(servers_mo), duration) + ) + + return servers_info diff --git a/lib/intersight/compute_mo.py b/lib/intersight/compute_mo.py new file mode 100644 index 00000000..7de38f1f --- /dev/null +++ b/lib/intersight/compute_mo.py @@ -0,0 +1,71 @@ +class ComputeMo(): + def __init__(self): + pass + + def get_management_ip(self, server_mo): + if 'KvmIpAddresses' in server_mo: + for kvm_ip in server_mo['KvmIpAddresses']: + if kvm_ip['ClassId'] == 'compute.IpAddress': + return kvm_ip['Address'] + return None + + def get(self, server_id, settings={}): + server_mo = self.rack_handler.get(server_id) + if server_mo is None: + server_mo = self.blade_handler.get(server_id) + + if server_mo is None: + return None + + return self.get_server_info(server_mo, settings, log_id=self.log_id) + + def get_mo(self, match_rules=None, include_rack=False, rack_expand=None, include_blade=False, blade_expand=None, cache_ttl=None): + servers_mo = [] + + if include_rack: + rack_servers = None + if rack_expand is None and cache_ttl is not None: + rack_servers = self.cache_handler.get_intersight_cache_entry( + 'inventory.rack.%s' % (self.iaccount), + cache_ttl=cache_ttl + ) + + if rack_servers is None: + if rack_expand is not None and len(rack_expand) > 0: + self.rack_handler.set_get_expand(','.join(rack_expand)) + rack_servers = self.rack_handler.get_all() + self.cache_handler.set_intersight_cache_entry( + 'inventory.rack.%s' % (self.iaccount), + rack_servers + ) + + if rack_servers is not None: + servers_mo = servers_mo + rack_servers + + if include_blade: + blade_servers = None + if blade_expand is None and cache_ttl is not None: + blade_servers = self.cache_handler.get_intersight_cache_entry( + 'inventory.blade.%s' % (self.iaccount), + cache_ttl=cache_ttl + ) + + if blade_servers is None: + if blade_expand is not None and len(blade_expand) > 0: + self.blade_handler.set_get_expand(','.join(blade_expand)) + blade_servers = self.blade_handler.get_all() + self.cache_handler.set_intersight_cache_entry( + 'inventory.blade.%s' % (self.iaccount), + blade_servers + ) + + if blade_servers is not None: + servers_mo = servers_mo + blade_servers + + selected_servers_mo = [] + for server_mo in servers_mo: + server_mo['ManagementIp'] = self.get_management_ip(server_mo) + if self.match_server_mo(server_mo, match_rules): + selected_servers_mo.append(server_mo) + + return selected_servers_mo diff --git a/lib/intersight/compute_nx_output.py b/lib/intersight/compute_nx_output.py new file mode 100644 index 00000000..b59f3046 --- /dev/null +++ b/lib/intersight/compute_nx_output.py @@ -0,0 +1,329 @@ +class ComputeNxOutput(): + def __init__(self, log_id=None): + pass + + def print_nx(self, server, title=False): + self.print_nx_summary(server, title=title) + self.print_nx_mac(server, title=title) + self.print_nx_lacp(server, title=title) + self.print_nx_lldp(server, title=title) + + def print_nx_summary(self, server, title=False): + if title: + self.my_output.default( + 'Interface - Nexus Summary [#%s]' % (len(server['MacAddressInfo'])), + underline=True, + before_newline=True + ) + + if len(server['MacAddressInfo']) == 0: + self.my_output.default('None') + return + + for item in server['MacAddressInfo']: + item['__Output'] = {} + in_nx = False + if item['mac'] is not None: + in_nx = True + item['macTick'] = '\u2713' + item['__Output']['macTick'] = 'Green' + else: + item['macTick'] = '\u2717' + item['__Output']['macTick'] = 'Red' + + if item['interface'] is not None: + in_nx = True + item['lacpTick'] = '\u2713' + item['__Output']['lacpTick'] = 'Green' + else: + item['lacpTick'] = '\u2717' + item['__Output']['lacpTick'] = 'Red' + + if item['adjacency'] is not None: + in_nx = True + item['lldpTick'] = '\u2713' + item['__Output']['lldpTick'] = 'Green' + else: + item['lldpTick'] = '\u2717' + item['__Output']['lldpTick'] = 'Red' + + if in_nx: + item['nxTick'] = '\u2713' + item['__Output']['nxTick'] = 'Green' + else: + item['nxTick'] = '\u2717' + item['__Output']['nxTick'] = 'Red' + + server['MacAddressInfo'] = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'nxTick', + 'macTick', + 'lacpTick', + 'lldpTick', + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'Nexus', + 'MAC', + 'LACP', + 'LLDP' + ] + + self.my_output.my_table( + server['MacAddressInfo'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_nx_mac(self, server, skip_empty=True, title=False): + macs = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + info = [] + + for item in macs: + if item['mac'] is None: + if skip_empty: + continue + item['mac'] = {} + item['mac']['nexus_name'] = '--' + item['mac']['vlan'] = '--' + item['mac']['mac_addr'] = '--' + item['mac']['type'] = '--' + item['mac']['age'] = '--' + item['mac']['is_secure'] = '--' + item['mac']['is_ntfy'] = '--' + item['mac']['port'] = '--' + + info.append( + item + ) + + if len(info) == 0: + return + + if title: + self.my_output.default( + 'MAC Address Table [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'mac.nexus_name', + 'mac.vlan', + 'mac.mac_addr', + 'mac.type', + 'mac.age', + 'mac.is_secure', + 'mac.is_ntfy', + 'mac.port' + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'Device', + 'VLAN', + 'MAC', + 'Type', + 'Age', + 'Sec', + 'Ntfy', + 'Port' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_nx_lacp(self, server, skip_empty=True, title=False): + macs = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + info = [] + for mac in macs: + if mac['interface'] is None or len(mac['interface']) == 0: + if skip_empty: + continue + + mac['interface'] = {} + mac['interface']['nexus_name'] = '--' + mac['interface']['interface'] = '--' + mac['port'] = [] + port_info = {} + port_info['port'] = '--' + port_info['partner_mac'] = '--' + port_info['partner_port_num'] = '--' + port_info['partner_port_state'] = '--' + mac['port'].append(port_info) + else: + if 'port' not in mac: + mac['port'] = [] + + for interface_info in mac['interface']: + for port_info in interface_info['port']: + mac['port'].append( + port_info + ) + + info.append( + mac + ) + + if len(info) == 0: + return + + if title: + self.my_output.default( + 'LACP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'interface.nexus_name', + 'interface.interface', + 'port.port', + 'port.partner_mac', + 'port.partner_port_num', + 'port.partner_port_state' + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'Device', + 'Interface', + 'Port', + 'Partner MAC', + 'Partner Port', + 'Partner State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['port'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_nx_lldp(self, server, skip_empty=True, title=False): + macs = sorted( + server['MacAddressInfo'], + key=lambda i: ( + i['AdapterModel'], + i['InterfaceName'], + ) + ) + + info = [] + for mac in macs: + if mac['adjacency'] is None: + if skip_empty: + continue + mac['adjacency'] = {} + mac['adjacency']['nexus_name'] = '--' + mac['adjacency']['l_port_id'] = '--' + mac['adjacency']['chassis_id'] = '--' + mac['adjacency']['port_id'] = '--' + + info.append( + mac + ) + + if len(info) == 0: + return + + if title: + self.my_output.default( + 'LLDP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot', + 'adjacency.nexus_name', + 'adjacency.l_port_id', + 'adjacency.chassis_id', + 'adjacency.port_id', + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot', + 'Device', + 'Interface', + 'Nbr Device ID', + 'Nbr Port ID' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) diff --git a/lib/intersight/compute_output.py b/lib/intersight/compute_output.py new file mode 100644 index 00000000..55759600 --- /dev/null +++ b/lib/intersight/compute_output.py @@ -0,0 +1,2790 @@ +import csv + +from lib import filter_helper +from lib import output_helper + +from lib.intersight.compute_aci_output import ComputeAciOutput +from lib.intersight.cond_alarm.output import ComputeCondAlarmOutput +from lib.intersight.compute_nx_output import ComputeNxOutput +from lib.intersight.equipment_psu.output import ComputePsuOutput +from lib.intersight.tam_advisory_instance.output import TamAdvisoryInstanceOutput + + +class ComputeOutput( + ComputeAciOutput, + ComputeCondAlarmOutput, + ComputeNxOutput, + ComputePsuOutput, + TamAdvisoryInstanceOutput + ): + def __init__(self, log_id=None): + self.my_output = output_helper.OutputHelper(log_id=log_id) + ComputeAciOutput.__init__(self) + ComputeCondAlarmOutput.__init__(self) + ComputeNxOutput.__init__(self) + ComputePsuOutput.__init__(self) + TamAdvisoryInstanceOutput.__init__(self) + + def print_summary_table(self, servers, legend_on=False, title=False): + if title: + self.my_output.default( + 'Server Summary [#%s]' % (len(servers)), + underline=True, + before_newline=True + ) + + if len(servers) == 0: + self.my_output.default('None') + return + + order = [] + headers = [] + + if servers[0]['StateEnabled']: + order = order + [ + 'FlagState', + 'FlagManagement' + ] + + headers = headers + [ + 'SF', + 'MF' + ] + + if 'Workflow' in servers[0]: + order = order + [ + 'FlagWorkflow' + ] + + headers = headers + [ + 'WF (%sd)' % (servers[0]['Workflow']['Days']) + ] + + for server in servers: + if 'Workflow' in server: + if len(server['FlagWorkflow']) == 0: + server['FlagWorkflow'] = '--' + + row_separator = False + for server in servers: + server['TagT'] = [] + for item in server['Tags']: + server['TagT'].append( + '%s:%s' % ( + item['Key'], + item['Value'] + ) + ) + + if len(server['TagT']) > 1: + row_separator = True + + if len(server['TagT']) == 0: + server['TagT'].append('--') + + order = order + [ + 'Name', + 'Moid', + 'TagT', + 'TypeModel', + 'Serial', + 'ManagementIp', + 'Cpu', + 'TotalMemoryUnit' + ] + + headers = headers + [ + 'Name', + 'Moid', + 'Tag', + 'Model', + 'Serial', + 'IP', + 'CPU', + 'Memory' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + servers, + order, + ['TagT'] + ), + order=order, + headers=headers, + row_separator=row_separator, + table=True + ) + + if legend_on: + self.print_flags_legend() + + def print_flags_legend(self): + legend = {} + legend['power'] = '(P+) on (P-) off' + legend['health'] = '(H)ealthy (W)arning (C)ritical' + legend['locator'] = '(L)ocator on' + + self.my_output.dictionary( + legend, + title='State Flags (SF)', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'power', + 'health', + 'locator' + ], + title_keys=[ + 'Power', + 'Health', + 'Locator' + ] + ) + + legend = {} + legend['connected'] = '(C) connected (c) disconnected' + legend['ucsm'] = '(U)csm ready (u)csm capable' + legend['redfish'] = '(R)edfish ready (r)edfish capable' + legend['imc'] = '(I)mc ready (i)imc capable' + + self.my_output.dictionary( + legend, + title='Management Flags (MF)', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'connected', + 'ucsm', + 'redfish', + 'imc' + ], + title_keys=[ + 'Intersight API', + 'UCSM API', + 'Redfish API', + 'IMC API' + ] + ) + + legend = {} + legend['running'] = '(R)' + legend['last'] = '(F)' + legend['some'] = '(f)' + + self.my_output.dictionary( + legend, + title='Workflow Flags (SF)', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'running', + 'last', + 'some' + ], + title_keys=[ + 'Running', + 'Last Failed', + 'Failed' + ] + ) + + def print_summary_dictionary(self, server): + self.my_output.dictionary( + server, + title='Identity', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'Moid', + 'Name', + 'Type', + 'Model', + 'Serial', + 'ManagementIp' + ], + title_keys=[ + 'Server ID', + 'Name', + 'Type', + 'Model', + 'Serial', + 'IP' + ] + ) + + if server['Redfish']['Capable']: + self.my_output.dictionary( + server['Redfish'], + title='Redfish', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'Capable', + 'Enabled' + ], + title_keys=[ + 'Capable', + 'Enabled' + ] + ) + + self.my_output.dictionary( + server, + title='State', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'OperPowerState', + 'LocatorLedOn', + 'Health', + 'ManagementMode', + 'Connected', + 'FirmwareVersion', + 'PsuSummary', + 'FanSummary' + ], + title_keys=[ + 'Power', + 'Locator', + 'Health', + 'Mode', + 'Connected', + 'Firmware', + 'PSU', + 'Fan' + ] + ) + + self.my_output.dictionary( + server, + title='CPU and Memory', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'NumCpus', + 'NumThreads', + 'NumCpuCores', + 'NumCpuCoresEnabled', + 'TotalMemoryUnit' + ], + title_keys=[ + 'CPU Sockets', + 'Threads', + 'Cores', + 'Enabled Cores', + 'Memory' + ] + ) + + keys = [ + 'StorageControllerCount', + 'PhysicalDiskCount', + 'PhysicalDiskCapacityUnit', + 'VirtualDiskCount' + ] + + match = False + for key in keys: + if key in server: + match = True + break + + if match: + self.my_output.dictionary( + server, + title='Storage', + underline=False, + prefix="- ", + justify=True, + keys=keys, + title_keys=[ + 'Controllers', + 'Disks count', + 'Disks capacity', + 'Virtual Disks' + ] + ) + + def print_board(self, servers, title=False): + info = [] + for server in servers: + if 'BoardInfo' in server: + item = server['BoardInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Motherboard Hardware Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'BoardId', + 'Vendor', + 'ProcessorsCount', + 'MemoryArraysCount', + 'PciSwitchCount', + 'PciCoprocessorCardsCount', + 'GraphicsCardsCount', + 'StorageControllersCount', + 'StorageFlexFlashControllersCount', + 'StorageFlexUtilControllersCount', + 'SecurityUnitsCount', + 'EquipmentTpmsCount' + ] + + headers = [ + 'Server', + 'Board Id', + 'Vendor', + 'CPU', + 'MemArr', + 'PCI Switch', + 'PCI Cooprocessor', + 'Graphics', + 'Storage Ctrl', + 'FlexFlash Ctrl', + 'FlexUtil Ctrl', + 'Sec', + 'TPM' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_boot(self, servers, title=False): + info = [] + for server in servers: + if 'BootInfo' in server: + item = server['BootInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Boot [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'ConfiguredBootMode', + 'ActualBootMode', + 'SecureBoot', + 'Order.Order', + 'Order.Name', + 'Order.Type', + 'Order.State' + ] + + headers = [ + 'Server', + 'Configured Boot Mode', + 'Actual Boot Mode', + 'Secure Boot', + 'Order', + 'Name', + 'Type', + 'State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Order'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_chassis(self, server): + if 'ChassisInfo' not in server: + return + + keys = [ + 'Name', + 'Model', + 'Serial', + 'Blades', + 'Health' + ] + + headers = [ + 'Name', + 'Model', + 'Serial', + 'Blades', + 'Health' + ] + + self.my_output.dictionary( + server['ChassisInfo'], + title='Chassis', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_connector(self, servers, title=False): + info = [] + for server in servers: + if 'ConnectorInfo' in server: + item = server['ConnectorInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Connector [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'ConnectionStatus', + 'ConnectorVersion', + 'ClaimedByUserName', + 'ClaimedTime', + 'ConnectionStatusLastChangeTime', + 'PlatformType', + 'DeviceExternalIpAddress' + ] + + headers = [ + 'Server', + 'Connection Status', + 'Connector Version', + 'Claimed By', + 'Claimed Time', + 'Connection Status Last Update', + 'Platform Type', + 'Device External IP Address' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_contract(self, servers, title=False): + info = [] + for server in servers: + if 'ContractInfo' in server: + item = server['ContractInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Contract [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'ContractStatus', + 'ContractNumber', + 'ServiceStartDate', + 'ServiceEndDate', + 'ContractUpdatedTime', + 'ServiceDescription', + 'ServiceLevel', + 'ServiceSku', + 'PurchaseOrderNumber', + 'SalesOrderNumber' + ] + + headers = [ + 'Server', + 'Contract Status', + 'Contract Number', + 'Start Date', + 'End Date', + 'Last Updated', + 'Service Description', + 'Service Level', + 'Service Sku', + 'Purchase Order Number', + 'Sales Order Number' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_cpu(self, servers, title=False): + info = [] + for server in servers: + if 'CpuInfo' in server: + for item in server['CpuInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'CPU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'StateTick', + 'ProcessorId', + 'SocketDesignation', + 'Vendor', + 'Architecture', + 'Model', + 'NumCores', + 'NumCoresEnabled', + 'NumThreads', + 'Speed', + 'Stepping', + 'Presence', + 'OperState', + 'Thermal' + ] + + headers = [ + 'Server', + 'State', + 'CPU Id', + 'Socket', + 'Vendor', + 'Arch', + 'Model', + 'Cores', + 'Enabled', + 'Threads', + 'Speed [GHz]', + 'Stepping', + 'Presence', + 'OperState', + 'Thermal' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_fan_module(self, servers, title=False): + info = [] + for server in servers: + if 'FanModuleInfo' in server: + for item in server['FanModuleInfo']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Fan Module [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'StateTick', + 'Name', + 'OperState', + 'Presence' + ] + + headers = [ + 'Server', + 'State', + 'Fan Module', + 'OperState', + 'Presence' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_fan(self, servers, title=False): + info = [] + for server in servers: + if 'FanInfo' in server: + for item in server['FanInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Fan [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'StateTick', + 'Name', + 'OperState', + 'Presence' + ] + + headers = [ + 'Server', + 'State', + 'Fan', + 'OperState', + 'Presence', + 'Dn' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_firmware(self, servers, title=False): + info = [] + for server in servers: + if 'FirmwarewComponents' in server: + for item in server['FirmwarewComponents']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Firmware [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'Component', + 'Type', + 'PackageVersion', + 'Version', + 'Dn' + ] + + headers = [ + 'Server', + 'Name', + 'Component', + 'Type', + 'PackageVersion', + 'Version', + 'Dn' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_gpu(self, servers, title=False): + info = [] + for server in servers: + if 'GpuInfo' in server: + for item in server['GpuInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'GPU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Model', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'FirmwareVersion' + ] + + headers = [ + 'Server', + 'GPU Device Model', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'Firmware' + ] + + for item in info: + for key in order: + if key not in item: + item[key] = None + + if item[key] is None or len(item[key]) == 0: + item[key] = '--' + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_hcl_summary(self, servers, title=False): + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'HCL Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Status' + ] + + headers = [ + 'Server', + 'Overall' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_hcl_hardware(self, servers, title=False): + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'HCL Server Hardware Compliance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'HardwareStatus', + 'HclModel', + 'HclProcessor', + 'HclFirmwareVersion' + ] + + headers = [ + 'Server', + 'Status', + 'Model', + 'CPU', + 'Firmware' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_hcl_software(self, servers, title=False): + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'HCL Server Software Compliance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'SoftwareStatus', + 'Reason', + 'HclOsVendor', + 'HclOsVersion' + ] + + headers = [ + 'Server', + 'Status', + 'Reason', + 'OS Vendor', + 'OS Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_hcl_component(self, servers, title=False): + info = [] + for server in servers: + if 'HclInfo' in server: + item = server['HclInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'HCL Server Adapter Compliance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'ComponentStatus', + 'Details.Status', + 'Details.HardwareStatus', + 'Details.SoftwareStatus', + 'Details.Reason', + 'Details.HclModel', + 'Details.HclCimcVersion', + 'Details.HclDriverName', + 'Details.HclDriverVersion', + 'Details.HclFirmwareVersion' + ] + + headers = [ + 'Server', + 'Status', + 'Component', + 'Hardware', + 'Software', + 'Reason', + 'Model', + 'Cimc Version', + 'Driver Name', + 'Driver Version', + 'Firmware Version' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Details'] + ), + order=order, + headers=headers, + underline=True, + table=True, + allow_order_subkeys=True, + row_separator=True + ) + + # order = [ + # 'Status', + # 'HardwareStatus', + # 'SoftwareStatus', + # 'Reason', + # 'HclModel', + # 'HclCimcVersion', + # 'HclDriverName', + # 'HclDriverVersion', + # 'HclFirmwareVersion' + # ] + + # headers = [ + # 'Status', + # 'Hardware', + # 'Software', + # 'Reason', + # 'Model', + # 'Cimc Version', + # 'Driver Name', + # 'Driver Version', + # 'Firmware Version' + # ] + + # self.my_output.my_table( + # server['HclInfo']['Details'], + # order=order, + # headers=headers, + # underline=True, + # table=True + # ) + + def print_hcl(self, servers, title=True): + self.print_hcl_summary(servers, title=title) + self.print_hcl_hardware(servers, title=title) + self.print_hcl_software(servers, title=title) + self.print_hcl_component(servers, title=title) + + def print_memory(self, servers, title=False): + info = [] + for server in servers: + if 'MemoryInfo' in server: + for item in server['MemoryInfo']: + if '__show' in item and not item['__show']: + continue + + if item['Presence'] == 'equipped': + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Memory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'OperState', + 'Presence', + 'MemoryId', + 'ArrayId', + 'Bank', + 'Location', + 'CapacityUnit', + 'Clock', + 'FormFactor', + 'Type', + 'Model', + 'Serial' + ] + + headers = [ + 'Server', + 'Oper', + 'Presence', + 'Id', + 'Array', + 'Bank', + 'Location', + 'Capacity', + 'Clock', + 'Form Factor', + 'Type', + 'Model', + 'Serial' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_cimc(self, servers, title=False): + info = [] + for server in servers: + if 'CimcInfo' in server: + for item in server['CimcInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'IMC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'IpAddress', + 'Mask', + 'Gateway', + 'MacAddress' + ] + + headers = [ + 'Server', + 'IP', + 'Mask', + 'Gateway', + 'MAC' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_adapters(self, servers, title=False): + info = [] + for server in servers: + if 'AdaptersInfo' in server: + for item in server['AdaptersInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Network Adapters [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + for key in ['Pid']: + if key not in item: + item[key] = None + if item[key] is None or len(item[key]) == 0: + item[key] = '--' + + order = [ + 'ServerName', + 'Name', + 'PciSlot', + 'Model', + 'Pid', + 'Serial', + 'Vendor', + 'HostEthIfsCount', + 'HostFcIfsCount', + 'ExtEthIfsCount' + ] + + headers = [ + 'Server', + 'Name', + 'PciSlot', + 'Model', + 'PID', + 'Serial', + 'Vendor', + 'Eth', + 'HBA', + 'DCE' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_ext_eth(self, servers, title=False): + info = [] + for server in servers: + if 'ExtEthInfo' in server: + for item in server['ExtEthInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'External Ethernet (MLOM) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'AdapterModel', + 'InterfaceId', + 'MacAddress' + ] + + headers = [ + 'Server', + 'Adapter Model', + 'Interface ID', + 'MAC Address' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_host_eth(self, servers, title=False): + info = [] + for server in servers: + if 'HostEthInfo' in server: + for item in server['HostEthInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Host Ethernet [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'AdapterName', + 'AdapterModel', + 'Name', + 'MacAddress' + ] + + headers = [ + 'Server', + 'Adapter Name', + 'Adapter Model', + 'Interface Name', + 'MAC Address' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_host_fc(self, servers, title=False): + info = [] + for server in servers: + if 'HostFcInfo' in server: + for item in server['HostFcInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Host FC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'AdapterName', + 'AdapterModel', + 'Name', + 'Wwnn', + 'Wwpn' + ] + + headers = [ + 'Server', + 'Adapter Name', + 'Adapter Model', + 'Interface Name', + 'WWNN', + 'WWPN' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_kvm(self, servers, title=False): + info = [] + for server in servers: + if 'KvmInfo' in server: + item = server['KvmInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'KVM [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'KvmServerStateEnabled', + 'KvmVendor', + 'TunneledKvm', + 'KvmIpAddresses.Name', + 'KvmIpAddresses.Address', + 'KvmIpAddresses.Subnet', + 'KvmIpAddresses.DefaultGateway', + 'KvmIpAddresses.HttpPort', + 'KvmIpAddresses.HttpsPort', + 'KvmIpAddresses.KvmPort', + 'KvmIpAddresses.KvmVlan' + ] + + headers = [ + 'Server', + 'Kvm Server Enabled', + 'Kvm Vendor', + 'Tunneled Kvm', + 'Address Name', + 'Address', + 'Subnet', + 'Gateway', + 'Http Port', + 'Https Port', + 'Kvm Port', + 'Kvm Vlan' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['KvmIpAddresses'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_license(self, servers, title=False): + if title: + self.my_output.default( + 'License [#%s]' % (len(servers)), + underline=True, + before_newline=True + ) + + if len(servers) == 0: + self.my_output.default('None') + return + + order = [ + 'Name', + 'LicenseInfo.Tier' + ] + + headers = [ + 'Server', + 'License' + ] + + self.my_output.my_table( + servers, + order=order, + headers=headers, + table=True, + allow_order_subkeys=True + ) + + def print_net(self, servers, title=False): + self.print_adapters(servers, title=title) + self.print_ext_eth(servers, title=title) + self.print_host_eth(servers, title=title) + self.print_host_fc(servers, title=title) + + def print_mac(self, server, title=False): + if 'MacAddressInfo' not in server: + return + + if title: + self.my_output.default( + 'MAC Address [#%s]' % (len(server['MacAddressInfo'])), + underline=True, + before_newline=True + ) + + if len(server['MacAddressInfo']) == 0: + self.my_output.default('None') + return + + macs = sorted( + server['MacAddressInfo'], + key=lambda i: i['MacAddress'] + ) + + order = [ + 'MacAddress', + 'InterfaceName', + 'AdapterModel', + 'AdapterPciSlot' + ] + + headers = [ + 'MAC Address', + 'Interface', + 'Adapter', + 'Pci Slot' + ] + + if len(macs) > 0 and 'Fabric' in macs[0]: + order = order + [ + 'Fabric.Type', + 'Fabric.Controller', + 'Fabric.Node', + 'Fabric.Port', + 'Fabric.Source' + ] + + headers = headers + [ + 'Fabric Type', + 'Controller', + 'Node', + 'Port', + 'Source' + ] + + self.my_output.my_table( + macs, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + else: + self.my_output.my_table( + macs, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_pci(self, servers, title=False): + info = [] + for server in servers: + if 'PciDevicesInfo' in server: + for item in server['PciDevicesInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'PCI [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + item['ModelT'] = filter_helper.get_string_chunks( + item['Model'], + 40 + ) + + order = [ + 'ServerName', + 'ModelT', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'FirmwareVersion' + ] + + headers = [ + 'Server', + 'PCI Device Model', + 'Pid', + 'Serial', + 'SlotId', + 'Vendor', + 'Firmware' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ModelT'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + row_separator=True, + underline=True, + table=True + ) + + def print_pci_node(self, servers, title=False): + info = [] + for server in servers: + if 'PciNodesInfo' in server: + for item in server['PciNodesInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'PCI Node [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'SlotId', + 'Model', + 'Serial', + 'GpuInfo.ControllerId', + 'GpuInfo.Model', + 'GpuInfo.Serial', + 'GpuInfo.Vendor' + ] + + headers = [ + 'Server', + 'Slot', + 'Model', + 'Serial', + 'GPU - Id', + 'GPU - Model', + 'GPU - Serial', + 'GPU - Vendor' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['GpuInfo'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_power_consumption(self, servers, title=False): + info = [] + for server in servers: + if 'Power' in server and server['Power'] is not None: + item = server['Power']['Data']['PowerControl'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Power Consumption [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'PowerConsumedWatts', + 'MinConsumedWatts', + 'AverageConsumedWatts', + 'MaxConsumedWatts', + 'LimitException' + ] + + headers = [ + 'Server', + 'Current', + 'Min', + 'Average', + 'Max', + 'Limit action' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True + ) + + def print_power_voltage(self, servers, title=False): + info = [] + for server in servers: + if 'Power' in server and server['Power'] is not None: + for item in server['Power']['Data']['Voltage']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Power Sensor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'ReadingVolts', + 'UpperThresholdCritical' + ] + + headers = [ + 'Server', + 'Sensor Name', + 'State', + 'Health', + 'Volts', + 'Upper Threshold' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True + ) + + def print_power_supply(self, servers, title=False): + info = [] + for server in servers: + if 'Power' in server and server['Power'] is not None: + for item in server['Power']['Data']['PowerSupply']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Power Supply [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'SerialNumber', + 'FirmwareVersion', + 'PowerOutputWatts', + 'PowerInputWatts', + 'MaximumVoltage', + 'MinimumVoltage', + 'MaximumFrequencyHz', + 'MinimumFrequencyHz' + ] + + headers = [ + 'Server', + 'PSU Name', + 'State', + 'Health', + 'Serial', + 'Firmware', + 'Output (Watt)', + 'Input (Watt)', + 'Max (V)', + 'Min (V)', + 'Max (Hz)', + 'Min (Hz)' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True + ) + + def print_power(self, servers, title=False): + self.print_power_consumption(servers, title=title) + self.print_power_voltage(servers, title=title) + self.print_power_supply(servers, title=title) + + def print_profile(self, servers, title=False): + info = [] + for server in servers: + if 'ProfileInfo' in server: + if server['ProfileInfo'] is not None: + item = server['ProfileInfo'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Profile [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'ConfigState', + 'ModTime', + 'TargetPlatform', + 'Policies.Name', + 'Policies.ClassId', + 'Policies.ModTime', + 'Policies.Shared', + 'Policies.InSync' + ] + + headers = [ + 'Server', + 'Profile', + 'State', + 'Last Modified', + 'Target Platform', + 'Policy Name', + 'Class Id', + 'Modification Time', + 'Shared', + 'In Sync' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Policies'] + ), + order=order, + headers=headers, + underline=True, + table=True, + allow_order_subkeys=True, + row_separator=True + ) + + def print_storage_controllers(self, servers, title=False): + info = [] + for server in servers: + if 'StorageControllerInfo' in server: + for item in server['StorageControllerInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Storage Controller [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + for key in ['Model', 'Serial', 'RaidSupport']: + if item[key] is None or len(item[key]) == 0: + item[key] = '--' + + item['ModelT'] = filter_helper.get_string_chunks( + item['Model'], + 30 + ) + + order = [] + headers = [] + if len(servers) > 1: + order = ['ServerName'] + headers = ['Server'] + + order = order + [ + 'ControllerId', + 'ModelT', + 'Vendor', + 'Serial', + 'Presence', + 'PciSlot', + 'RaidSupport', + 'PhysicalDiskCount', + 'VirtualDriveCount' + ] + + headers = headers + [ + 'Controller', + 'Model', + 'Vendor', + 'Serial', + 'Presence', + 'PCI Slot', + 'Raid Support', + 'PD', + 'VD' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ModelT'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + row_separator=True, + underline=True, + table=True + ) + + def print_physical_disks_state(self, servers, title=False): + info = [] + for server in servers: + if 'PhysicalDiskInfo' in server: + for item in server['PhysicalDiskInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Physical Disk - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + for key in ['DiskState', 'VirtualDriveId', 'DriveFirmware']: + if item[key] is None or len(item[key]) == 0: + item[key] = '--' + + order = [] + headers = [] + if len(servers) > 1: + order = ['ServerName'] + headers = ['Server'] + + order = order + [ + 'StateTick', + 'StorageControllerId', + 'DiskId', + 'VirtualDriveId', + 'SizeUnit', + 'Type', + 'Protocol', + 'BootableTick', + 'LinkSpeed', + 'DriveFirmware', + 'DiskState', + 'Presence' + ] + + headers = headers + [ + 'State', + 'Controller', + 'Disk Id', + 'VD', + 'Size', + 'Type', + 'Protocol', + 'Bootable', + 'Link Speed', + 'Fw', + 'State', + 'Presence' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_physical_disks_inventory(self, servers, title=False): + info = [] + for server in servers: + if 'PhysicalDiskInfo' in server: + for item in server['PhysicalDiskInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Physical Disk - Inventory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + for item in info: + for key in ['Pid', 'Model', 'PartNumber', 'Vendor', 'Serial']: + if key not in item: + item[key] = None + + if item[key] is None or len(item[key]) == 0: + item[key] = '--' + + order = [] + headers = [] + if len(servers) > 1: + order = ['ServerName'] + headers = ['Server'] + + order = order + [ + 'DiskId', + 'Pid', + 'Model', + 'PartNumber', + 'Vendor', + 'Serial' + ] + + headers = headers + [ + 'Disk Id', + 'Pid', + 'Model', + 'PN', + 'Vendor', + 'Serial' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_physical_disks(self, servers, title=False): + self.print_physical_disks_state(servers, title=title) + self.print_physical_disks_inventory(servers, title=title) + + def print_virtual_drives(self, servers, title=False): + info = [] + for server in servers: + if 'VirtualDisks' in server: + for item in server['VirtualDisks']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Virtual Drive [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [] + headers = [] + if len(servers) > 1: + order = ['ServerName'] + headers = ['Server'] + + order = order + [ + 'StateTick', + 'StorageControllerId', + 'VirtualDriveId', + 'SizeUnit', + 'PhysicalDiskCount', + 'Type', + 'Name', + 'BootableTick', + 'ActualWriteCachePolicy', + 'DriveState' + ] + + headers = headers + [ + 'State', + 'Controller', + 'Drive Id', + 'Size', + 'Disks', + 'Type', + 'Name', + 'Bootable', + 'Write Cache', + 'Drive State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_thermal_summary(self, servers, title=False): + info = [] + for server in servers: + if 'Thermal' in server: + item = server['Thermal']['Summary'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Thermal Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'SensorHealth', + 'HighestTemperature', + 'SmallestGap', + 'OverThreshold', + 'FanHealth' + ] + + headers = [ + 'Server', + 'Sensors Health', + 'Highest (C)', + 'Smallest Gap (C)', + 'Over Threshold', + 'Fans Health' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True + ) + + def print_thermal_sensor(self, servers, title=False): + info = [] + for server in servers: + if 'Thermal' in server: + for item in server['Thermal']['Data']['Temperature']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Thermal Sensor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + + headers = [ + 'Server', + 'Sensor Name', + 'State', + 'Health', + 'Location', + 'Value (Celcius)', + 'Upper Threshold (Celcius)' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True + ) + + def print_thermal_fan(self, servers, title=False): + info = [] + for server in servers: + if 'Thermal' in server: + for item in server['Thermal']['Data']['Fan']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Thermal Fan [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'State', + 'Health', + 'Value' + ] + + headers = [ + 'Server', + 'Fan Name', + 'State', + 'Health', + 'Value' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=False, + table=True + ) + + def print_thermal(self, servers, title=False): + self.print_thermal_summary(servers, title=title) + self.print_thermal_sensor(servers, title=title) + self.print_thermal_fan(servers, title=title) + + def print_tpm(self, servers, title=False): + info = [] + for server in servers: + if 'TpmInfo' in server: + for item in server['TpmInfo']: + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Trusted Platform Module [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Presence', + 'ActivationStatus', + 'AdminState', + 'Version', + 'Model', + 'Vendor', + 'Serial', + 'FirmwareVersion' + ] + + headers = [ + 'Server', + 'TPM', + 'Activation Status', + 'Admin State', + 'Version', + 'Model', + 'Vendor', + 'Serial', + 'Firmware Version' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_workflows(self, servers, workflow_count=10, title=False): + info = [] + for server in servers: + if 'Workflow' in server: + workflows = server['Workflow']['Last'][:workflow_count] + for workflow in workflows: + item = workflow + item['ServerName'] = server['Name'] + info.append(item) + + if title: + self.my_output.default( + 'Workflow [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Moid', + 'Name', + 'CreateTime', + 'Status', + 'Duration' + ] + + headers = [ + 'Server', + 'Workflow Moid', + 'Name', + 'Create Time', + 'Status', + 'Duration' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_inventory_rack(self, server_info, title=False): + if title: + self.my_output.default( + 'Server Inventory (R): %s' % (server_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + server_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_inventory_chassis(self, chassis_info, title=False): + if title: + self.my_output.default( + 'Chassis Inventory: %s' % (chassis_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + chassis_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_inventory_blade(self, server_info, title=False): + if title: + self.my_output.default( + 'Server Inventory (B): %s' % (server_info['Name']), + underline=True, + before_newline=True + ) + + order = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + headers = [ + 'Type', + 'Name', + 'Model', + 'Vendor', + 'Serial', + 'Pid' + ] + + self.my_output.my_table( + server_info['Inventory'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_inventory(self, servers, chassiz_info, title=False): + for server in servers: + if server['Type'] == 'Rack': + self.print_inventory_rack( + server, + title=title + ) + + chassis_moid = [] + for server in servers: + if server['Type'] == 'Blade': + if server['ChassisMoid'] not in chassis_moid: + chassis_moid.append( + server['ChassisMoid'] + ) + + for chassis_info in chassiz_info: + if chassis_info['Moid'] in chassis_moid: + self.print_inventory_chassis( + chassis_info, + title=title + ) + + for server in servers: + if server['Type'] == 'Blade': + if server['ChassisMoid'] == chassis_info['Moid']: + self.print_inventory_blade( + server, + title=title + ) + + def print_inventory_csv(self, servers_info, chassiz_info, inventory_filename): + fields = [ + 'Inventory Type', + 'Inventory Name', + 'Inventory Model', + 'Inventory Vendor', + 'Inventory Serial', + 'Inventory PID', + 'Top Owner', + 'Chassis Serial', + 'Chassis PID', + 'Chassis Name', + 'Server Serial', + 'Server PID', + 'Server Name' + ] + rows = [] + + for server_info in servers_info: + if server_info['Type'] == 'Rack': + for inventory_info in server_info['Inventory']: + row = [] + row.append(inventory_info['Type']) + row.append(inventory_info['Name']) + row.append(inventory_info['Model']) + row.append(inventory_info['Vendor']) + row.append(inventory_info['Serial']) + row.append(inventory_info['Pid']) + row.append('Server') + row.append('N/A') + row.append('N/A') + row.append('N/A') + row.append(inventory_info['ServerSerial']) + row.append(inventory_info['ServerPid']) + row.append(server_info['Name']) + rows.append( + row + ) + + chassis_moid = [] + for server_info in servers_info: + if server_info['Type'] == 'Blade': + if server_info['ChassisMoid'] not in chassis_moid: + chassis_moid.append( + server_info['ChassisMoid'] + ) + + for chassis_info in chassiz_info: + if chassis_info['Moid'] in chassis_moid: + for inventory_info in chassis_info['Inventory']: + row = [] + row.append(inventory_info['Type']) + row.append(inventory_info['Name']) + row.append(inventory_info['Model']) + row.append(inventory_info['Vendor']) + row.append(inventory_info['Serial']) + row.append(inventory_info['Pid']) + row.append('Chassis') + row.append(chassis_info['ChassisSerial']) + row.append(chassis_info['ChassisPid']) + row.append(chassis_info['Name']) + row.append('N/A') + row.append('N/A') + row.append('N/A') + rows.append( + row + ) + + for server_info in servers_info: + if server_info['Type'] == 'Blade': + if server_info['ChassisMoid'] == chassis_info['Moid']: + for inventory_info in server_info['Inventory']: + row = [] + row.append(inventory_info['Type']) + row.append(inventory_info['Name']) + row.append(inventory_info['Model']) + row.append(inventory_info['Vendor']) + row.append(inventory_info['Serial']) + row.append(inventory_info['Pid']) + row.append('Chassis') + row.append(chassis_info['ChassisSerial']) + row.append(chassis_info['ChassisPid']) + row.append(chassis_info['Name']) + row.append(inventory_info['ServerSerial']) + row.append(inventory_info['ServerPid']) + row.append(server_info['Name']) + rows.append( + row + ) + + with open(inventory_filename, 'w', newline='') as file_handler: + write = csv.writer(file_handler) + write.writerow(fields) + for row in rows: + write.writerow(row) + + def print_vc_vms(self, servers_info, vc_hosts, vc_vms, title=False): + if title: + self.my_output.default( + 'Server - vCenter Virtual Machine', + underline=True, + before_newline=True + ) + + row_separator = False + for server_info in servers_info: + server_info['TagT'] = [] + for item in server_info['Tags']: + server_info['TagT'].append( + '%s:%s' % ( + item['Key'], + item['Value'] + ) + ) + + if len(server_info['TagT']) > 1: + row_separator = True + + if len(server_info['TagT']) == 0: + server_info['TagT'].append('--') + + server_info['VcHostname'] = '--' + server_info['VirtualMachine'] = [] + for vc_host in vc_hosts: + if server_info['Serial'] == vc_host['serial']: + server_info['VcHostname'] = vc_host['name'] + for vc_vm in vc_vms: + if vc_vm['host'] == vc_host['name']: + server_info['VirtualMachine'].append( + vc_vm['name'] + ) + + if len(server_info['VirtualMachine']) > 1: + row_separator = True + + order = [ + 'Name', + 'TagT', + 'TypeModel', + 'Serial', + 'ManagementIp', + 'VcHostname', + 'VirtualMachine' + ] + + headers = [ + 'Name', + 'Tag', + 'Model', + 'Serial', + 'IP', + 'vCenter Host', + 'Virtual Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + servers_info, + order, + ['TagT', 'VirtualMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=row_separator, + underline=True, + table=True + ) diff --git a/lib/intersight/compute_rack/__init__.py b/lib/intersight/compute_rack/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/compute_rack/class.md b/lib/intersight/compute_rack/class.md new file mode 100644 index 00000000..a72b2160 --- /dev/null +++ b/lib/intersight/compute_rack/class.md @@ -0,0 +1,260 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Adapters": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e533a", + "ObjectType": "adapter.Unit", + "link": "https://www.intersight.com/api/v1/adapter/Units/6311ac4676752d31398e533a" + } + ], + "AdminPowerState": "policy", + "AlarmSummary": { + "ClassId": "compute.AlarmSummary", + "Critical": 0, + "ObjectType": "compute.AlarmSummary", + "Warning": 1 + }, + "Alerts": [], + "Ancestors": [], + "AssetTag": "", + "AvailableMemory": 688128, + "BiosBootmode": null, + "BiosPostComplete": false, + "BiosTokenSettings": null, + "BiosVfSelectMemoryRasConfiguration": { + "ClassId": "mo.MoRef", + "Moid": "6311ae0876752d31398e9a37", + "ObjectType": "bios.VfSelectMemoryRasConfiguration", + "link": "https://www.intersight.com/api/v1/bios/VfSelectMemoryRasConfigurations/6311ae0876752d31398e9a37" + }, + "Biosunits": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5336", + "ObjectType": "bios.Unit", + "link": "https://www.intersight.com/api/v1/bios/Units/6311ac4676752d31398e5336" + } + ], + "Bmc": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a52", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/6311aae876752d31398e1a52" + }, + "Board": { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + "BootCddDevices": [], + "BootDeviceBootSecurity": null, + "BootDeviceBootmode": null, + "BootHddDevices": [], + "BootIscsiDevices": [], + "BootNvmeDevices": [], + "BootPchStorageDevices": [], + "BootPxeDevices": [], + "BootSanDevices": [], + "BootSdDevices": [], + "BootUefiShellDevices": [], + "BootUsbDevices": [], + "BootVmediaDevices": [], + "ClassId": "compute.RackUnit", + "ConnectionStatus": "A", + "CreateTime": "2022-09-02T07:04:08.416Z", + "DeviceMoId": "61c35fa36f72612d3005590c", + "Dn": "sys/rack-unit-3", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "Fanmodules": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c81", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/6311ac8376752d31398e5c81" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c85", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/6311ac8376752d31398e5c85" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c89", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/6311ac8376752d31398e5c89" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c8d", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/6311ac8376752d31398e5c8d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c91", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/6311ac8376752d31398e5c91" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c95", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/6311ac8376752d31398e5c95" + } + ], + "FaultSummary": 0, + "GenericInventoryHolders": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b39576752d31398f844f", + "ObjectType": "inventory.GenericInventoryHolder", + "link": "https://www.intersight.com/api/v1/inventory/GenericInventoryHolders/6311b39576752d31398f844f" + } + ], + "GraphicsCards": [], + "HardwareUuid": "", + "InventoryDeviceInfo": null, + "KvmIpAddresses": [ + { + "Address": "", + "Category": "Equipment", + "ClassId": "compute.IpAddress", + "DefaultGateway": "", + "Dn": "sys/rack-unit-3/mgmt/ipv4-pooled-addr", + "HttpPort": 80, + "HttpsPort": 443, + "KvmPort": 2068, + "KvmVlan": 0, + "Name": "Outband", + "ObjectType": "compute.IpAddress", + "Subnet": "255.255.255.0", + "Type": "VnicIpV4PooledAddr" + } + ], + "KvmServerStateEnabled": false, + "KvmVendor": "", + "LocatorLed": { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c7f", + "ObjectType": "equipment.LocatorLed", + "link": "https://www.intersight.com/api/v1/equipment/LocatorLeds/6311ac8376752d31398e5c7f" + }, + "ManagementMode": "UCSM", + "MemoryArrays": [], + "MemorySpeed": "1866", + "MgmtIdentity": null, + "MgmtIpAddress": "", + "ModTime": "2022-09-16T09:32:59.721Z", + "Model": "UCSC-C220-M4S", + "Moid": "6311aae876752d31398e1a50", + "Name": "berlin-ucsm-3", + "NumAdaptors": 1, + "NumCpuCores": 28, + "NumCpuCoresEnabled": 28, + "NumCpus": 2, + "NumEthHostInterfaces": 3, + "NumFcHostInterfaces": 0, + "NumThreads": 56, + "ObjectType": "compute.RackUnit", + "OperPowerState": "on", + "OperReason": [], + "OperState": "ok", + "Operability": "operable", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "PciDevices": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c6", + "ObjectType": "pci.Device", + "link": "https://www.intersight.com/api/v1/pci/Devices/6311b01a76752d31398ef2c6" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2f8", + "ObjectType": "pci.Device", + "link": "https://www.intersight.com/api/v1/pci/Devices/6311b01a76752d31398ef2f8" + } + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PlatformType": "UCSFI", + "Presence": "equipped", + "PreviousFru": null, + "Processors": [], + "Psus": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c3b", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/6311ac8376752d31398e5c3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c3d", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/6311ac8376752d31398e5c3d" + } + ], + "RackEnclosureSlot": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "SasExpanders": [], + "Serial": "FCH2031V0YM", + "ServerId": 3, + "ServiceProfile": "org-root/ls-esxi-246", + "SharedScope": "", + "StorageControllers": [], + "StorageEnclosures": [], + "Tags": [ + { + "Key": "Intersight.LicenseTier", + "Value": "Premier" + } + ], + "TopSystem": { + "ClassId": "mo.MoRef", + "Moid": "61c35fac76752d3139f50de9", + "ObjectType": "top.System", + "link": "https://www.intersight.com/api/v1/top/Systems/61c35fac76752d3139f50de9" + }, + "TopologyScanStatus": "", + "TotalMemory": 688128, + "TunneledKvm": false, + "UnitPersonality": [], + "UserLabel": "", + "Uuid": "1435af2a-2b44-4dc8-906d-bba6b92f14d5", + "Vendor": "Cisco Systems Inc", + "Vmedia": null + } +``` \ No newline at end of file diff --git a/lib/intersight/compute_rack/main.py b/lib/intersight/compute_rack/main.py new file mode 100644 index 00000000..3a9633ab --- /dev/null +++ b/lib/intersight/compute_rack/main.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class ComputeRack(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'compute rackunit' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) diff --git a/lib/intersight/compute_server_setting/__init__.py b/lib/intersight/compute_server_setting/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/compute_server_setting/class.md b/lib/intersight/compute_server_setting/class.md new file mode 100644 index 00000000..0ad56887 --- /dev/null +++ b/lib/intersight/compute_server_setting/class.md @@ -0,0 +1,124 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "AdminLocatorLedState": "None", + "AdminPowerState": "Policy", + "Ancestors": [], + "CertificatesAction": null, + "ClassId": "compute.ServerSetting", + "CmosReset": "Ready", + "ConfigState": "Applied", + "CreateTime": "2020-12-20T18:50:42.762Z", + "DeviceMoId": "5fdf9cf26f72612d300aaca0", + "Dn": "sys/rack-unit-1", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "FrontPanelLockState": "Unlock", + "KvmReset": "Ready", + "LocatorLed": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9d156176752d35e4b534", + "ObjectType": "equipment.LocatorLed", + "link": "https://www.intersight.com/api/v1/equipment/LocatorLeds/5fdf9d156176752d35e4b534" + }, + "ModTime": "2022-09-30T16:16:23.99Z", + "Moid": "5fdf9d026573732d30fdb471", + "Name": "", + "ObjectType": "compute.ServerSetting", + "OneTimeBootDevice": "", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fdf9cf26f72612d300aaca0" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PersistentMemoryOperation": { + "AdminAction": "None", + "ClassId": "compute.PersistentMemoryOperation", + "IsSecurePassphraseSet": false, + "Modules": [], + "ObjectType": "compute.PersistentMemoryOperation" + }, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9cf26f72612d300aaca0", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fdf9cf26f72612d300aaca0" + }, + "Rn": "", + "RunningWorkflow": null, + "Server": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9d026176752d35e4ac4e", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9d026176752d35e4ac4e" + }, + "ServerConfig": { + "AssetTag": "022C2CE", + "ClassId": "compute.ServerConfig", + "ObjectType": "compute.ServerConfig", + "UserLabel": "aio-3-p2b-eu-spdc-WZP23400AKL" + }, + "ServerOpStatus": [ + { + "ClassId": "compute.ServerOpStatus", + "ConfigState": "Applied", + "ObjectType": "compute.ServerOpStatus", + "WorkflowType": "compute.ServerPowerOn" + }, + { + "ClassId": "compute.ServerOpStatus", + "ConfigState": "Applied", + "ObjectType": "compute.ServerOpStatus", + "WorkflowType": "compute.ServerPowerCycle" + }, + { + "ClassId": "compute.ServerOpStatus", + "ConfigState": "Applied", + "ObjectType": "compute.ServerOpStatus", + "WorkflowType": "compute.ServerPowerOff" + } + ], + "SharedScope": "", + "StorageControllerOperation": { + "AdminAction": "None", + "ClassId": "compute.StorageControllerOperation", + "ControllerId": "", + "ObjectType": "compute.StorageControllerOperation" + }, + "StoragePhysicalDriveOperation": { + "AdminAction": "None", + "ClassId": "compute.StoragePhysicalDriveOperation", + "ControllerId": "", + "ObjectType": "compute.StoragePhysicalDriveOperation", + "PhysicalDrives": [] + }, + "StorageVirtualDriveOperation": { + "AdminAction": "None", + "ClassId": "compute.StorageVirtualDriveOperation", + "ControllerId": "", + "ObjectType": "compute.StorageVirtualDriveOperation", + "VirtualDrives": [] + }, + "Tags": [], + "TpmReset": "None", + "TunneledKvmState": "Ready" + } +``` \ No newline at end of file diff --git a/lib/intersight/compute_server_setting/info.py b/lib/intersight/compute_server_setting/info.py new file mode 100644 index 00000000..defbf254 --- /dev/null +++ b/lib/intersight/compute_server_setting/info.py @@ -0,0 +1,24 @@ +class ComputeServerSettingInfo(): + def __init__(self): + pass + + def get_by_device_moid(self, device_moid, cache=True): + if cache: + self.prepare_cache() + else: + self.cache = self.get_all() + + if self.cache is None: + return None + + for item in self.cache: + if item['DeviceMoId'] == device_moid: + return item + + return None + + def get_id_by_device_moid(self, device_moid, cache=True): + item = self.get_by_device_moid(device_moid, cache=cache) + if item is not None: + return item['Moid'] + return None diff --git a/lib/intersight/compute_server_setting/main.py b/lib/intersight/compute_server_setting/main.py new file mode 100644 index 00000000..1c22dfee --- /dev/null +++ b/lib/intersight/compute_server_setting/main.py @@ -0,0 +1,15 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.compute_server_setting.info import ComputeServerSettingInfo + + +class ComputeServerSetting(IntersightCommon, ComputeServerSettingInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'compute serversetting' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + ComputeServerSettingInfo.__init__(self) + + def set(self, attributes): + create_iobject = 'compute updatecomputeserversetting' + command = 'isctl create %s %s' % (create_iobject, attributes) + response = self.isctl.create(command) + return response diff --git a/lib/intersight/computes_summary.py b/lib/intersight/computes_summary.py new file mode 100644 index 00000000..4d9bd62a --- /dev/null +++ b/lib/intersight/computes_summary.py @@ -0,0 +1,552 @@ +from lib import info_helper +from lib import output_helper + + +class ComputesSummary(): + """Class for server summary + """ + def __init__(self, settings, log_id=None): + self.info_handler = info_helper.InfoHelper(log_id=log_id) + self.my_output = output_helper.OutputHelper(log_id=log_id) + self.settings = settings + + def get_type_summary(self, summary, servers): + type_dict = {} + type_dict['Rack'] = 0 + type_dict['Blade'] = 0 + + for server in servers: + if server['Type'] == 'Rack': + type_dict['Rack'] = type_dict['Rack'] + 1 + else: + type_dict['Blade'] = type_dict['Blade'] + 1 + + summary['type'] = type_dict + + return summary + + def print_type_summary(self, summary): + if 'type' in summary: + self.my_output.dictionary( + summary['type'], + title='Type', + underline=False, + prefix="- ", + justify=True, + keys=summary['type'].keys(), + start='' + ) + + def get_model_summary(self, summary, servers): + models_dict = {} + for server in servers: + model_name = server['Model'] + if model_name not in models_dict: + models_dict[model_name] = 1 + continue + + models_dict[model_name] = models_dict[model_name] + 1 + + models_list = [] + for model_name in models_dict: + models_list.append( + dict( + key=model_name, + value=models_dict[model_name] + ) + ) + + summary['models_dict'] = dict(sorted(models_dict.items())) + summary['models_list'] = models_list + + return summary + + def print_model_summary(self, summary): + if 'models_dict' in summary: + self.my_output.dictionary( + summary['models_dict'], + title='Models', + underline=False, + prefix="- ", + justify=True, + keys=summary['models_dict'].keys(), + start='' + ) + + def get_max_summary(self, summary, servers): + max_dict = {} + max_dict['CpuSockets'] = 0 + max_dict['CpuCores'] = 0 + max_dict['CpuThreads'] = 0 + max_dict['Memory'] = 0 + if self.settings['storage']: + max_dict['Storage Controllers'] = 0 + max_dict['Total Disk Capacity'] = 0 + max_dict['HDD Count'] = 0 + max_dict['HDD Capacity'] = 0 + max_dict['SSD Count'] = 0 + max_dict['SSD Capacity'] = 0 + if self.settings['pci']: + max_dict['PCI Devices'] = 0 + + for server in servers: + max_dict['CpuSockets'] = max( + max_dict['CpuSockets'], + server['NumCpus'] + ) + max_dict['CpuCores'] = max( + max_dict['CpuCores'], + server['NumCpuCores'] + ) + max_dict['CpuThreads'] = max( + max_dict['CpuThreads'], + server['NumThreads'] + ) + max_dict['Memory'] = max( + max_dict['Memory'], + server['TotalMemoryGB'] + ) + if self.settings['storage']: + max_dict['Storage Controllers'] = max( + max_dict['Storage Controllers'], + server['StorageControllerCount'] + ) + max_dict['Total Disk Capacity'] = max( + max_dict['Total Disk Capacity'], + server['PhysicalDiskCapacity'] + ) + max_dict['HDD Count'] = max( + max_dict['HDD Count'], + server['HddDiskCount'] + ) + max_dict['HDD Capacity'] = max( + max_dict['HDD Capacity'], + server['HddDiskCapacity'] + ) + max_dict['SSD Count'] = max( + max_dict['SSD Count'], + server['SsdDiskCount'] + ) + max_dict['SSD Capacity'] = max( + max_dict['SSD Capacity'], + server['SsdDiskCapacity'] + ) + + if self.settings['pci']: + max_dict['PCI Devices'] = max( + max_dict['PCI Devices'], + len(server['PciModels']) + ) + + if self.settings['storage']: + for key in ['Total Disk Capacity', 'HDD Capacity', 'SSD Capacity']: + max_dict[key] = self.info_handler.convert_storage(max_dict[key]) + + summary['max'] = max_dict + + return summary + + def print_max_summary(self, summary): + if 'max' in summary: + self.my_output.dictionary( + summary['max'], + title='Maximum', + underline=False, + prefix="- ", + justify=True, + keys=summary['max'].keys(), + start='' + ) + + def get_power_summary(self, summary, servers): + power_dict = {} + power_dict['On'] = 0 + power_dict['Off'] = 0 + + for server in servers: + if server['OperPowerState'] == 'on': + power_dict['On'] = power_dict['On'] + 1 + else: + power_dict['Off'] = power_dict['Off'] + 1 + + summary['power'] = power_dict + + return summary + + def print_power_summary(self, summary): + if 'power' in summary: + self.my_output.dictionary( + summary['power'], + title='Power', + underline=False, + prefix="- ", + justify=True, + keys=summary['power'].keys(), + start='' + ) + + def get_health_summary(self, summary, servers): + health_dict = {} + health_dict['Healthy'] = 0 + health_dict['Warning'] = 0 + health_dict['Critical'] = 0 + + for server in servers: + if server['AlarmSummary']['Warning'] == 0 and server['AlarmSummary']['Critical'] == 0: + health_dict['Healthy'] = health_dict['Healthy'] + 1 + if server['AlarmSummary']['Warning'] > 0 and server['AlarmSummary']['Critical'] == 0: + health_dict['Warning'] = health_dict['Warning'] + 1 + if server['AlarmSummary']['Critical'] > 0: + health_dict['Critical'] = health_dict['Critical'] + 1 + + summary['health'] = health_dict + + return summary + + def print_health_summary(self, summary): + if 'health' in summary: + self.my_output.dictionary( + summary['health'], + title='Health', + underline=False, + prefix="- ", + justify=True, + keys=summary['health'].keys(), + start='' + ) + + def get_locator_summary(self, summary, servers): + locator_dict = {} + locator_dict['On'] = 0 + locator_dict['Off'] = 0 + + supported = False + for server in servers: + if 'LocatorLedOn' in server: + supported = True + if server['LocatorLedOn']: + locator_dict['On'] = locator_dict['On'] + 1 + else: + locator_dict['Off'] = locator_dict['Off'] + 1 + + if supported: + summary['locator'] = locator_dict + + return summary + + def print_locator_summary(self, summary): + if 'locator' in summary: + self.my_output.dictionary( + summary['locator'], + title='Locator', + underline=False, + prefix="- ", + justify=True, + keys=summary['locator'].keys(), + start='' + ) + + def get_management_summary(self, summary, servers): + management_dict = {} + management_dict['Standalone'] = 0 + management_dict['UCSM'] = 0 + + for server in servers: + if server['ManagementMode'] == 'UCSM': + management_dict['UCSM'] = management_dict['UCSM'] + 1 + else: + management_dict['Standalone'] = management_dict['Standalone'] + 1 + + summary['management'] = management_dict + + return summary + + def print_management_summary(self, summary): + if 'management' in summary: + self.my_output.dictionary( + summary['management'], + title='Management Mode', + underline=False, + prefix="- ", + justify=True, + keys=summary['management'].keys(), + start='' + ) + + def get_fan_summary(self, summary, servers): + if not self.settings['fan']: + return summary + + fan_dict = {} + fan_dict['All up'] = 0 + fan_dict['Some down'] = 0 + + for server in servers: + if server['FanHealthy']: + fan_dict['All up'] = fan_dict['All up'] + 1 + else: + fan_dict['Some down'] = fan_dict['Some down'] + 1 + + summary['fan'] = fan_dict + + return summary + + def print_fan_summary(self, summary): + if 'fan' in summary: + self.my_output.dictionary( + summary['fan'], + title='Server Fans', + underline=False, + prefix="- ", + justify=True, + keys=summary['fan'].keys(), + start='' + ) + + def get_psu_summary(self, summary, servers): + if not self.settings['psu']: + return summary + + psu_dict = {} + psu_dict['All up'] = 0 + psu_dict['Some down'] = 0 + + for server in servers: + if server['PsuHealthy']: + psu_dict['All up'] = psu_dict['All up'] + 1 + else: + psu_dict['Some down'] = psu_dict['Some down'] + 1 + + summary['psu'] = psu_dict + + return summary + + def print_psu_summary(self, summary): + if 'psu' in summary: + self.my_output.dictionary( + summary['psu'], + title='Server Psus', + underline=False, + prefix="- ", + justify=True, + keys=summary['psu'].keys(), + start='' + ) + + def get_pci_summary(self, summary, servers): + if not self.settings['pci']: + return summary + + pci_dict = {} + + for server in servers: + for pci_model in server['PciModels']: + if pci_model not in pci_dict: + pci_dict[pci_model] = 1 + continue + + pci_dict[pci_model] = pci_dict[pci_model] + 1 + + summary['pci'] = dict(sorted(pci_dict.items())) + + return summary + + def print_pci_summary(self, summary): + if 'pci' in summary: + self.my_output.dictionary( + summary['pci'], + title='PCI Models', + underline=False, + prefix="- ", + justify=True, + keys=summary['pci'].keys(), + start='' + ) + + def get_fw_summary(self, summary, servers): + if not self.settings['fw']: + return summary + + fw_dict = {} + for server in servers: + fw_name = server['FirmwareVersion'] + if fw_name not in fw_dict: + fw_dict[fw_name] = 1 + continue + + fw_dict[fw_name] = fw_dict[fw_name] + 1 + + summary['fw'] = dict(sorted(fw_dict.items())) + + return summary + + def print_fw_summary(self, summary): + if 'fw' in summary: + self.my_output.dictionary( + summary['fw'], + title='Firmware', + underline=False, + prefix="- ", + justify=True, + keys=summary['fw'].keys(), + start='' + ) + + def get_workflow_summary(self, summary, servers): + if not self.settings['workflow']: + return summary + + workflow_running_count = 0 + workflow_success_count = 0 + workflow_failed_count = 0 + workflow_names_dict = {} + workflow_servers_count = 0 + workflow_no_servers_count = 0 + + for server in servers: + if server['Workflow']['Running'] is None and len(server['Workflow']['Last']) == 0: + workflow_no_servers_count = workflow_no_servers_count + 1 + continue + + workflow_servers_count = workflow_servers_count + 1 + + if server['Workflow']['Running'] is not None: + workflow_running_count = workflow_running_count + 1 + workflow_name = server['Workflow']['Running']['Name'] + if workflow_name not in workflow_names_dict: + workflow_names_dict[workflow_name] = 1 + else: + workflow_names_dict[workflow_name] = workflow_names_dict[workflow_name] + 1 + + for workflow_item in server['Workflow']['Last']: + if workflow_item['Completed']: + workflow_success_count = workflow_success_count + 1 + else: + workflow_failed_count = workflow_failed_count + 1 + + workflow_name = workflow_item['Name'] + if workflow_name not in workflow_names_dict: + workflow_names_dict[workflow_name] = 1 + else: + workflow_names_dict[workflow_name] = workflow_names_dict[workflow_name] + 1 + + summary['workflow'] = {} + summary['workflow']['running_count'] = workflow_running_count + summary['workflow']['success_count'] = workflow_success_count + summary['workflow']['failed_count'] = workflow_failed_count + summary['workflow']['names'] = workflow_names_dict + summary['workflow']['servers_count'] = workflow_servers_count + summary['workflow']['no_servers_count'] = workflow_no_servers_count + + return summary + + def print_workflow_summary(self, summary): + if 'workflow' in summary: + self.my_output.dictionary( + summary['workflow'], + title='Last Workflows Summary', + underline=False, + prefix="- ", + justify=True, + keys=[ + 'running_count', + 'success_count', + 'failed_count', + 'servers_count', + 'no_servers_count' + ], + title_keys=[ + 'Running', + 'Success', + 'Failed', + 'Servers with workflows', + 'Servers with no workflows' + ], + start='' + ) + + self.my_output.dictionary( + summary['workflow']['names'], + title='Workflow Names', + underline=False, + prefix="- ", + justify=True, + keys=summary['workflow']['names'].keys(), + start='' + ) + + def get_tags_summary(self, summary, servers): + tags = {} + + for server in servers: + for tag in server['Tags']: + if tag['Key'] == 'Intersight.LicenseTier': + continue + + tag_kv = '%s:%s' % ( + tag['Key'], + tag['Value'] + ) + + if tag_kv not in tags: + tags[tag_kv] = {} + tags[tag_kv]['count'] = 0 + tags[tag_kv]['server'] = [] + + tags[tag_kv]['count'] = tags[tag_kv]['count'] + 1 + tags[tag_kv]['server'].append(server['Name']) + + summary['tags'] = tags + return summary + + def print_tags_summary(self, summary): + self.my_output.default( + 'Tag' + ) + + tags = sorted( + summary['tags'] + ) + for tag in tags: + self.my_output.default( + '- %s: %s' % ( + tag, + summary['tags'][tag]['count'] + ) + ) + + def get_summary(self, servers): + summary = {} + + summary['count'] = len(servers) + summary = self.get_type_summary(summary, servers) + summary = self.get_model_summary(summary, servers) + summary = self.get_max_summary(summary, servers) + summary = self.get_power_summary(summary, servers) + summary = self.get_health_summary(summary, servers) + summary = self.get_locator_summary(summary, servers) + summary = self.get_management_summary(summary, servers) + summary = self.get_fan_summary(summary, servers) + summary = self.get_psu_summary(summary, servers) + summary = self.get_pci_summary(summary, servers) + summary = self.get_fw_summary(summary, servers) + summary = self.get_workflow_summary(summary, servers) + summary = self.get_tags_summary(summary, servers) + + return summary + + def print_summary(self, summary): + self.my_output.default('\nSelected servers count: %s\n' % (summary['count'])) + self.print_type_summary(summary) + self.print_model_summary(summary) + self.print_power_summary(summary) + self.print_max_summary(summary) + self.print_health_summary(summary) + self.print_locator_summary(summary) + self.print_management_summary(summary) + self.print_fan_summary(summary) + self.print_psu_summary(summary) + self.print_pci_summary(summary) + self.print_fw_summary(summary) + self.print_workflow_summary(summary) + self.print_tags_summary(summary) diff --git a/lib/intersight/computes_worfklow.py b/lib/intersight/computes_worfklow.py new file mode 100644 index 00000000..a283988c --- /dev/null +++ b/lib/intersight/computes_worfklow.py @@ -0,0 +1,170 @@ +from lib import output_helper + +class ComputesWorkflow(): + """Class for servers' workflows + """ + def __init__(self, log_id=None): + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def failed_workflow_match(self, workflow, failed): + if not failed: + return True + + if workflow['Status'] == 'FAILED': + return True + + return False + + def completed_workflow_match(self, workflow, completed): + if not completed: + return True + + if workflow['Status'] == 'COMPLETED': + return True + + return False + + def power_workflow_match(self, workflow, power): + if not power: + return True + + if workflow['Name'] in ['Power On', 'Power Off', 'Power Cycle', 'Reboot IMC', 'Shut Down OS', 'Hard Reset']: + return True + + return False + + def os_workflow_match(self, workflow, os_filter): + if not os_filter: + return True + + if workflow['Name'] in ['InstallOS', 'Operating System Install']: + return True + + return False + + def fw_workflow_match(self, workflow, fw_filter): + if not fw_filter: + return True + + # TBD !!! + + return False + + def match_workflow(self, workflow, settings): + if not self.failed_workflow_match(workflow, settings['failed']): + return False + + if not self.completed_workflow_match(workflow, settings['completed']): + return False + + if not self.power_workflow_match(workflow, settings['power']): + return False + + if not self.os_workflow_match(workflow, settings['os']): + return False + + if not self.fw_workflow_match(workflow, settings['fw']): + return False + + return True + + def get_servers_workflows(self, servers, settings): + workflows = [] + + for server in servers: + if server['Workflow']['Running'] is not None: + if self.match_workflow(server['Workflow']['Running'], settings): + workflow_info = {} + workflow_info['__Output'] = {} + + workflow_info['server_id'] = server['Moid'] + workflow_info['server_state'] = server['FlagState'] + workflow_info['__Output']['server_state'] = server['__Output']['FlagState'] + workflow_info['server_name'] = server['Name'] + workflow_info['server_ip'] = server['ManagementIp'] + workflow_info['server_serial'] = server['Serial'] + + workflow_info['workflow_id'] = server['Workflow']['Running']['Moid'] + workflow_info['name'] = server['Workflow']['Running']['Name'] + workflow_info['created'] = server['Workflow']['Running']['CreateTime'] + workflow_info['created_epoch'] = server['Workflow']['Running']['CreateTimeEpoch'] + workflow_info['duration'] = 'In progress...' + + workflow_info['__Output']['status'] = 'Yellow' + workflow_info['status'] = 'RUNNING %s%%' % (server['Workflow']['Running']['Progress']) + + workflows.append(workflow_info) + + count = settings['count'] + if count < 0: + count = 1000 + + for workflow_item in server['Workflow']['Last']: + if self.match_workflow(workflow_item, settings): + workflow_info = {} + workflow_info['__Output'] = {} + + workflow_info['server_id'] = server['Moid'] + workflow_info['__Output']['server_state'] = server['__Output']['FlagState'] + workflow_info['server_state'] = server['FlagState'] + workflow_info['server_name'] = server['Name'] + workflow_info['server_ip'] = server['ManagementIp'] + workflow_info['server_serial'] = server['Serial'] + + workflow_info['workflow_id'] = workflow_item['Moid'] + workflow_info['name'] = workflow_item['Name'] + workflow_info['created'] = workflow_item['CreateTime'] + workflow_info['created_epoch'] = workflow_item['CreateTimeEpoch'] + workflow_info['duration'] = workflow_item['Duration'] + + workflow_info['__Output']['status'] = workflow_item['__Output']['Status'] + workflow_info['status'] = workflow_item['Status'] + + workflows.append(workflow_info) + count = count - 1 + if count == 0: + break + + if settings['sorted'] == 'date': + workflows = sorted(workflows, key=lambda i: i['created_epoch'], reverse=True) + + if settings['sorted'] == 'server': + workflows = sorted(workflows, key=lambda i: (i['server_name'], -i['created_epoch'])) + + if settings['sorted'] == 'workflow': + workflows = sorted(workflows, key=lambda i: (i['name'], -i['created_epoch'])) + + return workflows + + def print_workflows(self, workflows): + order = [ + 'server_state', + 'server_name', + 'server_ip', + 'server_serial', + 'workflow_id', + 'name', + 'created', + 'duration', + 'status', + ] + + headers = [ + 'SF', + 'Server Name', + 'Server IP', + 'Serial', + 'Workflow ID', + 'Name', + 'Create Time', + 'Duration', + 'Status' + ] + + self.my_output.my_table( + workflows, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/intersight/cond_alarm/__init__.py b/lib/intersight/cond_alarm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/cond_alarm/class.md b/lib/intersight/cond_alarm/class.md new file mode 100644 index 00000000..bf037fdd --- /dev/null +++ b/lib/intersight/cond_alarm/class.md @@ -0,0 +1,66 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "Acknowledge": "None", + "AcknowledgeBy": "", + "AcknowledgeTime": "0001-01-01T00:00:00Z", + "AffectedMo": { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304cd8", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632b15b576752d3236304cd8" + }, + "AffectedMoDisplayName": "ucsX/chassis-1/psu-3", + "AffectedMoId": "", + "AffectedMoType": "", + "AffectedObject": "", + "AncestorMoId": "632b13c876752d32362fc175", + "AncestorMoType": "equipment.Chassis", + "Ancestors": [], + "ClassId": "cond.Alarm", + "Code": "EquipmentChassisPsuInputLost", + "CreateTime": "2022-09-21T13:49:14.691Z", + "CreationTime": "2022-09-21T13:49:14.21Z", + "Description": "Power supply ucsX/chassis-1/psu-3 has no AC input", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "LastTransitionTime": "2022-09-21T13:49:14.21Z", + "ModTime": "2022-10-14T10:36:06.483Z", + "Moid": "632b165a65696e2d33b64fac", + "MsAffectedObject": "", + "Name": "EquipmentChassisPsuInputLost", + "ObjectType": "cond.Alarm", + "OrigSeverity": "Warning", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Severity": "Warning", + "SharedScope": "", + "Tags": [ + { + "Key": "cisco.meta.AlarmSource", + "Value": "Intersight" + } + ] + } +``` \ No newline at end of file diff --git a/lib/intersight/cond_alarm/info.py b/lib/intersight/cond_alarm/info.py new file mode 100644 index 00000000..229bb19c --- /dev/null +++ b/lib/intersight/cond_alarm/info.py @@ -0,0 +1,155 @@ +import time +from datetime import datetime + +from lib import filter_helper + + +class CondAlarmInfo(): + def __init__(self): + self.cond_alarm = None + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['AffectedType'] = managed_object['AffectedMo']['ObjectType'] + info['AffectedMoid'] = managed_object['AffectedMo']['Moid'] + info['AffectedName'] = managed_object['AffectedMoDisplayName'] + info['AncestorMoId'] = managed_object['AncestorMoId'] + info['AncestorMoType'] = managed_object['AncestorMoType'] + info['CreateTime'] = managed_object['CreateTime'] + info['LastTransitionTime'] = managed_object['LastTransitionTime'] + if '.' in managed_object['LastTransitionTime']: + info['Timestamp'] = int( + time.mktime( + datetime.strptime( + info['LastTransitionTime'], + '%Y-%m-%dT%H:%M:%S.%f%z' + ).timetuple() + ) + ) + else: + info['Timestamp'] = int( + time.mktime( + datetime.strptime( + info['LastTransitionTime'], + '%Y-%m-%dT%H:%M:%SZ' + ).timetuple() + ) + ) + + info['Description'] = managed_object['Description'] + info['Acknowledge'] = managed_object['Acknowledge'] + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + info['Code'] = managed_object['Code'] + + info['Severity'] = managed_object['Severity'] + if info['Severity'] == 'Critical': + info['__Output']['Severity'] = 'Red' + + if info['Severity'] == 'Warning': + info['__Output']['Severity'] = 'Yellow' + + if info['Severity'] == 'Info': + info['__Output']['Severity'] = 'Blue' + + return info + + def get_infos(self): + if self.cond_alarm is not None: + return self.cond_alarm + + managed_objects = self.get_all() + if managed_objects is None: + return None + + self.cond_alarm = [] + for managed_object in managed_objects: + self.cond_alarm.append( + self.get_info( + managed_object + ) + ) + + self.log.intersight_mo( + 'cond_alarm.info', + self.cond_alarm + ) + + return self.cond_alarm + + def match_cond_alarm(self, cond_alarm_info, cond_alarm_filter, last_moids): + if cond_alarm_filter is None or len(cond_alarm_filter) == 0: + return True + + for rule in cond_alarm_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + key_found = False + + if key == 'timestamp': + key_found = True + if not filter_helper.match_timestamp(value, cond_alarm_info['Timestamp']): + return False + + if key == 'severity': + key_found = True + if value != 'any': + if not filter_helper.match_string(value, cond_alarm_info['Severity']): + return False + + if key == 'code': + key_found = True + if not filter_helper.match_string(value, cond_alarm_info['Code']) and not filter_helper.match_string(value, cond_alarm_info['Name']): + return False + + if key == 'cleared': + key_found = True + if value == 'False': + if cond_alarm_info['Severity'] == 'Cleared': + return False + + if key == 'new': + key_found = True + if value == 'True': + if last_moids is not None: + if cond_alarm_info['Moid'] in last_moids and cond_alarm_info['LastTransitionTime'] == last_moids[cond_alarm_info['Moid']]: + return False + + if not key_found: + self.log.error( + 'match_cond_alarm', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cond_alarms(self, cond_alarm_filter=None, update_moid_cache=False): + all_cond_alarms = self.get_infos() + if all_cond_alarms is None: + return None + + last_moids = self.get_iaccount_json_file('cond_alarm_moids') + cond_alarms = [] + + for cond_alarm_info in all_cond_alarms: + if not self.match_cond_alarm(cond_alarm_info, cond_alarm_filter, last_moids): + continue + + cond_alarms.append(cond_alarm_info) + + cond_alarms = sorted( + cond_alarms, + key=lambda i: i['Timestamp'], + reverse=True + ) + + if update_moid_cache: + moids = {} + for cond_alarm in all_cond_alarms: + moids[cond_alarm['Moid']] = cond_alarm['LastTransitionTime'] + self.set_iaccount_json_file('cond_alarm_moids', moids) + + return cond_alarms diff --git a/lib/intersight/cond_alarm/main.py b/lib/intersight/cond_alarm/main.py new file mode 100644 index 00000000..40152752 --- /dev/null +++ b/lib/intersight/cond_alarm/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.cond_alarm.info import CondAlarmInfo + + +class CondAlarm(IntersightCommon, CondAlarmInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'cond alarm' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + CondAlarmInfo.__init__(self) diff --git a/lib/intersight/cond_alarm/output.py b/lib/intersight/cond_alarm/output.py new file mode 100644 index 00000000..af7a598d --- /dev/null +++ b/lib/intersight/cond_alarm/output.py @@ -0,0 +1,169 @@ +from lib import filter_helper + + +class ComputeCondAlarmOutput(): + def __init__(self): + pass + + def print_server_alarm_summary(self, servers, title=False): + info = [] + for server in servers: + if 'AlarmSummary' in server: + item = server['AlarmSummary'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Alarm Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Critical', + 'Warning', + 'Info' + ] + + headers = [ + 'Server', + 'Critical', + 'Warning', + 'Info' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_server_alarm(self, servers, title=False): + info = [] + for server in servers: + for item in server['AlarmInfo']: + item['ServerName'] = server['Name'] + item['DescriptionT'] = filter_helper.get_string_chunks( + item['Description'], + 40, + separator=' ' + ) + info.append( + item + ) + + if len(info) > 0: + if title: + self.my_output.default( + 'Alarm [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'ServerName', + 'Severity', + 'DescriptionT', + 'CreateTime', + 'AffectedType', + 'AffectedName' + ] + + headers = [ + 'Server', + 'Severity', + 'Description', + 'Create Time', + 'Affected Type', + 'Affected Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['DescriptionT'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + def print_alarm(self, alarms, title=False): + info = [] + for alarm in alarms: + alarm['DescriptionT'] = filter_helper.get_string_chunks( + alarm['Description'], + 40, + separator=' ' + ) + alarm['AffectedTypeT'] = alarm['AffectedType'].split('.') + alarm['AffectedNameT'] = alarm['AffectedName'].split('/') + alarm['NameCodeT'] = [] + alarm['NameCodeT'].append(alarm['Name']) + if alarm['Name'] != alarm['Code']: + alarm['NameCodeT'].append('Code: %s' % (alarm['Code'])) + + alarm['TimeT'] = [] + alarm['TimeT'].append('(C) %s' % (alarm['CreateTime'])) + alarm['TimeT'].append('(U) %s' % (alarm['LastTransitionTime'])) + + info.append( + alarm + ) + + if len(info) > 0: + if title: + self.my_output.default( + 'Alarm [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'Severity', + 'AffectedTypeT', + 'AffectedNameT', + 'TimeT', + 'NameCodeT', + 'DescriptionT' + ] + + headers = [ + 'Severity', + 'Affected Type', + 'Affected Name', + 'When', + 'Alarm', + 'Description' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['AffectedTypeT', 'DescriptionT', 'AffectedNameT', 'NameCodeT', 'TimeT'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/intersight/cond_hclstatus/__init__.py b/lib/intersight/cond_hclstatus/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/cond_hclstatus/class.md b/lib/intersight/cond_hclstatus/class.md new file mode 100644 index 00000000..2f12eb60 --- /dev/null +++ b/lib/intersight/cond_hclstatus/class.md @@ -0,0 +1,98 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [], + "ClassId": "cond.HclStatus", + "ComponentStatus": "Not-Evaluated", + "CreateTime": "2020-04-07T09:58:47.968Z", + "Details": [ + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ff173736f2d3181b134", + "ObjectType": "cond.HclStatusDetail", + "link": "https://www.intersight.com/api/v1/cond/HclStatusDetails/5e8c4ff173736f2d3181b134" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c500b73736f2d3181c175", + "ObjectType": "cond.HclStatusDetail", + "link": "https://www.intersight.com/api/v1/cond/HclStatusDetails/5e8c500b73736f2d3181c175" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c500b73736f2d3181c173", + "ObjectType": "cond.HclStatusDetail", + "link": "https://www.intersight.com/api/v1/cond/HclStatusDetails/5e8c500b73736f2d3181c173" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c500b73736f2d3181c174", + "ObjectType": "cond.HclStatusDetail", + "link": "https://www.intersight.com/api/v1/cond/HclStatusDetails/5e8c500b73736f2d3181c174" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6175060173736f2d311e55cb", + "ObjectType": "cond.HclStatusDetail", + "link": "https://www.intersight.com/api/v1/cond/HclStatusDetails/6175060173736f2d311e55cb" + } + ], + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "HardwareStatus": "Validated", + "HclFirmwareVersion": "4.1(2)", + "HclModel": "UCSC-C220-M4S", + "HclOsVendor": "", + "HclOsVersion": "", + "HclProcessor": "Intel Xeon E5-2600 v3 Series processors", + "InvFirmwareVersion": "4.1(2f)", + "InvModel": "UCSC-C220-M4S", + "InvOsVendor": "", + "InvOsVersion": " ", + "InvProcessor": "Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz", + "ManagedObject": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed26176752d32d51c40", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5e8c4ed26176752d32d51c40" + }, + "ModTime": "2023-01-01T08:01:10.793Z", + "Moid": "5e8c4ed773736f2d31815ce0", + "ObjectType": "cond.HclStatus", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5e8c4ecd6f72612d302b11a6" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Reason": "Missing-Os-Info", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ecd6f72612d302b11a6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5e8c4ecd6f72612d302b11a6" + }, + "ServerReason": "Missing-Os-Driver-Info", + "SharedScope": "", + "SoftwareStatus": "Incomplete", + "Status": "Incomplete", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/cond_hclstatus/info.py b/lib/intersight/cond_hclstatus/info.py new file mode 100644 index 00000000..07a599a1 --- /dev/null +++ b/lib/intersight/cond_hclstatus/info.py @@ -0,0 +1,35 @@ +class CondHclStatusInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['ComponentStatus'] = managed_object['ComponentStatus'] + info['HardwareStatus'] = managed_object['HardwareStatus'] + info['HclFirmwareVersion'] = managed_object['HclFirmwareVersion'] + info['HclModel'] = managed_object['HclModel'] + info['HclOsVendor'] = managed_object['HclOsVendor'] + info['HclOsVersion'] = managed_object['HclOsVersion'] + info['HclProcessor'] = managed_object['HclProcessor'] + info['Moid'] = managed_object['Moid'] + info['Reason'] = managed_object['Reason'] + info['ServerReason'] = managed_object['ServerReason'] + info['SoftwareStatus'] = managed_object['SoftwareStatus'] + info['Status'] = managed_object['Status'] + + for key in ['Status', 'SoftwareStatus', 'HardwareStatus', 'ComponentStatus']: + if info[key] == 'Incomplete': + info['__Output'][key] = 'Red' + + if info[key] == 'Not-Listed': + info['__Output'][key] = 'Yellow' + + if info[key] == 'Validated': + info['__Output'][key] = 'Green' + + if info[key] == 'Not-Evaluated': + info['__Output'][key] = 'Yellow' + + return info diff --git a/lib/intersight/cond_hclstatus/main.py b/lib/intersight/cond_hclstatus/main.py new file mode 100644 index 00000000..ac6b0821 --- /dev/null +++ b/lib/intersight/cond_hclstatus/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.cond_hclstatus.info import CondHclStatusInfo + + +class CondHclStatus(IntersightCommon, CondHclStatusInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'cond hclstatus' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + CondHclStatusInfo.__init__(self) diff --git a/lib/intersight/cond_hclstatus_detail/__init__.py b/lib/intersight/cond_hclstatus_detail/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/cond_hclstatus_detail/class.md b/lib/intersight/cond_hclstatus_detail/class.md new file mode 100644 index 00000000..9e2745bc --- /dev/null +++ b/lib/intersight/cond_hclstatus_detail/class.md @@ -0,0 +1,77 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed773736f2d31815ce0", + "ObjectType": "cond.HclStatus", + "link": "https://www.intersight.com/api/v1/cond/HclStatuses/5e8c4ed773736f2d31815ce0" + } + ], + "ClassId": "cond.HclStatusDetail", + "Component": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4fec6176752d32d62e0b", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/5e8c4fec6176752d32d62e0b" + }, + "CreateTime": "2020-04-07T10:03:29.535Z", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "HardwareStatus": "Not-Evaluated", + "HclCimcVersion": "4.1(2)", + "HclDriverName": "", + "HclDriverVersion": "", + "HclFirmwareVersion": "24.12.1-0456", + "HclModel": "Cisco 12G SAS Modular Raid Controller", + "HclStatus": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed773736f2d31815ce0", + "ObjectType": "cond.HclStatus", + "link": "https://www.intersight.com/api/v1/cond/HclStatuses/5e8c4ed773736f2d31815ce0" + }, + "InvCimcVersion": "4.1(2f)", + "InvDriverName": "", + "InvDriverVersion": "", + "InvFirmwareVersion": "24.12.1-0456", + "InvModel": "Cisco 12G SAS Modular Raid Controller", + "ModTime": "2022-05-09T13:35:25.208Z", + "Moid": "5e8c4ff173736f2d3181b134", + "ObjectType": "cond.HclStatusDetail", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5e8c4ecd6f72612d302b11a6" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed773736f2d31815ce0", + "ObjectType": "cond.HclStatus", + "link": "https://www.intersight.com/api/v1/cond/HclStatuses/5e8c4ed773736f2d31815ce0" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Reason": "Missing-Os-Driver-Info", + "SharedScope": "", + "SoftwareStatus": "Not-Evaluated", + "Status": "Incomplete", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/cond_hclstatus_detail/info.py b/lib/intersight/cond_hclstatus_detail/info.py new file mode 100644 index 00000000..ef9fee99 --- /dev/null +++ b/lib/intersight/cond_hclstatus_detail/info.py @@ -0,0 +1,40 @@ +class CondHclStatusDetailInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'HardwareStatus', + 'HclCimcVersion', + 'HclDriverName', + 'HclDriverVersion', + 'HclFirmwareVersion', + 'HclModel', + 'Reason', + 'SoftwareStatus', + 'Status', + 'Moid' + ] + + for key in keys: + if key in managed_object: + info[key] = managed_object[key] + + for key in ['Status', 'SoftwareStatus', 'HardwareStatus']: + if key in info: + if info[key] == 'Incomplete': + info['__Output'][key] = 'Red' + + if info[key] == 'Not-Listed': + info['__Output'][key] = 'Yellow' + + if info[key] == 'Validated': + info['__Output'][key] = 'Green' + + if info[key] == 'Not-Evaluated': + info['__Output'][key] = 'Yellow' + + return info diff --git a/lib/intersight/cond_hclstatus_detail/main.py b/lib/intersight/cond_hclstatus_detail/main.py new file mode 100644 index 00000000..f4b5c73c --- /dev/null +++ b/lib/intersight/cond_hclstatus_detail/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.cond_hclstatus_detail.info import CondHclStatusDetailInfo + + +class CondHclStatusDetail(IntersightCommon, CondHclStatusDetailInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'cond hclstatusdetail' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + CondHclStatusDetailInfo.__init__(self) diff --git a/lib/intersight/equipment_chassis/__init__.py b/lib/intersight/equipment_chassis/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_chassis/class.md b/lib/intersight/equipment_chassis/class.md new file mode 100644 index 00000000..bd42856d --- /dev/null +++ b/lib/intersight/equipment_chassis/class.md @@ -0,0 +1,210 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AlarmSummary": { + "ClassId": "compute.AlarmSummary", + "Critical": 0, + "ObjectType": "compute.AlarmSummary", + "Warning": 2 + }, + "Ancestors": [], + "Blades": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b15b976752d3236304e93", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b15b976752d3236304e93" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b15b976752d3236304ea8", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b15b976752d3236304ea8" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b163a76752d3236307256", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b163a76752d3236307256" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b163b76752d32363072e7", + "ObjectType": "compute.Blade", + "link": "https://www.intersight.com/api/v1/compute/Blades/632b163b76752d32363072e7" + } + ], + "ChassisId": 2, + "ClassId": "equipment.Chassis", + "ConnectionPath": "A,B", + "ConnectionStatus": "A,B", + "CreateTime": "2022-09-21T13:38:18.807Z", + "Description": "Cisco Blade Server Chassis, 7U with Eight Vertical Blade Server Slots", + "DeviceMoId": "632999466f72612d39b26942", + "Dn": "chassis-2", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "ExpanderModules": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b15b476752d3236304bd4", + "ObjectType": "equipment.ExpanderModule", + "link": "https://www.intersight.com/api/v1/equipment/ExpanderModules/632b15b476752d3236304bd4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b15b476752d3236304be1", + "ObjectType": "equipment.ExpanderModule", + "link": "https://www.intersight.com/api/v1/equipment/ExpanderModules/632b15b476752d3236304be1" + } + ], + "FanControl": { + "ClassId": "mo.MoRef", + "Moid": "632b15b476752d3236304be5", + "ObjectType": "equipment.FanControl", + "link": "https://www.intersight.com/api/v1/equipment/FanControls/632b15b476752d3236304be5" + }, + "Fanmodules": [ + { + "ClassId": "mo.MoRef", + "Moid": "632c69f576752d3236941a5b", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632c69f576752d3236941a5b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f576752d3236941a70", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632c69f576752d3236941a70" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f576752d3236941aa4", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632c69f576752d3236941aa4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f576752d3236941ab3", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632c69f576752d3236941ab3" + } + ], + "FaultSummary": 0, + "InventoryDeviceInfo": null, + "Ioms": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2c0", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13ca76752d32362fc2c0" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c68b376752d323693c512", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632c68b376752d323693c512" + } + ], + "LocatorLed": null, + "ManagementInterface": null, + "ManagementMode": "Intersight", + "ModTime": "2022-10-14T10:35:57.395Z", + "Model": "UCSX-9508", + "Moid": "632b13ca76752d32362fc2b9", + "Name": "ucsX-2", + "ObjectType": "equipment.Chassis", + "OperReason": [], + "OperState": "OK", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "PartNumber": "68-6847-03 ", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "Pid": "UCSX-9508", + "PlatformType": "", + "PowerControlState": { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419ce", + "ObjectType": "power.ControlState", + "link": "https://www.intersight.com/api/v1/power/ControlStates/632c69f476752d32369419ce" + }, + "Presence": "", + "PreviousFru": null, + "ProductName": "Cisco UCSX 9508 Chassis", + "PsuControl": { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419c8", + "ObjectType": "equipment.PsuControl", + "link": "https://www.intersight.com/api/v1/equipment/PsuControls/632c69f476752d32369419c8" + }, + "Psus": [ + { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419a8", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632c69f476752d32369419a8" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419ac", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632c69f476752d32369419ac" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419b0", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632c69f476752d32369419b0" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419b4", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632c69f476752d32369419b4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419ba", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632c69f476752d32369419ba" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c69f476752d32369419c1", + "ObjectType": "equipment.Psu", + "link": "https://www.intersight.com/api/v1/equipment/Psus/632c69f476752d32369419c1" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Revision": "0", + "Rn": "", + "Sasexpanders": [], + "Serial": "FOX2615P18G", + "SharedScope": "", + "Siocs": [], + "Sku": "UCSX-9508", + "StorageEnclosures": [], + "Tags": [], + "Vendor": "Cisco Systems Inc", + "Vid": "V01", + "VirtualDriveContainer": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_chassis/main.py b/lib/intersight/equipment_chassis/main.py new file mode 100644 index 00000000..60d71933 --- /dev/null +++ b/lib/intersight/equipment_chassis/main.py @@ -0,0 +1,36 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class EquipmentChassis(IntersightCommon): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'equipment chassis' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + + def filter(self, name_filter='', serial_filter='', model_filter=''): + items = IntersightCommon.get_all(self) + if items is None: + return None + + if len(name_filter) == 0 and len(serial_filter) == 0 and len(model_filter) == 0: + return items + + filtered = [] + for item in items: + if len(name_filter) > 0 and name_filter.lower() not in item['Name'].lower(): + continue + + if len(serial_filter) > 0: + found = False + for item_filter in serial_filter.split(','): + if item_filter.lower() in item['Serial'].lower(): + found = True + + if not found: + continue + + if len(model_filter) > 0 and model_filter.lower() not in item['Model'].lower(): + continue + + filtered.append(item) + + return filtered diff --git a/lib/intersight/equipment_expander_module/__init__.py b/lib/intersight/equipment_expander_module/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_expander_module/class.md b/lib/intersight/equipment_expander_module/class.md new file mode 100644 index 00000000..e5b997ce --- /dev/null +++ b/lib/intersight/equipment_expander_module/class.md @@ -0,0 +1,97 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "64be876876752d39013ea7f4", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/64be876876752d39013ea7f4" + } + ], + "ClassId": "equipment.ExpanderModule", + "CreateTime": "2023-07-24T14:24:42.766Z", + "DeviceMoId": "64be6ab66f726131018165d8", + "Dn": "chassis-1-expander-mod-1", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "64be876876752d39013ea7f4", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/64be876876752d39013ea7f4" + }, + "FanModules": [ + { + "ClassId": "mo.MoRef", + "Moid": "64be89aa76752d39013f544d", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/64be89aa76752d39013f544d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be89ab76752d39013f545f", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/64be89ab76752d39013f545f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be89ab76752d39013f5471", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/64be89ab76752d39013f5471" + } + ], + "IsUpgraded": false, + "ModTime": "2023-08-31T08:46:47.514Z", + "Model": "UCSX-9508-RBLK", + "ModuleId": 1, + "Moid": "64be89aa76752d39013f542d", + "ObjectType": "equipment.ExpanderModule", + "OperReason": [], + "OperState": "OK", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "64be6ab66f726131018165d8" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "64be876876752d39013ea7f4", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/64be876876752d39013ea7f4" + }, + "PartNumber": "73-19787-04 ", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "64be6ab66f726131018165d8", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/64be6ab66f726131018165d8" + }, + "Revision": "", + "Rn": "", + "Serial": "FCH2631760N", + "SharedScope": "", + "Tags": [], + "Vendor": "Cisco Systems Inc" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_expander_module/info.py b/lib/intersight/equipment_expander_module/info.py new file mode 100644 index 00000000..36a09632 --- /dev/null +++ b/lib/intersight/equipment_expander_module/info.py @@ -0,0 +1,47 @@ +class EquipmentExpanderModuleInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['Model'] = managed_object['Model'] + + if managed_object['Presence'] == 'equipped' and managed_object['OperState'].lower() in ['ok', 'operable']: + info['On'] = True + info['OperTick'] = '\u2713' + info['__Output']['OperTick'] = 'Green' + else: + info['On'] = False + info['OperTick'] = '\u2717' + info['__Output']['OperTick'] = 'Red' + + info['FanMoids'] = [] + for fan in managed_object['FanModules']: + info['FanMoids'].append(fan['Moid']) + info['FansCount'] = len( + info['FanMoids'] + ) + + info['Name'] = 'X-Fabric #%s' % ( + managed_object['ModuleId'] + ) + + info['ModuleId'] = managed_object['ModuleId'] + info['OperState'] = managed_object['OperState'] + info['PartNumber'] = managed_object['PartNumber'].strip() + info['Pid'] = managed_object['Model'] + + info['Presence'] = managed_object['Presence'] + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + info['Serial'] = managed_object['Serial'] + info['Vendor'] = managed_object['Vendor'] + + return info diff --git a/lib/intersight/equipment_expander_module/main.py b/lib/intersight/equipment_expander_module/main.py new file mode 100644 index 00000000..558a2e24 --- /dev/null +++ b/lib/intersight/equipment_expander_module/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_expander_module.info import EquipmentExpanderModuleInfo + + +class EquipmentExpanderModule(IntersightCommon, EquipmentExpanderModuleInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'equipment expandermodule' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + EquipmentExpanderModuleInfo.__init__(self) diff --git a/lib/intersight/equipment_fan/__init__.py b/lib/intersight/equipment_fan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_fan/class.md b/lib/intersight/equipment_fan/class.md new file mode 100644 index 00000000..efe45503 --- /dev/null +++ b/lib/intersight/equipment_fan/class.md @@ -0,0 +1,93 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304d17", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632b15b576752d3236304d17" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + } + ], + "ClassId": "equipment.Fan", + "CreateTime": "2022-09-21T13:46:29.627Z", + "Description": "Fan Module for UCSX 9508 Blade Server Chassis", + "DeviceMoId": "632999466f72612d39b26942", + "DisplayNames": { + "hierarchical": [ + "fan-1" + ], + "short": [ + "Fan-1" + ] + }, + "Dn": "chassis-1-tray-1-mod-3-fan-1", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EquipmentFanModule": { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304d17", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632b15b576752d3236304d17" + }, + "EquipmentFex": null, + "FanId": 1, + "FanModuleId": 0, + "InventoryDeviceInfo": null, + "ModTime": "2022-10-14T10:35:57.076Z", + "Model": "UCSX-9508-FAN", + "ModuleId": 3, + "Moid": "632b15b576752d3236304d18", + "ObjectType": "equipment.Fan", + "OperReason": [], + "OperState": "OK", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304d17", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632b15b576752d3236304d17" + }, + "PartNumber": "73-19422-04 ", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "Pid": "UCSX-9508-FAN", + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Revision": "0", + "Rn": "", + "Serial": "FCH254671AW", + "SharedScope": "", + "Sku": "UCSX-9508-FAN", + "Tags": [], + "TrayId": 1, + "Vendor": "Cisco Systems Inc", + "Vid": "V01" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_fan/info.py b/lib/intersight/equipment_fan/info.py new file mode 100644 index 00000000..c6a11d96 --- /dev/null +++ b/lib/intersight/equipment_fan/info.py @@ -0,0 +1,84 @@ +class EquipmentFanInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + keys = [ + 'Dn', + 'FanId', + 'FanModuleId', + 'Model', + 'ModuleId', + 'OperState', + 'PartNumber', + 'Pid', + 'Presence', + 'Serial', + 'Sku', + 'Vendor', + 'TrayId' + ] + + info = {} + info['__Output'] = {} + for key in keys: + if isinstance(managed_object[key], str): + info[key] = managed_object[key].strip() + continue + + info[key] = managed_object[key] + + if info['FanModuleId'] == 0: + fan_module_id_fixed = False + if 'chassis-' in info['Dn'] and '-tray-' in info['Dn'] and '-mod-' in info['Dn'] and '-fan-' in info['Dn']: + # chassis-1-tray-1-mod-1-fan-1 + info['FanModuleId'] = int(info['Dn'].split('-mod-')[1].split('-fan-')[0]) + fan_module_id_fixed = True + + if len(info['Dn'].split('/')) == 4: + # sys/rack-unit-1/fan-module-1-6/fan-2 + fan_module_dn = info['Dn'].split('/')[2] + info['FanModuleId'] = int(fan_module_dn.split('-')[-1]) + fan_module_id_fixed = True + + if not fan_module_id_fixed: + self.log.error( + 'equipment_fan', + 'Unsupported dn format: %s' % (info['Dn']) + ) + + info['Name'] = 'Fan Module %s - Fan %s' % ( + info['FanModuleId'], + info['FanId'] + ) + + if info['Pid'] is None or len(info['Pid']) == 0: + info['Pid'] = info['Model'] + + info['On'] = False + if managed_object['Presence'].lower() == 'equipped' and managed_object['OperState'].lower() == 'operable': + info['On'] = True + + if managed_object['Presence'].lower() == 'equipped' and managed_object['OperState'].lower() == 'ok': + info['On'] = True + + if info['Presence'].lower() == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + if info['OperState'].lower() in ['operable', 'ok']: + info['__Output']['OperState'] = 'Green' + else: + info['__Output']['OperState'] = 'Red' + + if info['On']: + info['__Output']['On'] = 'Green' + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['__Output']['On'] = 'Red' + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + return info diff --git a/lib/intersight/equipment_fan/main.py b/lib/intersight/equipment_fan/main.py new file mode 100644 index 00000000..4ca7cfe5 --- /dev/null +++ b/lib/intersight/equipment_fan/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_fan.info import EquipmentFanInfo + + +class EquipmentFan(IntersightCommon, EquipmentFanInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'equipment fan' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EquipmentFanInfo.__init__(self) diff --git a/lib/intersight/equipment_fan_control/__init__.py b/lib/intersight/equipment_fan_control/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_fan_control/class.md b/lib/intersight/equipment_fan_control/class.md new file mode 100644 index 00000000..18c2e2cc --- /dev/null +++ b/lib/intersight/equipment_fan_control/class.md @@ -0,0 +1,68 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2b9", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13ca76752d32362fc2b9" + } + ], + "ClassId": "equipment.FanControl", + "CreateTime": "2022-09-21T13:46:28.525Z", + "DeviceMoId": "", + "Dn": "chassis-2-fan-control", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2b9", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13ca76752d32362fc2b9" + }, + "InventoryDeviceInfo": null, + "ModTime": "2022-10-14T10:35:58.425Z", + "Mode": "LowPower", + "Model": "", + "Moid": "632b15b476752d3236304be5", + "ObjectType": "equipment.FanControl", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2b9", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13ca76752d32362fc2b9" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "Presence": "", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Revision": "", + "Rn": "", + "Serial": "", + "SharedScope": "", + "Tags": [], + "Vendor": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_fan_control/info.py b/lib/intersight/equipment_fan_control/info.py new file mode 100644 index 00000000..7ef00262 --- /dev/null +++ b/lib/intersight/equipment_fan_control/info.py @@ -0,0 +1,16 @@ +class EquipmentFanControlInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + keys = [ + 'Moid', + 'Dn', + 'Mode' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + return info diff --git a/lib/intersight/equipment_fan_control/main.py b/lib/intersight/equipment_fan_control/main.py new file mode 100644 index 00000000..4b137812 --- /dev/null +++ b/lib/intersight/equipment_fan_control/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_fan_control.info import EquipmentFanControlInfo + + +class EquipmentFanControl(IntersightCommon, EquipmentFanControlInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'equipment fancontrol' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EquipmentFanControlInfo.__init__(self) diff --git a/lib/intersight/equipment_fan_module/__init__.py b/lib/intersight/equipment_fan_module/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_fan_module/class.md b/lib/intersight/equipment_fan_module/class.md new file mode 100644 index 00000000..12c19cb5 --- /dev/null +++ b/lib/intersight/equipment_fan_module/class.md @@ -0,0 +1,95 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "ClassId": "equipment.FanModule", + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + }, + "CreateTime": "2022-09-02T07:10:59.837Z", + "Description": "", + "DeviceMoId": "61c35fa36f72612d3005590c", + "Dn": "sys/rack-unit-3/fan-module-1-3", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": null, + "EquipmentExpanderModule": null, + "EquipmentIoCard": null, + "EquipmentRackEnclosure": null, + "Fans": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c97", + "ObjectType": "equipment.Fan", + "link": "https://www.intersight.com/api/v1/equipment/Fans/6311ac8376752d31398e5c97" + } + ], + "InventoryDeviceInfo": null, + "ModTime": "2022-09-02T07:12:59.708Z", + "Model": "", + "ModuleId": 3, + "Moid": "6311ac8376752d31398e5c95", + "NetworkElement": null, + "ObjectType": "equipment.FanModule", + "OperReason": [], + "OperState": "operable", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + }, + "PartNumber": "", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Pid": "", + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "Serial": "N/A", + "SharedScope": "", + "Sku": "", + "Tags": [], + "TrayId": 0, + "Vendor": "N/A", + "Vid": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_fan_module/info.py b/lib/intersight/equipment_fan_module/info.py new file mode 100644 index 00000000..31049e0a --- /dev/null +++ b/lib/intersight/equipment_fan_module/info.py @@ -0,0 +1,51 @@ +class EquipmentFanModuleInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + if managed_object is None: + return None + + info = {} + info['__Output'] = {} + for key in ['Moid', 'ModuleId', 'OperState', 'Presence', 'Dn']: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['Name'] = 'Fan Module %s' % (info['ModuleId']) + if 'Fans' not in managed_object: + print(managed_object) + + info['FanCount'] = len(managed_object['Fans']) + info['FanMoids'] = [] + for fan in managed_object['Fans']: + info['FanMoids'].append(fan['Moid']) + + if info['Presence'].lower() == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + if info['OperState'].lower() in ['operable', 'ok']: + info['__Output']['OperState'] = 'Green' + else: + info['__Output']['OperState'] = 'Red' + + info['On'] = False + if info['Presence'] == 'equipped' and info['OperState'] == 'operable': + info['On'] = True + + if info['Presence'] == 'equipped' and info['OperState'].lower() == 'ok': + info['On'] = True + + if info['On']: + info['__Output']['On'] = 'Green' + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['__Output']['On'] = 'Red' + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + return info diff --git a/lib/intersight/equipment_fan_module/main.py b/lib/intersight/equipment_fan_module/main.py new file mode 100644 index 00000000..d4da842e --- /dev/null +++ b/lib/intersight/equipment_fan_module/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_fan_module.info import EquipmentFanModuleInfo + + +class EquipmentFanModule(IntersightCommon, EquipmentFanModuleInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'equipment fanmodule' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EquipmentFanModuleInfo.__init__(self) diff --git a/lib/intersight/equipment_iocard/__init__.py b/lib/intersight/equipment_iocard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_iocard/class.md b/lib/intersight/equipment_iocard/class.md new file mode 100644 index 00000000..7a664aaa --- /dev/null +++ b/lib/intersight/equipment_iocard/class.md @@ -0,0 +1,357 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + } + ], + "ClassId": "equipment.IoCard", + "ConnectionPath": "A", + "ConnectionStatus": "A", + "CreateTime": "2022-09-21T13:38:16.424Z", + "DcSupported": true, + "Description": "Cisco UCS 9108-25G 8 Port IFM", + "DeviceMoId": "632999466f72612d39b26942", + "Dn": "chassis-1-ioc-2", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + }, + "EquipmentFex": null, + "FanModules": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304d3d", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632b15b576752d3236304d3d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304d58", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632b15b576752d3236304d58" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b15b576752d3236304d6f", + "ObjectType": "equipment.FanModule", + "link": "https://www.intersight.com/api/v1/equipment/FanModules/632b15b576752d3236304d6f" + } + ], + "HostPorts": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad6", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad6" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac0", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac0" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5acc", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5acc" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5abf", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5abf" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac6", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac6" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac7", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac7" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad4", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad8", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad8" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac1", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac1" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac4", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5acf", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5acf" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad2", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad3", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad3" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac9", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad5", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5adb", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5adb" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac2", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac8", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac8" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5add", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5add" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5aca", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5aca" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5acb", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5acb" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5acd", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5acd" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ace", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ace" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac5", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ac3", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ac3" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad0", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad0" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5adc", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5adc" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad7", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad7" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5abe", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5abe" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad1", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad1" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ad9", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ad9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b158c6373582d415a5ada", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632b158c6373582d415a5ada" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c6acd6373582d415a8b96", + "ObjectType": "ether.HostPort", + "link": "https://www.intersight.com/api/v1/ether/HostPorts/632c6acd6373582d415a8b96" + } + ], + "InbandIpAddresses": [ + { + "Address": "", + "Category": "Equipment", + "ClassId": "compute.IpAddress", + "DefaultGateway": "", + "Dn": "", + "HttpPort": 80, + "HttpsPort": 443, + "KvmPort": 2068, + "KvmVlan": 89, + "Name": "Inband", + "ObjectType": "compute.IpAddress", + "Subnet": "255.255.255.0", + "Type": "MgmtInterface" + } + ], + "InventoryDeviceInfo": null, + "MgmtController": { + "ClassId": "mo.MoRef", + "Moid": "632b15b676752d3236304def", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/632b15b676752d3236304def" + }, + "ModTime": "2022-10-14T10:35:57.125Z", + "Model": "UCSX-I-9108-25G", + "ModuleId": 2, + "Moid": "632b13c876752d32362fc17c", + "NetworkPorts": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc189", + "ObjectType": "ether.NetworkPort", + "link": "https://www.intersight.com/api/v1/ether/NetworkPorts/632b13c876752d32362fc189" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c81e776752d32369da82f", + "ObjectType": "ether.NetworkPort", + "link": "https://www.intersight.com/api/v1/ether/NetworkPorts/632c81e776752d32369da82f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c81ed76752d32369daa9c", + "ObjectType": "ether.NetworkPort", + "link": "https://www.intersight.com/api/v1/ether/NetworkPorts/632c81ed76752d32369daa9c" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632c81fe76752d32369db10a", + "ObjectType": "ether.NetworkPort", + "link": "https://www.intersight.com/api/v1/ether/NetworkPorts/632c81fe76752d32369db10a" + } + ], + "ObjectType": "equipment.IoCard", + "OperReason": [], + "OperState": "OK", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + }, + "PartNumber": "73-20533-03 ", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "PhysicalDeviceRegistration": { + "ClassId": "mo.MoRef", + "Moid": "632b15886f72612d39c6702a", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632b15886f72612d39c6702a" + }, + "Pid": "UCSX-I-9108-25G", + "Presence": "equipped", + "PreviousFru": null, + "ProductName": "Cisco UCS 9108-25G", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Revision": "0", + "Rn": "", + "Serial": "FCH261770RN", + "SharedScope": "", + "Side": "bottom", + "Sku": "UCSX-I-9108-25G", + "Tags": [], + "Vendor": "Cisco Systems Inc", + "Version": "4.2(2c)", + "Vid": "V01" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_iocard/info.py b/lib/intersight/equipment_iocard/info.py new file mode 100644 index 00000000..b67fb463 --- /dev/null +++ b/lib/intersight/equipment_iocard/info.py @@ -0,0 +1,103 @@ +from lib import ip_helper + + +class EquipmentIoCardInfo(): + def __init__(self): + pass + + def is_iocard_on(self, item): + if item is None: + return False + + if item['Presence'] == 'equipped' and item['OperState'] == 'OK': + return True + + return False + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['Model'] = managed_object['Model'] + info['ConnectionPath'] = managed_object['ConnectionPath'] + info['ConnectionStatus'] = managed_object['ConnectionStatus'] + info['Description'] = managed_object['Description'] + info['ManagementIp'] = None + info['ManagementSubnet'] = None + info['ManagementPrefix'] = None + info['ManagementCidr'] = None + info['ManagementGateway'] = None + info['ManagementVlan'] = None + + if managed_object['Presence'] == 'equipped' and managed_object['OperState'].lower() in ['ok', 'operable']: + info['On'] = True + info['OperTick'] = '\u2713' + info['__Output']['OperTick'] = 'Green' + else: + info['On'] = False + info['OperTick'] = '\u2717' + info['__Output']['OperTick'] = 'Red' + + if managed_object['InbandIpAddresses'] is not None: + for inband in managed_object['InbandIpAddresses']: + if inband['ClassId'] == 'compute.IpAddress': + info['ManagementIp'] = inband['Address'] + info['ManagementSubnet'] = inband['Subnet'] + info['ManagementPrefix'] = ip_helper.netmask_to_prefix( + info['ManagementSubnet'] + ) + info['ManagementCidr'] = '%s/%s' % ( + info['ManagementIp'], + info['ManagementPrefix'] + ) + info['ManagementGateway'] = inband['DefaultGateway'] + info['ManagementVlan'] = inband['KvmVlan'] + + info['FanMoids'] = [] + for fan in managed_object['FanModules']: + info['FanMoids'].append(fan['Moid']) + info['FansCount'] = len( + info['FanMoids'] + ) + + info['HostPorts'] = [] + for port in managed_object['HostPorts']: + info['HostPorts'].append(port['Moid']) + info['HostPortsCount'] = len( + info['HostPorts'] + ) + + info['NetworkPorts'] = [] + for port in managed_object['NetworkPorts']: + info['NetworkPorts'].append(port['Moid']) + info['NetworkPortsCount'] = len( + info['NetworkPorts'] + ) + + info['Name'] = 'I/O #%s (%s)' % ( + managed_object['ModuleId'], + managed_object['Side'].lower() + ) + + info['ModuleId'] = managed_object['ModuleId'] + info['OperState'] = managed_object['OperState'] + info['PartNumber'] = managed_object['PartNumber'].strip() + info['Pid'] = managed_object['Pid'] + if info['Pid'] is None or len(info['Pid']) == 0: + info['Pid'] = info['Model'] + + info['Presence'] = managed_object['Presence'] + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + info['ProductName'] = managed_object['ProductName'] + info['Serial'] = managed_object['Serial'] + info['Side'] = managed_object['Side'] + info['Version'] = managed_object['Version'] + info['Vendor'] = managed_object['Vendor'] + + return info diff --git a/lib/intersight/equipment_iocard/main.py b/lib/intersight/equipment_iocard/main.py new file mode 100644 index 00000000..2aac8b5b --- /dev/null +++ b/lib/intersight/equipment_iocard/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_iocard.info import EquipmentIoCardInfo + + +class EquipmentIoCard(IntersightCommon, EquipmentIoCardInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'equipment iocard' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + EquipmentIoCardInfo.__init__(self) diff --git a/lib/intersight/equipment_led/__init__.py b/lib/intersight/equipment_led/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_led/class.md b/lib/intersight/equipment_led/class.md new file mode 100644 index 00000000..d5f3e5bc --- /dev/null +++ b/lib/intersight/equipment_led/class.md @@ -0,0 +1,74 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6026b0086176752d350dec89", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6026b0086176752d350dec89" + } + ], + "ClassId": "equipment.LocatorLed", + "Color": "unknown", + "ComputeBlade": null, + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "6026b0086176752d350dec89", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6026b0086176752d350dec89" + }, + "CreateTime": "2021-02-12T16:43:03.88Z", + "DeviceMoId": "6026afe76f72612d305f5af6", + "Dn": "sys/rack-unit-1/locator-led", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": null, + "EquipmentFex": null, + "InventoryDeviceInfo": null, + "ModTime": "2022-05-09T13:35:48.286Z", + "Moid": "6026b0176176752d350df2ad", + "ObjectType": "equipment.LocatorLed", + "OperState": "off", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "6026afe76f72612d305f5af6" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6026b0086176752d350dec89", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6026b0086176752d350dec89" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Rn": "", + "SharedScope": "", + "StoragePhysicalDisk": { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2de", + "ObjectType": "storage.PhysicalDisk", + "link": "https://www.intersight.com/api/v1/storage/PhysicalDisks/6311b01a76752d31398ef2de" + }, + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_led/info.py b/lib/intersight/equipment_led/info.py new file mode 100644 index 00000000..097d88ad --- /dev/null +++ b/lib/intersight/equipment_led/info.py @@ -0,0 +1,10 @@ +class EquipmentLedInfo(): + def __init__(self): + pass + + def is_locator_led_on(self, managed_object): + if managed_object is None or 'OperState' not in managed_object or managed_object['OperState'] is None: + return False + if managed_object['OperState'].lower() == 'off': + return False + return True diff --git a/lib/intersight/equipment_led/main.py b/lib/intersight/equipment_led/main.py new file mode 100644 index 00000000..116adc41 --- /dev/null +++ b/lib/intersight/equipment_led/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_led.info import EquipmentLedInfo + + +class EquipmentLed(IntersightCommon, EquipmentLedInfo): + def __init__(self, iaccount, get_filter='"OperState eq \'on\'"', log_id=None): + self.iobject = 'equipment locatorled' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EquipmentLedInfo.__init__(self) diff --git a/lib/intersight/equipment_psu/__init__.py b/lib/intersight/equipment_psu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_psu/class.md b/lib/intersight/equipment_psu/class.md new file mode 100644 index 00000000..ea296f94 --- /dev/null +++ b/lib/intersight/equipment_psu/class.md @@ -0,0 +1,51 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5efdfb9d6176752d3559bb60", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/5efdfb9d6176752d3559bb60" + } + ], + "ClassId": "equipment.Psu", + "ComputeRackUnit": null, + "CreateTime": "2020-07-02T15:22:12.078Z", + "Description": "", + "DeviceMoId": "5efdfb7e6f72612d30e4501e", + "Dn": "sys/chassis-1/psu-4", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "5efdfb9d6176752d3559bb60", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/5efdfb9d6176752d3559bb60" + }, + "EquipmentFex": null, + "EquipmentRackEnclosure": null, + "InventoryDeviceInfo": null, + "ModTime": "2021-06-11T06:52:19.353Z", + "Model": "PS-2112-9S-LF", + "Moid": "5efdfba46176752d3559be1a", + "Name": "", + "NetworkElement": null, + "ObjectType": "equipment.Psu", + "OperReason": [], + "ClassId": "mo.MoRef", + "Moid": "62614bdd6f72612d3331038b", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/62614bdd6f72612d3331038b" + }, + "Revision": "", + "Rn": "", + "Serial": "LIT21182DMM", + "SharedScope": "", + "Sku": "", + "Tags": [], + "Vendor": "Cisco Systems Inc", + "Vid": "", + "Voltage": "" + } + """ +``` \ No newline at end of file diff --git a/lib/intersight/equipment_psu/info.py b/lib/intersight/equipment_psu/info.py new file mode 100644 index 00000000..5c7d6526 --- /dev/null +++ b/lib/intersight/equipment_psu/info.py @@ -0,0 +1,78 @@ +class EquipmentPsuInfo(): + def __init__(self): + pass + + def is_psu_on(self, managed_object): + if managed_object is None: + return False + + if managed_object['Presence'] != 'equipped': + return False + + if managed_object['Voltage'] == 'ok': + return True + + try: + if int(managed_object['Voltage']) > 0: + return True + except BaseException: + pass + + return False + + def get_info(self, managed_object): + if managed_object is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'Moid', + 'Name', + 'Model', + 'Serial', + 'Vendor', + 'Dn', + 'Model', + 'Vendor', + 'Voltage', + 'Presence', + 'Pid' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['Id'] = info['Dn'].split('-')[-1] + if info['Name'] is None or len(info['Name']) == 0: + info['Name'] = 'PSU #%s' % (info['Id']) + + if info['Pid'] is None or len(info['Pid']) == 0: + info['Pid'] = info['Model'] + + info['On'] = self.is_psu_on( + managed_object + ) + + if info['On']: + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + if info['Voltage'].lower() == 'ok': + info['__Output']['Voltage'] = 'Green' + else: + info['__Output']['Voltage'] = 'Red' + + if info['Presence'].lower() == 'equipped': + info['PresenceTick'] = '\u2713' + info['__Output']['PresenceTick'] = 'Green' + else: + info['PresenceTick'] = '\u2717' + info['__Output']['PresenceTick'] = 'Red' + + return info diff --git a/lib/intersight/equipment_psu/main.py b/lib/intersight/equipment_psu/main.py new file mode 100644 index 00000000..2498535e --- /dev/null +++ b/lib/intersight/equipment_psu/main.py @@ -0,0 +1,10 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_psu.info import EquipmentPsuInfo + + +class EquipmentPsu(IntersightCommon, EquipmentPsuInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'equipment psu' + self.cache_key = 'psu' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id, cache_key=self.cache_key) + EquipmentPsuInfo.__init__(self) diff --git a/lib/intersight/equipment_psu/output.py b/lib/intersight/equipment_psu/output.py new file mode 100644 index 00000000..0066ac9d --- /dev/null +++ b/lib/intersight/equipment_psu/output.py @@ -0,0 +1,59 @@ +class ComputePsuOutput(): + def __init__(self): + pass + + def print_psu(self, servers, title=False): + info = [] + for server in servers: + if 'PsuInfo' in server: + for item in server['PsuInfo']: + if '__show' in item and not item['__show']: + continue + + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'PSU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'Name', + 'StateTick', + 'PresenceTick', + 'Voltage', + 'Model', + 'Serial', + 'Vendor' + ] + + headers = [ + 'Server', + 'Name', + 'State', + 'Present', + 'Voltage', + 'Model', + 'Serial', + 'Vendor' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) diff --git a/lib/intersight/equipment_psu_control/__init__.py b/lib/intersight/equipment_psu_control/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_psu_control/class.md b/lib/intersight/equipment_psu_control/class.md new file mode 100644 index 00000000..733fa3e4 --- /dev/null +++ b/lib/intersight/equipment_psu_control/class.md @@ -0,0 +1,81 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "619d058176752d313994941f", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/619d058176752d313994941f" + } + ], + "ClassId": "equipment.PsuControl", + "ClusterState": "slot-2-master", + "CreateTime": "2021-11-23T15:15:13.797Z", + "DeviceMoId": "618942976f72612d309dfbe1", + "Dn": "sys/chassis-1/psu-contr", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "619d058176752d313994941f", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/619d058176752d313994941f" + }, + "InputPowerState": "ok", + "InventoryDeviceInfo": null, + "ModTime": "2022-07-12T20:02:43.736Z", + "Model": "", + "Moid": "619d058176752d3139949427", + "Name": "", + "ObjectType": "equipment.PsuControl", + "OperQualifier": "", + "OperReason": [], + "OperState": "ok", + "OutputPowerState": "ok", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "618942976f72612d309dfbe1" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "619d058176752d313994941f", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/619d058176752d313994941f" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "", + "PreviousFru": null, + "Redundancy": "n+1", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "618942976f72612d309dfbe1", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/618942976f72612d309dfbe1" + }, + "Revision": "", + "Rn": "", + "Serial": "", + "SharedScope": "", + "Tags": [], + "Vendor": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_psu_control/info.py b/lib/intersight/equipment_psu_control/info.py new file mode 100644 index 00000000..b881461b --- /dev/null +++ b/lib/intersight/equipment_psu_control/info.py @@ -0,0 +1,40 @@ +class EquipmentPsuControlInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'Model', + 'Serial', + 'Vendor', + 'Dn', + 'InputPowerState', + 'OperState', + 'OutputPowerState', + 'Redundancy' + ] + for key in keys: + info[key] = managed_object[key] + + keys = [ + 'InputPowerState', + 'OperState', + 'OutputPowerState' + ] + for key in keys: + info[key] = info[key].lower() + if info[key] == '': + info['%sTick' % (key)] = '' + continue + + if info[key] == 'ok': + info['%sTick' % (key)] = '\u2713' + info['__Output']['%sTick' % (key)] = 'Green' + else: + info['%sTick' % (key)] = '\u2717' + info['__Output']['%sTick' % (key)] = 'Red' + + return info diff --git a/lib/intersight/equipment_psu_control/main.py b/lib/intersight/equipment_psu_control/main.py new file mode 100644 index 00000000..24b7caa7 --- /dev/null +++ b/lib/intersight/equipment_psu_control/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_psu_control.info import EquipmentPsuControlInfo + + +class EquipmentPsuControl(IntersightCommon, EquipmentPsuControlInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'equipment psucontrol' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + EquipmentPsuControlInfo.__init__(self) diff --git a/lib/intersight/equipment_tpm/__init__.py b/lib/intersight/equipment_tpm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/equipment_tpm/class.md b/lib/intersight/equipment_tpm/class.md new file mode 100644 index 00000000..7c6b9528 --- /dev/null +++ b/lib/intersight/equipment_tpm/class.md @@ -0,0 +1,85 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "ActivationStatus": "unknown", + "AdminState": "unknown", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed96176752d32d52214", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5e8c4ed96176752d32d52214" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed26176752d32d51c40", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5e8c4ed26176752d32d51c40" + } + ], + "ClassId": "equipment.Tpm", + "ComputeBoard": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed96176752d32d52214", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5e8c4ed96176752d32d52214" + }, + "CreateTime": "2020-04-07T10:02:13.533Z", + "DeviceMoId": "5e8c4ecd6f72612d302b11a6", + "Dn": "sys/rack-unit-1/board/tpm", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "FirmwareVersion": "", + "InventoryDeviceInfo": null, + "ModTime": "2022-05-09T13:36:01.073Z", + "Model": "NA", + "Moid": "5e8c4fa56176752d32d5e4bd", + "ObjectType": "equipment.Tpm", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5e8c4ecd6f72612d302b11a6" + ], + "Ownership": "unknown", + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed96176752d32d52214", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5e8c4ed96176752d32d52214" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "empty", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ecd6f72612d302b11a6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5e8c4ecd6f72612d302b11a6" + }, + "Revision": "", + "Rn": "", + "Serial": "NA", + "SharedScope": "", + "Tags": [], + "TpmId": 0, + "Vendor": "NA", + "Version": "NA" + } +``` \ No newline at end of file diff --git a/lib/intersight/equipment_tpm/info.py b/lib/intersight/equipment_tpm/info.py new file mode 100644 index 00000000..15b09d6a --- /dev/null +++ b/lib/intersight/equipment_tpm/info.py @@ -0,0 +1,45 @@ +class EquipmentTpmInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'ActivationStatus', + 'AdminState', + 'FirmwareVersion', + 'Model', + 'Moid', + 'Presence', + 'Serial', + 'TpmId', + 'Vendor', + 'Version' + ] + + for key in keys: + info[key] = managed_object[key] + + if info['ActivationStatus'].lower() == 'activated': + info['__Output']['ActivationStatus'] = 'Green' + + if info['ActivationStatus'].lower() == 'unknown': + info['__Output']['ActivationStatus'] = 'Yellow' + + if info['AdminState'].lower() == 'unknown': + info['__Output']['AdminState'] = 'Yellow' + + if info['AdminState'].lower() == 'enabled': + info['__Output']['AdminState'] = 'Green' + + if info['AdminState'].lower() == 'disabled': + info['__Output']['AdminState'] = 'Red' + + if info['Presence'].lower() == 'empty': + info['__Output']['Presence'] = 'Yellow' + else: + info['__Output']['Presence'] = 'Green' + + return info diff --git a/lib/intersight/equipment_tpm/main.py b/lib/intersight/equipment_tpm/main.py new file mode 100644 index 00000000..85750d25 --- /dev/null +++ b/lib/intersight/equipment_tpm/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.equipment_tpm.info import EquipmentTpmInfo + + +class EquipmentTpm(IntersightCommon, EquipmentTpmInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'equipment tpm' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EquipmentTpmInfo.__init__(self) diff --git a/lib/intersight/ethernet_host_port/__init__.py b/lib/intersight/ethernet_host_port/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/ethernet_host_port/class.md b/lib/intersight/ethernet_host_port/class.md new file mode 100644 index 00000000..5ddaf699 --- /dev/null +++ b/lib/intersight/ethernet_host_port/class.md @@ -0,0 +1,83 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AcknowledgedPeerInterface": null, + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13c976752d32362fc244", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13c976752d32362fc244" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + } + ], + "ClassId": "ether.HostPort", + "CreateTime": "2022-09-21T13:53:33.015Z", + "DeviceMoId": "632999466f72612d39b26942", + "Dn": "chassis-1-ioc-1-muxhostport-port-28", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EquipmentIoCardBase": { + "ClassId": "mo.MoRef", + "Moid": "632b13c976752d32362fc244", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13c976752d32362fc244" + }, + "MacAddress": "A8:4F:B1:55:4D:9E", + "ModTime": "2022-11-12T10:34:19.385Z", + "Mode": "access", + "ModuleId": 1, + "Moid": "632b175c6373582d42a0227d", + "ObjectType": "ether.HostPort", + "OperSpeed": "auto", + "OperState": "down", + "OperStateQual": "admin-down", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b13c976752d32362fc244", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13c976752d32362fc244" + }, + "PeerDn": "", + "PeerInterface": null, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "PortChannelId": 0, + "PortId": 28, + "PortType": "Ethernet", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Rn": "", + "Role": "unknown", + "SharedScope": "", + "SlotId": 1, + "Speed": "auto", + "SwitchId": "B", + "Tags": [], + "TransceiverType": "unknown" + } +``` \ No newline at end of file diff --git a/lib/intersight/ethernet_host_port/info.py b/lib/intersight/ethernet_host_port/info.py new file mode 100644 index 00000000..bf60afe5 --- /dev/null +++ b/lib/intersight/ethernet_host_port/info.py @@ -0,0 +1,39 @@ +class EthernetHostPortInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['Name'] = '%s/%s/%s' % ( + managed_object['ModuleId'], + managed_object['SlotId'], + managed_object['PortId'] + ) + info['IoModuleId'] = managed_object['EquipmentIoCardBase']['Moid'] + info['MacAddress'] = managed_object['MacAddress'] + info['Mode'] = managed_object['Mode'] + info['ModuleId'] = managed_object['ModuleId'] + info['OperSpeed'] = managed_object['OperSpeed'] + info['OperState'] = managed_object['OperState'] + info['Up'] = False + if info['OperState'] == 'up': + info['Up'] = True + info['OperStateQual'] = managed_object['OperStateQual'] + info['PeerDn'] = managed_object['PeerDn'] + info['PeerInterfaceId'] = None + info['PeerInterfaceType'] = None + if managed_object['PeerInterface'] is not None: + info['PeerInterfaceId'] = managed_object['PeerInterface']['Moid'] + info['PeerInterfaceType'] = managed_object['PeerInterface']['ObjectType'] + info['PortChannelId'] = managed_object['PortChannelId'] + info['PortId'] = managed_object['PortId'] + info['PortType'] = managed_object['PortType'] + info['SlotId'] = managed_object['SlotId'] + info['Speed'] = managed_object['Speed'] + info['SwitchId'] = managed_object['SwitchId'] + info['Role'] = managed_object['Role'] + info['TransceiverType'] = managed_object['TransceiverType'] + + return info diff --git a/lib/intersight/ethernet_host_port/main.py b/lib/intersight/ethernet_host_port/main.py new file mode 100644 index 00000000..b0840bc1 --- /dev/null +++ b/lib/intersight/ethernet_host_port/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.ethernet_host_port.info import EthernetHostPortInfo + + +class EthernetHostPort(IntersightCommon, EthernetHostPortInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'ether hostport' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EthernetHostPortInfo.__init__(self) diff --git a/lib/intersight/ethernet_network_port/__init__.py b/lib/intersight/ethernet_network_port/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/ethernet_network_port/class.md b/lib/intersight/ethernet_network_port/class.md new file mode 100644 index 00000000..427bb823 --- /dev/null +++ b/lib/intersight/ethernet_network_port/class.md @@ -0,0 +1,85 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AcknowledgedPeerInterface": { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98dd", + "ObjectType": "ether.PhysicalPort", + "link": "https://www.intersight.com/api/v1/ether/PhysicalPorts/6329994b76752d3236cd98dd" + }, + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc17c", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13c876752d32362fc17c" + }, + { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc175", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13c876752d32362fc175" + } + ], + "ClassId": "ether.NetworkPort", + "CreateTime": "2022-09-22T15:40:29.432Z", + "DeviceMoId": "632999466f72612d39b26942", + "Dn": "chassis-1-ioc-2-slot-2-port-3", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EquipmentIoCardBase": { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc17c", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13c876752d32362fc17c" + }, + "ModTime": "2022-10-14T10:35:57.25Z", + "ModuleId": 0, + "Moid": "632c81ed76752d32369daa9c", + "ObjectType": "ether.NetworkPort", + "OperState": "up", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b13c876752d32362fc17c", + "ObjectType": "equipment.IoCard", + "link": "https://www.intersight.com/api/v1/equipment/IoCards/632b13c876752d32362fc17c" + }, + "PeerDn": "", + "PeerInterface": { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98dd", + "ObjectType": "ether.PhysicalPort", + "link": "https://www.intersight.com/api/v1/ether/PhysicalPorts/6329994b76752d3236cd98dd" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "PortId": 3, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Rn": "", + "SharedScope": "", + "SlotId": 2, + "Speed": "10G", + "SwitchId": "A", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/ethernet_network_port/info.py b/lib/intersight/ethernet_network_port/info.py new file mode 100644 index 00000000..a6660abd --- /dev/null +++ b/lib/intersight/ethernet_network_port/info.py @@ -0,0 +1,31 @@ +class EthernetNetworkPortInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['Name'] = '%s/%s' % ( + managed_object['SlotId'], + managed_object['PortId'] + ) + + info['IoModuleId'] = managed_object['EquipmentIoCardBase']['Moid'] + info['ModuleId'] = managed_object['ModuleId'] + info['OperState'] = managed_object['OperState'] + info['Up'] = False + if info['OperState'] == 'up': + info['Up'] = True + info['PeerDn'] = managed_object['PeerDn'] + info['PeerInterfaceId'] = None + info['PeerInterfaceType'] = None + if managed_object['PeerInterface'] is not None: + info['PeerInterfaceId'] = managed_object['PeerInterface']['Moid'] + info['PeerInterfaceType'] = managed_object['PeerInterface']['ObjectType'] + info['PortId'] = managed_object['PortId'] + info['SlotId'] = managed_object['SlotId'] + info['Speed'] = managed_object['Speed'] + info['SwitchId'] = managed_object['SwitchId'] + + return info diff --git a/lib/intersight/ethernet_network_port/main.py b/lib/intersight/ethernet_network_port/main.py new file mode 100644 index 00000000..7df3d590 --- /dev/null +++ b/lib/intersight/ethernet_network_port/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.ethernet_network_port.info import EthernetNetworkPortInfo + + +class EthernetNetworkPort(IntersightCommon, EthernetNetworkPortInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'ether networkport' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EthernetNetworkPortInfo.__init__(self) \ No newline at end of file diff --git a/lib/intersight/ethernet_physical_port/__init__.py b/lib/intersight/ethernet_physical_port/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/ethernet_physical_port/class.md b/lib/intersight/ethernet_physical_port/class.md new file mode 100644 index 00000000..d94de2d3 --- /dev/null +++ b/lib/intersight/ethernet_physical_port/class.md @@ -0,0 +1,103 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AcknowledgedPeerInterface": null, + "AdminSpeed": "", + "AdminState": "Enabled", + "AggregatePortId": 0, + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98b3", + "ObjectType": "port.Group", + "link": "https://www.intersight.com/api/v1/port/Groups/6329994b76752d3236cd98b3" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98b1", + "ObjectType": "equipment.SwitchCard", + "link": "https://www.intersight.com/api/v1/equipment/SwitchCards/6329994b76752d3236cd98b1" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98af", + "ObjectType": "network.Element", + "link": "https://www.intersight.com/api/v1/network/Elements/6329994b76752d3236cd98af" + } + ], + "ClassId": "ether.PhysicalPort", + "CreateTime": "2022-09-20T10:43:23.203Z", + "DeviceMoId": "632999466f72612d39b26942", + "DisplayNames": { + "hierarchical": [ + "ethport-21" + ], + "short": [ + "Ethport-21" + ] + }, + "Dn": "switch-FDO26340DE3/slot-1/switch-ether/port-21", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "InventoryDeviceInfo": null, + "LicenseGrace": "", + "LicenseState": "", + "MacAddress": "00:08:31:1B:AA:5C", + "ModTime": "2022-11-12T18:32:04.303Z", + "Mode": "fex-fabric", + "Moid": "6329994b76752d3236cd98dd", + "Name": "", + "ObjectType": "ether.PhysicalPort", + "OperSpeed": "25G", + "OperState": "up", + "OperStateQual": "none", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98b3", + "ObjectType": "port.Group", + "link": "https://www.intersight.com/api/v1/port/Groups/6329994b76752d3236cd98b3" + }, + "PeerDn": "", + "PeerInterface": null, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "PortChannelId": 1025, + "PortGroup": { + "ClassId": "mo.MoRef", + "Moid": "6329994b76752d3236cd98b3", + "ObjectType": "port.Group", + "link": "https://www.intersight.com/api/v1/port/Groups/6329994b76752d3236cd98b3" + }, + "PortId": 21, + "PortSubGroup": null, + "PortType": "", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Rn": "", + "Role": "Server", + "SharedScope": "", + "SlotId": 1, + "SwitchId": "A", + "Tags": [], + "TransceiverType": "SFP-25G-AOC2M" + } +``` \ No newline at end of file diff --git a/lib/intersight/ethernet_physical_port/info.py b/lib/intersight/ethernet_physical_port/info.py new file mode 100644 index 00000000..e01dea9a --- /dev/null +++ b/lib/intersight/ethernet_physical_port/info.py @@ -0,0 +1,26 @@ +class EthernetPhysicalPortInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['Moid'] = managed_object['Moid'] + info['Dn'] = managed_object['Dn'] + info['Name'] = '%s/%s' % ( + managed_object['SlotId'], + managed_object['PortId'] + ) + info['AdminState'] = managed_object['AdminState'] + info['AggregatePortId'] = managed_object['AggregatePortId'] + info['MacAddress'] = managed_object['MacAddress'] + info['Mode'] = managed_object['Mode'] + info['OperSpeed'] = managed_object['OperSpeed'] + info['OperState'] = managed_object['OperState'] + info['PortId'] = managed_object['PortId'] + info['PortChannelId'] = managed_object['PortChannelId'] + info['Role'] = managed_object['Role'] + info['SlotId'] = managed_object['SlotId'] + info['SwitchId'] = managed_object['SwitchId'] + info['TransceiverType'] = managed_object['TransceiverType'] + + return info diff --git a/lib/intersight/ethernet_physical_port/main.py b/lib/intersight/ethernet_physical_port/main.py new file mode 100644 index 00000000..d0b28bf0 --- /dev/null +++ b/lib/intersight/ethernet_physical_port/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.ethernet_physical_port.info import EthernetPhysicalPortInfo + + +class EthernetPhysicalPort(IntersightCommon, EthernetPhysicalPortInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'ether physicalport' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + EthernetPhysicalPortInfo.__init__(self) \ No newline at end of file diff --git a/lib/intersight/graphics_card/__init__.py b/lib/intersight/graphics_card/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/graphics_card/class.md b/lib/intersight/graphics_card/class.md new file mode 100644 index 00000000..d2e7bb98 --- /dev/null +++ b/lib/intersight/graphics_card/class.md @@ -0,0 +1,250 @@ +``` +{ + "AccountMoid": "5a0a0877b657050001659aff", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6d", + "ObjectType": "pci.Node", + "link": "https://intersight.com/api/v1/pci/Nodes/6621228b76752d3001efbc6d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "65fa07d976752d300152cacb", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/65fa07d976752d300152cacb" + } + ], + "CardId": 0, + "ClassId": "graphics.Card", + "ComputeBlade": null, + "ComputeBoard": null, + "ComputeRackUnit": null, + "CreateTime": "2024-04-18T13:39:23.741Z", + "Description": "NVIDIA A40 PCIe FHFL DS 48GB GDDR6 300W", + "DeviceId": 8757, + "DeviceMoId": "65fa990a6f72613001fcd492", + "Dn": "/redfish/v1/Systems/FCH25337EJ9/Processors/CHASSIS-SLOT4-RISER1A-SLOT1", + "DomainGroupMoid": "5b2541917a7662743465cfeb", + "ExpanderSlot": "", + "FirmwareVersion": "94.02.5C.00.03-G133.0200.00.05", + "GpuId": "PCIe-Node4-GPU1", + "GraphicsControllers": [ + { + "AccountMoid": "5a0a0877b657050001659aff", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6d", + "ObjectType": "pci.Node", + "link": "https://intersight.com/api/v1/pci/Nodes/6621228b76752d3001efbc6d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "65fa07d976752d300152cacb", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/65fa07d976752d300152cacb" + } + ], + "ClassId": "graphics.Controller", + "ControllerId": 1, + "CreateTime": "2024-04-18T13:39:23.747Z", + "DeviceMoId": "", + "Dn": "/redfish/v1/Systems/FCH25337EJ9/Processors/CHASSIS-SLOT4-RISER1A-SLOT1-1", + "DomainGroupMoid": "5b2541917a7662743465cfeb", + "GraphicsCard": { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + }, + "InventoryDeviceInfo": null, + "IsUpgraded": false, + "ModTime": "2024-05-08T13:30:09.592Z", + "Model": "UCSC-GPU-A40", + "Moid": "6621228b76752d3001efbc71", + "ObjectType": "graphics.Controller", + "Owners": [ + "5a0a0877b657050001659aff", + "65f9b2676f72613001fad35d", + "65fa990a6f72613001fcd492" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + }, + "PciAddr": "31:0.0", + "PciSlot": "CHASSIS-SLOT4-RISER1A-SLOT1", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddec94c6972652d3101bdce", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5ddec94c6972652d3101bdce" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": null, + "Revision": "", + "Rn": "", + "Serial": "1562721013334", + "SharedScope": "", + "Tags": [], + "Vendor": "NVIDIA" + } + ], + "InventoryDeviceInfo": null, + "IsPlatformSupported": true, + "IsUpgraded": true, + "ModTime": "2024-05-12T23:05:04.197Z", + "Mode": "", + "Model": "UCSC-GPU-A40", + "Moid": "6621228b76752d3001efbc6f", + "NumGpus": "1", + "ObjectType": "graphics.Card", + "OperReason": [], + "OperState": "OK", + "Owners": [ + "5a0a0877b657050001659aff", + "65f9b2676f72613001fad35d", + "65fa990a6f72613001fcd492" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6d", + "ObjectType": "pci.Node", + "link": "https://intersight.com/api/v1/pci/Nodes/6621228b76752d3001efbc6d" + }, + "PartNumber": "30-100281-01", + "PciAddress": "", + "PciAddressList": "", + "PciDevice": null, + "PciNode": { + "AccountMoid": "5a0a0877b657050001659aff", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "65fa07d976752d300152cacb", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/65fa07d976752d300152cacb" + } + ], + "ChassisId": "1", + "ClassId": "pci.Node", + "ComputeBlade": { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + "CreateTime": "2024-04-18T13:39:23.733Z", + "DeviceMoId": "65fa990a6f72613001fcd492", + "Dn": "/redfish/v1/Chassis/FCH261171XR/Assembly#/Assemblies/CHASSIS-SLOT4", + "DomainGroupMoid": "5b2541917a7662743465cfeb", + "GraphicsCards": [ + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + } + ], + "InventoryDeviceInfo": null, + "IsUpgraded": false, + "ModTime": "2024-05-08T13:30:09.583Z", + "Model": "UCSX-440P", + "Moid": "6621228b76752d3001efbc6d", + "ObjectType": "pci.Node", + "OperReason": [], + "Owners": [ + "5a0a0877b657050001659aff", + "65f9b2676f72613001fad35d", + "65fa990a6f72613001fcd492" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddec94c6972652d3101bdce", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5ddec94c6972652d3101bdce" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "65fa990a6f72613001fcd492", + "ObjectType": "asset.DeviceRegistration", + "link": "https://intersight.com/api/v1/asset/DeviceRegistrations/65fa990a6f72613001fcd492" + }, + "Revision": "", + "Rn": "", + "Serial": "FCH261171XR", + "SharedScope": "", + "SlotId": "4", + "Tags": [], + "Vendor": "Cisco Systems Inc" + }, + "PciSlot": "CHASSIS-SLOT4-RISER1A-SLOT1", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddec94c6972652d3101bdce", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5ddec94c6972652d3101bdce" + } + ], + "Pid": "UCSC-GPU-A40", + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "65fa990a6f72613001fcd492", + "ObjectType": "asset.DeviceRegistration", + "link": "https://intersight.com/api/v1/asset/DeviceRegistrations/65fa990a6f72613001fcd492" + }, + "Revision": "", + "Rn": "", + "RunningFirmware": [], + "Serial": "1562721013334", + "SharedScope": "", + "SubDeviceId": 5210, + "SubVendorId": 4318, + "Tags": [], + "Vendor": "NVIDIA", + "VendorId": 4318 +} +``` \ No newline at end of file diff --git a/lib/intersight/graphics_card/info.py b/lib/intersight/graphics_card/info.py new file mode 100644 index 00000000..32cc4a20 --- /dev/null +++ b/lib/intersight/graphics_card/info.py @@ -0,0 +1,50 @@ +class GraphicsCardInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + keys = [ + 'CardId', + 'Description', + 'DeviceId', + 'Dn', + 'FirmwareVersion', + 'GpuId', + 'Model', + 'Moid', + 'NumGpus', + 'OperState', + 'PartNumber', + 'PciSlot', + 'Pid', + 'Presence', + 'Serial', + 'SubDeviceId', + 'SubVendorId', + 'Vendor', + 'VendorId' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['SlotId'] = info['PciSlot'] + + info['ChassisMoid'] = None + info['BladeMoid'] = None + info['PciNodeId'] = None + + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['ObjectType'] == 'pci.Node': + info['PciNodeId'] = ancestor_mo['Moid'] + + if ancestor_mo['ObjectType'] == 'compute.Blade': + info['BladeMoid'] = ancestor_mo['Moid'] + + if ancestor_mo['ObjectType'] == 'equipment.Chassis': + info['ChassisMoid'] = ancestor_mo['Moid'] + + return info diff --git a/lib/intersight/graphics_card/main.py b/lib/intersight/graphics_card/main.py new file mode 100644 index 00000000..f10fe041 --- /dev/null +++ b/lib/intersight/graphics_card/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.graphics_card.info import GraphicsCardInfo + + +class GraphicsCard(IntersightCommon, GraphicsCardInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'graphics card' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + GraphicsCardInfo.__init__(self) diff --git a/lib/intersight/graphics_controller/__init__.py b/lib/intersight/graphics_controller/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/graphics_controller/class.md b/lib/intersight/graphics_controller/class.md new file mode 100644 index 00000000..72bd21c5 --- /dev/null +++ b/lib/intersight/graphics_controller/class.md @@ -0,0 +1,79 @@ +``` +{ + "AccountMoid": "5a0a0877b657050001659aff", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6d", + "ObjectType": "pci.Node", + "link": "https://intersight.com/api/v1/pci/Nodes/6621228b76752d3001efbc6d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "65fa07d976752d300152cacb", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/65fa07d976752d300152cacb" + } + ], + "ClassId": "graphics.Controller", + "ControllerId": 1, + "CreateTime": "2024-04-18T13:39:23.747Z", + "DeviceMoId": "", + "Dn": "/redfish/v1/Systems/FCH25337EJ9/Processors/CHASSIS-SLOT4-RISER1A-SLOT1-1", + "DomainGroupMoid": "5b2541917a7662743465cfeb", + "GraphicsCard": { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + }, + "InventoryDeviceInfo": null, + "IsUpgraded": false, + "ModTime": "2024-05-08T13:30:09.592Z", + "Model": "UCSC-GPU-A40", + "Moid": "6621228b76752d3001efbc71", + "ObjectType": "graphics.Controller", + "Owners": [ + "5a0a0877b657050001659aff", + "65f9b2676f72613001fad35d", + "65fa990a6f72613001fcd492" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + }, + "PciAddr": "31:0.0", + "PciSlot": "CHASSIS-SLOT4-RISER1A-SLOT1", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddec94c6972652d3101bdce", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5ddec94c6972652d3101bdce" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": null, + "Revision": "", + "Rn": "", + "Serial": "1562721013334", + "SharedScope": "", + "Tags": [], + "Vendor": "NVIDIA" +} +``` \ No newline at end of file diff --git a/lib/intersight/graphics_controller/info.py b/lib/intersight/graphics_controller/info.py new file mode 100644 index 00000000..4e3915a5 --- /dev/null +++ b/lib/intersight/graphics_controller/info.py @@ -0,0 +1,45 @@ +class GraphicsControllerInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + keys = [ + 'ControllerId', + 'Dn', + 'Model', + 'Moid', + 'PciAddr', + 'PciSlot', + 'Presence', + 'Serial', + 'Vendor' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['Pid'] = info['Model'] + info['SlotId'] = info['PciSlot'] + + info['ChassisMoid'] = None + info['BladeMoid'] = None + info['PciNodeId'] = None + info['GraphicsCardId'] = None + + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['ObjectType'] == 'graphics.Card': + info['GraphicsCardId'] = ancestor_mo['Moid'] + + if ancestor_mo['ObjectType'] == 'pci.Node': + info['PciNodeId'] = ancestor_mo['Moid'] + + if ancestor_mo['ObjectType'] == 'compute.Blade': + info['BladeMoid'] = ancestor_mo['Moid'] + + if ancestor_mo['ObjectType'] == 'equipment.Chassis': + info['ChassisMoid'] = ancestor_mo['Moid'] + + return info diff --git a/lib/intersight/graphics_controller/main.py b/lib/intersight/graphics_controller/main.py new file mode 100644 index 00000000..473e7e59 --- /dev/null +++ b/lib/intersight/graphics_controller/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.graphics_controller.info import GraphicsControllerInfo + + +class GraphicsController(IntersightCommon, GraphicsControllerInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'graphics controller' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + GraphicsControllerInfo.__init__(self) diff --git a/lib/intersight/hcl_operating_system/__init__.py b/lib/intersight/hcl_operating_system/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/hcl_operating_system/class.md b/lib/intersight/hcl_operating_system/class.md new file mode 100644 index 00000000..2fa359ea --- /dev/null +++ b/lib/intersight/hcl_operating_system/class.md @@ -0,0 +1,24 @@ +``` + { + "AccountMoid": "", + "Ancestors": [], + "ClassId": "hcl.OperatingSystem", + "CreateTime": "2019-02-08T01:20:11.049Z", + "DomainGroupMoid": "SystemDomainGroup", + "ModTime": "2019-02-08T01:20:11.053Z", + "Moid": "5c5cd94b3535383637d7b0b4", + "ObjectType": "hcl.OperatingSystem", + "Owners": [ + "system" + ], + "SharedScope": "", + "Tags": [], + "Vendor": { + "ClassId": "mo.MoRef", + "Moid": "5b7370f16836726e35cc7025", + "ObjectType": "hcl.OperatingSystemVendor", + "link": "https://www.intersight.com/api/v1/hcl/OperatingSystemVendors/5b7370f16836726e35cc7025" + }, + "Version": "CentOS 7.6" + } +``` \ No newline at end of file diff --git a/lib/intersight/hcl_operating_system/main.py b/lib/intersight/hcl_operating_system/main.py new file mode 100644 index 00000000..b32a383a --- /dev/null +++ b/lib/intersight/hcl_operating_system/main.py @@ -0,0 +1,44 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight import hcl_operating_system_vendor + + +class HclOperatingSystem(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'hcl operatingsystem' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + self.log_id = log_id + + def get_vendor_versions(self, vendor_id): + all_versions = IntersightCommon.get_all(self) + if all_versions is None: + return None + + vendor_versions = [] + for version in all_versions: + if version['Vendor']['Moid'] == vendor_id: + vendor_versions.append(version) + + return vendor_versions + + def get_vendor_version_id(self, vendor_id, version_name): + version = self.get_vendor_version(vendor_id, version_name) + if version is not None: + return version['Moid'] + return None + + def get_vendor_version(self, vendor_id, version_name): + all_versions = IntersightCommon.get_all(self) + if all_versions is None: + return None + + for version in all_versions: + if version['Vendor']['Moid'] == vendor_id: + if version['Version'] == version_name: + return version + + return None + + def is_vendor_version(self, vendor_id, version_name): + if self.get_vendor_version(vendor_id, version_name) is None: + return False + return True diff --git a/lib/intersight/hcl_operating_system_vendor/__init__.py b/lib/intersight/hcl_operating_system_vendor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/hcl_operating_system_vendor/class.md b/lib/intersight/hcl_operating_system_vendor/class.md new file mode 100644 index 00000000..2a37f173 --- /dev/null +++ b/lib/intersight/hcl_operating_system_vendor/class.md @@ -0,0 +1,18 @@ +``` + { + "AccountMoid": "", + "Ancestors": [], + "ClassId": "hcl.OperatingSystemVendor", + "CreateTime": "2018-08-15T00:16:49.873Z", + "DomainGroupMoid": "SystemDomainGroup", + "ModTime": "2018-08-15T00:16:49.886Z", + "Moid": "5b7370f16836726e35cc7028", + "Name": "Microsoft", + "ObjectType": "hcl.OperatingSystemVendor", + "Owners": [ + "system" + ], + "SharedScope": "", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/hcl_operating_system_vendor/main.py b/lib/intersight/hcl_operating_system_vendor/main.py new file mode 100644 index 00000000..8b586024 --- /dev/null +++ b/lib/intersight/hcl_operating_system_vendor/main.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class HclOperatingSystemVendor(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'hcl operatingsystemvendor' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) diff --git a/lib/intersight/intersight_common.py b/lib/intersight/intersight_common.py new file mode 100644 index 00000000..df223b4b --- /dev/null +++ b/lib/intersight/intersight_common.py @@ -0,0 +1,269 @@ +import traceback +import time +from datetime import datetime + +from lib import isctl_helper +from lib import log_helper +from lib import info_helper +from lib import iaccount_helper + + +class IntersightCommon(): + def __init__(self, iaccount, iobject, get_filter=None, silent=False, verbose=False, debug=False, log_id=None, cache_key=None): + self.log = log_helper.Log(log_id=log_id) + self.iaccount = iaccount + self.isctl = isctl_helper.Isctl(iaccount, log_id=log_id) + self.iobject = iobject + self.info_helper = info_helper.InfoHelper(log_id=log_id) + self.ia_helper = iaccount_helper.IntersightAccount() + self.cache = None + self.cache_key = cache_key + if get_filter is None: + self.get_filter = '' + else: + self.get_filter = '--filter %s' % (get_filter) + self.get_expand = '' + self.get_order = '' + + self.flags = {} + self.flags['silent'] = silent + self.flags['verbose'] = verbose + self.flags['debug'] = debug + + def prepare_cache(self, force=False): + if self.cache_key is not None: + if self.log.is_cache(self.cache_key): + self.cache = self.log.get_cache(self.cache_key) + + if self.cache is None or force: + self.cache = self.get_all() + + def get_cache_moid(self, moid): + self.prepare_cache() + if self.cache is not None: + for item in self.cache: + if item['Moid'] == moid: + return item + return None + + def set_get_expand(self, get_expand): + self.get_expand = '--expand "%s"' % (get_expand) + + def set_get_filter(self, get_filter): + self.get_filter = '--filter "%s"' % (get_filter) + + def set_get_order(self, get_order): + self.get_filter = '--orderby "%s"' % (get_order) + + def get_top(self, top): + api_debug = True + if len(self.get_filter) == 0: + api_debug = False + + command = 'isctl get %s %s %s %s -o json --top %s' % ( + self.iobject, + self.get_filter, + self.get_expand, + self.get_order, + top + ) + + response = self.isctl.get(command, api_debug=api_debug) + return response + + def get_all(self, max_errors=3, error_timeout=1): + all_results = [] + top = 100 + skip = 0 + errors = 0 + + api_debug = True + if len(self.get_filter) == 0: + api_debug = False + + while True: + if skip == 0: + command = 'isctl get %s %s %s %s -o json --top %s' % ( + self.iobject, + self.get_filter, + self.get_expand, + self.get_order, + top + ) + else: + command = 'isctl get %s %s %s %s -o json --top %s --skip %s' % ( + self.iobject, + self.get_filter, + self.get_expand, + self.get_order, + top, + skip + ) + + response = self.isctl.get(command, api_debug=api_debug) + + if response is None: + self.log.error('iwe_common.get_all', 'Command failed: %s' % (command)) + if errors >= max_errors: + self.log.error('iwe_common.get_all', 'Max command failures: %s' % (command)) + break + + errors = errors + 1 + time.sleep(error_timeout) + continue + + all_results = all_results + response + if len(response) < top: + break + + skip = skip + top + + self.cache = all_results + return all_results + + def get(self, moid): + command = 'isctl get %s %s moid %s -o json' % ( + self.iobject, + self.get_expand, + moid + ) + response = self.isctl.get(command, api_debug=True) + return response + + def get_filtered(self, get_filter): + current_filter = self.get_filter + self.get_filter = get_filter + response = self.get_all() + self.get_filter = current_filter + return response + + def get_moid(self, name): + command = 'isctl get %s name "%s" -o json' % (self.iobject, name) + response = self.isctl.get(command, api_debug=True) + if response is None: + return None + if isinstance(response, list): + return None + return response['Moid'] + + def get_name(self, moid): + return self.get_object_attribute(moid, 'Name') + + def is_moid(self, moid): + return bool(self.get(moid) is not None) + + def is_name(self, name): + return bool(self.get_moid(name) is not None) + + def get_by_name(self, name): + command = 'isctl get %s name "%s" -o json' % (self.iobject, name) + response = self.isctl.get(command, api_debug=True) + if response is None: + return None + if isinstance(response, list): + return None + return response + + def get_moids_list(self): + return self.get_objects_attribute('Moid') + + def get_moids_dict(self): + moids = {} + attributes_list = self.get_objects_attributes(['Moid', 'Name']) + if attributes_list is not None: + for attributes in attributes_list: + moids[attributes['Moid']] = attributes['Name'] + return moids + + def get_object_attribute(self, moid, attribute_name): + attribute_value = None + item = self.get(moid) + if item is not None: + if attribute_name in item: + attribute_value = item[attribute_name] + return attribute_value + + def get_object_attributes(self, moid, attribute_names): + attribute_values = None + item = self.get(moid) + if item is not None: + attribute_values = {} + for attribute_name in attribute_names: + if attribute_name in item: + attribute_values[attribute_name] = item[attribute_name] + return attribute_values + + def get_objects_attribute(self, attribute_name, unique_only=False, sort=False): + attributes = [] + items = self.get_all() + if items is not None: + for i in items: + if attribute_name in i: + if not unique_only or i[attribute_name] not in attributes: + attributes.append(i[attribute_name]) + + if sort: + try: + attributes = sorted(attributes) + except BaseException: + self.log.error('iwe_common.get_objects_attribute', 'Sort failed: %s' % (traceback.format_exc())) + return None + + return attributes + + def get_objects_attributes(self, attribute_names, order_by=None): + objects_attributes = None + items = self.get_all() + if items is not None: + objects_attributes = [] + for item in items: + attributes = {} + for attribute_name in attribute_names: + if attribute_name in item: + attributes[attribute_name] = item[attribute_name] + + objects_attributes.append(attributes) + + if order_by is not None: + try: + objects_attributes = sorted(objects_attributes, key=lambda i: i[order_by]) + except BaseException: + self.log.error('iwe_common.get_objects_attributes', 'Sort failed: %s' % (traceback.format_exc())) + + return objects_attributes + + def create(self, attributes, get_response=False, json_conversion=True): + command = 'isctl create %s %s' % (self.iobject, attributes) + response = self.isctl.create(command, get_response=get_response, json_conversion=json_conversion) + return response + + def update(self, moid, attributes): + command = 'isctl update %s moid %s %s' % (self.iobject, moid, attributes) + response = self.isctl.update(command) + return response + + def delete(self, moid): + command = 'isctl delete %s moid %s' % (self.iobject, moid) + response = self.isctl.delete(command) + return response + + def convert_time_epoch(self, time_string): + """Return epoch ms time from string in workflow info object + + Args: + time_string (string): time string + + Returns: + int: epoch ms + """ + try: + time_string = time_string.replace('T', ' ').replace('Z', '000') + return int(datetime.strptime(time_string, '%Y-%m-%d %H:%M:%S.%f').timestamp() * 1000) + except BaseException: + return None + + def get_iaccount_json_file(self, filename): + return self.ia_helper.get_iaccount_json_file(self.iaccount, filename) + + def set_iaccount_json_file(self, filename, content): + return self.ia_helper.set_iaccount_json_file(self.iaccount, filename, content) diff --git a/lib/intersight/lcm/__init__.py b/lib/intersight/lcm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/lcm/common.py b/lib/intersight/lcm/common.py new file mode 100644 index 00000000..586869fc --- /dev/null +++ b/lib/intersight/lcm/common.py @@ -0,0 +1,300 @@ +import time +import json + +from progress.bar import IncrementalBar + +from lib.intersight import compute +from lib import isctl_helper +from lib import log_helper +from lib import output_helper +from lib.intersight.organization import main as organization +from lib.intersight.compute_server_setting import main as compute_server_setting +from lib.intersight.workflow import main as workflow +from lib.intersight.workflow_task_info import main as workflow_task_info +from lib.intersight import workflow_info + + +class LcmServerCommon(): + def __init__(self, iaccount, silent=False, verbose=False, debug=False, log_id=None): + self.iaccount = iaccount + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper(log_id=log_id) + self.isctl = isctl_helper.Isctl(iaccount, log_id=log_id) + self.compute_handler = compute.Compute(iaccount, log_id=log_id) + self.workflow_handler = workflow.Workflow(iaccount, log_id=log_id) + self.workflow_task_info_handler = workflow_task_info.WorkflowTaskInfo(iaccount, log_id=log_id) + self.organization = organization.Organization(iaccount, log_id=log_id) + self.server_setting_handler = compute_server_setting.ComputeServerSetting(iaccount, log_id=log_id) + self.workflow_info_handler = workflow_info.WorkflowInfo( + iaccount, + silent=silent, + verbose=verbose, + debug=debug, + log_id=log_id + ) + + self.flags = {} + self.flags['silent'] = silent + self.flags['verbose'] = verbose + self.flags['debug'] = debug + + self.my_output.set_flags(self.flags['silent'], self.flags['verbose'], self.flags['debug']) + + def show_flags(self): + self.my_output.dictionary(self.flags, title='Flags', stream='debug') + + def get_server_setting_id(self, device_moid): + server_setting_id = self.server_setting_handler.get_id_by_device_moid( + device_moid + ) + if server_setting_id is None: + self.log.error( + 'get_server_setting_id', + 'No server setting id for device moid: %s' % (device_moid) + ) + return server_setting_id + + def get_server_workflow_info(self, servers_mo): + settings = {} + settings['workflow'] = 86400 + + cache_ttl = 1 + self.compute_handler.set_cache( + servers_mo, + settings, + cache_ttl + ) + + match_rules = {} + servers_info = self.compute_handler.get_info( + servers_mo, + settings, + match_rules, + cache_ttl, + prepare_cache=False + ) + + return servers_info + + def wait_workflows_start(self, servers, workflow_name, max_start_time=30): + start_time = int(time.time()) + for server in servers: + self.log.debug( + 'lcm_server_common.wait_workflows_start', + 'Server %s' % ( + server['Moid'] + ) + ) + server['LcmWorkflowId'] = None + + if not self.flags['silent']: + bar_handler = IncrementalBar('Workflows started', max=len(servers)) + bar_handler.goto(0) + + while True: + workflows = self.workflow_handler.get_last() + if workflows is None: + if int(time.time()) - start_time > max_start_time: + self.my_output.error('Max start waiting time elapsed') + return None + + time.sleep(5) + continue + + started = 0 + for server in servers: + if server['LcmWorkflowId'] is not None: + started = started + 1 + continue + + for workflow_item in workflows: + if not self.workflow_handler.is_server_workflow(server['Moid'], workflow_item): + continue + + if workflow_item['Name'] != workflow_name: + continue + + in_server_workflows = False + for server_workflow in server['Workflow']['Last']: + if workflow_item['Moid'] == server_workflow['Moid']: + in_server_workflows = True + break + + if in_server_workflows: + continue + + server['LcmWorkflowId'] = workflow_item['Moid'] + self.log.debug( + 'lcm_server_common.wait_workflows_start', + 'Server %s Workflow %s' % ( + server['Moid'], + workflow_item['Moid'] + ) + ) + started = started + 1 + break + + if not self.flags['silent']: + bar_handler.goto(started) + + if started == len(servers): + break + + if int(time.time()) - start_time > max_start_time: + self.my_output.error('Max start waiting time elapsed') + return None + + time.sleep(5) + + if not self.flags['silent']: + bar_handler.finish() + self.my_output.files_only('Workflows started: [#######################] %s/%s' % (len(servers), len(servers))) + + return servers + + def wait_workflows_end(self, servers, max_complete_time=60): + start_time = int(time.time()) + + if not self.flags['silent']: + bar_handler = IncrementalBar('Workflows finished', max=len(servers)) + bar_handler.goto(0) + + while True: + workflows = self.workflow_handler.get_last() + if workflows is None: + if int(time.time()) - start_time > max_complete_time: + self.my_output.error('Max start waiting time elapsed') + return None + + time.sleep(5) + continue + + finished = 0 + for server in servers: + server['__Output'] = {} + server['LcmWorkflowFinished'] = False + server['LcmWorkflowCompleted'] = False + + for workflow_item in workflows: + if workflow_item['Moid'] == server['LcmWorkflowId']: + server['LcmWorkflowStatus'] = workflow_item['Status'] + server['LcmWorkflowInfo'] = self.workflow_handler.get_info(workflow_item) + + if workflow_item['Status'] == 'COMPLETED': + server['LcmWorkflowFinished'] = True + server['LcmWorkflowCompleted'] = True + server['__Output']['LcmWorkflowStatus'] = 'Green' + finished = finished + 1 + + if workflow_item['Status'] == 'FAILED': + server['LcmWorkflowFinished'] = True + server['LcmWorkflowCompleted'] = False + server['__Output']['LcmWorkflowStatus'] = 'Red' + finished = finished + 1 + + break + + if not self.flags['silent']: + bar_handler.goto(finished) + + if finished == len(servers): + break + + if int(time.time()) - start_time > max_complete_time: + self.my_output.error('Max complete waiting time elapsed') + return None + + time.sleep(5) + + if not self.flags['silent']: + bar_handler.finish() + self.my_output.files_only('Workflows finished: [#######################] %s/%s' % (len(servers), len(servers))) + + for server in servers: + self.log.debug( + 'lcm_server_common.wait_workflows_end', + 'Server %s Workflow %s Status %s Finished %s Completed %s' % ( + server['Moid'], + server['LcmWorkflowId'], + server['LcmWorkflowStatus'], + server['LcmWorkflowFinished'], + server['LcmWorkflowCompleted'] + ) + ) + + return servers + + def wait_workflows(self, servers, workflow_name, max_start_time=120, max_complete_time=120, summary=False, details=False): + self.log.debug( + 'lcm_server_common.wait_workflows', + workflow_name + ) + + servers = self.wait_workflows_start(servers, workflow_name, max_start_time=max_start_time) + if servers is None: + return False + + servers = self.wait_workflows_end(servers, max_complete_time=max_complete_time) + if servers is None: + return False + + if self.flags['silent']: + return True + + if summary: + headers = [ + 'Server Moid', + 'Server Name', + 'Workflow ID', + 'Workflow Name', + 'Duration', + 'Status' + ] + + order = [ + 'Moid', + 'Name', + 'LcmWorkflowId', + 'LcmWorkflowInfo.Name', + 'LcmWorkflowInfo.Duration', + 'LcmWorkflowStatus' + ] + + self.my_output.my_table( + servers, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + success = True + for server in servers: + server_workflow_info = {} + server_workflow_info['server'] = server + server_workflow_info['workflow'] = server['LcmWorkflowInfo'] + server_workflow_info['tasks'] = self.workflow_task_info_handler.get_workflow_tasks_info( + server['LcmWorkflowId'] + ) + if details: + self.workflow_info_handler.print_workflow_info(server_workflow_info) + else: + self.workflow_info_handler.print_workflow_info(server_workflow_info, stream='info') + success = success and server['LcmWorkflowFinished'] and server['LcmWorkflowCompleted'] + + self.log.debug( + 'lcm_server_common.wait_workflows', + json.dumps( + servers, + indent=4 + ) + ) + + self.log.debug( + 'lcm_server_common.wait_workflows', + 'Success %s' % ( + success + ) + ) + + return success diff --git a/lib/intersight/lcm/locator.py b/lib/intersight/lcm/locator.py new file mode 100644 index 00000000..9fe1d432 --- /dev/null +++ b/lib/intersight/lcm/locator.py @@ -0,0 +1,79 @@ +from progress.bar import IncrementalBar + +from lib.intersight.lcm.common import LcmServerCommon + + +class LcmServerLocator(LcmServerCommon): + def __init__(self, iaccount, wait=True, dry_run=False, silent=False, verbose=False, debug=False, log_id=None): + self.dry_run = dry_run + self.wait = wait + self.max_start_time = 30 + self.max_complete_time = 60 + self.verbose = verbose + LcmServerCommon.__init__( + self, + iaccount, + silent=silent, + verbose=verbose, + debug=debug, + log_id=log_id + ) + + def locator_task(self, servers_mo, admin_state, workflow_name): + target_servers_mo = [] + for server_mo in servers_mo: + if 'ServerSettingId' not in server_mo: + server_mo['ServerSettingId'] = self.get_server_setting_id( + server_mo['DeviceMoId'] + ) + if server_mo['ServerSettingId'] is None: + continue + + server_mo['attributes'] = 'moid %s --AdminLocatorLedState %s' % ( + server_mo['ServerSettingId'], + admin_state + ) + command = 'isctl create compute updatecomputeserversetting %s' % (server_mo['attributes'].replace(' --', '\n\t--')) + self.my_output.info(command) + if self.dry_run: + self.my_output.default(command) + + target_servers_mo.append( + server_mo + ) + + if self.dry_run: + return True + + if self.wait: + self.my_output.default('Collect workflow information...') + servers = self.get_server_workflow_info(servers_mo) + + bar_handler = IncrementalBar('%s request' % (workflow_name), max=len(target_servers_mo)) + bar_handler.goto(0) + for server_mo in target_servers_mo: + if not self.server_setting_handler.set(server_mo['attributes']): + self.my_output.error('Request failed: %s' % (server_mo['attributes'])) + return False + bar_handler.next() + bar_handler.finish() + self.my_output.files_only('%s request: [#######################] %s/%s' % (workflow_name, len(target_servers_mo), len(target_servers_mo))) + + success = True + if self.wait: + success = self.wait_workflows( + servers, + workflow_name, + max_start_time=self.max_start_time, + max_complete_time=self.max_complete_time, + summary=True, + details=self.verbose + ) + + return success + + def locator_on(self, servers_mo): + return self.locator_task(servers_mo, 'On', 'Turn On Locator') + + def locator_off(self, servers_mo): + return self.locator_task(servers_mo, 'Off', 'Turn Off Locator') diff --git a/lib/intersight/lcm/power.py b/lib/intersight/lcm/power.py new file mode 100644 index 00000000..57ed0e5b --- /dev/null +++ b/lib/intersight/lcm/power.py @@ -0,0 +1,99 @@ +from progress.bar import IncrementalBar + +from lib.intersight.lcm.common import LcmServerCommon + + +class LcmServerPower(LcmServerCommon): + def __init__(self, iaccount, wait=True, dry_run=False, silent=False, verbose=False, debug=False, log_id=None): + self.dry_run = dry_run + self.silent = silent + self.wait = wait + self.max_start_time = 30 + self.max_complete_time = 60 + self.verbose = verbose + LcmServerCommon.__init__( + self, + iaccount, + silent=silent, + verbose=verbose, + debug=debug, + log_id=log_id + ) + + def power_task(self, servers_mo, power_state, workflow_name, label): + target_servers_mo = [] + for server_mo in servers_mo: + if 'ServerSettingId' not in server_mo: + server_mo['ServerSettingId'] = self.get_server_setting_id( + server_mo['DeviceMoId'] + ) + if server_mo['ServerSettingId'] is None: + continue + + server_mo['attributes'] = 'moid %s --AdminPowerState %s' % ( + server_mo['ServerSettingId'], + power_state + ) + command = 'isctl create compute updatecomputeserversetting %s' % (server_mo['attributes'].replace(' --', '\n\t--')) + self.my_output.info(command) + if self.dry_run: + self.my_output.default(command) + + target_servers_mo.append( + server_mo + ) + + if self.dry_run: + return True + + if self.wait: + self.my_output.default('Collect workflow information...') + servers = self.get_server_workflow_info(servers_mo) + + if self.silent: + for server_mo in target_servers_mo: + if not self.server_setting_handler.set(server_mo['attributes']): + self.my_output.error('Request failed: %s' % (server_mo['attributes'])) + return False + + if not self.silent: + bar_handler = IncrementalBar('%s request' % (label), max=len(target_servers_mo)) + bar_handler.goto(0) + for server_mo in target_servers_mo: + if not self.server_setting_handler.set(server_mo['attributes']): + self.my_output.error('Request failed: %s' % (server_mo['attributes'])) + return False + bar_handler.next() + bar_handler.finish() + self.my_output.files_only('%s request: [#######################] %s/%s' % (label, len(target_servers_mo), len(target_servers_mo))) + + success = True + if self.wait: + success = self.wait_workflows( + servers, + workflow_name, + max_start_time=self.max_start_time, + max_complete_time=self.max_complete_time, + summary=True, + details=self.verbose + ) + + return success + + def power_on(self, servers_mo): + return self.power_task(servers_mo, 'PowerOn', 'Power On', 'Power On') + + def power_off(self, servers_mo): + return self.power_task(servers_mo, 'PowerOff', 'Power Off', 'Power Off') + + def power_cycle(self, servers_mo): + return self.power_task(servers_mo, 'PowerCycle', 'Power Cycle', 'Power Cycle') + + def power_hard(self, servers_mo): + return self.power_task(servers_mo, 'HardReset', 'Hard Reset', 'Hard Reset') + + def power_reboot(self, servers_mo): + return self.power_task(servers_mo, 'Reboot', 'Reboot Management Controller', 'Reboot Management Controller') + + def power_shut(self, servers_mo): + return self.power_task(servers_mo, 'Shutdown', 'Shut Down OS', 'OS Shutdown') diff --git a/lib/intersight/lcm/tag.py b/lib/intersight/lcm/tag.py new file mode 100644 index 00000000..39f69b84 --- /dev/null +++ b/lib/intersight/lcm/tag.py @@ -0,0 +1,214 @@ +import json +from progress.bar import IncrementalBar + +from lib.intersight.lcm.common import LcmServerCommon +from lib import filter_helper + + +class LcmServerTag(LcmServerCommon): + def __init__(self, iaccount, wait=True, dry_run=False, silent=False, verbose=False, debug=False, log_id=None): + self.dry_run = dry_run + self.wait = wait + self.max_start_time = 30 + self.max_complete_time = 60 + LcmServerCommon.__init__( + self, + iaccount, + silent=silent, + verbose=verbose, + debug=debug, + log_id=log_id + ) + + def is_equal(self, tags_a, tags_b): + if len(tags_a) != len(tags_b): + return False + + for tag_a in tags_a: + tag_match = False + for tag_b in tags_b: + if tag_a['Key'] == tag_b['Key']: + if tag_a['Value'] == tag_b['Value']: + tag_match = True + break + + if not tag_match: + return False + + return True + + def add_tags(self, tags, new_tags): + for new_tag in new_tags: + updated = False + for tag in tags: + if tag['Key'] == new_tag.split(':')[0]: + tag['Value'] = new_tag.split(':')[1] + updated = True + + if not updated: + item = {} + item['Key'] = new_tag.split(':')[0] + item['Value'] = new_tag.split(':')[1] + tags.append( + item + ) + + return tags + + def add(self, servers_mo, tags): + commands = [] + for server_mo in servers_mo: + target_tag = self.add_tags( + server_mo['Tags'], + tags + ) + + if server_mo['ObjectType'] == 'compute.RackUnit': + command = 'isctl update compute rackunit moid %s --Tags=\'%s\'' % ( + server_mo['Moid'], + json.dumps(target_tag) + ) + + if server_mo['ObjectType'] == 'compute.Blade': + command = 'isctl update compute blade moid %s --Tags=\'%s\'' % ( + server_mo['Moid'], + json.dumps(target_tag) + ) + + commands.append(command) + if self.dry_run: + self.my_output.default(command) + + if self.dry_run: + return True + + bar_handler = IncrementalBar('Add tag request', max=len(commands)) + bar_handler.goto(0) + for command in commands: + if not self.isctl.update(command): + self.my_output.error('Command failed: %s' % (command)) + return False + bar_handler.next() + bar_handler.finish() + + return True + + def delete_tags(self, tags, delete_tags, except_tags=None): + new_tags = [] + for tag in tags: + if tag['Key'] == 'Intersight.LicenseTier': + new_tags.append(tag) + continue + + if except_tags is not None: + to_delete = True + for except_tag in except_tags: + if filter_helper.match_string(except_tag.split(':')[0], tag['Key']): + if filter_helper.match_string(except_tag.split(':')[1], tag['Value']): + to_delete = False + new_tags.append(tag) + + if not to_delete: + continue + + to_delete = False + for delete_tag in delete_tags: + if filter_helper.match_string(delete_tag.split(':')[0], tag['Key']): + if filter_helper.match_string(delete_tag.split(':')[1], tag['Value']): + to_delete = True + break + + if not to_delete: + new_tags.append( + tag + ) + + return new_tags + + def delete(self, servers_mo, tags): + commands = [] + for server_mo in servers_mo: + target_tag = self.delete_tags( + server_mo['Tags'], + tags + ) + + if self.is_equal(server_mo['Tags'], target_tag): + continue + + if server_mo['ObjectType'] == 'compute.RackUnit': + command = 'isctl update compute rackunit moid %s --Tags=\'%s\'' % ( + server_mo['Moid'], + json.dumps(target_tag) + ) + + if server_mo['ObjectType'] == 'compute.Blade': + command = 'isctl update compute blade moid %s --Tags=\'%s\'' % ( + server_mo['Moid'], + json.dumps(target_tag) + ) + + commands.append(command) + if self.dry_run: + self.my_output.default(command) + + if self.dry_run: + return True + + bar_handler = IncrementalBar('Delete tag request', max=len(commands)) + bar_handler.goto(0) + for command in commands: + if not self.isctl.update(command): + self.my_output.error('Command failed: %s' % (command)) + return False + bar_handler.next() + bar_handler.finish() + + return True + + def set(self, servers_mo, add_tags, delete_tags, except_tags): + commands = [] + for server_mo in servers_mo: + target_tags = self.delete_tags( + server_mo['Tags'], + delete_tags, + except_tags=except_tags + ) + + target_tags = self.add_tags( + target_tags, + add_tags + ) + + if self.is_equal(server_mo['Tags'], target_tags): + continue + + if server_mo['ObjectType'] == 'compute.RackUnit': + command = 'isctl update compute rackunit moid %s --Tags=\'%s\'' % ( + server_mo['Moid'], + json.dumps(target_tags) + ) + + if server_mo['ObjectType'] == 'compute.Blade': + command = 'isctl update compute blade moid %s --Tags=\'%s\'' % ( + server_mo['Moid'], + json.dumps(target_tags) + ) + + commands.append(command) + if self.dry_run: + self.my_output.default(command) + + if self.dry_run: + return True + + bar_handler = IncrementalBar('Set tag request', max=len(commands)) + bar_handler.goto(0) + for command in commands: + if not self.isctl.update(command): + self.my_output.error('Command failed: %s' % (command)) + return False + bar_handler.next() + bar_handler.finish() + + return True diff --git a/lib/intersight/management_interface/__init__.py b/lib/intersight/management_interface/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/management_interface/class.md b/lib/intersight/management_interface/class.md new file mode 100644 index 00000000..4f8c48d0 --- /dev/null +++ b/lib/intersight/management_interface/class.md @@ -0,0 +1,89 @@ +``` +{ + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "64b6a47476752d3901d8610d", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/64b6a47476752d3901d8610d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64b6a46976752d3901d85cfc", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/64b6a46976752d3901d85cfc" + } + ], + "ClassId": "management.Interface", + "CreateTime": "2023-07-18T14:40:41.987Z", + "DeviceMoId": "64b6a4486f726131019abb0a", + "Dn": "sys/rack-unit-1/mgmt/if-1", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EquipmentChassis": null, + "Gateway": "", + "HostName": "comp1-p1z-eu-spdc-WZP26510CZH", + "InventoryDeviceInfo": null, + "IpAddress": "", + "Ipv4Address": "", + "Ipv4Gateway": "", + "Ipv4Mask": "255.255.255.224", + "Ipv6Address": "::", + "Ipv6Gateway": "::", + "Ipv6Prefix": 64, + "MacAddress": "EC:F4:0C:38:32:B8", + "ManagementController": { + "ClassId": "mo.MoRef", + "Moid": "64b6a47476752d3901d8610d", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/64b6a47476752d3901d8610d" + }, + "Mask": "255.255.255.224", + "ModTime": "2023-09-26T17:54:02.076Z", + "Moid": "64b6a46976752d3901d85cfb", + "ObjectType": "management.Interface", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "64b6a4486f726131019abb0a" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "64b6a47476752d3901d8610d", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/64b6a47476752d3901d8610d" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "64b6a4486f726131019abb0a", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/64b6a4486f726131019abb0a" + }, + "Rn": "", + "SharedScope": "", + "SwitchId": "", + "Tags": [], + "UemConnStatus": "", + "VirtualHostName": "", + "VlanId": 1 +} +``` \ No newline at end of file diff --git a/lib/intersight/management_interface/info.py b/lib/intersight/management_interface/info.py new file mode 100644 index 00000000..7fa48d6d --- /dev/null +++ b/lib/intersight/management_interface/info.py @@ -0,0 +1,29 @@ +class ManagementInterfaceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'Gateway', + 'HostName', + 'IpAddress', + 'Ipv4Address', + 'Ipv4Gateway', + 'Ipv4Mask', + 'Ipv6Address', + 'Ipv6Gateway', + 'Ipv6Prefix', + 'MacAddress', + 'Mask', + 'Moid', + 'DeviceMoId' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + return info diff --git a/lib/intersight/management_interface/main.py b/lib/intersight/management_interface/main.py new file mode 100644 index 00000000..84595d91 --- /dev/null +++ b/lib/intersight/management_interface/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.management_interface.info import ManagementInterfaceInfo + + +class ManagementInterface(IntersightCommon, ManagementInterfaceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'management interface' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + ManagementInterfaceInfo.__init__(self) diff --git a/lib/intersight/memory_unit/__init__.py b/lib/intersight/memory_unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/memory_unit/class.md b/lib/intersight/memory_unit/class.md new file mode 100644 index 00000000..e57ee35d --- /dev/null +++ b/lib/intersight/memory_unit/class.md @@ -0,0 +1,112 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "AdminState": "policy", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c4d", + "ObjectType": "memory.Array", + "link": "https://www.intersight.com/api/v1/memory/Arrays/6311ac8376752d31398e5c4d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "ArrayId": 1, + "Bank": 1, + "Capacity": "16384", + "ClassId": "memory.Unit", + "Clock": "2400", + "CreateTime": "2022-09-02T07:10:59.81Z", + "DeviceMoId": "61c35fa36f72612d3005590c", + "DisplayNames": { + "hierarchical": [ + "memory-unit-DIMM_H3" + ], + "short": [ + "Memory-DIMM_H3" + ] + }, + "Dn": "sys/rack-unit-3/board/memarray-1/mem-24", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "FormFactor": "DIMM", + "InventoryDeviceInfo": null, + "Latency": "0.400000", + "Location": "DIMM_H3", + "MemoryArray": { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c4d", + "ObjectType": "memory.Array", + "link": "https://www.intersight.com/api/v1/memory/Arrays/6311ac8376752d31398e5c4d" + }, + "MemoryId": 24, + "ModTime": "2022-09-02T07:18:38.404Z", + "Model": "M393A2K40BB1-CRC", + "Moid": "6311ac8376752d31398e5c7d", + "ObjectType": "memory.Unit", + "OperPowerState": "not-supported", + "OperReason": [], + "OperState": "operable", + "Operability": "unknown", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311ac8376752d31398e5c4d", + "ObjectType": "memory.Array", + "link": "https://www.intersight.com/api/v1/memory/Arrays/6311ac8376752d31398e5c4d" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "Serial": "322E755D", + "Set": 0, + "SharedScope": "", + "Speed": "unspecified", + "Tags": [], + "Thermal": "ok", + "Type": "DDR4", + "Vendor": "0xCE00", + "Visibility": "yes", + "Width": "64" + } +``` \ No newline at end of file diff --git a/lib/intersight/memory_unit/info.py b/lib/intersight/memory_unit/info.py new file mode 100644 index 00000000..3ccc8983 --- /dev/null +++ b/lib/intersight/memory_unit/info.py @@ -0,0 +1,102 @@ +class MemoryUnitInfo(): + def __init__(self): + pass + + def is_memory_unit_ok(self, info): + if info['OperState'].lower() not in ['operable', 'ok']: + return False + + if info['Presence'].lower() not in ['equipped']: + return False + + if info['Thermal'].lower() not in ['ok', '']: + return False + + return True + + def get_memory_unit_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'ArrayId', + 'Bank', + 'Capacity', + 'Clock', + 'Description', + 'Dn', + 'FormFactor', + 'Latency', + 'Location', + 'MemoryId', + 'Model', + 'OperState', + 'Pid', + 'Presence', + 'Serial', + 'Speed', + 'Thermal', + 'Type', + 'Vendor' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['LatencyUnit'] = '' + if info['Latency'] not in ['unspecified', '']: + info['LatencyUnit'] = '%s ns' % ( + round( + float(info['Latency']), + 2 + ) + ) + + info['CapacityUnit'] = '' + if info['Capacity'] != 'unspecified': + info['CapacityUnit'] = self.info_helper.convert_memory( + int(info['Capacity']) * 1024 * 1024, + precision=0 + ) + + info['MemoryArrayId'] = None + info['ChassisId'] = None + info['ServerId'] = None + info['BoardId'] = None + for ancestor in managed_object['Ancestors']: + if ancestor['ObjectType'] == 'memory.Array': + info['MemoryArrayId'] = ancestor['Moid'] + if ancestor['ObjectType'] == 'compute.Board': + info['BoardId'] = ancestor['Moid'] + if ancestor['ObjectType'] == 'equipment.Chassis': + info['ChassisId'] = ancestor['Moid'] + if ancestor['ObjectType'] == 'compute.Blade': + info['ServerId'] = ancestor['Moid'] + if ancestor['ObjectType'] == 'compute.RackUnit': + info['ServerId'] = ancestor['Moid'] + + if info['Presence'].lower() in ['equipped']: + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + if info['OperState'].lower() in ['operable', 'ok']: + info['__Output']['OperState'] = 'Green' + else: + info['__Output']['OperState'] = 'Red' + + if len(info['Thermal']) > 0: + if info['Thermal'].lower() == 'ok': + info['__Output']['Thermal'] = 'Green' + else: + info['__Output']['Thermal'] = 'Red' + + if self.is_memory_unit_ok(info): + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + return info diff --git a/lib/intersight/memory_unit/main.py b/lib/intersight/memory_unit/main.py new file mode 100644 index 00000000..106d18af --- /dev/null +++ b/lib/intersight/memory_unit/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.memory_unit.info import MemoryUnitInfo + + +class MemoryUnit(IntersightCommon, MemoryUnitInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'memory unit' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + MemoryUnitInfo.__init__(self) diff --git a/lib/intersight/network_element_summary/__init__.py b/lib/intersight/network_element_summary/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/network_element_summary/class.md b/lib/intersight/network_element_summary/class.md new file mode 100644 index 00000000..bf45e345 --- /dev/null +++ b/lib/intersight/network_element_summary/class.md @@ -0,0 +1,103 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AdminEvacState": "disabled", + "AdminInbandInterfaceState": "disabled", + "AlarmSummary": { + "ClassId": "compute.AlarmSummary", + "Critical": 0, + "ObjectType": "compute.AlarmSummary", + "Warning": 0 + }, + "Ancestors": [], + "AvailableMemory": "", + "BundleVersion": "4.2(2c)", + "Chassis": "", + "ClassId": "network.ElementSummary", + "ConfModTs": "", + "ConfModTsBackup": "", + "ConnectionStatus": "Connected", + "CreateTime": "2022-09-20T10:43:23.145Z", + "DefaultDomain": "", + "DeviceMoId": "632999466f72612d39b26942", + "Dn": "switch-FDO26340DE3", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EthernetMode": "", + "EthernetSwitchingMode": "end-host", + "FaultSummary": 0, + "FcMode": "", + "FcSwitchingMode": "end-host", + "Firmware": "", + "FirmwareVersion": "9.3(5)I42(2c)", + "InbandIpAddress": "", + "InbandIpGateway": "", + "InbandIpMask": "255.255.255.0", + "InbandVlan": 0, + "Ipv4Address": "", + "ManagementMode": "Intersight", + "ModTime": "2022-11-17T08:40:04.045Z", + "Model": "UCS-FI-6454", + "Moid": "6329994b76752d3236cd98af", + "Name": "ucsX FI-A", + "NumEtherPorts": 54, + "NumEtherPortsConfigured": 16, + "NumEtherPortsLinkUp": 16, + "NumExpansionModules": 0, + "NumFcPorts": 0, + "NumFcPortsConfigured": 0, + "NumFcPortsLinkUp": 0, + "ObjectType": "network.ElementSummary", + "OperEvacState": "disabled", + "Operability": "online", + "OutOfBandIpAddress": "", + "OutOfBandIpGateway": "", + "OutOfBandIpMask": "255.255.255.0", + "OutOfBandIpv4Address": "", + "OutOfBandIpv4Gateway": "", + "OutOfBandIpv4Mask": "", + "OutOfBandIpv6Address": "", + "OutOfBandIpv6Gateway": "", + "OutOfBandIpv6Prefix": "", + "OutOfBandMac": "00:08:31:1B:AA:40", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "PartNumber": "", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "Presence": "", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "Revision": "0", + "Rn": "", + "Serial": "FDO26340DE3", + "SharedScope": "", + "SourceObjectType": "network.Element", + "Status": "", + "SwitchId": "A", + "SwitchType": "FabricInterconnect", + "SystemUpTime": "", + "Tags": [], + "Thermal": "ok", + "TotalMemory": 64265, + "Vendor": "Cisco Systems, Inc.", + "Version": "9.3(5)I42(2c)" + } +``` \ No newline at end of file diff --git a/lib/intersight/network_element_summary/info.py b/lib/intersight/network_element_summary/info.py new file mode 100644 index 00000000..e1444087 --- /dev/null +++ b/lib/intersight/network_element_summary/info.py @@ -0,0 +1,50 @@ +class NetworkElementSummaryInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + info['Moid'] = managed_object['Moid'] + info['Name'] = managed_object['Name'] + + if managed_object['AlarmSummary']['Warning'] == 0 and managed_object['AlarmSummary']['Critical'] == 0: + if managed_object['AlarmSummary']['Info'] == 0: + info['Health'] = 'Healthy' + info['HealthSummary'] = 'Healthy' + info['__Output']['HealthSummary'] = 'Green' + else: + info['Health'] = 'Warnings' + info['HealthSummary'] = 'Healthy (%s)' % (managed_object['AlarmSummary']['Info']) + info['__Output']['HealthSummary'] = 'Blue' + + if managed_object['AlarmSummary']['Warning'] > 0 and managed_object['AlarmSummary']['Critical'] == 0: + info['Health'] = 'Warnings' + info['HealthSummary'] = 'Warnings (%s)' % (managed_object['AlarmSummary']['Warning']) + info['__Output']['HealthSummary'] = 'Yellow' + + if managed_object['AlarmSummary']['Critical'] > 0: + info['Health'] = 'Critical' + info['HealthSummary'] = 'Critical (%s)' % (managed_object['AlarmSummary']['Critical']) + info['__Output']['HealthSummary'] = 'Red' + + info['ConnectionStatus'] = managed_object['ConnectionStatus'] + info['Dn'] = managed_object['Dn'] + info['Model'] = managed_object['Model'] + info['NumEtherPorts'] = managed_object['NumEtherPorts'] + info['NumEtherPortsConfigured'] = managed_object['NumEtherPortsConfigured'] + info['NumEtherPortsLinkUp'] = managed_object['NumEtherPortsLinkUp'] + info['NumEtherPortsSummary'] = '%s/%s/%s' % ( + info['NumEtherPortsLinkUp'], + info['NumEtherPortsConfigured'], + info['NumEtherPorts'] + ) + info['OutOfBandIpAddress'] = managed_object['OutOfBandIpAddress'] + info['OutOfBandIpGateway'] = managed_object['OutOfBandIpGateway'] + info['OutOfBandIpMask'] = managed_object['OutOfBandIpMask'] + info['Serial'] = managed_object['Serial'] + info['SwitchId'] = managed_object['SwitchId'] + info['Version'] = managed_object['Version'] + + return info diff --git a/lib/intersight/network_element_summary/main.py b/lib/intersight/network_element_summary/main.py new file mode 100644 index 00000000..2dbd4348 --- /dev/null +++ b/lib/intersight/network_element_summary/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.network_element_summary.info import NetworkElementSummaryInfo + + +class NetworkElementSummary(IntersightCommon, NetworkElementSummaryInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'network elementsummary' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + NetworkElementSummaryInfo.__init__(self) diff --git a/lib/intersight/organization/__init__.py b/lib/intersight/organization/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/organization/class.md b/lib/intersight/organization/class.md new file mode 100644 index 00000000..41f1055d --- /dev/null +++ b/lib/intersight/organization/class.md @@ -0,0 +1,41 @@ +``` + { + "Account": { + "ClassId": "mo.MoRef", + "Moid": "5be4b2ce67626c6d661ca38d", + "ObjectType": "iam.Account", + "link": "https://www.intersight.com/api/v1/iam/Accounts/5be4b2ce67626c6d661ca38d" + }, + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [], + "ClassId": "organization.Organization", + "CreateTime": "2019-12-09T10:09:55.507Z", + "Description": "EMEAR Service Provider DC Specialists", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "ModTime": "2020-11-02T17:27:23.443Z", + "Moid": "5dee1d736972652d321d26b5", + "Name": "EMEAR-SPDC-Specialists", + "ObjectType": "organization.Organization", + "Owners": [ + "5be4b2ce67626c6d661ca38d" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + } + ], + "ResourceGroups": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d716972652d321d269f", + "ObjectType": "resource.Group", + "link": "https://www.intersight.com/api/v1/resource/Groups/5dee1d716972652d321d269f" + } + ], + "SharedScope": "", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/organization/main.py b/lib/intersight/organization/main.py new file mode 100644 index 00000000..8bc3f80e --- /dev/null +++ b/lib/intersight/organization/main.py @@ -0,0 +1,42 @@ +import re +import traceback + +from lib.intersight.intersight_common import IntersightCommon + + +class Organization(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'organization organization' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + + def filter(self, tag=None, name=None, name_pattern=None, details=True): + filtered = [] + try: + response = IntersightCommon.get_all(self) + if response is None: + self.log.error('organization.filter', 'Possible bug on get all') + return filtered + + for item in response: + if tag is not None: + if tag not in item['Tags']: + continue + + if name is not None: + if item['Name'] != name: + continue + + if name_pattern is not None: + if not re.match(name_pattern, item['Name']): + continue + + if details: + filtered.append(item) + else: + filtered.append(item['Moid']) + + except BaseException: + self.log.error('organization.filter', traceback.format_exc()) + return None + + return filtered diff --git a/lib/intersight/os_configuration_file/__init__.py b/lib/intersight/os_configuration_file/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/os_configuration_file/main.py b/lib/intersight/os_configuration_file/main.py new file mode 100644 index 00000000..07dc5076 --- /dev/null +++ b/lib/intersight/os_configuration_file/main.py @@ -0,0 +1,24 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class OsConfigurationFile(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'os configurationfile' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + + def get_file_for_os(self, hcl_version_id): + os_files = [] + items = self.get_all() + if items is None: + return os_files + + for item in items: + match = False + for distribution in item['Distributions']: + if distribution['ObjectType'] == 'hcl.OperatingSystem' and distribution['Moid'] == hcl_version_id: + match = True + break + if match: + os_files.append(item) + + return os_files diff --git a/lib/intersight/os_image/__init__.py b/lib/intersight/os_image/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/os_image/os_image.py b/lib/intersight/os_image/os_image.py new file mode 100644 index 00000000..e4b92a15 --- /dev/null +++ b/lib/intersight/os_image/os_image.py @@ -0,0 +1,426 @@ +import json +import traceback +import yaml + +from lib.intersight.intersight_common import IntersightCommon +from lib import ip_helper +from lib.intersight import organization +from lib.intersight import hcl_operating_system_vendor +from lib.intersight import hcl_operating_system +from lib.intersight import software_repository_catalog + + +class OsImage(IntersightCommon): + """Class for Intersight operating system image + + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736567612d30276cb1", + "ObjectType": "softwarerepository.Catalog", + "link": "https://www.intersight.com/api/v1/softwarerepository/Catalogs/5dee1d736567612d30276cb1" + } + ], + "Catalog": { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736567612d30276cb1", + "ObjectType": "softwarerepository.Catalog", + "link": "https://www.intersight.com/api/v1/softwarerepository/Catalogs/5dee1d736567612d30276cb1" + }, + "ClassId": "softwarerepository.OperatingSystemFile", + "CreateTime": "2022-09-25T14:42:02.675Z", + "Description": "", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "DownloadCount": 0, + "ImportAction": "None", + "ImportState": "MetaOnly", + "ImportedTime": "0001-01-01T00:00:00Z", + "LastAccessTime": "0001-01-01T00:00:00Z", + "Md5eTag": "", + "Md5sum": "", + "ModTime": "2022-09-25T14:42:03.013Z", + "Moid": "633068b96567612d304a7844", + "Name": "Ubuntu 22.04LTS", + "ObjectType": "softwarerepository.OperatingSystemFile", + "Owners": [ + "5be4b2ce67626c6d661ca38d" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736567612d30276cb1", + "ObjectType": "softwarerepository.Catalog", + "link": "https://www.intersight.com/api/v1/softwarerepository/Catalogs/5dee1d736567612d30276cb1" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + } + ], + "ReleaseDate": "0001-01-01T00:00:00Z", + "Sha512sum": "", + "SharedScope": "", + "Size": 0, + "SoftwareAdvisoryUrl": "", + "Source": { + "ClassId": "softwarerepository.HttpServer", + "IsPasswordSet": false, + "LocationLink": "http:///2-IMAGES/ubuntu-22.04.1-live-server-amd64.iso", + "ObjectType": "softwarerepository.HttpServer", + "Username": "" + }, + "Tags": [], + "Vendor": "Ubuntu", + "Version": "Ubuntu Server 22.04 LTS", + "Verified": true, + "Link": "http:///2-IMAGES/ubuntu-22.04.1-live-server-amd64.iso" + } + """ + def __init__(self, iaccount, log_id=None): + self.iobject = 'softwarerepository operatingsystemfile' + self.hcl_os_vendor_handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=log_id) + self.hcl_os_version_handler = hcl_operating_system.HclOperatingSystem(iaccount, log_id=log_id) + + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + self.log_id = log_id + self.my_output = None + + def get_all(self, max_errors=3, error_timeout=1): + """Get all OS image objects + + Args: + max_errors (int, optional): if API call fails retry until max_errors. Defaults to 3. + error_timeout (int, optional): if API response takes longer than error_timeout, then consider API as failed. Defaults to 1. + + Extend the raw get API call with custom attributes + - Organization: organization name + - Type: url, nfs + - Link: normalized location + - Verified: check if url is reachable. not supported for nfs type + + Note: cfs type not supported + + Returns: + list of dict: list of Intersight OS image objects + """ + images = IntersightCommon.get_all(self, max_errors=max_errors, error_timeout=error_timeout) + if images is None: + return images + + organization_handler = organization.Organization(self.iaccount) + organizations = organization_handler.get_moids_dict() + + verified = [] + + keys = [ + 'Moid', + 'Name', + 'Source', + 'Tags', + 'Vendor', + 'Version' + ] + + for image in images: + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = image[key] + + organization_id = None + for permission in image['PermissionResources']: + if permission['ObjectType'] == 'organization.Organization': + organization_id = permission['Moid'] + + if organization_id is None or organization_id not in organizations: + # Organization ID must exist + continue + + info['Organization'] = organizations[organization_id] + info['Verified'] = False + info['Type'] = None + info['Link'] = None + + if info['Source']['ClassId'] not in ['softwarerepository.HttpServer', 'softwarerepository.NfsServer']: + continue + + if info['Source']['ClassId'] == 'softwarerepository.HttpServer': + info['Type'] = 'url' + info['Link'] = image['Source']['LocationLink'] + info['Verified'] = ip_helper.is_url_accessible(info['Link']) + + if info['Verified']: + info['__Output']['Link'] = 'Green' + else: + info['__Output']['Link'] = 'Red' + + if info['Source']['ClassId'] == 'softwarerepository.NfsServer': + info['Type'] = 'nfs' + info['Link'] = image['Source']['FileLocation'] + info['Verified'] = False + + verified.append(info) + + return verified + + def validate_add(self, image, name_unique=True): + """Validate os image create attributes + + Args: + image (dict): image attributes + name_unique (bool, optional): check if Name already exists. Defaults to True. + + Expected attributes: Name, Vendor, Version, Link and Organization + Vendor and Version must be defined in HCL catalog + Organization (name) must exist + If name_unique, then Name cannot already exist + + Returns: + bool: validation success + string: if validation fails, contains information on the reason + """ + try: + if not isinstance(image, dict): + return False, 'Dict image attributes required' + + for key in ['Name', 'Vendor', 'Version', 'Link', 'Organization']: + if key not in image: + return False, 'Attribute %s required' % (key) + + if image['Vendor'] == '': + return False, 'Define vendor' + + vendor_attributes = self.hcl_os_vendor_handler.get_by_name(image['Vendor']) + if vendor_attributes is None: + return False, 'Vendor not found: %s' % (image['Vendor']) + vendor_id = vendor_attributes['Moid'] + + if image['Version'] == '': + return False, 'Define version' + + if not self.hcl_os_version_handler.is_vendor_version(vendor_id, image['Version']): + return False, 'Invalid version for vendor: %s' % (image['Version']) + + organization_handler = organization.Organization(self.iaccount) + if organization_handler.get_by_name(image['Organization']) is None: + return False, 'Organization not found: %s' % (image['Organization']) + + if name_unique: + if self.is_name(image['Name']): + return False, 'Name %s already defined' % (image['Name']) + + except BaseException: + return False, traceback.format_exc() + + return True, None + + def add(self, attributes): + """Create os image object in Intersight + + Args: + attributes (dict): Expected keys Name, Vendor, Version, Type, Link and Organization + + The bulk of code takes attributes and formats that with the Intersight specific parameters + Catalog is found based on Organization value + + Returns: + bool: success or failure + """ + create_attributes = '' + for key in ['Name', 'Vendor', 'Version']: + value = str(attributes[key]) + if len(value.split(' ')) > 1: + create_attributes = '%s --%s=\'%s\'' % (create_attributes, key, value) + else: + create_attributes = '%s --%s=%s' % (create_attributes, key, value) + + if attributes['Type'] not in ['url', 'nfs']: + return False + + if attributes['Type'] == 'url': + source = {} + source['ClassId'] = 'softwarerepository.HttpServer' + source['LocationLink'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.HttpServer' + create_attributes = '%s --%s=\'%s\'' % (create_attributes, 'Source', json.dumps(source)) + + if attributes['Type'] == 'nfs': + source = {} + source['ClassId'] = 'softwarerepository.NfsServer' + source['FileLocation'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.NfsServer' + create_attributes = '%s --%s=\'%s\'' % (create_attributes, 'Source', json.dumps(source)) + + organization_handler = organization.Organization(self.iaccount) + organization_id = organization_handler.get_by_name(attributes['Organization'])['Moid'] + + src_handler = software_repository_catalog.SoftwareRepositoryCatalog(self.iaccount) + catalog_id = src_handler.get_user_catalog_id(organization_id) + if catalog_id is None: + return False + + create_attributes = '%s --Catalog=MoRef[Moid:%s]' % (create_attributes, catalog_id) + + return IntersightCommon.create(self, create_attributes) + + def get_set_output(self, images): + """Prepare YAML-based format from list of os image attributes + + Args: + images (list of dict): Os image objects likely returned by get_all method + + Select subset of image object attributes that are supported by set operation + - Moid, Name, Vendor, Version, Type, Link + + Returns: + string: YAML-formatted output + """ + if images is None: + return None + + set_output = [] + for image in images: + item = {} + for key in ['Moid', 'Name', 'Vendor', 'Version', 'Type', 'Link']: + item[key] = image[key] + + set_output.append(item) + + try: + output = yaml.dump( + set_output, + default_flow_style=False + ) + except BaseException: + output = None + + return output + + def validate_set(self, images): + """Check os image user input for set/update operation + + Args: + images (list of dict): User defined os image attributes + + Each entry in the list must have keys: ... + + Returns: + boolean: validation successful + string: failed validation description + """ + try: + ids = self.get_moids_list() + if ids is None: + return False, 'Exception in intersight os image check' + + if not isinstance(images, list): + return False, 'List required' + + for image in images: + if not isinstance(image, dict): + return False, 'List of dict required' + + if image['Moid'] not in ids: + return False, 'SCU Moid not found: %s' % (image['Moid']) + + if 'Name' in image and len(image['Name']) > 0: + if self.is_name(image['Name']): + return False, 'Name %s already defined' % (image['Name']) + + is_link = False + if 'Link' in image and len(image['Link']) > 0: + is_link = True + + is_type = False + if 'Type' in image and len(image['Type']) > 0: + is_type = True + + if is_link and is_type: + if image['Type'] not in ['url', 'nfs']: + return False, 'Unsupported type: %s' % (image['Type']) + + if image['Link'].startswith('http'): + if not ip_helper.is_url_valid(image['Link']): + return False, 'Invalid link: %s' % (image['Link']) + + is_vendor = False + if 'Vendor' in image and len(image['Vendor']) > 0: + is_vendor = True + + is_version = False + if 'Version' in image and len(image['Version']) > 0: + is_version = True + + if is_vendor and is_version: + vendor_attributes = self.hcl_os_vendor_handler.get_by_name(image['Vendor']) + if vendor_attributes is None: + return False, 'Vendor not found: %s' % (image['Vendor']) + vendor_id = vendor_attributes['Moid'] + + if image['Version'] == '': + return False, 'Define version' + + if not self.hcl_os_version_handler.is_vendor_version(vendor_id, image['Version']): + return False, 'Invalid version for vendor: %s' % (image['Version']) + else: + if not is_vendor and not is_version: + pass + else: + return False, 'Define both vendor and version' + + except BaseException: + return False, traceback.format_exc() + + return True, None + + def update(self, moid, attributes): + """Update OS image object in Intersight + + Args: + moid (string): Moid of os image object to be updated + attributes (dict): Expected keys Name, Vendor, Version, Type, Link + + Format image attributes with the Intersight specific parameters + Supported Type: url and nfs + + Returns: + bool: success or failure + """ + update_attributes = '' + for key in ['Name', 'Vendor', 'Version']: + if key in attributes and len(attributes[key]) > 0: + value = str(attributes[key]) + if len(value.split(' ')) > 1: + update_attributes = '%s --%s=\"%s\"' % (update_attributes, key, value) + else: + update_attributes = '%s --%s=%s' % (update_attributes, key, value) + + is_link = False + if 'Link' in attributes and len(attributes['Link']) > 0: + is_link = True + + is_type = False + if 'Type' in attributes and len(attributes['Type']) > 0: + is_type = True + + if is_link and is_type: + if attributes['Type'] == 'url': + source = {} + source['ClassId'] = 'softwarerepository.HttpServer' + source['LocationLink'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.HttpServer' + update_attributes = '%s --%s=\'%s\'' % (update_attributes, 'Source', json.dumps(source)) + + if attributes['Type'] == 'nfs': + source = {} + source['ClassId'] = 'softwarerepository.NfsServer' + source['FileLocation'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.NfsServer' + update_attributes = '%s --%s=\'%s\'' % (update_attributes, 'Source', json.dumps(source)) + + return IntersightCommon.update(self, moid, update_attributes) diff --git a/lib/intersight/os_install/__init__.py b/lib/intersight/os_install/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/os_install/main.py b/lib/intersight/os_install/main.py new file mode 100644 index 00000000..7ae9ea4e --- /dev/null +++ b/lib/intersight/os_install/main.py @@ -0,0 +1,169 @@ +import json +from lib import output_helper +from lib.intersight.intersight_common import IntersightCommon + + +class OsInstall(IntersightCommon): + def __init__(self, iaccount, dry_run=False, silent=False, verbose=False, debug=False, log_id=None): + self.iobject = 'os install' + self.dry_run = dry_run + IntersightCommon.__init__(self, iaccount, self.iobject, silent=silent, verbose=verbose, debug=debug, log_id=log_id) + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def create_embedded(self, attributes): + """Create os install object in Intersight to trigger bare metal OS installation + + Returns: + bool: success or failure + """ + create_attributes = '' + create_attributes = '%s --InstallMethod vMedia' % (create_attributes) + create_attributes = '%s --Server="MoRef:ComputeRackUnitRelationship[Moid:%s]"' % (create_attributes, attributes['server_id']) + create_attributes = '%s --Image=MoRef[Moid:%s]' % (create_attributes, attributes['image']['id']) + create_attributes = '%s --OsduImage=MoRef[Moid:%s]' % (create_attributes, attributes['scu_id']) + create_attributes = '%s --Organization=MoRef[Moid:%s]' % (create_attributes, attributes['organization_id']) + + install_target = {} + install_target['ObjectType'] = 'os.VirtualDrive' + install_target['StorageControllerSlotId'] = attributes['storage_controller_slot'] + install_target['Id'] = attributes['virtual_drive_id'] + install_target['Name'] = attributes['virtual_drive_name'] + create_attributes = '%s --InstallTarget=\'%s\'' % (create_attributes, json.dumps(install_target)) + + answers = {} + answers['Source'] = 'Embedded' + create_attributes = '%s --Answers=\'%s\'' % (create_attributes, json.dumps(answers)) + + command = 'isctl create os install %s' % (create_attributes.replace(' --', '\n\t--')) + self.my_output.info(command) + if self.dry_run: + self.my_output.default(command) + return dict(success=True) + + response = IntersightCommon.create( + self, + create_attributes, + get_response=True, + json_conversion=True + ) + return response + + def create_template_dhcp(self, attributes): + """Create os install object in Intersight to trigger bare metal OS installation + + Returns: + bool: success or failure + """ + create_attributes = '' + create_attributes = '%s --InstallMethod vMedia' % (create_attributes) + create_attributes = '%s --Server="MoRef:ComputeRackUnitRelationship[Moid:%s]"' % (create_attributes, attributes['server_id']) + create_attributes = '%s --Image=MoRef[Moid:%s]' % (create_attributes, attributes['image']['id']) + create_attributes = '%s --ConfigurationFile=MoRef[Moid:%s]' % (create_attributes, attributes['configuration_file_id']) + create_attributes = '%s --OsduImage=MoRef[Moid:%s]' % (create_attributes, attributes['scu_id']) + create_attributes = '%s --Organization=MoRef[Moid:%s]' % (create_attributes, attributes['organization_id']) + + install_target = {} + install_target['ObjectType'] = 'os.VirtualDrive' + install_target['StorageControllerSlotId'] = attributes['storage_controller_slot'] + install_target['Id'] = attributes['virtual_drive_id'] + install_target['Name'] = attributes['virtual_drive_name'] + create_attributes = '%s --InstallTarget=\'%s\'' % (create_attributes, json.dumps(install_target)) + + answers = {} + answers['Source'] = 'Template' + answers['IpConfigType'] = 'DHCP' + answers['IpConfiguration'] = {} + answers['IpConfiguration']['ObjectType'] = 'os.Ipv4Configuration' + if attributes['interface_mac'] == '': + answers['NetworkDevice'] = attributes['interface_name'] + else: + answers['NetworkDevice'] = attributes['interface_mac'] + answers['Hostname'] = attributes['hostname'] + answers['IsRootPasswordCrypted'] = False + answers['RootPassword'] = attributes['password'] + create_attributes = '%s --Answers=\'%s\'' % (create_attributes, json.dumps(answers)) + + command = 'isctl create os install %s' % (create_attributes.replace(' --', '\n\t--')) + self.my_output.info(command) + if self.dry_run: + self.my_output.default(command) + return dict(success=True) + + response = IntersightCommon.create( + self, + create_attributes, + get_response=True, + json_conversion=True + ) + return response + + def create_template_static(self, attributes): + """Create os install object in Intersight to trigger bare metal OS installation + + Returns: + bool: success or failure + """ + create_attributes = '' + create_attributes = '%s --InstallMethod vMedia' % (create_attributes) + create_attributes = '%s --Server="MoRef:ComputeRackUnitRelationship[Moid:%s]"' % (create_attributes, attributes['server_id']) + create_attributes = '%s --Image=MoRef[Moid:%s]' % (create_attributes, attributes['image']['id']) + create_attributes = '%s --ConfigurationFile=MoRef[Moid:%s]' % (create_attributes, attributes['configuration_file_id']) + create_attributes = '%s --OsduImage=MoRef[Moid:%s]' % (create_attributes, attributes['scu_id']) + create_attributes = '%s --Organization=MoRef[Moid:%s]' % (create_attributes, attributes['organization_id']) + + install_target = {} + install_target['ObjectType'] = 'os.VirtualDrive' + install_target['StorageControllerSlotId'] = attributes['storage_controller_slot'] + install_target['Id'] = attributes['virtual_drive_id'] + install_target['Name'] = attributes['virtual_drive_name'] + create_attributes = '%s --InstallTarget=\'%s\'' % (create_attributes, json.dumps(install_target)) + + answers = {} + answers['Source'] = 'Template' + answers['IpConfigType'] = 'static' + answers['IpConfiguration'] = {} + answers['IpConfiguration']['ObjectType'] = 'os.Ipv4Configuration' + answers['IpConfiguration']['IpV4Config'] = {} + answers['IpConfiguration']['IpV4Config']['IpAddress'] = attributes['ipv4_address'] + answers['IpConfiguration']['IpV4Config']['Netmask'] = attributes['ipv4_mask'] + answers['IpConfiguration']['IpV4Config']['Gateway'] = attributes['ipv4_gateway'] + if attributes['interface_mac'] == '': + answers['NetworkDevice'] = attributes['interface_name'] + else: + answers['NetworkDevice'] = attributes['interface_mac'] + answers['Nameserver'] = attributes['nameserver'] + answers['Hostname'] = attributes['hostname'] + answers['IsRootPasswordCrypted'] = False + answers['RootPassword'] = attributes['password'] + create_attributes = '%s --Answers=\'%s\'' % (create_attributes, json.dumps(answers)) + + command = 'isctl create os install %s' % (create_attributes.replace(' --', '\n\t--')) + self.my_output.info(command) + if self.dry_run: + self.my_output.default(command) + return dict(success=True) + + response = IntersightCommon.create( + self, + create_attributes, + get_response=True, + json_conversion=True + ) + return response + + def create_os_install(self, attributes): + """Create os install object in Intersight to trigger bare metal OS installation + + Returns: + bool: success or failure + """ + if attributes['type'] == 'embedded': + return self.create_embedded(attributes) + + if attributes['type'] == 'template': + if attributes['ip_config'] == 'dhcp': + return self.create_template_dhcp(attributes) + if attributes['ip_config'] == 'static': + return self.create_template_static(attributes) + + return dict(success=False, response=None) diff --git a/lib/intersight/pci_device/__init__.py b/lib/intersight/pci_device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/pci_device/class.md b/lib/intersight/pci_device/class.md new file mode 100644 index 00000000..d7e072bf --- /dev/null +++ b/lib/intersight/pci_device/class.md @@ -0,0 +1,79 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5fe295aa6176752d35119a62", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fe295aa6176752d35119a62" + } + ], + "ClassId": "pci.Device", + "ComputeBlade": null, + "ComputeRackUnit": { + "ClassId": "mo.MoRef", + "Moid": "5fe295aa6176752d35119a62", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fe295aa6176752d35119a62" + }, + "CreateTime": "2020-12-23T00:57:54.621Z", + "DeviceId": "", + "DeviceMoId": "5fe295916f72612d306438ac", + "Dn": "sys/rack-unit-1/equipped-slot-MLOM", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "FirmwareVersion": "4.4(1g)", + "GraphicsCards": [], + "InventoryDeviceInfo": null, + "ModTime": "2022-06-13T09:25:04.527Z", + "Model": "UCS VIC 1227 10Gbps 2 port CNA SFP+", + "Moid": "5fe296126176752d3511c18a", + "ObjectType": "pci.Device", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fe295916f72612d306438ac" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5fe295aa6176752d35119a62", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fe295aa6176752d35119a62" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Pid": "UCSC-MLOM-CSC-02", + "Presence": "", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fe295916f72612d306438ac", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fe295916f72612d306438ac" + }, + "Revision": "", + "Rn": "", + "Serial": "", + "SharedScope": "", + "SlotId": "MLOM", + "Tags": [], + "Vendor": "0x1137" + } +``` \ No newline at end of file diff --git a/lib/intersight/pci_device/info.py b/lib/intersight/pci_device/info.py new file mode 100644 index 00000000..36945467 --- /dev/null +++ b/lib/intersight/pci_device/info.py @@ -0,0 +1,40 @@ +class PciDeviceInfo(): + def __init__(self): + pass + + def get_pid(self, managed_object): + if 'ComputeRackUnit' in managed_object and managed_object['ComputeRackUnit'] is not None: + if managed_object['Pid'] in [None, 'N/A', 'UNKNOWN', '']: + return None + return managed_object['Pid'] + + if 'ComputeBlade' in managed_object and managed_object['ComputeBlade'] is not None: + if managed_object['Pid'] in [None, 'N/A', 'UNKNOWN', '']: + return managed_object['Model'] + + return managed_object['Pid'] + + return None + + def get_model(self, managed_object): + return managed_object['Model'] + + def get_info(self, managed_object): + info = {} + + keys = [ + 'SlotId', + 'Vendor', + 'FirmwareVersion', + 'Dn', + 'Serial' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['Pid'] = self.get_pid(managed_object) + info['Model'] = self.get_model(managed_object) + + return info diff --git a/lib/intersight/pci_device/main.py b/lib/intersight/pci_device/main.py new file mode 100644 index 00000000..cfb09097 --- /dev/null +++ b/lib/intersight/pci_device/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.pci_device.info import PciDeviceInfo + + +class PciDevice(IntersightCommon, PciDeviceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'pci device' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + PciDeviceInfo.__init__(self) diff --git a/lib/intersight/pci_node/__init__.py b/lib/intersight/pci_node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/pci_node/class.md b/lib/intersight/pci_node/class.md new file mode 100644 index 00000000..edc89448 --- /dev/null +++ b/lib/intersight/pci_node/class.md @@ -0,0 +1,80 @@ +``` +{ + "AccountMoid": "5a0a0877b657050001659aff", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "65fa07d976752d300152cacb", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/65fa07d976752d300152cacb" + } + ], + "ChassisId": "1", + "ClassId": "pci.Node", + "ComputeBlade": { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + "CreateTime": "2024-04-18T13:39:23.733Z", + "DeviceMoId": "65fa990a6f72613001fcd492", + "Dn": "/redfish/v1/Chassis/FCH261171XR/Assembly#/Assemblies/CHASSIS-SLOT4", + "DomainGroupMoid": "5b2541917a7662743465cfeb", + "GraphicsCards": [ + { + "ClassId": "mo.MoRef", + "Moid": "6621228b76752d3001efbc6f", + "ObjectType": "graphics.Card", + "link": "https://intersight.com/api/v1/graphics/Cards/6621228b76752d3001efbc6f" + } + ], + "InventoryDeviceInfo": null, + "IsUpgraded": false, + "ModTime": "2024-05-08T13:30:09.583Z", + "Model": "UCSX-440P", + "Moid": "6621228b76752d3001efbc6d", + "ObjectType": "pci.Node", + "OperReason": [], + "Owners": [ + "5a0a0877b657050001659aff", + "65f9b2676f72613001fad35d", + "65fa990a6f72613001fcd492" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "66211b4976752d3001ec6be2", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/66211b4976752d3001ec6be2" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddec94c6972652d3101bdce", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5ddec94c6972652d3101bdce" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "65fa990a6f72613001fcd492", + "ObjectType": "asset.DeviceRegistration", + "link": "https://intersight.com/api/v1/asset/DeviceRegistrations/65fa990a6f72613001fcd492" + }, + "Revision": "", + "Rn": "", + "Serial": "FCH261171XR", + "SharedScope": "", + "SlotId": "4", + "Tags": [], + "Vendor": "Cisco Systems Inc" +} +``` \ No newline at end of file diff --git a/lib/intersight/pci_node/info.py b/lib/intersight/pci_node/info.py new file mode 100644 index 00000000..3d2c8dfe --- /dev/null +++ b/lib/intersight/pci_node/info.py @@ -0,0 +1,46 @@ +class PciNodeInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + + keys = [ + 'ChassisId', + 'Dn', + 'Model', + 'Moid', + 'Presence', + 'Serial', + 'SlotId', + 'Vendor' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + info['Pid'] = info['Model'] + + info['GraphicsCardsMoids'] = [] + if 'GraphicsCards' in managed_object and managed_object['GraphicsCards'] is not None: + for gcard_mo in managed_object['GraphicsCards']: + info['GraphicsCardsMoids'].append( + gcard_mo['Moid'] + ) + + info['NumGraphicsCards'] = len( + info['GraphicsCardsMoids'] + ) + + info['BladeMoid'] = None + info['ChassisMoid'] = None + + for ancestor_mo in managed_object['Ancestors']: + if ancestor_mo['ObjectType'] == 'compute.Blade': + info['BladeMoid'] = ancestor_mo['Moid'] + + if ancestor_mo['ObjectType'] == 'compute.equipment.Chassis': + info['ChassisMoid'] = ancestor_mo['Moid'] + + return info diff --git a/lib/intersight/pci_node/main.py b/lib/intersight/pci_node/main.py new file mode 100644 index 00000000..96a68f97 --- /dev/null +++ b/lib/intersight/pci_node/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.pci_node.info import PciNodeInfo + + +class PciNode(IntersightCommon, PciNodeInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'pci node' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + PciNodeInfo.__init__(self) diff --git a/lib/intersight/power_control_state/__init__.py b/lib/intersight/power_control_state/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/power_control_state/class.md b/lib/intersight/power_control_state/class.md new file mode 100644 index 00000000..796e5c8c --- /dev/null +++ b/lib/intersight/power_control_state/class.md @@ -0,0 +1,67 @@ +``` + { + "AccountMoid": "5a58c3ba3768393836cb0f1b", + "AllocatedPower": 0, + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2b9", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13ca76752d32362fc2b9" + } + ], + "ClassId": "power.ControlState", + "CreateTime": "2022-09-22T13:58:12.808Z", + "DomainGroupMoid": "5b2541957a7662743465d06d", + "EquipmentChassis": { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2b9", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13ca76752d32362fc2b9" + }, + "ExtendedPowerCapacity": "Enabled", + "GridMaxPower": 7000, + "MaxRequiredPower": 8079, + "MinRequiredPower": 4190, + "ModTime": "2022-11-03T02:42:48.686Z", + "Moid": "632c69f476752d32369419ce", + "N1MaxPower": 10500, + "N2MaxPower": 7000, + "NonRedundantMaxPower": 12174, + "ObjectType": "power.ControlState", + "Owners": [ + "5a58c3ba3768393836cb0f1b", + "632999466f72612d39b26942" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "632b13ca76752d32362fc2b9", + "ObjectType": "equipment.Chassis", + "link": "https://www.intersight.com/api/v1/equipment/Chasses/632b13ca76752d32362fc2b9" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ddee0c26972652d33555a3b", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5ddee0c26972652d33555a3b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63493b8a6972652d33272ab6", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/63493b8a6972652d33272ab6" + } + ], + "PowerRebalancing": "Enabled", + "PowerSaveMode": "Enabled", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "632999466f72612d39b26942", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/632999466f72612d39b26942" + }, + "SharedScope": "", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/power_control_state/info.py b/lib/intersight/power_control_state/info.py new file mode 100644 index 00000000..469194f0 --- /dev/null +++ b/lib/intersight/power_control_state/info.py @@ -0,0 +1,58 @@ +class PowerControlStateInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'Moid', + 'AllocatedPower', + 'ExtendedPowerCapacity', + 'GridMaxPower', + 'MaxRequiredPower', + 'MinRequiredPower', + 'N1MaxPower', + 'N2MaxPower', + 'NonRedundantMaxPower', + 'PowerRebalancing', + 'PowerSaveMode' + ] + for key in keys: + info[key] = managed_object[key] + + if info['PowerRebalancing'] == 'Enabled': + info['__Output']['PowerRebalancing'] = 'Green' + else: + info['__Output']['PowerRebalancing'] = 'Red' + + if info['PowerSaveMode'] == 'Enabled': + info['__Output']['PowerSaveMode'] = 'Green' + else: + info['__Output']['PowerSaveMode'] = 'Red' + + if info['ExtendedPowerCapacity'] == 'Enabled': + info['__Output']['ExtendedPowerCapacity'] = 'Green' + else: + info['__Output']['ExtendedPowerCapacity'] = 'Red' + + if managed_object['AllocatedPower'] == 0: + managed_object['AllocatedBudget'] = 'Not set' + else: + managed_object['AllocatedBudget'] = managed_object['AllocatedPower'] + + keys = [ + 'AllocatedPower', + 'GridMaxPower', + 'MaxRequiredPower', + 'MinRequiredPower', + 'N1MaxPower', + 'N2MaxPower', + 'NonRedundantMaxPower' + ] + + for key in keys: + info['%sUnit' % (key)] = '%s W' % (str(info[key])) + + return info diff --git a/lib/intersight/power_control_state/main.py b/lib/intersight/power_control_state/main.py new file mode 100644 index 00000000..49e9cf57 --- /dev/null +++ b/lib/intersight/power_control_state/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.power_control_state.info import PowerControlStateInfo + + +class PowerControlState(IntersightCommon, PowerControlStateInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'power controlstate' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + PowerControlStateInfo.__init__(self) diff --git a/lib/intersight/processor_unit/__init__.py b/lib/intersight/processor_unit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/processor_unit/class.md b/lib/intersight/processor_unit/class.md new file mode 100644 index 00000000..684fcb64 --- /dev/null +++ b/lib/intersight/processor_unit/class.md @@ -0,0 +1,95 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed96176752d32d52214", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5e8c4ed96176752d32d52214" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed26176752d32d51c40", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5e8c4ed26176752d32d51c40" + } + ], + "Architecture": "Xeon", + "ClassId": "processor.Unit", + "ComputeBlade": null, + "ComputeBoard": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed96176752d32d52214", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5e8c4ed96176752d32d52214" + }, + "ComputeRackUnit": null, + "CreateTime": "2020-04-07T10:03:24.112Z", + "DeviceMoId": "5e8c4ecd6f72612d302b11a6", + "Dn": "sys/rack-unit-1/board/cpu-2", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InventoryDeviceInfo": null, + "ModTime": "2022-05-09T13:36:01.136Z", + "Model": "Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz", + "Moid": "5e8c4fec6176752d32d62da8", + "NetworkElement": null, + "NumCores": 8, + "NumCoresEnabled": "8", + "NumThreads": "16", + "ObjectType": "processor.Unit", + "OperPowerState": "", + "OperReason": [], + "OperState": "operable", + "Operability": "", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5e8c4ecd6f72612d302b11a6" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed96176752d32d52214", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5e8c4ed96176752d32d52214" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "Presence": "equipped", + "PreviousFru": null, + "ProcessorId": 2, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ecd6f72612d302b11a6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5e8c4ecd6f72612d302b11a6" + }, + "Revision": "", + "Rn": "", + "Serial": "", + "SharedScope": "", + "SocketDesignation": "CPU2", + "Speed": 2.4, + "Stepping": "2", + "Tags": [], + "Thermal": "", + "Vendor": "Intel(R) Corporation" + } +``` \ No newline at end of file diff --git a/lib/intersight/processor_unit/info.py b/lib/intersight/processor_unit/info.py new file mode 100644 index 00000000..ee5878ad --- /dev/null +++ b/lib/intersight/processor_unit/info.py @@ -0,0 +1,72 @@ +class ProcessorUnitInfo(): + def __init__(self): + pass + + def is_processor_unit_ok(self, info): + if info['OperState'].lower() not in ['operable', 'ok']: + return False + + if info['Presence'].lower() not in ['equipped']: + return False + + if info['Thermal'].lower() not in ['ok', '']: + return False + + return True + + def get_processor_unit_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'Architecture', + 'Model', + 'NumCores', + 'NumCoresEnabled', + 'NumThreads', + 'Pid', + 'OperState', + 'Presence', + 'ProcessorId', + 'SocketDesignation', + 'Speed', + 'Stepping', + 'Vendor', + 'Thermal' + ] + for key in keys: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + if info['OperState'].lower() in ['operable', 'ok']: + info['__Output']['OperState'] = 'Green' + else: + info['__Output']['OperState'] = 'Red' + + if len(info['Thermal']) > 0: + if info['Thermal'].lower() == 'ok': + info['__Output']['Thermal'] = 'Green' + else: + info['__Output']['Thermal'] = 'Red' + + if self.is_processor_unit_ok(info): + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + info['VendorName'] = 'unknown' + if info['Vendor'] is not None: + if info['Vendor'].startswith('Intel'): + info['VendorName'] = 'intel' + if info['Vendor'].startswith('Advanced Micro Devices'): + info['VendorName'] = 'amd' + + return info diff --git a/lib/intersight/processor_unit/main.py b/lib/intersight/processor_unit/main.py new file mode 100644 index 00000000..3f0cbc56 --- /dev/null +++ b/lib/intersight/processor_unit/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.processor_unit.info import ProcessorUnitInfo + + +class ProcessorUnit(IntersightCommon, ProcessorUnitInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'processor unit' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + ProcessorUnitInfo.__init__(self) diff --git a/lib/intersight/running_firmware/__init__.py b/lib/intersight/running_firmware/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/running_firmware/class.md b/lib/intersight/running_firmware/class.md new file mode 100644 index 00000000..ec8f72a1 --- /dev/null +++ b/lib/intersight/running_firmware/class.md @@ -0,0 +1,84 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4f076176752d32d54b2a", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/5e8c4f076176752d32d54b2a" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ed26176752d32d51c40", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5e8c4ed26176752d32d51c40" + } + ], + "BiosUnit": null, + "ClassId": "firmware.RunningFirmware", + "Component": "system", + "CreateTime": "2020-04-07T09:59:29.217Z", + "DeviceMoId": "5e8c4ecd6f72612d302b11a6", + "Dn": "sys/rack-unit-1/mgmt/fw-system", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "GraphicsCard": null, + "InventoryDeviceInfo": null, + "ManagementController": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4f076176752d32d54b2a", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/5e8c4f076176752d32d54b2a" + }, + "ModTime": "2022-05-09T13:36:01.248Z", + "Moid": "5e8c4f016176752d32d5448c", + "NetworkElements": [], + "ObjectType": "firmware.RunningFirmware", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5e8c4ecd6f72612d302b11a6" + ], + "PackageVersion": "", + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4f076176752d32d54b2a", + "ObjectType": "management.Controller", + "link": "https://www.intersight.com/api/v1/management/Controllers/5e8c4f076176752d32d54b2a" + }, + "PciSwitch": null, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5e8c4ecd6f72612d302b11a6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5e8c4ecd6f72612d302b11a6" + }, + "Rn": "", + "SharedScope": "", + "StorageController": null, + "StorageFlexFlashController": null, + "StoragePhysicalDisk": null, + "Tags": [], + "Type": "blade-controller", + "Version": "4.1(2f)" + } +``` \ No newline at end of file diff --git a/lib/intersight/running_firmware/info.py b/lib/intersight/running_firmware/info.py new file mode 100644 index 00000000..8fedb587 --- /dev/null +++ b/lib/intersight/running_firmware/info.py @@ -0,0 +1,46 @@ +class RunningFirmwareInfo(): + def __init__(self): + pass + + def get_firmware_name(self, info): + if info['Type'] == 'adaptor': + return 'Adapter' + + if info['Type'] == 'blade-bios': + return 'BIOS' + + if info['Type'] == 'local-disk': + return 'Disk' + + if info['Type'] == 'storage-controller': + return 'Storage Controller' + + if info['Component'] == 'boot-loader' and info['Type'] == 'blade-controller': + return 'Board Controller' + + if info['Component'] == 'system' and info['Type'] == 'blade-controller': + return 'CIMC Controller' + + return '' + + def get_info(self, managed_object): + keys = [ + 'Component', + 'Dn', + 'Type', + 'PackageVersion', + 'Version' + ] + info = {} + for key in keys: + info[key] = managed_object[key].replace('\n', '') + + info['Name'] = self.get_firmware_name(info) + + return info + + def get_version(self, managed_objects): + for managed_object in managed_objects: + if managed_object['Component'] == 'system' and managed_object['Type'] == 'blade-controller': + return managed_object['Version'] + return None diff --git a/lib/intersight/running_firmware/main.py b/lib/intersight/running_firmware/main.py new file mode 100644 index 00000000..58a9b57b --- /dev/null +++ b/lib/intersight/running_firmware/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.running_firmware.info import RunningFirmwareInfo + + +class RunningFirmware(IntersightCommon, RunningFirmwareInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'firmware runningfirmware' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + RunningFirmwareInfo.__init__(self) diff --git a/lib/intersight/scu/__init__.py b/lib/intersight/scu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/scu/class.md b/lib/intersight/scu/class.md new file mode 100644 index 00000000..ac232d16 --- /dev/null +++ b/lib/intersight/scu/class.md @@ -0,0 +1,81 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736567612d30276cb1", + "ObjectType": "softwarerepository.Catalog", + "link": "https://www.intersight.com/api/v1/softwarerepository/Catalogs/5dee1d736567612d30276cb1" + } + ], + "BundleType": "", + "Catalog": { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736567612d30276cb1", + "ObjectType": "softwarerepository.Catalog", + "link": "https://www.intersight.com/api/v1/softwarerepository/Catalogs/5dee1d736567612d30276cb1" + }, + "ClassId": "firmware.ServerConfigurationUtilityDistributable", + "ComponentMeta": [], + "CreateTime": "2022-09-22T08:53:14.662Z", + "Description": "", + "DistributableMetas": [], + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "DownloadCount": 0, + "Guid": "", + "ImageType": "", + "ImportAction": "None", + "ImportState": "MetaOnly", + "ImportedTime": "0001-01-01T00:00:00Z", + "LastAccessTime": "0001-01-01T00:00:00Z", + "Md5eTag": "", + "Md5sum": "", + "Mdfid": "", + "ModTime": "2022-09-22T08:53:14.85Z", + "Model": "", + "Moid": "632c227a6567612d30187910", + "Name": "SCU 6.2.2a", + "ObjectType": "firmware.ServerConfigurationUtilityDistributable", + "Owners": [ + "5be4b2ce67626c6d661ca38d" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736567612d30276cb1", + "ObjectType": "softwarerepository.Catalog", + "link": "https://www.intersight.com/api/v1/softwarerepository/Catalogs/5dee1d736567612d30276cb1" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + } + ], + "PlatformType": "", + "RecommendedBuild": "", + "Release": null, + "ReleaseDate": "0001-01-01T00:00:00Z", + "ReleaseNotesUrl": "", + "Sha512sum": "", + "SharedScope": "", + "Size": 0, + "SoftwareAdvisoryUrl": "", + "SoftwareTypeId": "", + "Source": { + "ClassId": "softwarerepository.HttpServer", + "IsPasswordSet": false, + "LocationLink": "http:///2-IMAGES/cisco/ucs_c-series/ucs-scu-6.2.2a.iso", + "ObjectType": "softwarerepository.HttpServer", + "Username": "" + }, + "SupportedModels": [ + "c220 m5" + ], + "Tags": [], + "Vendor": "Cisco", + "Version": "6.2.2a" + } +``` \ No newline at end of file diff --git a/lib/intersight/scu/main.py b/lib/intersight/scu/main.py new file mode 100644 index 00000000..f3be1a76 --- /dev/null +++ b/lib/intersight/scu/main.py @@ -0,0 +1,327 @@ +import traceback +import json +import yaml + +from lib.intersight.intersight_common import IntersightCommon +from lib import ip_helper +from lib.intersight import software_repository_catalog +from lib.intersight import organization + + +class SoftwareConfigurationUtility(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'firmware serverconfigurationutilitydistributable' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + self.log_id = log_id + self.my_output = None + + def get_all(self, max_errors=3, error_timeout=1): + """Get all SCU objects + + Args: + max_errors (int, optional): if API call fails retry until max_errors. Defaults to 3. + error_timeout (int, optional): if API response takes longer than error_timeout, then consider API as failed. Defaults to 1. + + Extend the raw get API call with custom attributes + - Organization: organization name + - Type: url, nfs + - Link: normalized location + - Verified: check if url is reachable. not supported for nfs type + + Note: cfs type not supported + + Returns: + list of dict: list of Intersight SCU objects + """ + scus = IntersightCommon.get_all(self, max_errors=max_errors, error_timeout=error_timeout) + if scus is None: + return scus + + organization_handler = organization.Organization(self.iaccount) + organizations = organization_handler.get_moids_dict() + + verified = [] + keys = [ + 'Moid', + 'Name', + 'Source', + 'SupportedModels', + 'Tags', + 'Vendor', + 'Version' + ] + + for scu in scus: + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = scu[key] + + organization_id = None + for permission in scu['PermissionResources']: + if permission['ObjectType'] == 'organization.Organization': + organization_id = permission['Moid'] + + if organization_id is None or organization_id not in organizations: + # Organization ID must exist + continue + + info['Organization'] = organizations[organization_id] + + info['Verified'] = False + info['Link'] = None + info['Type'] = None + + if info['Source']['ClassId'] not in ['softwarerepository.HttpServer', 'softwarerepository.NfsServer']: + continue + + if info['Source']['ClassId'] == 'softwarerepository.HttpServer': + info['Type'] = 'url' + info['Link'] = scu['Source']['LocationLink'] + info['Verified'] = ip_helper.is_url_accessible(info['Link']) + + if info['Verified']: + info['__Output']['Link'] = 'Green' + else: + info['__Output']['Link'] = 'Red' + + if info['Source']['ClassId'] == 'softwarerepository.NfsServer': + info['Type'] = 'nfs' + info['Link'] = scu['Source']['FileLocation'] + info['Verified'] = False + + verified.append(info) + + return verified + + def validate_add(self, scu, name_unique=True): + """Validate SCU create attributes + + Args: + scus (dict): scu attributes + name_unique (bool, optional): check if Name already exists. Defaults to True. + + Expected attributes: Name, Version, Link and Organization + Organization (name) must exist + If name_unique, then Name cannot already exist + + Returns: + bool: validation success + string: if validation fails, contains information on the reason + """ + try: + if not isinstance(scu, dict): + return False, 'Dict scu attributes required' + + for key in ['Name', 'Version', 'Link', 'Organization']: + if key not in scu: + return False, 'Attribute %s required' % (key) + + for key in ['Name', 'Version', 'Link']: + if len(scu[key]) == 0: + return False, 'Attribute value %s required' % (key) + + if name_unique: + if self.is_name(scu['Name']): + return False, 'Name %s already defined' % (scu['Name']) + + if not ip_helper.is_url_valid(scu['Link']): + return False, 'Invalid link: %s' % (scu['Link']) + + organization_handler = organization.Organization(self.iaccount) + if organization_handler.get_by_name(scu['Organization']) is None: + return False, 'Organization not found: %s' % (scu['Organization']) + + except BaseException: + return False, traceback.format_exc() + + return True, None + + def add(self, attributes): + """Create SCU object in Intersight + + Args: + attributes (dict): Expected keys Name, Version, Type, Link and Organization + + The bulk of code takes attributes and formats that with the Intersight specific parameters + SupportedModels is hard-coded + Catalog is found based on Organization value + + Returns: + bool: success or failure + """ + create_attributes = '' + for key in ['Name', 'Version']: + value = str(attributes[key]) + if len(value.split(' ')) > 1: + create_attributes = '%s --%s=\'%s\'' % (create_attributes, key, value) + else: + create_attributes = '%s --%s=%s' % (create_attributes, key, value) + + if attributes['Type'] not in ['url', 'nfs']: + return False + + if attributes['Type'] == 'url': + source = {} + source['ClassId'] = 'softwarerepository.HttpServer' + source['LocationLink'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.HttpServer' + create_attributes = '%s --%s=\'%s\'' % (create_attributes, 'Source', json.dumps(source)) + + if attributes['Type'] == 'nfs': + source = {} + source['ClassId'] = 'softwarerepository.NfsServer' + source['FileLocation'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.NfsServer' + create_attributes = '%s --%s=\'%s\'' % (create_attributes, 'Source', json.dumps(source)) + + create_attributes = '%s --SupportedModels=ucs' % (create_attributes) + + organization_handler = organization.Organization(self.iaccount) + organization_id = organization_handler.get_by_name(attributes['Organization'])['Moid'] + + src_handler = software_repository_catalog.SoftwareRepositoryCatalog(self.iaccount) + catalog_id = src_handler.get_user_catalog_id(organization_id) + if catalog_id is None: + return False + + create_attributes = '%s --Catalog=MoRef[Moid:%s]' % (create_attributes, catalog_id) + + return IntersightCommon.create(self, create_attributes) + + def get_set_output(self, scus): + """Prepare YAML-based format from list of SCUs attributes + + Args: + scus (list of dict): SCU objects likely returned by get_all method + + Select subset of scu object attributes that are supported by scu set operation + - Moid, Name, Version, Type, Link + + Returns: + string: YAML-formatted output + """ + if scus is None: + return None + + set_output = [] + for scu in scus: + item = {} + for key in ['Moid', 'Name', 'Version', 'Type', 'Link']: + item[key] = scu[key] + + set_output.append(item) + + try: + output = yaml.dump( + set_output, + default_flow_style=False + ) + except BaseException: + output = None + + return output + + def validate_set(self, scus): + """Check SCU user input for set/update operation + + Args: + scus (list of dict): User defined SCUs attributes + + Each entry in the list must have Moid key + The rest of the fields is optional: Name, Version, Type, Link + Organizaiton is not allowed to be updated + Moid must exist + Supported type: url and nfs + + Returns: + boolean: validation successful + string: failed validation description + """ + try: + ids = self.get_moids_list() + if ids is None: + return False, 'Exception in intersight scu check' + + if not isinstance(scus, list): + return False, 'List of dict required' + + for scu in scus: + if not isinstance(scu, dict): + return False, 'List of dict required' + + if scu['Moid'] not in ids: + return False, 'SCU Moid not found: %s' % (scu['Moid']) + + if 'Name' in scu and len(scu['Name']) > 0: + if self.is_name(scu['Name']): + return False, 'Name %s already defined' % (scu['Name']) + + is_link = False + if 'Link' in scu and len(scu['Link']) > 0: + is_link = True + + is_type = False + if 'Type' in scu and len(scu['Type']) > 0: + is_type = True + + if is_link and is_type: + if scu['Type'] not in ['url', 'nfs']: + return False, 'Unsupported type: %s' % (scu['Type']) + + if scu['Link'].startswith('http'): + if not ip_helper.is_url_valid(scu['Link']): + return False, 'Invalid link: %s' % (scu['Link']) + + except BaseException: + return False, traceback.format_exc() + + return True, None + + def update(self, moid, attributes): + """Update SCU object in Intersight + + Args: + moid (string): Moid of SCU object to be updated + attributes (dict): Optional keys Name, Version, Type, Link + + Format SCU attributes with the Intersight specific parameters + Supported Type: url and nfs + + Returns: + bool: success or failure + """ + update_attributes = '' + for key in ['Name', 'Version']: + if key in attributes and len(attributes[key]) > 0: + value = str(attributes[key]) + if len(value.split(' ')) > 1: + update_attributes = '%s --%s=\'%s\'' % (update_attributes, key, value) + else: + update_attributes = '%s --%s=%s' % (update_attributes, key, value) + + is_link = False + if 'Link' in attributes and len(attributes['Link']) > 0: + is_link = True + + is_type = False + if 'Type' in attributes and len(attributes['Type']) > 0: + is_type = True + + if is_link and is_type: + if attributes['Type'] == 'url': + source = {} + source['ClassId'] = 'softwarerepository.HttpServer' + source['LocationLink'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.HttpServer' + update_attributes = '%s --%s=\'%s\'' % (update_attributes, 'Source', json.dumps(source)) + + if attributes['Type'] == 'nfs': + source = {} + source['ClassId'] = 'softwarerepository.NfsServer' + source['FileLocation'] = attributes['Link'] + source['ObjectType'] = 'softwarerepository.NfsServer' + update_attributes = '%s --%s=\'%s\'' % (update_attributes, 'Source', json.dumps(source)) + + return IntersightCommon.update(self, moid, update_attributes) diff --git a/lib/intersight/search_item/__init__.py b/lib/intersight/search_item/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/search_item/main.py b/lib/intersight/search_item/main.py new file mode 100644 index 00000000..65a88512 --- /dev/null +++ b/lib/intersight/search_item/main.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class SearchItem(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'search searchitem' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) diff --git a/lib/intersight/server_profile/__init__.py b/lib/intersight/server_profile/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/server_profile/class.md b/lib/intersight/server_profile/class.md new file mode 100644 index 00000000..64016d6c --- /dev/null +++ b/lib/intersight/server_profile/class.md @@ -0,0 +1,99 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Action": "No-op", + "ActionParams": [], + "Ancestors": [], + "AssignedServer": { + "ClassId": "mo.MoRef", + "Moid": "5fa04baa6176752d35cc0518", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fa04baa6176752d35cc0518" + }, + "AssociatedServer": null, + "ClassId": "server.Profile", + "ConfigChangeContext": { + "ClassId": "policy.ConfigChangeContext", + "ConfigChangeError": "", + "ConfigChangeState": "Ok", + "InitialConfigContext": { + "ClassId": "policy.ConfigContext", + "ConfigState": "", + "ConfigType": "", + "ControlAction": "", + "ErrorState": "", + "ObjectType": "policy.ConfigContext", + "OperState": "" + }, + "ObjectType": "policy.ConfigChangeContext" + }, + "ConfigChangeDetails": [], + "ConfigChanges": { + "Changes": [], + "ClassId": "policy.ConfigChange", + "Disruptions": [], + "ObjectType": "policy.ConfigChange" + }, + "ConfigContext": { + "ClassId": "policy.ConfigContext", + "ConfigState": "Assigned", + "ConfigType": "", + "ControlAction": "No-op", + "ErrorState": "", + "ObjectType": "policy.ConfigContext", + "OperState": "Ok" + }, + "ConfigResult": { + "ClassId": "mo.MoRef", + "Moid": "6389df9277696e2d31f8b559", + "ObjectType": "server.ConfigResult", + "link": "https://www.intersight.com/api/v1/server/ConfigResults/6389df9277696e2d31f8b559" + }, + "CreateTime": "2022-12-02T11:20:50.851Z", + "Description": "", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "IsPmcDeployedSecurePassphraseSet": false, + "ModTime": "2022-12-02T11:21:04.557Z", + "Moid": "6389df9277696e2d31f8b557", + "Name": "test2", + "ObjectType": "server.Profile", + "Organization": { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + "Owners": [ + "5be4b2ce67626c6d661ca38d" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + } + ], + "PolicyBucket": [], + "ReservationReferences": [], + "ResourceLease": { + "ClassId": "mo.MoRef", + "Moid": "6389df9f6962752d30868fc3", + "ObjectType": "resourcepool.Lease", + "link": "https://www.intersight.com/api/v1/resourcepool/Leases/6389df9f6962752d30868fc3" + }, + "RunningWorkflows": [], + "ServerAssignmentMode": "Static", + "ServerPool": null, + "SharedScope": "", + "SrcTemplate": null, + "StaticUuidAddress": "", + "Tags": [], + "TargetPlatform": "Standalone", + "Type": "instance", + "Uuid": "", + "UuidAddressType": "NONE", + "UuidLease": null, + "UuidPool": null + } +``` \ No newline at end of file diff --git a/lib/intersight/server_profile/info.py b/lib/intersight/server_profile/info.py new file mode 100644 index 00000000..983405e3 --- /dev/null +++ b/lib/intersight/server_profile/info.py @@ -0,0 +1,45 @@ +class ServerProfileInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + keys = [ + 'Name', + 'ModTime', + 'Moid', + 'ServerAssignmentMode', + 'TargetPlatform', + 'Type' + ] + + for key in keys: + info[key] = managed_object[key] + + info['ConfigState'] = managed_object['ConfigContext']['ConfigState'] + info['ConfigChangeState'] = managed_object['ConfigChangeContext']['ConfigChangeState'] + + if info['ConfigState'].lower() == 'out-of-sync': + info['__Output']['ConfigState'] = 'Red' + + if info['ConfigState'].lower() == 'assigned': + info['__Output']['ConfigState'] = 'Yellow' + + if info['ConfigState'].lower() == 'validating': + info['__Output']['ConfigState'] = 'Blue' + + if info['ConfigState'].lower() == 'associated': + info['__Output']['ConfigState'] = 'Green' + + info['ConfigChangeDetails'] = [] + for config_change_details in managed_object['ConfigChangeDetails']: + config_change_info = {} + config_change_info['EntityMoid'] = config_change_details['ConfigChangeContext']['EntityMoid'] + config_change_info['EntityType'] = config_change_details['ConfigChangeContext']['EntityType'] + info['ConfigChangeDetails'].append( + config_change_info + ) + + return info diff --git a/lib/intersight/server_profile/main.py b/lib/intersight/server_profile/main.py new file mode 100644 index 00000000..56a3d6e8 --- /dev/null +++ b/lib/intersight/server_profile/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.server_profile.info import ServerProfileInfo + + +class ServerProfile(IntersightCommon, ServerProfileInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'server profile' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + ServerProfileInfo.__init__(self) diff --git a/lib/intersight/settings.py b/lib/intersight/settings.py new file mode 100644 index 00000000..d61c1a3a --- /dev/null +++ b/lib/intersight/settings.py @@ -0,0 +1,159 @@ +import os +import json +import traceback + +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class IntersightSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self) + + self.log = log_helper.Log(log_id=log_id) + self.log_id = log_id + self.my_output = None + + self.intersight_settings_filename = os.path.join( + self.settings_dir, + 'intersight' + ) + + if not self.initialize_intersight_settings(): + raise ValueError('Intersight settings initialization failed') + + def initialize_intersight_settings(self): + if not os.path.isfile(self.intersight_settings_filename): + settings = self.get_intersight_default_settings() + if not self.set_intersight_settings(settings): + return False + + if settings['CacheEnabled']: + os.makedirs( + settings['ComputeCacheDirectory'], + exist_ok=True + ) + + settings_changed = False + settings = self.get_intersight_settings() + + if 'CacheEnabled' not in settings: + settings['CacheEnabled'] = True + settings_changed = True + + if 'CacheTtl' not in settings: + settings['CacheTtl'] = 600 + settings_changed = True + + if 'ComputeCacheDirectory' not in settings: + settings['ComputeCacheDirectory'] = os.path.join( + self.settings_dir, + 'compute' + ) + + if settings_changed: + self.set_intersight_settings( + settings + ) + + return True + + def get_intersight_settings(self): + if not os.path.isfile(self.intersight_settings_filename): + return None + + try: + with open(self.intersight_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_intersight_settings', traceback.format_exc()) + return None + + return settings + + def set_intersight_settings(self, settings): + try: + with open(self.intersight_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_intersight_settings', traceback.format_exc()) + return False + + return True + + def set_cache_enabled(self): + settings = self.get_intersight_settings() + settings['CacheEnabled'] = True + return self.set_intersight_settings(settings) + + def set_cache_disabled(self): + settings = self.get_intersight_settings() + settings['CacheEnabled'] = False + return self.set_intersight_settings(settings) + + def set_cache_ttl(self, ttl): + if not isinstance(ttl, int): + self.log.error('set_cache_ttl', 'ttl must be integer') + return False + + if ttl <= 0: + self.log.error('set_cache_ttl', 'ttl must be integer gt 0') + return False + + settings = self.get_intersight_settings() + settings['CacheTtl'] = ttl + return self.set_intersight_settings(settings) + + def get_intersight_default_settings(self): + settings = {} + settings['CacheEnabled'] = True + settings['CacheTtl'] = 600 + settings['ComputeCacheDirectory'] = os.path.join( + self.settings_dir, + 'compute' + ) + return settings + + def get_intersight_cache_ttl(self): + settings = self.get_intersight_settings() + if not settings['CacheEnabled']: + return None + return settings['CacheTtl'] + + def print_intersight_settings(self): + if self.my_output is None: + self.my_output = output_helper.OutputHelper( + log_id=self.log_id, + verbose=False, + debug=False + ) + + settings = self.get_intersight_settings() + if settings is None: + self.my_output.error('Intersight settings not found') + return + + order = [ + 'CacheEnabled', + 'CacheTtl', + 'ComputeCacheDirectory' + ] + + headers = [ + 'Cache Enabled', + 'Cache TTL [sec]', + 'Compute Cache Directory' + ] + + self.my_output.dictionary( + settings, + title='Intersight Settings', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/intersight/software_repository_catalog/__init__.py b/lib/intersight/software_repository_catalog/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/software_repository_catalog/class.md b/lib/intersight/software_repository_catalog/class.md new file mode 100644 index 00000000..03536874 --- /dev/null +++ b/lib/intersight/software_repository_catalog/class.md @@ -0,0 +1,26 @@ +``` + { + "AccountMoid": "", + "Ancestors": [], + "ClassId": "softwarerepository.Catalog", + "CreateTime": "2019-01-18T01:41:26.956Z", + "DomainGroupMoid": "SystemDomainGroup", + "IsImagePullFailure": false, + "ModTime": "2019-01-18T01:41:27.145Z", + "Moid": "5c412ec66e6c356c358c33bf", + "Name": "system-catalog", + "ObjectType": "softwarerepository.Catalog", + "Organization": null, + "Owners": [ + "system" + ], + "SharedScope": "", + "System": { + "ClassId": "mo.MoRef", + "Moid": "5960901ca94eba000127e32c", + "ObjectType": "iam.System", + "link": "https://www.intersight.com/api/v1/iam/Systems/5960901ca94eba000127e32c" + }, + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/software_repository_catalog/main.py b/lib/intersight/software_repository_catalog/main.py new file mode 100644 index 00000000..4fe0eb20 --- /dev/null +++ b/lib/intersight/software_repository_catalog/main.py @@ -0,0 +1,44 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class SoftwareRepositoryCatalog(IntersightCommon): + """Class for intersight software repository catalog + { + "AccountMoid": "", + "Ancestors": [], + "ClassId": "softwarerepository.Catalog", + "CreateTime": "2019-01-18T01:41:26.956Z", + "DomainGroupMoid": "SystemDomainGroup", + "IsImagePullFailure": false, + "ModTime": "2019-01-18T01:41:27.145Z", + "Moid": "5c412ec66e6c356c358c33bf", + "Name": "system-catalog", + "ObjectType": "softwarerepository.Catalog", + "Organization": null, + "Owners": [ + "system" + ], + "SharedScope": "", + "System": { + "ClassId": "mo.MoRef", + "Moid": "5960901ca94eba000127e32c", + "ObjectType": "iam.System", + "link": "https://www.intersight.com/api/v1/iam/Systems/5960901ca94eba000127e32c" + }, + "Tags": [] + } + """ + def __init__(self, iaccount, log_id=None): + self.iobject = 'softwarerepository catalog' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + + def get_user_catalog_id(self, organization_id): + items = IntersightCommon.get_all(self) + if items is None: + return None + + for item in items: + if item['Name'] == 'user-catalog' and item['Organization']['Moid'] == organization_id: + return item['Moid'] + + return None diff --git a/lib/intersight/storage_controller/__init__.py b/lib/intersight/storage_controller/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/storage_controller/class.md b/lib/intersight/storage_controller/class.md new file mode 100644 index 00000000..818f8e9d --- /dev/null +++ b/lib/intersight/storage_controller/class.md @@ -0,0 +1,163 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "BackupBatteryUnit": null, + "ClassId": "storage.Controller", + "ComputeBlade": null, + "ComputeBoard": { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + "ComputeRackUnit": null, + "ConnectedSasExpander": false, + "ControllerFlags": "driveSecurityCapable", + "ControllerId": "1", + "ControllerStatus": "optimal", + "CreateTime": "2022-09-02T07:26:18.427Z", + "DefaultDriveMode": "", + "DeviceMoId": "61c35fa36f72612d3005590c", + "DiskGroup": [], + "DiskSlot": [], + "DisplayNames": { + "hierarchical": [ + "controller-1" + ], + "short": [ + "Controller-1" + ] + }, + "Dn": "sys/rack-unit-3/board/storage-SAS-1", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EccBucketLeakRate": 0, + "ForeignConfigPresent": false, + "HwRevision": "C0", + "InterfaceType": "", + "InventoryDeviceInfo": null, + "MaxVolumesSupported": 0, + "MemoryCorrectableErrors": 0, + "ModTime": "2022-09-02T07:41:09.15Z", + "Model": "LSI MegaRAID SAS 3108", + "Moid": "6311b01a76752d31398ef2c4", + "Name": "", + "ObjectType": "storage.Controller", + "OobInterfaceSupported": "yes", + "OperState": "unknown", + "Operability": "operable", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + "PciAddr": "04:00.0", + "PciSlot": "HBA", + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PersistentCacheSize": 0, + "PhysicalDiskExtensions": [], + "PhysicalDisks": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2cc", + "ObjectType": "storage.PhysicalDisk", + "link": "https://www.intersight.com/api/v1/storage/PhysicalDisks/6311b01a76752d31398ef2cc" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2d2", + "ObjectType": "storage.PhysicalDisk", + "link": "https://www.intersight.com/api/v1/storage/PhysicalDisks/6311b01a76752d31398ef2d2" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2d6", + "ObjectType": "storage.PhysicalDisk", + "link": "https://www.intersight.com/api/v1/storage/PhysicalDisks/6311b01a76752d31398ef2d6" + } + ], + "PinnedCacheState": 0, + "Presence": "equipped", + "PreviousFru": null, + "RaidSupport": "RAID0, RAID1, RAID5, RAID10, RAID50", + "RebuildRate": "30", + "RebuildRatePercent": 0, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "RunningFirmware": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c8", + "ObjectType": "firmware.RunningFirmware", + "link": "https://www.intersight.com/api/v1/firmware/RunningFirmwares/6311b01a76752d31398ef2c8" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2ca", + "ObjectType": "firmware.RunningFirmware", + "link": "https://www.intersight.com/api/v1/firmware/RunningFirmwares/6311b01a76752d31398ef2ca" + } + ], + "SelfEncryptEnabled": "", + "Serial": "SK61026231", + "SharedScope": "", + "SubOemId": "", + "SupportedStripSizes": "", + "Tags": [], + "TotalCacheSize": 0, + "Type": "SAS", + "Vendor": "LSI Corp.", + "VirtualDriveExtensions": [], + "VirtualDrives": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2f6", + "ObjectType": "storage.VirtualDrive", + "link": "https://www.intersight.com/api/v1/storage/VirtualDrives/6311b01a76752d31398ef2f6" + } + ] + } +``` \ No newline at end of file diff --git a/lib/intersight/storage_controller/info.py b/lib/intersight/storage_controller/info.py new file mode 100644 index 00000000..03a4c231 --- /dev/null +++ b/lib/intersight/storage_controller/info.py @@ -0,0 +1,113 @@ +class StorageControllerInfo(): + def __init__(self): + pass + + def get_board_info(self, storage_controllers_mo, physical_disks_mo=None): + if storage_controllers_mo is None: + return None + + controllers_info = [] + + keys = [ + 'Model', + 'Moid', + 'Vendor', + 'Serial', + 'Presence', + 'ControllerStatus', + 'PciAddr', + 'PciSlot', + 'ControllerId', + 'Dn', + 'RaidSupport' + ] + + for controller in storage_controllers_mo: + info = {} + info['__Output'] = {} + for key in keys: + info[key] = controller[key] + + info['Name'] = info['Dn'].split('/')[-1] + + if physical_disks_mo is None: + info['PhysicalDiskCount'] = len(controller['PhysicalDisks']) + info['PhysicalDiskIds'] = [] + for physical_disk in controller['PhysicalDisks']: + info['PhysicalDiskIds'].append(physical_disk['Moid']) + + if physical_disks_mo is not None: + candidate_moids = [] + for physical_disk in controller['PhysicalDisks']: + candidate_moids.append(physical_disk['Moid']) + + info['PhysicalDiskCount'] = 0 + info['PhysicalDiskIds'] = [] + for physical_disk_mo in physical_disks_mo: + if physical_disk_mo['Moid'] in candidate_moids: + if physical_disk_mo['DiskState'] != '': + info['PhysicalDiskCount'] = info['PhysicalDiskCount'] + 1 + info['PhysicalDiskIds'].append( + physical_disk_mo['Moid'] + ) + + info['VirtualDriveCount'] = len(controller['VirtualDrives']) + info['VirtualDriveIds'] = [] + for virtual_drive in controller['VirtualDrives']: + info['VirtualDriveIds'].append(virtual_drive['Moid']) + + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + controllers_info.append(info) + + return controllers_info + + def get_blade_info(self, controllers): + if controllers is None: + return None + + controllers_info = [] + + keys = [ + 'Model', + 'Moid', + 'Vendor', + 'Serial', + 'Presence', + 'ControllerStatus', + 'PciAddr', + 'PciSlot', + 'ControllerId', + 'Dn', + 'RaidSupport' + ] + + for controller in controllers: + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = controller[key] + + info['Name'] = info['Dn'].split('/')[-1] + info['PhysicalDiskCount'] = len(controller['PhysicalDisks']) + info['PhysicalDiskIds'] = [] + for physical_disk in controller['PhysicalDisks']: + info['PhysicalDiskIds'].append(physical_disk['Moid']) + + info['VirtualDriveCount'] = len(controller['VirtualDrives']) + info['VirtualDriveIds'] = [] + for virtual_drive in controller['VirtualDrives']: + info['VirtualDriveIds'].append(virtual_drive['Moid']) + + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + controllers_info.append(info) + + return controllers_info diff --git a/lib/intersight/storage_controller/main.py b/lib/intersight/storage_controller/main.py new file mode 100644 index 00000000..6d37d98a --- /dev/null +++ b/lib/intersight/storage_controller/main.py @@ -0,0 +1,51 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.storage_controller.info import StorageControllerInfo + + +class StorageController(IntersightCommon, StorageControllerInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'storage controller' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + StorageControllerInfo.__init__(self) + + def get_board_storage_controllers(self, board_id, cache=True): + if cache: + self.prepare_cache() + else: + self.cache = self.get_all() + + if self.cache is None: + return None + + controllers = [] + + for item in self.cache: + if item['ComputeBoard'] is not None: + if item['ComputeBoard']['Moid'] == board_id: + controllers.append(item) + + return controllers + + def get_blade_storage_controllers(self, blade_id, cache=True): + if cache: + self.prepare_cache() + else: + self.cache = self.get_all() + + if self.cache is None: + return None + + controllers = [] + + for item in self.cache: + if item['ComputeBlade'] is not None: + if item['ComputeBlade']['Moid'] == blade_id: + controllers.append(item) + continue + + for ancestor in item['Ancestors']: + if ancestor['ObjectType'] == 'compute.Blade' and ancestor['Moid'] == blade_id: + controllers.append(item) + continue + + return controllers diff --git a/lib/intersight/storage_disk_group/__init__.py b/lib/intersight/storage_disk_group/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/storage_disk_group/class.md b/lib/intersight/storage_disk_group/class.md new file mode 100644 index 00000000..47abe9d0 --- /dev/null +++ b/lib/intersight/storage_disk_group/class.md @@ -0,0 +1,194 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "64be8af676752d39013fb868", + "ObjectType": "storage.Controller", + "link": "https://intersight.com/api/v1/storage/Controllers/64be8af676752d39013fb868" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be89b276752d39013f581d", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/64be89b276752d39013f581d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be876876752d39013ea7f4", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/64be876876752d39013ea7f4" + } + ], + "ClassId": "storage.DiskGroup", + "CreateTime": "2023-10-30T10:11:24.944Z", + "DedicatedHotSpares": [], + "DeviceMoId": "64be89606f726131018403d6", + "Dn": "/redfish/v1/Systems/FCH26447781/Storage/MSTOR-RAID/DiskGroup-253-254", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "ModTime": "2024-05-08T19:14:40.442Z", + "Moid": "653f814c76752d39016f255b", + "Name": "", + "ObjectType": "storage.DiskGroup", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "64be6ab66f726131018165d8", + "64be89606f726131018403d6" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "64be8af676752d39013fb868", + "ObjectType": "storage.Controller", + "link": "https://intersight.com/api/v1/storage/Controllers/64be8af676752d39013fb868" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "RaidType": "RAID1", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "64be89606f726131018403d6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://intersight.com/api/v1/asset/DeviceRegistrations/64be89606f726131018403d6" + }, + "Rn": "", + "SharedScope": "", + "Spans": [ + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "653f814c76752d39016f255b", + "ObjectType": "storage.DiskGroup", + "link": "https://intersight.com/api/v1/storage/DiskGroups/653f814c76752d39016f255b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be8af676752d39013fb868", + "ObjectType": "storage.Controller", + "link": "https://intersight.com/api/v1/storage/Controllers/64be8af676752d39013fb868" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be89b276752d39013f581d", + "ObjectType": "compute.Blade", + "link": "https://intersight.com/api/v1/compute/Blades/64be89b276752d39013f581d" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be876876752d39013ea7f4", + "ObjectType": "equipment.Chassis", + "link": "https://intersight.com/api/v1/equipment/Chasses/64be876876752d39013ea7f4" + } + ], + "ClassId": "storage.Span", + "CreateTime": "2023-10-30T10:11:24.947Z", + "DeviceMoId": "64be89606f726131018403d6", + "DiskGroup": { + "ClassId": "mo.MoRef", + "Moid": "653f814c76752d39016f255b", + "ObjectType": "storage.DiskGroup", + "link": "https://intersight.com/api/v1/storage/DiskGroups/653f814c76752d39016f255b" + }, + "Dn": "/redfish/v1/Systems/FCH26447781/Storage/MSTOR-RAID/DiskGroup-253-254/Span-0", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "ModTime": "2023-10-30T10:11:24.96Z", + "Moid": "653f814c76752d39016f255a", + "ObjectType": "storage.Span", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "64be6ab66f726131018165d8", + "64be89606f726131018403d6" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "653f814c76752d39016f255b", + "ObjectType": "storage.DiskGroup", + "link": "https://intersight.com/api/v1/storage/DiskGroups/653f814c76752d39016f255b" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PhysicalDisks": [ + { + "ClassId": "mo.MoRef", + "Moid": "64be8b5c76752d39013fd8ad", + "ObjectType": "storage.PhysicalDisk", + "link": "https://intersight.com/api/v1/storage/PhysicalDisks/64be8b5c76752d39013fd8ad" + }, + { + "ClassId": "mo.MoRef", + "Moid": "64be8b5c76752d39013fd8b8", + "ObjectType": "storage.PhysicalDisk", + "link": "https://intersight.com/api/v1/storage/PhysicalDisks/64be8b5c76752d39013fd8b8" + } + ], + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "64be89606f726131018403d6", + "ObjectType": "asset.DeviceRegistration", + "link": "https://intersight.com/api/v1/asset/DeviceRegistrations/64be89606f726131018403d6" + }, + "Rn": "", + "SharedScope": "", + "Slots": [ + 253, + 254 + ], + "SpanId": 0, + "Tags": [] + } + ], + "StorageController": { + "ClassId": "mo.MoRef", + "Moid": "64be8af676752d39013fb868", + "ObjectType": "storage.Controller", + "link": "https://intersight.com/api/v1/storage/Controllers/64be8af676752d39013fb868" + }, + "Tags": [], + "VirtualDrives": [ + { + "ClassId": "mo.MoRef", + "Moid": "653f814c76752d39016f2553", + "ObjectType": "storage.VirtualDrive", + "link": "https://intersight.com/api/v1/storage/VirtualDrives/653f814c76752d39016f2553" + } + ] + } +``` \ No newline at end of file diff --git a/lib/intersight/storage_disk_group/main.py b/lib/intersight/storage_disk_group/main.py new file mode 100644 index 00000000..dc0243e0 --- /dev/null +++ b/lib/intersight/storage_disk_group/main.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class StorageDiskGroup(IntersightCommon): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'storage diskgroup' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) diff --git a/lib/intersight/storage_physical_disk/__init__.py b/lib/intersight/storage_physical_disk/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/storage_physical_disk/class.md b/lib/intersight/storage_physical_disk/class.md new file mode 100644 index 00000000..8735b08d --- /dev/null +++ b/lib/intersight/storage_physical_disk/class.md @@ -0,0 +1,160 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "BackgroundOperations": "", + "BlockSize": "512", + "Bootable": "false", + "ClassId": "storage.PhysicalDisk", + "ConfigurationCheckpoint": "", + "ConfigurationState": "not-applied", + "CreateTime": "2022-09-02T07:26:18.436Z", + "DeviceMoId": "61c35fa36f72612d3005590c", + "DisabledForRemoval": false, + "DiscoveredPath": "default", + "DiskId": "3", + "DiskState": "online", + "DisplayNames": { + "hierarchical": [ + "physicalDisk-3" + ], + "short": [ + "PhysicalDisk-3" + ] + }, + "Dn": "sys/rack-unit-3/board/storage-SAS-1/disk-3", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "DriveFirmware": "", + "DriveState": "", + "EncryptionStatus": "", + "FailurePredicted": false, + "FdeCapable": "", + "HotSpareType": "", + "IndicatorLed": "", + "InventoryDeviceInfo": null, + "LinkSpeed": "12-gbps", + "LinkState": "unknown", + "LocatorLed": { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2fd", + "ObjectType": "equipment.LocatorLed", + "link": "https://www.intersight.com/api/v1/equipment/LocatorLeds/6311b01a76752d31398ef2fd" + }, + "MaximumOperatingTemperature": 0, + "MediaErrorCount": 0, + "ModTime": "2022-09-02T07:41:09.148Z", + "Model": "ST1200MM0088", + "Moid": "6311b01a76752d31398ef2d6", + "Name": "", + "NonCoercedSizeBytes": 0, + "NumBlocks": "2341795840", + "ObjectType": "storage.PhysicalDisk", + "OperPowerState": "active", + "OperQualifierReason": "N/A", + "Operability": "operable", + "OperatingTemperature": 0, + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + }, + "PercentLifeLeft": 0, + "PercentReservedCapacityConsumed": 0, + "PerformancePercent": 0, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PhysicalBlockSize": "512", + "PhysicalDiskExtensions": [], + "Pid": "", + "PowerCycleCount": 0, + "PowerOnHours": 0, + "PowerOnHoursPercentage": 0, + "PredictedMediaLifeLeftPercent": 0, + "PredictiveFailureCount": 0, + "Presence": "equipped", + "PreviousFru": null, + "Protocol": "SAS", + "RawSize": "1144641", + "ReadErrorCountThreshold": 0, + "ReadIoErrorCount": 0, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "RunningFirmware": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2d8", + "ObjectType": "firmware.RunningFirmware", + "link": "https://www.intersight.com/api/v1/firmware/RunningFirmwares/6311b01a76752d31398ef2d8" + } + ], + "SasPorts": [], + "Secured": "", + "Serial": "S40222EH0000K701JJQ3", + "SharedScope": "", + "Size": "1143455", + "StorageController": { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + }, + "StorageEnclosure": null, + "Tags": [], + "Thermal": "unknown", + "ThresholdOperatingTemperature": 0, + "Type": "HDD", + "VariantType": "default", + "Vendor": "SEAGATE", + "WearStatusInDays": 0, + "WriteErrorCountThreshold": 0, + "WriteIoErrorCount": 0 + } +``` \ No newline at end of file diff --git a/lib/intersight/storage_physical_disk/info.py b/lib/intersight/storage_physical_disk/info.py new file mode 100644 index 00000000..e749f55b --- /dev/null +++ b/lib/intersight/storage_physical_disk/info.py @@ -0,0 +1,164 @@ +class StoragePhysicalDiskInfo(): + def __init__(self): + pass + + def get_compute_disks_size(self, disks_info): + if disks_info is None: + return 0 + + size = 0 + for disk_info in disks_info: + size = size + disk_info['SizeBytes'] + + return size + + def get_disk_size_bytes(self, size): + if isinstance(size, int): + return size + + if len(size.strip()) == 0: + return 0 + + factor = 1 + size_bytes = 0 + + if size.endswith('MB'): + factor = 1024 * 1024 + size_bytes = int(size.split('MB')[0].strip()) + + if size.endswith('GB'): + factor = 1024 * 1024 * 1024 + size_bytes = int(size.split('GB')[0].strip()) + + if size.endswith('TB'): + factor = 1024 * 1024 * 1024 * 1024 + size_bytes = int(size.split('TB')[0].strip()) + + # Default value in MB + if factor == 1: + factor = 1024 * 1024 + size_bytes = int(size.strip()) + + return size_bytes * factor + + def is_physical_disk_ok(self, info): + if info['Operability'] == 'operable' and info['Presence'] == 'equipped' and info['DiskState'].lower() in ['good', 'online', 'healthy', 'ok', '']: + return True + + if info['Operability'] == '' and info['Presence'] == 'equipped' and info['DiskState'].lower() in ['good', 'online', 'healthy', 'ok', '']: + return True + + if info['Operability'] == '' and info['Presence'] == '' and info['DiskState'].lower() in ['good', 'online', 'healthy', 'ok', '']: + return True + + return False + + def get_info(self, physical_disks_mo, disk_type=None, virtual_drives_info=None, storage_controllers_info=None): + if physical_disks_mo is None: + return None + + compute_disks_info = [] + + keys = [ + 'Moid', + 'Bootable', + 'DiskId', + 'DiskState', + 'Dn', + 'DriveFirmware', + 'DriveState', + 'LinkSpeed', + 'Model', + 'PartNumber', + 'Pid', + 'OperPowerState', + 'Operability', + 'Presence', + 'Protocol', + 'Serial', + 'Size', + 'Type', + 'Vendor' + ] + + for compute_disk in physical_disks_mo: + if compute_disk['DriveState'] == 'Absent': + continue + + info = {} + info['__Output'] = {} + + for key in keys: + if key not in compute_disk: + info[key] = None + else: + info[key] = compute_disk[key] + + try: + info['_DiskId'] = int(info['DiskId']) + except BaseException: + info['_DiskId'] = 0 + + info['SizeBytes'] = self.get_disk_size_bytes( + info['Size'] + ) + + info['SizeUnit'] = self.info_helper.convert_storage( + info['SizeBytes'] + ) + + info['VirtualDriveMoid'] = None + info['VirtualDriveId'] = '' + if virtual_drives_info is not None: + for virtual_drive_info in virtual_drives_info: + if compute_disk['DiskId'] in virtual_drive_info['PhysicalDiskIds']: + info['VirtualDriveMoid'] = virtual_drive_info['Moid'] + info['VirtualDriveId'] = virtual_drive_info['VirtualDriveId'] + + if compute_disk['Moid'] in virtual_drive_info['PhysicalDiskMoids']: + info['VirtualDriveMoid'] = virtual_drive_info['Moid'] + info['VirtualDriveId'] = virtual_drive_info['VirtualDriveId'] + + info['StorageControllerId'] = '' + info['StorageControllerName'] = '' + if storage_controllers_info is not None: + for storage_controller_info in storage_controllers_info: + if compute_disk['Moid'] in storage_controller_info['PhysicalDiskIds']: + info['StorageControllerId'] = storage_controller_info['ControllerId'] + info['StorageControllerName'] = storage_controller_info['Name'] + + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + if info['Operability'] == 'operable': + info['__Output']['Operability'] = 'Green' + else: + info['__Output']['Operability'] = 'Red' + + if len(info['DiskState']) > 0: + if info['DiskState'].lower() in ['good', 'online', 'healthy', 'ok']: + info['__Output']['DiskState'] = 'Green' + else: + info['__Output']['DiskState'] = 'Red' + + if info['Bootable'] == 'true': + info['BootableTick'] = '\u2713' + info['__Output']['BootableTick'] = 'Green' + else: + info['BootableTick'] = '\u2717' + info['__Output']['BootableTick'] = 'Red' + + if self.is_physical_disk_ok(info): + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + compute_disks_info.append(info) + + compute_disks_info = sorted(compute_disks_info, key=lambda i: i['_DiskId']) + + return compute_disks_info diff --git a/lib/intersight/storage_physical_disk/main.py b/lib/intersight/storage_physical_disk/main.py new file mode 100644 index 00000000..13ea882f --- /dev/null +++ b/lib/intersight/storage_physical_disk/main.py @@ -0,0 +1,39 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.storage_physical_disk.info import StoragePhysicalDiskInfo + + +class StoragePhysicalDisk(IntersightCommon, StoragePhysicalDiskInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'storage physicaldisk' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + StoragePhysicalDiskInfo.__init__(self) + + def get_compute_disks(self, compute_id, cache=True, disk_type=None): + if cache: + self.prepare_cache() + else: + self.cache = self.get_all() + + if self.cache is None: + return None + + disks = [] + + for item in self.cache: + if disk_type is not None and item['Type'] != disk_type: + continue + + match = False + for ancestor in item['Ancestors']: + if ancestor['ObjectType'] == 'compute.Board' and ancestor['Moid'] == compute_id: + match = True + break + + if ancestor['ObjectType'] == 'compute.Blade' and ancestor['Moid'] == compute_id: + match = True + break + + if match: + disks.append(item) + + return disks diff --git a/lib/intersight/storage_physical_disk_usage/__init__.py b/lib/intersight/storage_physical_disk_usage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/storage_physical_disk_usage/class.md b/lib/intersight/storage_physical_disk_usage/class.md new file mode 100644 index 00000000..b5babb34 --- /dev/null +++ b/lib/intersight/storage_physical_disk_usage/class.md @@ -0,0 +1,91 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "619f39d376752d31391db1b5", + "ObjectType": "storage.VirtualDrive", + "link": "https://www.intersight.com/api/v1/storage/VirtualDrives/619f39d376752d31391db1b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c5d6176752d35e46893", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/5fdf9c5d6176752d35e46893" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c056176752d35e44930", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/5fdf9c056176752d35e44930" + }, + { + "ClassId": "mo.MoRef", + "Moid": "5fdf9c016176752d35e44795", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/5fdf9c016176752d35e44795" + } + ], + "ClassId": "storage.PhysicalDiskUsage", + "CreateTime": "2021-11-25T07:23:00.055Z", + "DeviceMoId": "5fdf9be76f72612d300a8d81", + "Dn": "sys/rack-unit-1/board/storage-SAS-MRAID/vd-0/pd-10", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "InventoryDeviceInfo": null, + "ModTime": "2022-07-26T02:32:43.687Z", + "Moid": "619f39d476752d31391db1c8", + "NumberOfBlocks": "1873045504", + "ObjectType": "storage.PhysicalDiskUsage", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "5fdf9be76f72612d300a8d81" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "619f39d376752d31391db1b5", + "ObjectType": "storage.VirtualDrive", + "link": "https://www.intersight.com/api/v1/storage/VirtualDrives/619f39d376752d31391db1b5" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PhysicalDrive": "10", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "5fdf9be76f72612d300a8d81", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/5fdf9be76f72612d300a8d81" + }, + "Rn": "", + "SharedScope": "", + "Span": "0", + "StartingBlock": "0", + "State": "online", + "StorageVirtualDrive": { + "ClassId": "mo.MoRef", + "Moid": "619f39d376752d31391db1b5", + "ObjectType": "storage.VirtualDrive", + "link": "https://www.intersight.com/api/v1/storage/VirtualDrives/619f39d376752d31391db1b5" + }, + "Tags": [], + "VirtualDrive": "0" + } +``` \ No newline at end of file diff --git a/lib/intersight/storage_physical_disk_usage/main.py b/lib/intersight/storage_physical_disk_usage/main.py new file mode 100644 index 00000000..d909a9c3 --- /dev/null +++ b/lib/intersight/storage_physical_disk_usage/main.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class StoragePhysicalDiskUsage(IntersightCommon): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'storage physicaldiskusage' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) diff --git a/lib/intersight/storage_virtual_drive/__init__.py b/lib/intersight/storage_virtual_drive/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/storage_virtual_drive/class.md b/lib/intersight/storage_virtual_drive/class.md new file mode 100644 index 00000000..e7d44f33 --- /dev/null +++ b/lib/intersight/storage_virtual_drive/class.md @@ -0,0 +1,148 @@ +``` + { + "AccessPolicy": "read-write", + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "ActualWriteCachePolicy": "write-through", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311ac4676752d31398e5331", + "ObjectType": "compute.Board", + "link": "https://www.intersight.com/api/v1/compute/Boards/6311ac4676752d31398e5331" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311aae876752d31398e1a50", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6311aae876752d31398e1a50" + } + ], + "AvailableSize": "0", + "BlockSize": "512", + "Bootable": "true", + "ClassId": "storage.VirtualDrive", + "ConfigState": "orphaned", + "ConfiguredWriteCachePolicy": "write-through", + "ConnectionProtocol": "unspecified", + "CreateTime": "2022-09-02T07:26:18.446Z", + "DeviceMoId": "61c35fa36f72612d3005590c", + "DiskGroup": null, + "DisplayNames": { + "hierarchical": [ + "virtualDrive-RAID10_3456" + ], + "short": [ + "VirtualDrive-RAID10_3456" + ] + }, + "Dn": "sys/rack-unit-3/board/storage-SAS-1/vd-0", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "DriveCache": "no-change", + "DriveSecurity": "no", + "DriveState": "optimal", + "InventoryDeviceInfo": null, + "IoPolicy": "direct", + "ModTime": "2022-09-02T07:41:09.149Z", + "Model": "", + "Moid": "6311b01a76752d31398ef2f6", + "Name": "RAID10_3456", + "NumBlocks": "388624384", + "ObjectType": "storage.VirtualDrive", + "OperState": "undefined", + "Operability": "operable", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "61c35fa36f72612d3005590c" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "PhysicalBlockSize": "unknown", + "PhysicalDiskUsages": [], + "Presence": "equipped", + "PreviousFru": null, + "ReadPolicy": "normal", + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "61c35fa36f72612d3005590c", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/61c35fa36f72612d3005590c" + }, + "Revision": "0", + "Rn": "", + "SecurityFlags": "", + "Serial": "", + "SharedScope": "", + "Size": "2286910", + "StorageController": { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef2c4", + "ObjectType": "storage.Controller", + "link": "https://www.intersight.com/api/v1/storage/Controllers/6311b01a76752d31398ef2c4" + }, + "StorageVirtualDriveContainer": null, + "StripSize": "64", + "Tags": [], + "Type": "mirror-stripe", + "Uuid": "41b43588-6ba3-4849-8dca-2a0420468108", + "VdMemberEps": [ + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef305", + "ObjectType": "storage.VdMemberEp", + "link": "https://www.intersight.com/api/v1/storage/VdMemberEps/6311b01a76752d31398ef305" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef309", + "ObjectType": "storage.VdMemberEp", + "link": "https://www.intersight.com/api/v1/storage/VdMemberEps/6311b01a76752d31398ef309" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef30b", + "ObjectType": "storage.VdMemberEp", + "link": "https://www.intersight.com/api/v1/storage/VdMemberEps/6311b01a76752d31398ef30b" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6311b01a76752d31398ef30d", + "ObjectType": "storage.VdMemberEp", + "link": "https://www.intersight.com/api/v1/storage/VdMemberEps/6311b01a76752d31398ef30d" + } + ], + "Vendor": "", + "VendorUuid": "678da6e7-15d5-7460-23fe-a8c7196781e6", + "VirtualDriveExtension": null, + "VirtualDriveId": "0" + } +``` \ No newline at end of file diff --git a/lib/intersight/storage_virtual_drive/info.py b/lib/intersight/storage_virtual_drive/info.py new file mode 100644 index 00000000..b2a02c30 --- /dev/null +++ b/lib/intersight/storage_virtual_drive/info.py @@ -0,0 +1,136 @@ +class StorageVirtualDriveInfo(): + def __init__(self): + pass + + def get_virtual_drives_size(self, virtual_drives_info): + size = 0 + for virtual_drive_info in virtual_drives_info: + size = size + virtual_drive_info['SizeBytes'] + return size + + def get_disk_size_bytes(self, size): + if isinstance(size, int): + return size + + factor = 1 + size_bytes = 0 + + if size.endswith('MB'): + factor = 1024 * 1024 + size_bytes = int(size.split('MB')[0].strip()) + + if size.endswith('GB'): + factor = 1024 * 1024 * 1024 + size_bytes = int(size.split('GB')[0].strip()) + + if size.endswith('TB'): + factor = 1024 * 1024 * 1024 * 1024 + size_bytes = int(size.split('TB')[0].strip()) + + if factor == 1: + factor = 1024 * 1024 + size_bytes = int(size.strip()) + + return size_bytes * factor + + def is_virtual_drive_ok(self, info): + if info['Operability'] not in ['operable', 'ok', '']: + return False + + if info['Presence'] not in ['equipped', '']: + return False + + if info['DriveState'].lower() not in ['optimal']: + return False + + return True + + def get_info(self, virtual_drives_mo, storage_controllers_info=None): + if virtual_drives_mo is None: + return None + + virtual_drives_info = [] + + keys = [ + 'Moid', + 'Name', + 'Dn', + 'Size', + 'Type', + 'VirtualDriveId', + 'Bootable', + 'DriveState', + 'Operability', + 'Presence', + 'ActualWriteCachePolicy', + 'ConfiguredWriteCachePolicy', + 'IoPolicy' + ] + + for virtual_drive in virtual_drives_mo: + info = {} + info['__Output'] = {} + + for key in keys: + info[key] = virtual_drive[key] + + try: + info['_VirtualDriveId'] = int(info['VirtualDriveId']) + except BaseException: + info['_VirtualDriveId'] = 0 + + info['SizeBytes'] = self.get_disk_size_bytes( + info['Size'] + ) + + info['SizeUnit'] = self.info_helper.convert_storage( + info['SizeBytes'] + ) + + info['PhysicalDiskCount'] = max( + len(virtual_drive['PhysicalDiskUsages']), + len(virtual_drive['VdMemberEps']) + ) + + info['StorageControllerId'] = None + info['StorageControllerName'] = None + if storage_controllers_info is not None: + for storage_controller_info in storage_controllers_info: + if info['Moid'] in storage_controller_info['VirtualDriveIds']: + info['StorageControllerId'] = storage_controller_info['ControllerId'] + info['StorageControllerName'] = storage_controller_info['Name'] + + if info['Presence'] == 'equipped': + info['__Output']['Presence'] = 'Green' + else: + info['__Output']['Presence'] = 'Red' + + if info['Operability'] == 'operable': + info['__Output']['Operability'] = 'Green' + else: + info['__Output']['Operability'] = 'Red' + + if info['DriveState'].lower() == 'optimal': + info['__Output']['DriveState'] = 'Green' + else: + info['__Output']['DriveState'] = 'Red' + + if info['Bootable'] == 'true': + info['BootableTick'] = '\u2713' + info['__Output']['BootableTick'] = 'Green' + else: + info['BootableTick'] = '\u2717' + info['__Output']['BootableTick'] = 'Red' + + if self.is_virtual_drive_ok(info): + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + virtual_drives_info.append(info) + + virtual_drives_info = sorted(virtual_drives_info, key=lambda i: i['_VirtualDriveId']) + + return virtual_drives_info diff --git a/lib/intersight/storage_virtual_drive/main.py b/lib/intersight/storage_virtual_drive/main.py new file mode 100644 index 00000000..4d30df21 --- /dev/null +++ b/lib/intersight/storage_virtual_drive/main.py @@ -0,0 +1,36 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.storage_virtual_drive.info import StorageVirtualDriveInfo + + +class StorageVirtualDrive(IntersightCommon, StorageVirtualDriveInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'storage virtualdrive' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + StorageVirtualDriveInfo.__init__(self) + + def get_virtual_drives(self, compute_id, cache=True): + if cache: + self.prepare_cache() + else: + self.cache = self.get_all() + + if self.cache is None: + return None + + disks = [] + + for item in self.cache: + match = False + for ancestor in item['Ancestors']: + if ancestor['ObjectType'] == 'compute.Board' and ancestor['Moid'] == compute_id: + match = True + break + + if ancestor['ObjectType'] == 'compute.Blade' and ancestor['Moid'] == compute_id: + match = True + break + + if match: + disks.append(item) + + return disks diff --git a/lib/intersight/tam_advisory_definition/__init__.py b/lib/intersight/tam_advisory_definition/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/tam_advisory_definition/class.md b/lib/intersight/tam_advisory_definition/class.md new file mode 100644 index 00000000..f8816867 --- /dev/null +++ b/lib/intersight/tam_advisory_definition/class.md @@ -0,0 +1,171 @@ +``` + { + "AccountMoid": "5960901ca94eba000127e33a", + "Actions": [ + { + "AffectedObjectType": "hyperflex.Cluster", + "AlertType": "eolAdvisory", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 where ( datediff(current_date(), '2023-02-28' ) \u003e= 0 )" + } + ], + "Type": "restApi" + } + ], + "AdvisoryDetails": { + "AllMilestones": [ + { + "ClassId": "tam.Milestone", + "Date": "2021-11-10T00:00:00Z", + "Description": "The date that this software version was first available for download.", + "EndOffset": 2147483647, + "LabelHint": "upcoming", + "MilestoneType": "unknown", + "Name": "Release Date", + "ObjectType": "tam.Milestone", + "StartOffset": 0 + }, + { + "ClassId": "tam.Milestone", + "Date": "2022-07-31T00:00:00Z", + "Description": "The last date that Cisco Engineering may release any final software maintenance releases or bug fixes. After this date, Cisco Engineering may no longer develop, repair, maintain, or test the product software and only critical security updates will be provided on this release train. ", + "EndOffset": 2147483647, + "LabelHint": "upcoming", + "MilestoneType": "unknown", + "Name": "End of SW Maintenance (EOSM) Release Date", + "ObjectType": "tam.Milestone", + "StartOffset": 0 + }, + { + "ClassId": "tam.Milestone", + "Date": "2022-11-30T00:00:00Z", + "Description": "The last date to download the software through Cisco download page. The software is no longer available for download after this date.", + "EndOffset": 2147483647, + "LabelHint": "upcoming", + "MilestoneType": "unknown", + "Name": "End-of-Download (EOD) Date", + "ObjectType": "tam.Milestone", + "StartOffset": 0 + }, + { + "ClassId": "tam.Milestone", + "Date": "2022-07-31T00:00:00Z", + "Description": "The last date that Cisco may provide support for security vulnerabilities.", + "EndOffset": 2147483647, + "LabelHint": "upcoming", + "MilestoneType": "unknown", + "Name": "End of Security and Vulnerability Fixes", + "ObjectType": "tam.Milestone", + "StartOffset": 0 + }, + { + "ClassId": "tam.Milestone", + "Date": "2023-02-28T00:00:00Z", + "Description": "The last date to receive service and support for the software. After this date, all support services for the software are unavailable, and the software becomes obsolete. ", + "EndOffset": 2147483647, + "LabelHint": "upcoming", + "MilestoneType": "unknown", + "Name": "Last Date of Support", + "ObjectType": "tam.Milestone", + "StartOffset": 0 + } + ], + "ClassId": "tam.EolAdvisoryDetails", + "Description": "", + "Milestone": { + "ClassId": "tam.Milestone", + "Date": "2023-02-28T00:00:00Z", + "Description": "The last date to receive service and support for the software. After this date, all support services for the software are unavailable, and the software becomes obsolete.", + "EndOffset": 2147483647, + "LabelHint": "past", + "MilestoneType": "lastDateOfSupport", + "Name": "Last Date of Support", + "ObjectType": "tam.Milestone", + "StartOffset": 0 + }, + "ObjectType": "tam.EolAdvisoryDetails", + "Release": "5.0(1x)" + }, + "AdvisoryId": "hx-5.0.1x-ldos-critical", + "Ancestors": [], + "ApiDataSources": [ + { + "ClassId": "tam.ApiDataSource", + "MoType": "hyperflexCluster", + "Name": "ds1", + "ObjectType": "tam.ApiDataSource", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds1", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT ds1_Moid, ds1_AccountMoid, ds1_DomainGroupMoid, ds1_RegisteredDevice.Moid as ds1_RegisteredDeviceMoid, ds1_HxVersion FROM ds1 WHERE (ds1_HxVersion RLIKE '^5\\\\.0\\\\(1[a-z]') " + } + ], + "Type": "intersightApi" + } + ], + "ClassId": "tam.AdvisoryDefinition", + "CreateTime": "2023-07-28T00:08:31.798Z", + "DatePublished": "2022-06-28T00:00:00Z", + "DateUpdated": "2022-06-28T00:00:00Z", + "Description": "Software maintenance support for 5.0(1x) software release ended on July 31, 2022 as documented in the Recommended [Release Bulletin](https://www.cisco.com/c/en/us/td/docs/hyperconverged_systems/HyperFlex_HX_DataPlatformSoftware/release-guidelines-and-support-timeline/b-recommended-hx-data-platform-sw-releases.html#id_119415). No bug fixes, patches or maintenance releases will be provided for this Cisco HyperFlex Data Platform release after that date. The last date of support for Cisco Hyperflex Data Platform Software Versions 5.0(1x) is Feb 28, 2023. Software maintenance requires an active service contract.", + "DomainGroupMoid": "5b2541877a7662743465cc89", + "ExecuteOnPod": "tier1", + "ExternalUrl": "https://www.cisco.com/c/en/us/products/collateral/hyperconverged-infrastructure/hyperflex-hx-series/hyperflex-data-platform-soft-rel-5-0-1x-eol.html", + "ModTime": "2023-09-08T07:49:09.257Z", + "Moid": "64c306ff6f636b3901e9ee16", + "Name": "The last date to receive service and support for Hyperflex 5.0(1x) is past", + "ObjectType": "tam.AdvisoryDefinition", + "Organization": { + "ClassId": "mo.MoRef", + "Moid": "5dde9f896972652d3353a082", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dde9f896972652d3353a082" + }, + "OtherRefUrls": [], + "Owners": [ + "5960901ca94eba000127e33a", + "shared" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dde9f896972652d3353a082", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dde9f896972652d3353a082" + } + ], + "Recommendation": "Customers currently running HyperFlex Data Platform version 5.0(1x) should upgrade by Feb 28, 2023 to the latest Recommended Release. Cisco HyperFlex Data Platform’s Software Download page to get the latest Recommended Release can be found [here](https://software.cisco.com/download/home/286305544/type/286305994/release). Recommended release can be identified by the following\n- HyperFlex Recommended Release bulletin page found [here](https://www.cisco.com/c/en/us/td/docs/hyperconverged_systems/HyperFlex_HX_DataPlatformSoftware/release-guidelines-and-support-timeline/b-recommended-hx-data-platform-sw-releases.html).\n- Star next to the release name in [the software download page](https://software.cisco.com/download/home/286305544)\n\nHyperFlex Systems documents can be found [here](https://www.cisco.com/c/en/us/support/hyperconverged-systems/hyperflex-hx-data-platform-software/tsd-products-support-series-home.html).\nInstall and upgrade guides can be found [here](https://www.cisco.com/c/en/us/support/hyperconverged-systems/hyperflex-hx-data-platform-software/products-installation-guides-list.html).", + "S3DataSources": [], + "Severity": { + "ClassId": "tam.EolSeverity", + "Level": "critical", + "ObjectType": "tam.EolSeverity" + }, + "SharedScope": "shared", + "State": "ready", + "Tags": [], + "Type": "eolAdvisory", + "Version": "1.0", + "Workaround": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/tam_advisory_definition/info.py b/lib/intersight/tam_advisory_definition/info.py new file mode 100644 index 00000000..9804e196 --- /dev/null +++ b/lib/intersight/tam_advisory_definition/info.py @@ -0,0 +1,34 @@ +class TamAdvisoryDefinitionInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + keys = [ + 'AdvisoryId', + 'CreateTime', + 'DatePublished', + 'DateUpdated', + 'Description', + 'ExternalUrl', + 'Moid', + 'Name', + 'Recommendation', + 'Workaround' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + info['Urls'] = [] + info['Urls'].append( + managed_object['ExternalUrl'] + ) + + info['__Output'] = {} + info['__Output']['Severity'] = None + info['Severity'] = managed_object['Severity']['Level'] + if info['Severity'] == 'high': + info['__Output']['Severity'] = 'Red' + + return info diff --git a/lib/intersight/tam_advisory_definition/main.py b/lib/intersight/tam_advisory_definition/main.py new file mode 100644 index 00000000..bf7f8b7c --- /dev/null +++ b/lib/intersight/tam_advisory_definition/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.tam_advisory_definition.info import TamAdvisoryDefinitionInfo + + +class TamAdvisoryDefinition(IntersightCommon, TamAdvisoryDefinitionInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'tam advisorydefinition' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + TamAdvisoryDefinitionInfo.__init__(self) diff --git a/lib/intersight/tam_advisory_instance/__init__.py b/lib/intersight/tam_advisory_instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/tam_advisory_instance/class.md b/lib/intersight/tam_advisory_instance/class.md new file mode 100644 index 00000000..92d59fb5 --- /dev/null +++ b/lib/intersight/tam_advisory_instance/class.md @@ -0,0 +1,61 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Advisory": { + "ClassId": "mo.MoRef", + "Moid": "5fdc1ce26f636b2d39a879be", + "ObjectType": "tam.SecurityAdvisory", + "link": "https://www.intersight.com/api/v1/tam/SecurityAdvisories/5fdc1ce26f636b2d39a879be" + }, + "AffectedObject": { + "ClassId": "mo.MoRef", + "Moid": "6061d6c06176752d357360aa", + "ObjectType": "compute.RackUnit", + "link": "https://www.intersight.com/api/v1/compute/RackUnits/6061d6c06176752d357360aa" + }, + "AffectedObjectMoid": "6061d6c06176752d357360aa", + "AffectedObjectType": "compute.RackUnit", + "Ancestors": [], + "ClassId": "tam.AdvisoryInstance", + "CreateTime": "2021-03-29T22:03:24.9Z", + "DeviceRegistration": { + "ClassId": "mo.MoRef", + "Moid": "6061d69a6f72612d30c09961", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/6061d69a6f72612d30c09961" + }, + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "LastStateChangeTime": "0001-01-01T00:00:00Z", + "LastVerifiedTime": "0001-01-01T00:00:00Z", + "ModTime": "2022-05-09T13:35:16.297Z", + "Moid": "60624eac6f636b2d31a0f719", + "ObjectType": "tam.AdvisoryInstance", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "6061d69a6f72612d30c09961" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "SharedScope": "", + "State": "unknown", + "Tags": [] + } +``` \ No newline at end of file diff --git a/lib/intersight/tam_advisory_instance/info.py b/lib/intersight/tam_advisory_instance/info.py new file mode 100644 index 00000000..4729fa1f --- /dev/null +++ b/lib/intersight/tam_advisory_instance/info.py @@ -0,0 +1,13 @@ +class TamAdvisoryInstanceInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['AdvisoryMoid'] = managed_object['Advisory']['Moid'] + info['AffectedObjectType'] = managed_object['AffectedObjectType'] + info['AffectedObjectMoid'] = managed_object['AffectedObjectMoid'] + info['CreateTime'] = managed_object['CreateTime'] + info['Moid'] = managed_object['Moid'] + + return info diff --git a/lib/intersight/tam_advisory_instance/main.py b/lib/intersight/tam_advisory_instance/main.py new file mode 100644 index 00000000..909723ab --- /dev/null +++ b/lib/intersight/tam_advisory_instance/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.tam_advisory_instance.info import TamAdvisoryInstanceInfo + + +class TamAdvisoryInstance(IntersightCommon, TamAdvisoryInstanceInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'tam advisoryinstance' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + TamAdvisoryInstanceInfo.__init__(self) diff --git a/lib/intersight/tam_advisory_instance/output.py b/lib/intersight/tam_advisory_instance/output.py new file mode 100644 index 00000000..d43300b5 --- /dev/null +++ b/lib/intersight/tam_advisory_instance/output.py @@ -0,0 +1,160 @@ +from lib import filter_helper + + +class TamAdvisoryInstanceOutput(): + def __init__(self): + pass + + def print_advisory(self, servers, title=False): + info = [] + for server in servers: + if 'AdvisorySummary' in server: + item = server['AdvisorySummary'] + item['ServerName'] = server['Name'] + info.append( + item + ) + + if title: + self.my_output.default( + 'Advisory Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + if title: + self.my_output.default('None') + return + + order = [ + 'ServerName', + 'High', + 'Info' + ] + + headers = [ + 'Server', + 'High', + 'Info' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + advisories = {} + for server in servers: + for server_advisory in server['AdvisoryInfo']: + if server_advisory['Name'] not in advisories: + advisories[server_advisory['Name']] = server_advisory + advisories[server_advisory['Name']]['Server'] = [] + + advisories[server_advisory['Name']]['Server'].append( + server['Name'] + ) + + info = [] + for advisory_name in advisories: + item = advisories[advisory_name] + item['NameT'] = filter_helper.get_string_chunks( + item['Name'], + 40, + separator=' ' + ) + item['DescriptionT'] = filter_helper.get_string_chunks( + item['Description'].replace('\n', ''), + 40, + separator=' ' + ) + item['Server'] = sorted( + item['Server'], + key=lambda i: i.lower() + ) + info.append( + item + ) + + if len(info) > 0: + if title: + self.my_output.default( + 'Advisory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'Server', + 'Severity', + 'BaseScore', + 'NameT', + 'DescriptionT', + 'CveIds', + 'DatePublished', + 'DateUpdated' + ] + + headers = [ + 'Server', + 'Severity', + 'Score', + 'Name', + 'Description', + 'CveIds', + 'DatePublished', + 'DateUpdated' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Server', 'DescriptionT', 'NameT', 'CveIds'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) + + if len(info) > 0: + if title: + self.my_output.default( + 'Advisory Url [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'Server', + 'NameT', + 'Urls' + ] + + headers = [ + 'Server', + 'Name', + 'Urls' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['Server', 'NameT', 'Urls'] + ), + order=order, + headers=headers, + remove_empty_columns=True, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True + ) diff --git a/lib/intersight/tam_security_advisory/__init__.py b/lib/intersight/tam_security_advisory/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/tam_security_advisory/class.md b/lib/intersight/tam_security_advisory/class.md new file mode 100644 index 00000000..5c904067 --- /dev/null +++ b/lib/intersight/tam_security_advisory/class.md @@ -0,0 +1,334 @@ +``` + { + "AccountMoid": "5960901ca94eba000127e33a", + "Actions": [ + { + "AffectedObjectType": "compute.Blade", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE ((ds1_Firmware RLIKE '^(1|2|3|4\\\\.[01]|4\\\\.2\\\\(0|4\\\\.2\\\\(1[a-g]|4\\\\.2\\\\(2[a-b])' and ds1_Model RLIKE 'UCS.*B200.*M6') or (ds1_Firmware RLIKE '^(1|2|3|4|5\\\\.0\\\\(0|5\\\\.0\\\\(1[a-e]|5\\\\.0\\\\(2[a-b])' and ds1_Model RLIKE 'UCS.*X-210C-M6')) and ds1_SourceObjectType = 'compute.Blade'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.Blade", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE (ds1_Firmware RLIKE '^(1|2|3|4\\\\.0|4\\\\.1\\\\([0-9][a-z]|4\\\\.1\\\\([1-2][0-9][a-z]|4\\\\.1\\\\(3[0-2][a-z]|4\\\\.1\\\\(33[a-g]|4\\\\.2\\\\(1[a-g])' and ds1_Model RLIKE 'UCS.*(B200|B480).*M5') and ds1_SourceObjectType = 'compute.Blade'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.Blade", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE (ds1_Firmware RLIKE '^(1|2|3|4\\\\.0|4\\\\.1\\\\([0-9][a-z]|4\\\\.1\\\\([1-2][0-9][a-z]|4\\\\.1\\\\(3[0-2][a-z]|4\\\\.1\\\\(33[a])' and ds1_Model RLIKE '^(UCSB-EX-M4-2|UCSB-EX-M4-3)') and ds1_SourceObjectType = 'compute.Blade'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.Blade", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 JOIN ds3 ON ds1.ds1_Moid = ds3.ds3_ComputeBladeMoid JOIN ds2 ON ds3.ds3_Moid = ds2.ds2_BiosUnitMoid WHERE ds1.ds1_Model RLIKE 'UCS.*(B200|B420).*M4' and ds1.ds1_SourceObjectType = 'compute.Blade'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.Blade", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE ((ds1_Firmware RLIKE '^(1|2|3|4\\\\.0|4\\\\.1\\\\([012][a-z]|4\\\\.1\\\\(3[a-g])' and ds1_Model RLIKE 'UCS.*S3260.*M5') or (ds1_Firmware RLIKE '^(1|2|3|4\\\\.0|4\\\\.1\\\\([012][a-z]|4\\\\.1\\\\(3[a-e])' and ds1_Model RLIKE '^(UCS.*C3260.*M4|UCSC-C3K-M4)')) and ds1_SourceObjectType = 'compute.Blade'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.RackUnit", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE (ds1_Firmware RLIKE '^(1|2|3|4\\\\.[01]|4\\\\.2\\\\(0|4\\\\.2\\\\(1[a-i]|4\\\\.2\\\\(2[a-b])' and ds1_Model RLIKE 'UCS.*(C220|C240).*M6') and ds1_SourceObjectType = 'compute.RackUnit'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.RackUnit", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE (ds1_Firmware RLIKE '^(1|2|3|4\\\\.0|4\\\\.1\\\\([012][a-z]|4\\\\.1\\\\(3[a-g])' and ds1_Model RLIKE '^(UCS.*(C220|C240|C480).*M5|HX.*(220|240)C.*-M5)') and ds1_SourceObjectType = 'compute.RackUnit'" + } + ], + "Type": "restApi" + }, + { + "AffectedObjectType": "compute.RackUnit", + "AlertType": "psirt", + "ClassId": "tam.Action", + "Identifiers": [ + { + "ClassId": "tam.Identifiers", + "Name": "Moid", + "ObjectType": "tam.Identifiers", + "Value": "ds1_Moid" + } + ], + "Name": "", + "ObjectType": "tam.Action", + "OperationType": "create", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT * FROM ds1 WHERE (ds1_Firmware RLIKE '^(1|2|3|4\\\\.0|4\\\\.1\\\\([01][a-z]|4\\\\.1\\\\(2[a-j])' and ds1_Model RLIKE '^(UCS.*(C220|C240|C460).*M4|HX.*(220|240)C.*-M4)') and ds1_SourceObjectType = 'compute.RackUnit'" + } + ], + "Type": "restApi" + } + ], + "AdvisoryId": "INTEL-SA-00601", + "Ancestors": [], + "ApiDataSources": [ + { + "ClassId": "tam.ApiDataSource", + "MoType": "computePhysicalSummary", + "Name": "ds1", + "ObjectType": "tam.ApiDataSource", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds1", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT ds1_Moid, ds1_AccountMoid, ds1_DomainGroupMoid, ds1_RegisteredDevice.Moid as ds1_RegisteredDeviceMoid, ds1_SourceObjectType, ds1_Firmware, ds1_Serial, ds1_Model FROM ds1" + } + ], + "Type": "intersightApi" + }, + { + "ClassId": "tam.ApiDataSource", + "MoType": "firmwareRunningFirmware", + "Name": "ds2", + "ObjectType": "tam.ApiDataSource", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds2", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT ds2_Moid, ds2_AccountMoid, ds2_Ancestors, ds2_RegisteredDevice.Moid as ds2_RegisteredDeviceMoid, ds2_DomainGroupMoid, ds2_Version, ds2_Type, ds2_BiosUnit.Moid as ds2_BiosUnitMoid FROM ds2 WHERE ds2_Version RLIKE '(B200M4|B420M4)((\\\\.[0123])|(\\\\.4\\\\.0)|(\\\\.4\\\\.1\\\\.[01])|(\\\\.4\\\\.1\\\\.2[a-c]))'" + } + ], + "Type": "intersightApi" + }, + { + "ClassId": "tam.ApiDataSource", + "MoType": "biosUnit", + "Name": "ds3", + "ObjectType": "tam.ApiDataSource", + "Queries": [ + { + "ClassId": "tam.QueryEntry", + "Name": "qds3", + "ObjectType": "tam.QueryEntry", + "Priority": 1, + "Query": "SELECT ds3_Moid, ds3_AccountMoid, ds3_Ancestors, ds3_RegisteredDevice.Moid as ds3_RegisteredDeviceMoid, ds3_DomainGroupMoid, ds3_ComputeBlade.Moid as ds3_ComputeBladeMoid , ds3_RunningFirmware.Moid as ds3_RunningFirmwareMoid FROM ds3 WHERE ds3_Parent.ObjectType = 'compute.Blade'" + } + ], + "Type": "intersightApi" + } + ], + "BaseScore": 8.2, + "ClassId": "tam.SecurityAdvisory", + "CreateTime": "2022-07-08T01:54:22.459Z", + "CveIds": [ + "CVE-2021-0154", + "CVE-2021-0153", + "CVE-2021-33123", + "CVE-2021-0190", + "CVE-2021-33122", + "CVE-2021-0189", + "CVE-2021-33124", + "CVE-2021-33103", + "CVE-2021-0159", + "CVE-2021-0155", + "CVE-2021-0188", + "CVE-2022-0005", + "CVE-2022-21131", + "CVE-2022-21136", + "CVE-2022-21151" + ], + "DatePublished": "2022-05-10T00:00:00Z", + "DateUpdated": "2022-09-23T00:00:00Z", + "Description": "Potential security vulnerabilities in the BIOS firmware or BIOS authenticated code module for Cisco UCS M4, M5 and M6 generation of servers using Intel┬« Processors may allow escalation of privilege or information disclosure. Cisco is releasing BIOS updates to mitigate these potential vulnerabilities.\n\n", + "DomainGroupMoid": "5b2541877a7662743465cc89", + "EnvironmentalScore": 0, + "ExecuteOnPod": "tier1", + "ExternalUrl": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00601.html", + "ModTime": "2022-12-22T02:59:04.129Z", + "Moid": "62c78e4e6f636b2d39834d55", + "Name": "Intel 2022.1 IPU - BIOS Advisory", + "ObjectType": "tam.SecurityAdvisory", + "Organization": { + "ClassId": "mo.MoRef", + "Moid": "5dde9f896972652d3353a082", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dde9f896972652d3353a082" + }, + "OtherRefUrls": [ + "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00614.html", + "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00616.html", + "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00617.html" + ], + "Owners": [ + "5960901ca94eba000127e33a", + "shared" + ], + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dde9f896972652d3353a082", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dde9f896972652d3353a082" + } + ], + "Recommendation": "There are no workarounds that address this vulnerability.\n\n Fixed Releases \n\n Below firmware releases and later versions have fixes for the above mentioned vulnerabilities.\n\n UCS Servers Operating in Intersight Managed Mode\n\n|Platform Model|4.1(3) Release|4.2(1) Release|4.2(2) Release|\n |-------------------|------------|------------|------------|\n |ucs-c220-m6|NA|4.2(1j)|4.2(2f)|\n |ucs-c240-m6|NA|4.2(1j)|4.2(2f)|\n |ucs-b200-m6|NA|4.2(1h)|4.2(2d)|\n |ucs-x210-m6|NA|5.0(1f)|5.0(2d)|\n |ucs-c220-m5|4.1(3h)|NA|All|\n |ucs-c240-m5|4.1(3h)|NA|All|\n |ucs-c480-m5|4.1(3h)|NA|All|\n |ucs-s3260-m5|4.1(3h)|NA|All|\n |ucs-b200-m5|4.1(33h)|4.2(1h)|All|\n |ucs-b480-m5|4.1(33h)|4.2(1h)|All|\n\n\n\n UCS Servers Operating in Standalone Mode\n\n|Platform Model|4.1(2) Release|4.1(3) Release|4.2(1) Release|4.2(2) Release|\n |-------------------|------------|------------|------------|------------|\n |ucs-c220-m6|NA|NA|4.2(1j)|4.2(2f)|\n |ucs-c240-m6|NA|NA|4.2(1j)|4.2(2f)|\n |ucs-c220-m5|NA|4.1(3h)|NA|All|\n |ucs-c240-m5|NA|4.1(3h)|NA|All|\n |ucs-c480-m5|NA|4.1(3h)|NA|All|\n |ucs-s3260-m5|NA|4.1(3h)|NA|All|\n |ucs-c220-m4|4.1(2k)|NA|NA|NA|\n |ucs-c240-m4|4.1(2k)|NA|NA|NA|\n |ucs-c3260-m4|NA|4.1(3h)|NA|NA|\n |ucs-c460-m4|4.1(2k)|NA|NA|NA|\n\n\n\n UCS Servers Operating in UCSM Mode\n\n|Platform Model|4.1(3) Release|4.2(1) Release|4.2(2) Release|\n |-------------------|------------|------------|------------|\n |All Impacted Models (except M6 models)|4.1(3i)|4.2(1n)|All|\n |All M6 Models|NA|4.2(1n)|4.2(2c)|\n\n*NA - Not Applicable\n\n\n\n Please refer to below Cisco defect IDs for more information\n\n |Bug ID|Impacted Models|\n |----------------------------|-----------------------------------------------------|\n |[CSCwb67158](https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwb67158)| All M4 Models (except B260, B460, C460)|\n |[CSCwb67157](https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwb67157)|B260-M4, B460-M4, C460-M4|\n |[CSCwb67159](https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwb67159)|All M5 Models|\n |[CSCwb67205](https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwb67205)|All M6 Models|\n", + "Severity": { + "ClassId": "tam.PsirtSeverity", + "Level": "high", + "ObjectType": "tam.PsirtSeverity" + }, + "SharedScope": "shared", + "State": "ready", + "Status": "interim", + "Tags": [], + "TemporalScore": 0, + "Version": "1.1", + "Workaround": "" + } +``` \ No newline at end of file diff --git a/lib/intersight/tam_security_advisory/info.py b/lib/intersight/tam_security_advisory/info.py new file mode 100644 index 00000000..9bd325dd --- /dev/null +++ b/lib/intersight/tam_security_advisory/info.py @@ -0,0 +1,40 @@ +class TamSecurityAdvisoryInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + keys = [ + 'AdvisoryId', + 'BaseScore', + 'CreateTime', + 'CveIds', + 'DatePublished', + 'DateUpdated', + 'Description', + 'ExternalUrl', + 'Moid', + 'Name', + 'OtherRefUrls', + 'Recommendation', + 'Workaround' + ] + + info = {} + for key in keys: + info[key] = managed_object[key] + + info['Urls'] = [] + info['Urls'].append( + managed_object['ExternalUrl'] + ) + if managed_object['OtherRefUrls'] is not None: + for url in managed_object['OtherRefUrls']: + info['Urls'].append(url) + + info['__Output'] = {} + info['__Output']['Severity'] = None + info['Severity'] = managed_object['Severity']['Level'] + if info['Severity'] == 'high': + info['__Output']['Severity'] = 'Red' + + return info diff --git a/lib/intersight/tam_security_advisory/main.py b/lib/intersight/tam_security_advisory/main.py new file mode 100644 index 00000000..391ac73a --- /dev/null +++ b/lib/intersight/tam_security_advisory/main.py @@ -0,0 +1,9 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.tam_security_advisory.info import TamSecurityAdvisoryInfo + + +class TamSecurityAdvisory(IntersightCommon, TamSecurityAdvisoryInfo): + def __init__(self, iaccount, log_id=None): + self.iobject = 'tam securityadvisory' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) + TamSecurityAdvisoryInfo.__init__(self) diff --git a/lib/intersight/validations.py b/lib/intersight/validations.py new file mode 100644 index 00000000..59efa98b --- /dev/null +++ b/lib/intersight/validations.py @@ -0,0 +1,687 @@ +import click + +from lib.intersight import settings as intersight_settings + + +def validate_cache_ttl(user_cache_ttl, log_id=None): + settings_handler = intersight_settings.IntersightSettings( + log_id=log_id + ) + cache_ttl = settings_handler.get_intersight_cache_ttl() + if user_cache_ttl is not None: + try: + cache_ttl = int(user_cache_ttl) + except BaseException: + cache_ttl = -1 + + return cache_ttl + + +def validate_int_oper(value): + for prefix in ['ge', '>=', 'le', '<=', 'gt', '>', 'lt', '<', 'ne', '!=']: + if value.startswith(prefix): + try: + int_value = int(value.lstrip(prefix)) + return value, None + + except BaseException: + pass + + return None, 'wrong value format' + + try: + int_value = int(value) + return value, None + except BaseException: + pass + + return None, 'int value expected' + + +def name_filter(ctx, param, user_input): + filters = {} + filters['logical'] = 'or' + filters['rule'] = [] + + for item in user_input: + if item.lower() in ['_and_', 'and']: + filters['logical'] = 'and' + continue + + negative = False + if item.startswith('!'): + negative = True + item = item[1:] + + rule = {} + rule['negative'] = negative + rule['value'] = item + filters['rule'].append( + rule + ) + + return filters + + +def serial_filter(ctx, param, user_input): + filters = {} + filters['logical'] = 'or' + filters['rule'] = [] + + for user_input_item in user_input: + for item in user_input_item.split(','): + if item.lower() in ['_and_', 'and']: + filters['logical'] = 'and' + continue + + negative = False + if item.startswith('!'): + negative = True + item = item[1:] + + rule = {} + rule['negative'] = negative + rule['value'] = item + filters['rule'].append( + rule + ) + + return filters + + +def add_group_filter(serial_filters, group_filters): + for item in group_filters: + serial_filters['rule'].append( + dict( + negative=False, + value=item + ) + ) + return serial_filters + + +def get_serial_filter_from_mo(servers_mo): + filters = {} + filters['logical'] = 'or' + filters['rule'] = [] + + for server_mo in servers_mo: + rule = {} + rule['negative'] = False + rule['value'] = server_mo['Serial'] + filters['rule'].append( + rule + ) + + return filters + + +def model_filter(ctx, param, user_input): + filters = {} + filters['logical'] = 'or' + filters['rule'] = [] + + for item in user_input: + if item.lower() in ['_and_', 'and']: + filters['logical'] = 'and' + continue + + negative = False + if item.startswith('!'): + negative = True + item = item[1:] + + rule = {} + rule['negative'] = negative + rule['value'] = item + filters['rule'].append( + rule + ) + + return filters + + +def tag(ctx, param, user_input): + tags = [] + + for item in user_input: + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Tag validation failed: key:value format expected') + return None + + tags.append( + item + ) + + return tags + + +def tag_filter(ctx, param, user_input): + filters = {} + filters['logical'] = 'or' + filters['rule'] = [] + + for item in user_input: + if item.lower() in ['_and_', 'and']: + filters['logical'] = 'and' + continue + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Tag filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + + if key == '!': + if ctx is not None: + raise click.BadParameter('Tag filter validation failed: key expected') + return None + + if value == '': + if ctx is not None: + raise click.BadParameter('Tag filter validation failed: value expected') + return None + + negative = False + if key.startswith('!'): + negative = True + key = key[1:] + + rule = {} + rule['negative'] = negative + rule['key'] = key + rule['value'] = value + filters['rule'].append( + rule + ) + + return filters + + +def bot_cpu_filter(value): + try: + filter = cpu_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def cpu_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['core', 'socket', 'thread', 'vendor', 'arch', 'model']: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: unsupported key') + return None + + if key == 'core': + core_value, core_error = validate_int_oper(value) + if core_value is None: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: %s' % (core_error)) + return None + + filters['core'] = value + + if key == 'socket': + socket_value, socket_error = validate_int_oper(value) + if socket_value is None: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: %s' % (socket_error)) + return None + + filters['socket'] = value + + if key == 'thread': + thread_value, thread_error = validate_int_oper(value) + if thread_value is None: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: %s' % (thread_error)) + return None + + filters['thread'] = value + + if key == 'vendor': + filters['info'] = True + if value.lower() not in ['intel', 'amd']: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: unsupported vendor') + return None + + filters['vendor'] = value.lower() + + if key == 'arch': + filters['info'] = True + if value.lower() not in ['xeon', 'zen']: + if ctx is not None: + raise click.BadParameter('CPU filter validation failed: unsupported architecture') + return None + + filters['arch'] = value.lower() + + if key == 'model': + filters['info'] = True + filters['model'] = value + + return filters + + +def bot_gpu_filter(value): + try: + filter = gpu_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def gpu_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('GPU filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['slot', 'model']: + if ctx is not None: + raise click.BadParameter('GPU filter validation failed: unsupported key') + return None + + if key == 'slot': + filters['info'] = True + socket_value, socket_error = validate_int_oper(value) + if socket_value is None: + if ctx is not None: + raise click.BadParameter('GPU filter validation failed: %s' % (socket_error)) + return None + + filters['slot'] = value + + if key == 'model': + filters['info'] = True + filters['model'] = value + + return filters + + +def bot_memory_filter(value): + try: + filter = memory_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def memory_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Memory filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['size', 'dimm', 'model', 'serial']: + if ctx is not None: + raise click.BadParameter('Memory filter validation failed: unsupported key') + return None + + if key == 'size': + size_value, size_error = validate_int_oper(value) + if size_value is None: + if ctx is not None: + raise click.BadParameter('Memory filter validation failed: %s' % (size_error)) + return None + + filters['size'] = value + + if key == 'dimm': + filters['info'] = True + dimm_value, dimm_error = validate_int_oper(value) + if dimm_value is None: + if ctx is not None: + raise click.BadParameter('Memory filter validation failed: %s' % (dimm_error)) + return None + + filters['dimm'] = value + + if key == 'model': + filters['info'] = True + filters['model'] = value + + if key == 'serial': + filters['info'] = True + filters['serial'] = value + + return filters + + +def bot_pci_filter(value): + try: + filter = pci_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def pci_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('PCI filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['slot', 'model', 'pid']: + if ctx is not None: + raise click.BadParameter('PCI filter validation failed: unsupported key') + return None + + if key == 'slot': + filters['info'] = True + slot_value, slot_error = validate_int_oper(value) + if slot_value is None: + raise click.BadParameter('GPU filter validation failed: %s' % (slot_error)) + + filters['slot'] = value + + if key == 'model': + filters['info'] = True + filters['model'] = value + + if key == 'pid': + filters['info'] = True + filters['pid'] = value + + return filters + + +def bot_sc_filter(value): + try: + filter = sc_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def sc_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Storage controller filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['vendor', 'serial']: + if ctx is not None: + raise click.BadParameter('Storage controller filter validation failed: unsupported key') + return None + + if key == 'vendor': + filters['info'] = True + filters['vendor'] = value + + if key == 'serial': + filters['info'] = True + filters['serial'] = value + + return filters + + +def bot_pd_filter(value): + try: + filter = pd_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def pd_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Physical disk filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['type', 'proto', 'pid', 'model', 'serial', 'vendor', 'count']: + if ctx is not None: + raise click.BadParameter('Physical disk filter validation failed: unsupported key') + return None + + if key == 'type': + filters['info'] = True + filters['type'] = value + + if key == 'proto': + filters['info'] = True + filters['proto'] = value + + if key == 'pid': + filters['info'] = True + filters['pid'] = value + + if key == 'model': + filters['info'] = True + filters['model'] = value + + if key == 'serial': + filters['info'] = True + filters['serial'] = value + + if key == 'vendor': + filters['info'] = True + filters['vendor'] = value + + if key == 'count': + filters['info'] = True + count_value, count_error = validate_int_oper(value) + if count_value is None: + if ctx is not None: + raise click.BadParameter('Physical disk filter validation failed: %s' % (count_error)) + return None + + filters['count'] = value + + return filters + + +def bot_vd_filter(value): + try: + filter = vd_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def vd_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Virtual drive filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['count']: + if ctx is not None: + raise click.BadParameter('Virtual drive filter validation failed: unsupported key') + return None + + if key == 'count': + filters['info'] = True + count_value, count_error = validate_int_oper(value) + if count_value is None: + if ctx is not None: + raise click.BadParameter('Virtual drive filter validation failed: %s' % (count_error)) + return None + + filters['count'] = value + + return filters + + +def bot_fan_filter(value): + try: + filter = fan_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def fan_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('Fan filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['mod', 'unit', 'state']: + if ctx is not None: + raise click.BadParameter('Fan filter validation failed: unsupported key') + return None + + if key == 'mod': + filters['info'] = True + mod_value, mod_error = validate_int_oper(value) + if mod_value is None: + if ctx is not None: + raise click.BadParameter('Fan filter validation failed: %s' % (mod_error)) + return None + + filters['mod'] = value + + if key == 'unit': + filters['info'] = True + unit_value, unit_error = validate_int_oper(value) + if unit_value is None: + if ctx is not None: + raise click.BadParameter('Fan filter validation failed: %s' % (unit_error)) + return None + + filters['unit'] = value + + if key == 'state': + filters['info'] = True + if value.lower() not in ['ok', 'nok']: + if ctx is not None: + raise click.BadParameter('Fan filter validation failed: expected state ok or nok') + return None + + filters['state'] = value.lower() + + return filters + + +def bot_psu_filter(value): + try: + filter = psu_filter(None, None, value) + except BaseException: + filter = None + + return filter + + +def psu_filter(ctx, param, user_input): + filters = {} + filters['info'] = False + filters['enabled'] = False + + for item in user_input: + filters['enabled'] = True + + if len(item.split(':')) != 2: + if ctx is not None: + raise click.BadParameter('PSU filter validation failed: key:value format expected') + return None + + (key, value) = item.split(':') + if key not in ['model', 'serial', 'vendor', 'state']: + if ctx is not None: + raise click.BadParameter('PSU filter validation failed: unsupported key') + return None + + if key == 'state': + filters['info'] = True + if value.lower() not in ['ok', 'nok']: + if ctx is not None: + raise click.BadParameter('Fan filter validation failed: expected state ok or nok') + return None + + filters['state'] = value.lower() + + if key == 'model': + filters['info'] = True + filters['model'] = value + + if key == 'serial': + filters['info'] = True + filters['serial'] = value + + if key == 'vendor': + filters['info'] = True + filters['vendor'] = value + + return filters diff --git a/lib/intersight/virtualization_vmwarehost/__init__.py b/lib/intersight/virtualization_vmwarehost/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/virtualization_vmwarehost/class.md b/lib/intersight/virtualization_vmwarehost/class.md new file mode 100644 index 00000000..f14301c0 --- /dev/null +++ b/lib/intersight/virtualization_vmwarehost/class.md @@ -0,0 +1,172 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "63fa370e736c6f2d30b8c272", + "ObjectType": "virtualization.VmwareCluster", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareClusters/63fa370e736c6f2d30b8c272" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63fa370e736c6f2d30b8c260", + "ObjectType": "virtualization.VmwareDatacenter", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareDatacenters/63fa370e736c6f2d30b8c260" + }, + { + "ClassId": "mo.MoRef", + "Moid": "63fa370e736c6f2d30b8c255", + "ObjectType": "virtualization.VmwareVcenter", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareVcenters/63fa370e736c6f2d30b8c255" + } + ], + "BootTime": "2023-03-01T21:34:51.554Z", + "ClassId": "virtualization.VmwareHost", + "Cluster": { + "ClassId": "mo.MoRef", + "Moid": "63fa370e736c6f2d30b8c272", + "ObjectType": "virtualization.VmwareCluster", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareClusters/63fa370e736c6f2d30b8c272" + }, + "ConnectionState": "connected", + "CpuInfo": { + "ClassId": "virtualization.CpuInfo", + "Cores": 28, + "Description": "Intel(R) Xeon(R) CPU E5-2695 v3 @ 2.30GHz", + "ObjectType": "virtualization.CpuInfo", + "Sockets": 2, + "Speed": 2294, + "Vendor": "intel" + }, + "CreateTime": "2023-02-25T16:28:00.869Z", + "Datacenter": null, + "Datastores": [ + { + "ClassId": "mo.MoRef", + "Moid": "63fa371a736c6f2d30b8ce26", + "ObjectType": "virtualization.VmwareDatastore", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareDatastores/63fa371a736c6f2d30b8ce26" + } + ], + "DcInvPath": "/eu-spdc-dc", + "DistributedNetworks": [ + { + "ClassId": "mo.MoRef", + "Moid": "63fa3711736c6f2d30b8c30b", + "ObjectType": "virtualization.VmwareDistributedNetwork", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareDistributedNetworks/63fa3711736c6f2d30b8c30b" + } + ], + "DnsServers": [ + "", + "" + ], + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "HardwareInfo": { + "ClassId": "infra.HardwareInfo", + "CpuCores": 28, + "CpuSpeed": 2294, + "MemorySize": 274759602176, + "ObjectType": "infra.HardwareInfo" + }, + "HwPowerState": "PoweredOn", + "HyperFlexNode": null, + "HypervisorType": "ESXi", + "Identity": "HostSystem:host-2164", + "IsSshEnabled": true, + "MaintenanceMode": false, + "MemoryCapacity": { + "Capacity": 274759602176, + "ClassId": "virtualization.MemoryCapacity", + "Free": 124965277696, + "ObjectType": "virtualization.MemoryCapacity", + "Used": 149794324480 + }, + "ModTime": "2023-03-31T09:25:48.674Z", + "Model": "UCSC-C220-M4S", + "Moid": "63fa3710736c6f2d30b8c2b0", + "Name": "esx10", + "NetworkAdapterCount": 12, + "NtpServers": [ + "" + ], + "ObjectType": "virtualization.VmwareHost", + "Owners": [ + "5be4b2ce67626c6d661ca38d", + "63f9ce3f6f72612d31d940f9", + "63f9edb56f72612d395f0600", + "63fa37046f72612d39626f62" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "63fa370e736c6f2d30b8c272", + "ObjectType": "virtualization.VmwareCluster", + "link": "https://www.intersight.com/api/v1/virtualization/VmwareClusters/63fa370e736c6f2d30b8c272" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "625706a06972652d3202a8f9", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/625706a06972652d3202a8f9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "6242d1016972652d32eda017", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/6242d1016972652d32eda017" + } + ], + "ProcessorCapacity": { + "Capacity": 64245, + "ClassId": "virtualization.ComputeCapacity", + "Free": 43088, + "ObjectType": "virtualization.ComputeCapacity", + "Used": 21157 + }, + "ProductInfo": { + "Build": "19482537", + "ClassId": "virtualization.ProductInfo", + "ObjectType": "virtualization.ProductInfo", + "ProductName": "VMware ESXi", + "ProductType": "embeddedEsx", + "ProductVendor": "VMware, Inc.", + "Version": "7.0.3" + }, + "RegisteredDevice": { + "ClassId": "mo.MoRef", + "Moid": "63fa37046f72612d39626f62", + "ObjectType": "asset.DeviceRegistration", + "link": "https://www.intersight.com/api/v1/asset/DeviceRegistrations/63fa37046f72612d39626f62" + }, + "ResourceConsumed": { + "ClassId": "virtualization.VmwareResourceConsumption", + "CpuConsumed": 21157, + "MemoryConsumed": 142855, + "ObjectType": "virtualization.VmwareResourceConsumption" + }, + "Serial": "FCH2017V0TN", + "Server": { + "ClassId": "mo.MoRef", + "Moid": "5fa052a26176752d35ce6572", + "ObjectType": "compute.PhysicalSummary", + "link": "https://www.intersight.com/api/v1/compute/PhysicalSummaries/5fa052a26176752d35ce6572" + }, + "SharedScope": "", + "Status": "Ok", + "StorageAdapterCount": 4, + "Tags": [], + "TimeZone": "UTC", + "UpTime": "P29DT11H48M50S", + "Uuid": "0785f9dd-6c2d-d047-91b1-8d1055824d36", + "VcenterHostId": "host-2164", + "Vendor": "Cisco Systems Inc" + } +``` \ No newline at end of file diff --git a/lib/intersight/virtualization_vmwarehost/main.py b/lib/intersight/virtualization_vmwarehost/main.py new file mode 100644 index 00000000..31a3b41c --- /dev/null +++ b/lib/intersight/virtualization_vmwarehost/main.py @@ -0,0 +1,7 @@ +from lib.intersight.intersight_common import IntersightCommon + + +class VirtualizationVmwareHost(IntersightCommon): + def __init__(self, iaccount, log_id=None): + self.iobject = 'virtualization vmwarehost' + IntersightCommon.__init__(self, iaccount, self.iobject, log_id=log_id) diff --git a/lib/intersight/workflow/__init__.py b/lib/intersight/workflow/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/workflow/class.md b/lib/intersight/workflow/class.md new file mode 100644 index 00000000..c7b3f38a --- /dev/null +++ b/lib/intersight/workflow/class.md @@ -0,0 +1,216 @@ +``` + { + "Account": null, + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Action": "None", + "Ancestors": [], + "AssociatedObject": { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + }, + "ClassId": "workflow.WorkflowInfo", + "CleanupTime": "0001-01-01T00:00:00Z", + "CreateTime": "2022-04-13T19:53:12.956Z", + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "Email": "**************", + "EndTime": "0001-01-01T00:00:00Z", + "FailedWorkflowCleanupDuration": 2160, + "Input": { + "ActionProfile": { + "Moid": "624b3dfc7a6f722d3046b689", + "ObjectType": "kubernetes.ClusterProfile" + } + }, + "InstId": "f762caae-d921-46d3-bbf4-ea52f8ac2376", + "Internal": false, + "LastAction": "Start", + "Message": [], + "MetaVersion": 0, + "ModTime": "2022-04-13T19:53:26.878Z", + "Moid": "62572a28696f6e2d30a20838", + "Name": "Deploy Kubernetes Cluster Profile", + "ObjectType": "workflow.WorkflowInfo", + "Organization": null, + "Output": null, + "Owners": [ + "5be4b2ce67626c6d661ca38d" + ], + "ParentTaskInfo": null, + "PauseReason": "None", + "PendingDynamicWorkflowInfo": null, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + } + ], + "Progress": 10.97561, + "Properties": { + "Cancelable": { + "CancelableStates": [], + "ClassId": "workflow.CancelableType", + "Enabled": true, + "Mode": "ApiOnly", + "ObjectType": "workflow.CancelableType" + }, + "ClassId": "workflow.WorkflowInfoProperties", + "ObjectType": "workflow.WorkflowInfoProperties", + "Retryable": false, + "RollbackAction": "Disabled", + "RollbackOnFailure": false + }, + "RetryFromTaskName": "", + "SharedScope": "", + "Src": "razor", + "StartTime": "2022-04-13T19:53:12.977Z", + "Status": "RUNNING", + "SuccessWorkflowCleanupDuration": 2160, + "Tags": [], + "TaskInfos": [ + { + "ClassId": "mo.MoRef", + "Moid": "62572a29696f6e2d30a20845", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a29696f6e2d30a20845" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a29696f6e2d30a20855", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a29696f6e2d30a20855" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2a696f6e2d30a20861", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2a696f6e2d30a20861" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2b696f6e2d30a20876", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2b696f6e2d30a20876" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2b696f6e2d30a2087c", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2b696f6e2d30a2087c" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2c696f6e2d30a2088e", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2c696f6e2d30a2088e" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2d696f6e2d30a2089f", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2d696f6e2d30a2089f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2d696f6e2d30a208ab", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2d696f6e2d30a208ab" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2e696f6e2d30a208b9", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2e696f6e2d30a208b9" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a2f696f6e2d30a208c5", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a2f696f6e2d30a208c5" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a30696f6e2d30a208d1", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a30696f6e2d30a208d1" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a31696f6e2d30a208dd", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a31696f6e2d30a208dd" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a32696f6e2d30a208ef", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a32696f6e2d30a208ef" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a34696f6e2d30a20933", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a34696f6e2d30a20933" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a35696f6e2d30a2094c", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a35696f6e2d30a2094c" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a35696f6e2d30a2095f", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a35696f6e2d30a2095f" + }, + { + "ClassId": "mo.MoRef", + "Moid": "62572a36696f6e2d30a20971", + "ObjectType": "workflow.TaskInfo", + "link": "https://www.intersight.com/api/v1/workflow/TaskInfos/62572a36696f6e2d30a20971" + } + ], + "TraceId": "NB181ae694abcb5ab28b4eba75540327a9", + "Type": "UserDefined", + "UserActionRequired": false, + "UserId": "5f9ff9d37564612d306e9e5b", + "Variable": null, + "WaitReason": "None", + "WorkflowCtx": { + "ClassId": "workflow.WorkflowCtx", + "InitiatorCtx": { + "ClassId": "workflow.InitiatorContext", + "InitiatorMoid": "624b3dfc7a6f722d3046b689", + "InitiatorName": "milan-kali", + "InitiatorType": "kubernetes.ClusterProfile", + "ObjectType": "workflow.InitiatorContext" + }, + "ObjectType": "workflow.WorkflowCtx", + "TargetCtxList": [ + { + "ClassId": "workflow.TargetContext", + "ObjectType": "workflow.TargetContext", + "TargetMoid": "624b3dfc7a6f722d3046b689", + "TargetName": "milan-kali", + "TargetType": "kubernetes.ClusterProfile" + } + ], + "WorkflowMetaName": "", + "WorkflowSubtype": "", + "WorkflowType": "Deploy Kubernetes Cluster Profile" + }, + "WorkflowDefinition": { + "ClassId": "mo.MoRef", + "Moid": "5fdc0b65696f6e2d309790b0", + "ObjectType": "workflow.WorkflowDefinition", + "link": "https://www.intersight.com/api/v1/workflow/WorkflowDefinitions/5fdc0b65696f6e2d309790b0" + }, + "WorkflowMetaType": "UserDefined", + "WorkflowTaskCount": 36, + "WorkflowWorkerTaskCount": 82 + } +``` \ No newline at end of file diff --git a/lib/intersight/workflow/info.py b/lib/intersight/workflow/info.py new file mode 100644 index 00000000..d310962c --- /dev/null +++ b/lib/intersight/workflow/info.py @@ -0,0 +1,82 @@ +import time + + +class WorkflowInfo(): + def __init__(self): + pass + + def get_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in ['Moid', 'Name', 'Progress', 'CreateTime', 'StartTime', 'EndTime', 'Status', 'Type']: + info[key] = None + if key in managed_object: + info[key] = managed_object[key] + + for key in ['CreateTime', 'StartTime', 'EndTime']: + info['%sEpoch' % (key)] = self.convert_time_epoch(info[key]) + + info['Running'] = False + info['Completed'] = False + if managed_object['Status'] == 'RUNNING': + info['Running'] = True + + if not info['Running']: + if managed_object['Status'] in ['COMPLETED', 'FAILED']: + info['Completed'] = True + + if info['Status'].lower() == 'completed': + info['__Output']['Status'] = 'Green' + + if info['Status'].lower() == 'failed': + info['__Output']['Status'] = 'Red' + + if info['Completed']: + try: + seconds = int(info['EndTimeEpoch'] / 1000) - int(info['StartTimeEpoch'] / 1000) + info['Duration'] = time.strftime('%H:%M:%S', time.gmtime(seconds)) + except BaseException: + info['Duration'] = '' + else: + try: + seconds = int(time.time()) - int(info['StartTimeEpoch'] / 1000) + info['Duration'] = time.strftime('%H:%M:%S', time.gmtime(seconds)) + except BaseException: + info['Duration'] = '' + + return info + + def is_server_workflow(self, server_id, managed_object): + try: + if managed_object['Input']['Server']['Moid'] == server_id: + return True + except BaseException: + pass + + try: + if managed_object['Input']['ServerMoId'] == server_id: + return True + except BaseException: + pass + + try: + for target in managed_object['Input']['workflowContext']['TargetCtxList']: + if target['TargetMoid'] == server_id: + return True + except BaseException: + pass + + return False + + def get_last(self, count=10): + self.set_get_order('StartTime desc') + managed_objects = self.get_top(count) + if managed_objects is None: + self.log_handler.error( + 'workflow.get_last', + 'failed to get workflows' + ) + return + + return managed_objects diff --git a/lib/intersight/workflow/main.py b/lib/intersight/workflow/main.py new file mode 100644 index 00000000..bafa5780 --- /dev/null +++ b/lib/intersight/workflow/main.py @@ -0,0 +1,10 @@ +from lib.intersight.intersight_common import IntersightCommon +from lib.intersight.workflow.info import WorkflowInfo + + +class Workflow(IntersightCommon, WorkflowInfo): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'workflow workflowinfo' + self.cache_key = 'workflow' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id, cache_key=self.cache_key) + WorkflowInfo.__init__(self) diff --git a/lib/intersight/workflow_info.py b/lib/intersight/workflow_info.py new file mode 100644 index 00000000..c47b39ac --- /dev/null +++ b/lib/intersight/workflow_info.py @@ -0,0 +1,175 @@ +import json + +from lib import output_helper +from lib.intersight.workflow import main as workflow +from lib.intersight.workflow_task_info import main as workflow_task_info +from lib.intersight import compute + + +class WorkflowInfo(): + """Class for workflow info + """ + def __init__(self, iaccount, silent=False, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper(log_id=log_id) + self.workflow_handler = workflow.Workflow(iaccount, log_id=log_id) + self.workflow_task_info_handler = workflow_task_info.WorkflowTaskInfo(iaccount, log_id=log_id) + self.compute_handler = compute.Compute(iaccount, log_id=log_id) + + self.flags = {} + self.flags['silent'] = silent + self.flags['verbose'] = verbose + self.flags['debug'] = debug + + self.my_output.set_flags(self.flags['silent'], self.flags['verbose'], self.flags['debug']) + + def get_workflow_server_id(self, workflow_object): + if workflow_object['AssociatedObject']['ObjectType'] in ['compute.RackUnit', 'compute.Blade']: + return workflow_object['AssociatedObject']['Moid'] + + if workflow_object['Name'] == 'Operating System Install': + return workflow_object['Input']['Server']['Moid'] + + if workflow_object['Name'] == 'InstallOS': + return workflow_object['Input']['Server']['Moid'] + + self.my_output.debug('Failed to detect server identify in workflow object') + self.my_output.debug(json.dumps(workflow_object, indent=4)) + + return None + + def get_workflow_info(self, workflow_id): + """Return dictionary of server, workflow info and workflow tasks info + + Args: + workflow_id (string): workflow id to be found + + Workflow ID must exist + May be associated with server object type + Should have tasks + If checks fail, None value is returned + + Returns: + dictionary or None + """ + server_workflow_info = {} + workflow_object = self.workflow_handler.get(workflow_id) + server_workflow_info['workflow'] = self.workflow_handler.get_info( + workflow_object + ) + if server_workflow_info['workflow'] is None: + return None + + server_workflow_info['tasks'] = self.workflow_task_info_handler.get_workflow_tasks_info(workflow_id) + if server_workflow_info['tasks'] is None: + return None + + server_workflow_info['server'] = None + server_id = self.get_workflow_server_id(workflow_object) + if server_id is not None: + server_workflow_info['server'] = self.compute_handler.get( + server_id + ) + + return server_workflow_info + + def print_workflow_info(self, server_workflow_info, stream='default'): + if server_workflow_info['server'] is not None: + self.my_output.dictionary( + server_workflow_info['server'], + keys=[ + 'Name', + 'Model', + 'Serial', + 'ManagementIp' + ], + title_keys=[ + 'Name', + 'Model', + 'Serial', + 'IP' + ], + title="Server", + prefix="- ", + underline=False, + stream=stream + ) + + if server_workflow_info['workflow']['Status'] == 'RUNNING': + self.my_output.dictionary( + server_workflow_info['workflow'], + keys=[ + 'Moid', + 'Name', + 'Status', + 'CreateTime', + 'StartTime', + 'Progress', + 'Duration' + ], + title_keys=[ + 'Workflow ID', + 'Name', + 'Status', + 'Create Time', + 'Start Time', + 'Progress', + 'Duration' + ], + title="Workflow", + prefix="- ", + underline=False, + stream=stream + ) + else: + self.my_output.dictionary( + server_workflow_info['workflow'], + keys=[ + 'Moid', + 'Name', + 'Status', + 'CreateTime', + 'StartTime', + 'EndTime', + 'Duration' + ], + title_keys=[ + 'Workflow ID', + 'Name', + 'Status', + 'Create Time', + 'Start Time', + 'End Time', + 'Duration' + ], + title="Workflow", + prefix="- ", + underline=False, + stream=stream + ) + + if len(server_workflow_info['tasks']) > 0: + order = [ + 'Moid', + 'Description', + 'CreateTime', + 'Status', + 'Duration', + 'FailureReason' + ] + + headers = [ + 'Task Moid', + 'Description', + 'Create Time', + 'Status', + 'Duration', + 'Details' + ] + + self.my_output.my_table( + server_workflow_info['tasks'], + order=order, + headers=headers, + table=True, + stream=stream + ) diff --git a/lib/intersight/workflow_task_info/__init__.py b/lib/intersight/workflow_task_info/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/intersight/workflow_task_info/class.md b/lib/intersight/workflow_task_info/class.md new file mode 100644 index 00000000..83102542 --- /dev/null +++ b/lib/intersight/workflow_task_info/class.md @@ -0,0 +1,109 @@ +``` + { + "AccountMoid": "5be4b2ce67626c6d661ca38d", + "Ancestors": [ + { + "ClassId": "mo.MoRef", + "Moid": "5ffede86696f6e2d306283ec", + "ObjectType": "workflow.WorkflowInfo", + "link": "https://www.intersight.com/api/v1/workflow/WorkflowInfos/5ffede86696f6e2d306283ec" + } + ], + "ClassId": "workflow.TaskInfo", + "CreateTime": "2021-01-13T12:18:18.686Z", + "Description": "", + "DisplayNames": { + "hierarchical": [ + "Validate Cluster Configuration Before Deployment" + ], + "short": [ + "Validate Cluster Configuration Before Deployment" + ] + }, + "DomainGroupMoid": "5be4b2ce67626c6d661ca39c", + "EndTime": "2021-01-13T12:21:52.789Z", + "FailureReason": "Error Running Validations: Target HX1 failed with error: Failed to get cpu mode from ESX", + "Input": { + "hypervisorType": "0" + }, + "InstId": "5ddad97b-ef4b-4f60-b1e3-a28f0df85bbb", + "Internal": false, + "Label": "Validate Cluster Configuration Before Deployment", + "Message": [], + "ModTime": "2021-01-13T12:21:52.789Z", + "Moid": "5ffee50a696f6e2d30638a59", + "Name": "hyperflex.PreDeployClusterValidationTask", + "ObjectType": "workflow.TaskInfo", + "Output": { + "ConfigResultEntry": { + "AccountMoid": "", + "Ancestors": null, + "ClassId": "hyperflex.ConfigResultEntry", + "CompletedTime": "", + "ConfigResult": null, + "Context": { + "ClassId": "policy.ConfigResultContext", + "EntityData": null, + "EntityMoid": "", + "EntityName": "", + "EntityType": "", + "ObjectType": "policy.ConfigResultContext" + }, + "CreateTime": "0001-01-01T00:00:00Z", + "DomainGroupMoid": "", + "Message": "", + "ModTime": "0001-01-01T00:00:00Z", + "Moid": "5ffee50a616c652d3025aede", + "ObjectType": "hyperflex.ConfigResultEntry", + "OwnerId": "{moId:5ffee50a696f6e2d30638a59,instId:5ddad97b-ef4b-4f60-b1e3-a28f0df85bbb}", + "Owners": null, + "PermissionResources": null, + "SharedScope": "", + "State": "Errored", + "Tags": [], + "Type": "Config" + } + }, + "Owners": [ + "5be4b2ce67626c6d661ca38d" + ], + "Parent": { + "ClassId": "mo.MoRef", + "Moid": "5ffede86696f6e2d306283ec", + "ObjectType": "workflow.WorkflowInfo", + "link": "https://www.intersight.com/api/v1/workflow/WorkflowInfos/5ffede86696f6e2d306283ec" + }, + "PermissionResources": [ + { + "ClassId": "mo.MoRef", + "Moid": "5dee1d736972652d321d26b5", + "ObjectType": "organization.Organization", + "link": "https://www.intersight.com/api/v1/organization/Organizations/5dee1d736972652d321d26b5" + } + ], + "RefName": "hyperflex.PreDeployClusterValidationTask", + "RetryCount": 0, + "RollbackDisabled": false, + "RunningInstId": "5ddad97b-ef4b-4f60-b1e3-a28f0df85bbb", + "SharedScope": "", + "StartTime": "2021-01-13T12:18:18.686Z", + "Status": "FAILED", + "SubWorkflowInfo": null, + "SubWorkflowRetryHistory": null, + "Tags": [], + "TaskDefinition": { + "ClassId": "mo.MoRef", + "Moid": "5ff7c66a696f6e2d305c3256", + "ObjectType": "workflow.TaskDefinition", + "link": "https://www.intersight.com/api/v1/workflow/TaskDefinitions/5ff7c66a696f6e2d305c3256" + }, + "TaskInstIdList": [], + "TaskLoopInfo": null, + "WorkflowInfo": { + "ClassId": "mo.MoRef", + "Moid": "5ffede86696f6e2d306283ec", + "ObjectType": "workflow.WorkflowInfo", + "link": "https://www.intersight.com/api/v1/workflow/WorkflowInfos/5ffede86696f6e2d306283ec" + } + } +``` \ No newline at end of file diff --git a/lib/intersight/workflow_task_info/main.py b/lib/intersight/workflow_task_info/main.py new file mode 100644 index 00000000..cccaf351 --- /dev/null +++ b/lib/intersight/workflow_task_info/main.py @@ -0,0 +1,57 @@ +import time + +from lib.intersight.intersight_common import IntersightCommon + + +class WorkflowTaskInfo(IntersightCommon): + def __init__(self, iaccount, get_filter=None, log_id=None): + self.iobject = 'workflow taskinfo' + IntersightCommon.__init__(self, iaccount, self.iobject, get_filter=get_filter, log_id=log_id) + + def get_workflow_task_info(self, workflow_task_object): + info = {} + info['__Output'] = {} + for key in ['Moid', 'Name', 'Label', 'CreateTime', 'StartTime', 'EndTime', 'Status', 'FailureReason']: + info[key] = None + if key in workflow_task_object: + info[key] = workflow_task_object[key] + + info['Description'] = info['Name'] + if len(info['Label']) > 0: + info['Description'] = info['Label'] + + for key in ['CreateTime', 'StartTime', 'EndTime']: + info['%sEpoch' % (key)] = self.convert_time_epoch(info[key]) + + try: + seconds = int(info['EndTimeEpoch'] / 1000) - int(info['StartTimeEpoch'] / 1000) + info['Duration'] = time.strftime('%H:%M:%S', time.gmtime(seconds)) + except BaseException: + info['Duration'] = '' + + if info['Status'].lower() == 'completed': + info['__Output']['Status'] = 'Green' + + if info['Status'].lower() == 'failed': + info['__Output']['Status'] = 'Red' + + return info + + def get_workflow_tasks_info(self, workflow_id): + tasks = [] + self.set_get_filter("WorkflowInfo/Moid eq '%s'" % (workflow_id)) + workflow_task_objects = self.get_all() + if workflow_task_objects is not None: + for workflow_task_object in workflow_task_objects: + tasks.append( + self.get_workflow_task_info( + workflow_task_object + ) + ) + + try: + tasks = sorted(tasks, key=lambda i: i['CreateTimeEpoch']) + except BaseException: + pass + + return tasks diff --git a/lib/ip_helper.py b/lib/ip_helper.py new file mode 100644 index 00000000..5c1026e5 --- /dev/null +++ b/lib/ip_helper.py @@ -0,0 +1,445 @@ +import os +import re +import socket +import struct +import hashlib +import uuid +import requests +import validators +import sshpubkeys + + +def generate_uuid(seed): + md5_handler = hashlib.md5() + md5_handler.update(seed.encode('utf-8')) + return str(uuid.UUID(md5_handler.hexdigest())) + + +def normalize_mac_address(mac_address): + return mac_address.lower().replace(':', '').replace('.', '') + + +def is_mac_address(mac): + mac = normalize_mac_address(mac) + if len(mac) != 12: + return False + + for char in mac: + if char not in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']: + return False + + return True + + +def is_mac_equal(mac_a, mac_b): + if normalize_mac_address(mac_a) == normalize_mac_address(mac_b): + return True + return False + + +def is_mac_match(mac_a, mac_b): + mac_a = mac_a.replace(':', '').lower() + mac_b = mac_b.replace(':', '').replace('.', '').lower() + if mac_a in mac_b: + return True + return False + + +def is_valid_mac_address(address, mac_address_format='colon'): + try: + if mac_address_format == 'colon': + if re.match("[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", address.lower()): + return True + if mac_address_format == 'dotted': + if re.match("[0-9a-f]{4}([.]?)[0-9a-f]{4}([.]?)[0-9a-f]{4}$", address.lower()): + return True + except BaseException: + pass + return False + + +def is_valid_ipv4_address(address): + try: + socket.inet_pton(socket.AF_INET, address) + except AttributeError: # no inet_pton here, sorry + try: + socket.inet_aton(address) + except socket.error: + return False + return address.count('.') == 3 + except socket.error: # not a valid address + return False + except BaseException: + return False + + return True + + +def is_valid_ipv6_address(address): + try: + socket.inet_pton(socket.AF_INET6, address) + except socket.error: # not a valid address + return False + return True + + +def is_valid_ipv6_cidr(cidr): + valid = False + try: + network, net_bits = cidr.split('/') + if is_valid_ipv6_address(network) and int(net_bits) < 129 and int(net_bits) > 8: + valid = True + except BaseException: + pass + + return valid + + +def is_valid_ipv4_cidr(cidr): + valid = False + try: + if cidr == '0.0.0.0/0': + return True + + network, net_bits = cidr.split('/') + if is_valid_ipv4_address(network) and int( + net_bits) < 33 and int(net_bits) >= 8: + valid = True + except BaseException: + pass + + return valid + + +def cidr_to_netmask(cidr): + network, net_bits = cidr.split('/') + host_bits = 32 - int(net_bits) + netmask = socket.inet_ntoa(struct.pack('!I', (1 << 32) - (1 << host_bits))) + return network, netmask + + +def netmask_to_prefix(mask): + try: + prefix = sum(bin(int(x)).count('1') for x in mask.split('.')) + return prefix + except BaseException: + return None + + +def prefix_to_netmask(prefix): + host_bits = 32 - prefix + netmask = socket.inet_ntoa(struct.pack('!I', (1 << 32) - (1 << host_bits))) + return netmask + + +def ipv4_to_int(address): + return struct.unpack('>L', socket.inet_aton(address))[0] + + +def is_ipv4_in_cidr(address, cidr): + if not is_valid_ipv4_address(address): + return False + + netaddr, bits = cidr.split('/') + if not is_valid_ipv4_address(netaddr): + return False + if int(bits) < 8 or int(bits) > 32: + return False + + ip_address = struct.unpack('>L', socket.inet_aton(address))[0] + ip_address_cidr = ip_address & (4294967295 << (32 - int(bits))) + ip_network = struct.unpack('>L', socket.inet_aton(netaddr))[0] + ip_network_cidr = ip_network & (4294967295 << (32 - int(bits))) + + return ip_address_cidr == ip_network_cidr + + +def get_network_ipv4_in_cidr(cidr): + if not is_valid_ipv4_cidr(cidr): + return None + + netaddr, bits = cidr.split('/') + + if not is_valid_ipv4_address(netaddr): + return None + if int(bits) < 8 or int(bits) > 32: + return None + + ip_network = struct.unpack('>L', socket.inet_aton(netaddr))[0] + ip_network_cidr = ip_network & (4294967295 << (32 - int(bits))) + + return socket.inet_ntoa(struct.pack('>L', ip_network_cidr)) + + +def get_first_ipv4_in_cidr(cidr): + if not is_valid_ipv4_cidr(cidr): + return None + + netaddr, bits = cidr.split('/') + address = struct.unpack('>L', socket.inet_aton(netaddr))[0] + address = address + 1 + return socket.inet_ntoa(struct.pack('>L', address)) + + +def get_nth_ipv4_in_cidr(cidr, index): + if not is_valid_ipv4_cidr(cidr): + return None + + size = get_ipv4_cidr_size(cidr) + if size is None: + return None + + if index >= size: + return None + + netaddr, bits = cidr.split('/') + address = struct.unpack('>L', socket.inet_aton(netaddr))[0] + address = address + index + return socket.inet_ntoa(struct.pack('>L', address)) + + +def get_last_ipv4_in_cidr(cidr): + if not is_valid_ipv4_cidr(cidr): + return None + + netaddr, bits = cidr.split('/') + if netaddr == '0.0.0.0': + return '0.0.0.0' + + address = struct.unpack('>L', socket.inet_aton(netaddr))[0] + address = address + 2**(32 - int(bits)) - 2 + return socket.inet_ntoa(struct.pack('>L', address)) + + +def get_ipv4_cidr_size(cidr): + if not is_valid_ipv4_cidr(cidr): + return None + netaddr, bits = cidr.split('/') + return 2**(32 - int(bits)) - 2 + + +def get_nth_ipv4_from_address(address, index): + if not is_valid_ipv4_address(address): + return None + + numeric_address = struct.unpack('>L', socket.inet_aton(address))[0] + numeric_address = numeric_address + index + return socket.inet_ntoa(struct.pack('>L', numeric_address)) + + +def get_ipv4_addresses_in_range(start_address, end_address): + if not is_valid_ipv4_address(start_address): + return None + + if len(end_address.split('.')) == 4: + if not is_valid_ipv4_address(end_address): + return None + else: + end_address_octets = len(end_address.split('.')) + start_address_octets = 4 - end_address_octets + octets = start_address.split('.')[:start_address_octets] + end_address.split('.') + end_address = '.'.join(octets) + + if not is_valid_ipv4_address(end_address): + return None + + addresses = [start_address] + while True: + start_address = get_next_ipv4_address(start_address) + addresses.append(start_address) + if start_address == end_address: + break + + return addresses + + +def get_ipv4_address_count(start_address, end_address): + if not is_valid_ipv4_address(start_address): + return None + + if not is_valid_ipv4_address(end_address): + return None + + numeric_start_address = struct.unpack('>L', socket.inet_aton(start_address))[0] + numeric_end_address = struct.unpack('>L', socket.inet_aton(end_address))[0] + if numeric_end_address < numeric_start_address: + return None + + count = numeric_end_address - numeric_start_address + 1 + + return count + + +def get_lower_ipv4(ip_a, ip_b): + if not is_valid_ipv4_address(ip_a): + return None + + if not is_valid_ipv4_address(ip_b): + return None + + numeric_address_a = struct.unpack('>L', socket.inet_aton(ip_a))[0] + numeric_address_b = struct.unpack('>L', socket.inet_aton(ip_b))[0] + + if numeric_address_a < numeric_address_b: + return ip_a + + return ip_b + + +def is_subnet_in_subnet(subnet_a, subnet_b): + if not is_valid_ipv4_cidr(subnet_a): + return False + + if not is_valid_ipv4_cidr(subnet_b): + return False + + subnet_a = '%s/%s' % ( + get_network_ipv4_in_cidr(subnet_a), + subnet_a.split('/')[1] + ) + subnet_b = '%s/%s' % ( + get_network_ipv4_in_cidr(subnet_b), + subnet_b.split('/')[1] + ) + + subnet_a_min = get_first_ipv4_in_cidr(subnet_a) + subnet_a_max = get_last_ipv4_in_cidr(subnet_a) + subnet_b_min = get_first_ipv4_in_cidr(subnet_b) + subnet_b_max = get_last_ipv4_in_cidr(subnet_b) + if get_lower_ipv4(subnet_a_min, subnet_b_min) == subnet_b_min: + if get_lower_ipv4(subnet_a_max, subnet_b_max) == subnet_a_max: + return True + + return False + + +def get_next_ipv4_address(ip_address): + return get_nth_ipv4_from_address(ip_address, 1) + + +def is_url_valid(value): + return validators.url(value) + + +def is_url_accessible(url, timeout=1): + try: + if len(url.split(' ')) > 1: + return False + handler = requests.head(url, timeout=timeout) + if 'Content-Type' in handler.headers: + return True + except BaseException: + pass + return False + + +def download_url(url, filename, timeout=5): + try: + response = requests.get( + url, + timeout=timeout + ) + with open(filename, "wb") as file_handler: + file_handler.write(response.content) + except BaseException: + return None + return filename + + +def is_public_key_valid(value): + ssh = sshpubkeys.SSHKey(value, strict=True) + try: + ssh.parse() + except BaseException: + return False + return True + + +def get_file_md5(filename): + if not os.path.isfile(filename): + return None + hasher = hashlib.md5() + blocksize = 65536 + with open(filename, 'rb') as file_handler: + buf = file_handler.read(blocksize) + while len(buf) > 0: + hasher.update(buf) + buf = file_handler.read(blocksize) + md5 = hasher.hexdigest() + return md5 + + +def get_ip(name): + try: + ip_address = socket.gethostbyname(name) + except BaseException: + return None + return ip_address + + +def get_string_ipv4s(line): + ips = [] + candidates = re.findall(r'[0-9]+(?:\.[0-9]+){3}', line) + for candidate in candidates: + if is_valid_ipv4_address(candidate): + ips.append( + candidate + ) + return ips + + +def get_obscured_ipv4(address, allow_private_lead=True): + if not is_valid_ipv4_address(address): + return None + + octets = address.split('.') + new_octets = [] + for octet in octets: + new_octets.append( + '*' * len(octet) + ) + + if allow_private_lead: + if octets[0] in ['10', '172', '192']: + new_octets[0] = octets[0] + + return '.'.join(new_octets) + + +def get_string_macs_colon(line): + macs = [] + candidates = re.findall(r'([0-9a-f]{2}(?::[0-9a-f]{2}){5})', line, re.IGNORECASE) + for candidate in candidates: + if is_valid_mac_address(candidate, mac_address_format='colon'): + macs.append( + candidate + ) + return macs + + +def get_string_macs_dotted(line): + macs = [] + candidates = re.findall(r'([0-9a-f]{4}(?:.[0-9a-f]{4}){2})', line, re.IGNORECASE) + for candidate in candidates: + if is_valid_mac_address(candidate, mac_address_format='dotted'): + macs.append( + candidate + ) + return macs + + +def get_string_macs(line): + macs = [] + macs = macs + get_string_macs_colon(line) + macs = macs + get_string_macs_dotted(line) + return macs + + +def get_obscured_mac(address): + if is_valid_mac_address(address, mac_address_format='colon'): + return '**:**:**:**:**:**' + + if is_valid_mac_address(address, mac_address_format='dotted'): + return '****.****.****' + + return None diff --git a/lib/isctl_helper.py b/lib/isctl_helper.py new file mode 100644 index 00000000..f3a0e2fe --- /dev/null +++ b/lib/isctl_helper.py @@ -0,0 +1,218 @@ +import subprocess +import traceback +import json +import os +import time +import platform + +from lib import log_helper +from lib import iaccount_helper + + +class Isctl(): + def __init__(self, iaccount, log_id=None): + self.log = log_helper.Log(log_id=log_id) + self.iaccount = iaccount + + self.ia_handler = iaccount_helper.IntersightAccount() + self.configuration = self.ia_handler.get_iaccount_configuration_filename(iaccount) + + def command_fixup_windows(self, command): + escape_create = False + escape_update = False + if command.startswith('isctl create'): + escape_create = True + + if command.startswith('isctl update'): + escape_update = True + + command = command.replace('isctl ', 'isctl --config %s ' % (self.configuration)) + + if escape_create: + if '"' in command: + # isctl create ippool pool --Name aaa --Organization default --IpV4Blocks "[{\"From\": \"10.1.1.10\", \"To\": \"10.1.1.14\"}]" + command = command.replace('"', '\\"') + command = command.replace('\'', '"') + self.log.debug('isctl_helper.command_fixup_windows', command) + + if escape_update: + if '\'' in command: + # isctl create ippool pool --Name aaa --Organization default --IpV4Blocks "[{\"From\": \"10.1.1.10\", \"To\": \"10.1.1.14\"}]" + command = command.replace('"', '\\"') + command = command.replace('\'', '"') + self.log.debug('isctl_helper.command_fixup_windows', command) + + return command + + def isctl_exec_windows(self, command, json_conversion=False, retry=3): + try: + command = self.command_fixup_windows(command) + for i in range(0, retry): + start = int(time.time() * 1000) + with subprocess.Popen( + args=command, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + env=os.environ + ) as process: + + output, error = process.communicate() + duration = int(time.time() * 1000) - start + if process.returncode == 0: + if json_conversion: + try: + output = json.loads(output.decode('utf-8')) + except BaseException: + return False, traceback.format_exc(), duration + + return True, output, duration + + time.sleep(3) + + return False, error, duration + + except BaseException: + self.log.error('isctl_helper.isctl_exec', traceback.format_exc()) + return False, 'Exception', 0 + + def command_fixup_linux(self, command): + if 'isctl --config' not in command: + command = command.replace('isctl ', 'isctl --config %s ' % (self.configuration)) + return command + + def isctl_exec_linux(self, command, json_conversion=False, retry=3): + try: + command = self.command_fixup_linux(command) + for i in range(0, retry): + start = int(time.time() * 1000) + with subprocess.Popen( + args=command, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + env=os.environ + ) as process: + + output, error = process.communicate() + duration = int(time.time() * 1000) - start + if process.returncode == 0: + if json_conversion: + try: + output = json.loads(output.decode('utf-8')) + except BaseException: + return False, traceback.format_exc(), duration + + return True, output, duration + + time.sleep(3) + + return False, error, duration + + except BaseException: + self.log.error('isctl_helper.isctl_exec', traceback.format_exc()) + return False, 'Exception', None + + def isctl_exec(self, command, json_conversion=False, retry=3): + my_os = platform.system() + if my_os == 'Windows': + return self.isctl_exec_windows(command, json_conversion=json_conversion, retry=retry) + return self.isctl_exec_linux(command, json_conversion=json_conversion, retry=retry) + + def get(self, command, json_conversion=True, api_debug=False): + success, response, duration = self.isctl_exec( + command, + json_conversion=json_conversion + ) + if not success: + self.log.cli(command, False, duration) + try: + self.log.error('isctl_helper.get', command) + self.log.error('isctl_helper.get', response) + except BaseException: + pass + return None + + item_count = None + if json_conversion: + if isinstance(response, dict): + item_count = 1 + + if isinstance(response, list): + item_count = len(response) + + self.log.cli( + command, + True, + duration, + item_count=item_count + ) + + if api_debug: + self.log.api( + command, + response + ) + + return response + + def create(self, command, get_response=False, json_conversion=True): + if json_conversion: + command = '%s -o json' % (command) + + success, response, duration = self.isctl_exec( + command, + json_conversion=json_conversion + ) + if not success: + self.log.cli(command, False, duration) + try: + self.log.error('isctl_helper.create', command) + self.log.error('isctl_helper.create', response) + except BaseException: + pass + + if get_response: + return dict(success=False, response=response) + + return False + + self.log.cli(command, True, duration) + if get_response: + return dict(success=True, response=response) + + return True + + def update(self, command): + success, response, duration = self.isctl_exec( + command, + json_conversion=False + ) + if not success: + self.log.cli(command, False, duration) + try: + self.log.error('isctl_helper.update', command) + self.log.error('isctl_helper.update', response) + except BaseException: + pass + return False + + self.log.cli(command, True, duration) + return True + + def delete(self, command): + success, response, duration = self.isctl_exec( + command, + json_conversion=False + ) + if not success: + self.log.cli(command, False, duration) + try: + self.log.error('isctl_helper.delete', command) + self.log.error('isctl_helper.delete', response) + except BaseException: + pass + return False + + self.log.cli(command, True, duration) + return True diff --git a/lib/iso/__init__.py b/lib/iso/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/iso/__pycache__/__init__.cpython-310.pyc b/lib/iso/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..96fd9851 Binary files /dev/null and b/lib/iso/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/iso/__pycache__/kickstart.cpython-310.pyc b/lib/iso/__pycache__/kickstart.cpython-310.pyc new file mode 100644 index 00000000..8e15b65d Binary files /dev/null and b/lib/iso/__pycache__/kickstart.cpython-310.pyc differ diff --git a/lib/iso/autoinstall.py b/lib/iso/autoinstall.py new file mode 100644 index 00000000..ce8b0509 --- /dev/null +++ b/lib/iso/autoinstall.py @@ -0,0 +1,226 @@ +import os +import uuid +import platform +import subprocess + +from lib import input_validator +from lib import output_helper +from lib import ssh +from lib import template + + +class IsoAutoinstall(): + def __init__(self, template_name, log_id=None, verbose=False, debug=False): + self.template_name = template_name + self.my_output = output_helper.OutputHelper(verbose=verbose, debug=debug) + self.input_validator_handler = input_validator.InputValidator(log_id=log_id) + self.template_handler = template.Template(verbose=verbose, debug=debug) + self.verbose = verbose + self.debug = debug + + def get_script_filename(self): + template_dir = self.input_validator_handler.get_template_dir(self.template_name, template_category='vc') + if template_dir is None: + self.my_output.error('Template dir not found for template: %s' % (self.template_name)) + return None + + template_definition = self.input_validator_handler.get_template_definition(self.template_name, template_category='vc') + if template_definition is None: + self.my_output.error('Template definition not found for template: %s' % (self.template_name)) + return None + + files_dir = os.path.join(template_dir, 'files') + filename = os.path.join( + files_dir, + template_definition['main']['autoinstall_iso_create_script'] + ) + + if not os.path.isfile(filename): + self.my_output.error('Autoinstall iso create script not found: %s' % (filename)) + return None + + return filename + + def prepare_script(self, variables): + script_filename = self.get_script_filename() + if script_filename is None: + self.my_output.error('Get script filename failed') + return None + + content = self.template_handler.get_template( + script_filename, + variables, + replace_variables_enabled=True, + check_remaining_variables=False + ) + if content is None: + self.my_output.error('Script template failed') + return None + + target_filename = '/tmp/%s' % (str(uuid.uuid4())) + try: + with open(target_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + except BaseException: + self.my_output.error('Failed to prepare local script') + return None + + self.my_output.debug('Autoinstall preparation script') + self.my_output.debug(content) + + return target_filename + + def prepare_user_data(self, user_data_filename, variables, replace_variables_enabled=True): + user_data_content = self.template_handler.get_template( + user_data_filename, + variables, + replace_variables_enabled=replace_variables_enabled + ) + if user_data_content is None: + self.my_output.error('User data preparation failed') + return False + + user_data_filename = '/tmp/%s.user-data' % (str(uuid.uuid4())) + try: + with open(user_data_filename, 'w', encoding='utf-8', newline='\n') as file_handler: + file_handler.write(user_data_content) + + except BaseException: + self.my_output.error('Failed to save generated kickstart file: %s' % (user_data_filename)) + return None + + self.my_output.debug('User data') + self.my_output.debug(user_data_content) + + return user_data_filename + + def make_iso_local(self, script_filename, user_data_filename): + cmd = 'chmod a+x %s' % (script_filename) + os.system(cmd) + + command = './%s -u %s' % ( + script_filename, + user_data_filename + ) + + with subprocess.Popen( + args=command.split(' '), + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True + ) as process: + output, error = process.communicate() + + if process.returncode > 0: + self.my_output.error('Autoinstall preparation script failed') + self.my_output.default(output.decode('utf-8')) + self.my_output.default(error.decode('utf-8')) + return False + + self.my_output.info('Autoinstall preparation script successful') + self.my_output.debug(output.decode('utf-8')) + + return True + + def make_iso_remote(self, script_filename, user_data_filename, jump): + ssh_handler = ssh.Ssh( + jump['ip'], + jump['username'], + port=22, + password=jump['password'], + debug=self.debug + ) + + # Step 1: copy script + + success = ssh_handler.scp_file(script_filename, script_filename) + if not success: + self.my_output.error('Failed to copy autoinstall script file to remote host') + return False + self.my_output.debug('Copy autoinstall script file to remote host: %s' % (script_filename)) + + cmd = 'dos2unix %s' % (script_filename) + success, output, error = ssh_handler.run_cmd(cmd) + if not success: + self.my_output.error('Failed to run dos2unix command: %s' % (cmd)) + return False + + success, output, error = ssh_handler.run_cmd(cmd) + if not success: + self.my_output.error('Failed to run dos2unix command: %s' % (cmd)) + return False + + self.my_output.debug('Autoinstall script dos2unix changed') + + # Step 2: copy user data + + success = ssh_handler.scp_file(user_data_filename, user_data_filename) + if not success: + self.my_output.error('Failed to copy user data file to remote host') + return False + self.my_output.debug('Copy autoinstall user data file to remote host: %s' % (user_data_filename)) + + cmd = 'dos2unix %s' % (user_data_filename) + success, output, error = ssh_handler.run_cmd(cmd) + if not success: + self.my_output.error('Failed to run dos2unix command: %s' % (cmd)) + return False + + success, output, error = ssh_handler.run_cmd(cmd) + if not success: + self.my_output.error('Failed to run dos2unix command: %s' % (cmd)) + return False + + self.my_output.debug('User data dos2unix changed') + + # Step 3: execute script + + cmd = 'bash %s -u %s' % ( + script_filename, + user_data_filename + ) + success, output, error = ssh_handler.run_cmd(cmd, live_output=self.verbose) + if not success: + self.my_output.error('Autoinstall iso generation script failed: %s' % (cmd)) + return False + + self.my_output.debug('ISO generated and uploaded') + return True + + def generate_iso(self, user_data_filename, variables, jump, replace_variables_enabled=True): + user_data_filename = self.prepare_user_data( + user_data_filename, + variables, + replace_variables_enabled=replace_variables_enabled + ) + if user_data_filename is None: + self.my_output.error('Iso generation failed on user data preparation') + return False + + script_filename = self.prepare_script(variables) + if script_filename is None: + os.remove(user_data_filename) + self.my_output.error('Iso generation failed on script preparation') + return False + + my_os = platform.system() + if my_os == 'Linux': + if jump['enabled']: + success = self.make_iso_remote(script_filename, user_data_filename, jump) + + if not jump['enabled']: + success = self.make_iso_local(script_filename, user_data_filename) + + if my_os != 'Linux': + if jump['enabled']: + success = self.make_iso_remote(script_filename, user_data_filename, jump) + + if not jump['enabled']: + self.my_output.error('Autoinstall iso generatation requires Linux') + success = False + + os.remove(user_data_filename) + os.remove(script_filename) + + return success diff --git a/lib/iso/kickstart.py b/lib/iso/kickstart.py new file mode 100644 index 00000000..04b7e8da --- /dev/null +++ b/lib/iso/kickstart.py @@ -0,0 +1,156 @@ +import os +import sys +import uuid +import shutil +import platform + +from lib import file_helper +from lib import output_helper +from lib import ssh +from lib import template + + +class IsoKickstart(): + def __init__(self, debug=False): + self.my_output = output_helper.OutputHelper(debug=debug) + self.template_handler = template.Template(debug=debug) + + def get_make_iso_script_filename(self): + main_dir = file_helper.get_main_dir() + if main_dir is None: + return None + + script_filename = os.path.abspath( + os.path.join( + main_dir, 'templates/iso/make-iso.sh' + ) + ) + + return script_filename + + def make_iso_local(self, ks_filename, iso_filename): + if os.path.isfile(iso_filename): + os.remove(iso_filename) + + # Step 1: copy iso script + script_filename = self.get_make_iso_script_filename() + if script_filename is None: + self.my_output.error('Make iso script not found') + return False + + target_script_filename = '/tmp/%s' % (os.path.basename(script_filename)) + shutil.copyfile(script_filename, target_script_filename) + self.my_output.debug('Copy make iso script file to local host: %s' % (target_script_filename)) + + # Step 2: set script file settings + cmd = 'chmod a+x %s' % (target_script_filename) + os.system(cmd) + + # Step 3: execute script + target_iso_filename = '%s.iso' % (str(uuid.uuid4())) + cmd = '%s -s %s -d %s >/dev/null 2>&1' % ( + target_script_filename, + ks_filename, + iso_filename + ) + os.system(cmd) + + return os.path.isfile(iso_filename) + + def make_iso_remote(self, ks_filename, iso_filename, jump): + ssh_handler = ssh.Ssh( + jump['ip'], + jump['username'], + port=22, + password=jump['password'] + ) + + # Step 1: copy kickstart file + target_ks_filename = os.path.basename(ks_filename) + success = ssh_handler.scp_file(ks_filename, target_ks_filename) + if not success: + self.my_output.error('Failed to copy kickstart file to remote host') + return False + + self.my_output.debug('Copy kickstart file to remote host: %s' % (target_ks_filename)) + + # Step 2: copy iso script + script_filename = self.get_make_iso_script_filename() + if script_filename is None: + self.my_output.error('Make iso script not found') + return False + + target_script_filename = os.path.basename(script_filename) + success = ssh_handler.scp_file(script_filename, target_script_filename) + if not success: + self.my_output.error('Failed to copy make iso script file to remote host') + return False + self.my_output.debug('Copy make iso script file to remote host: %s' % (target_script_filename)) + + # Step 3: set script file settings + cmd = 'chmod a+x %s' % (target_script_filename) + success, output, error = ssh_handler.run_cmd(cmd) + if not success: + self.my_output.error('Failed to set make iso script file flags') + return False + self.my_output.debug('Script mode changed') + + # Step 4: execute script + target_iso_filename = '%s.iso' % (str(uuid.uuid4())) + cmd = './%s -s %s -d %s' % ( + target_script_filename, + target_ks_filename, + target_iso_filename + ) + success, output, error = ssh_handler.run_cmd(cmd) + if not success: + self.my_output.error('Failed to generate iso') + return False + self.my_output.debug('ISO generated: %s' % (target_iso_filename)) + + # Step 5: download generated iso + success = ssh_handler.scp_file(target_iso_filename, iso_filename, put=False) + if not success: + self.my_output.error('Failed to copy iso file from remote host') + return False + self.my_output.debug('Copy iso file to local host: %s' % (iso_filename)) + + # Step 6: delete uploaded files + + for filename in [target_iso_filename, target_ks_filename, target_script_filename]: + if not ssh_handler.delete_file(filename): + self.my_output.error('Failed to delete remote file: %s' % (filename)) + + return True + + def generate_iso(self, ks_template_filename, ks_attributes, iso_filename, jump): + ks_template = self.template_handler.get_template(ks_template_filename, ks_attributes) + if ks_template is None: + return False + + ks_filename = '/tmp/%s.ks' % (str(uuid.uuid4())) + try: + with open(ks_filename, 'w', encoding='utf-8', newline='\n') as file_handler: + file_handler.write(ks_template) + except BaseException: + self.my_output.error('Failed to save generated kickstart file: %s' % (ks_filename)) + return False + + my_os = platform.system() + if my_os == 'Linux': + success = self.make_iso_local(ks_filename, iso_filename) + if not success: + self.my_output.error('ISO generation failed') + return False + + if my_os != 'Linux': + if not jump['enabled']: + self.my_output.error('Kickstart iso generatation requires Linux') + return False + + success = self.make_iso_remote(ks_filename, iso_filename, jump) + if not success: + self.my_output.error('ISO generation failed') + return False + + return True diff --git a/lib/iwo/__init__.py b/lib/iwo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/iwo/__pycache__/__init__.cpython-310.pyc b/lib/iwo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f748a7ed Binary files /dev/null and b/lib/iwo/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/action.cpython-310.pyc b/lib/iwo/__pycache__/action.cpython-310.pyc new file mode 100644 index 00000000..175a8f0d Binary files /dev/null and b/lib/iwo/__pycache__/action.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/application.cpython-310.pyc b/lib/iwo/__pycache__/application.cpython-310.pyc new file mode 100644 index 00000000..c51a713f Binary files /dev/null and b/lib/iwo/__pycache__/application.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/chassis.cpython-310.pyc b/lib/iwo/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..38cac9b4 Binary files /dev/null and b/lib/iwo/__pycache__/chassis.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/client.cpython-310.pyc b/lib/iwo/__pycache__/client.cpython-310.pyc new file mode 100644 index 00000000..1250e372 Binary files /dev/null and b/lib/iwo/__pycache__/client.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/cluster.cpython-310.pyc b/lib/iwo/__pycache__/cluster.cpython-310.pyc new file mode 100644 index 00000000..5c78a5a1 Binary files /dev/null and b/lib/iwo/__pycache__/cluster.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/container.cpython-310.pyc b/lib/iwo/__pycache__/container.cpython-310.pyc new file mode 100644 index 00000000..18233951 Binary files /dev/null and b/lib/iwo/__pycache__/container.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/dc.cpython-310.pyc b/lib/iwo/__pycache__/dc.cpython-310.pyc new file mode 100644 index 00000000..d09376fc Binary files /dev/null and b/lib/iwo/__pycache__/dc.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/disk.cpython-310.pyc b/lib/iwo/__pycache__/disk.cpython-310.pyc new file mode 100644 index 00000000..23f49b23 Binary files /dev/null and b/lib/iwo/__pycache__/disk.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/main.cpython-310.pyc b/lib/iwo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..46e8c29f Binary files /dev/null and b/lib/iwo/__pycache__/main.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/namespace.cpython-310.pyc b/lib/iwo/__pycache__/namespace.cpython-310.pyc new file mode 100644 index 00000000..59f98194 Binary files /dev/null and b/lib/iwo/__pycache__/namespace.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/network.cpython-310.pyc b/lib/iwo/__pycache__/network.cpython-310.pyc new file mode 100644 index 00000000..0b736554 Binary files /dev/null and b/lib/iwo/__pycache__/network.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/phy.cpython-310.pyc b/lib/iwo/__pycache__/phy.cpython-310.pyc new file mode 100644 index 00000000..96766dfd Binary files /dev/null and b/lib/iwo/__pycache__/phy.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/pod.cpython-310.pyc b/lib/iwo/__pycache__/pod.cpython-310.pyc new file mode 100644 index 00000000..8aa3457d Binary files /dev/null and b/lib/iwo/__pycache__/pod.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/region.cpython-310.pyc b/lib/iwo/__pycache__/region.cpython-310.pyc new file mode 100644 index 00000000..264914c9 Binary files /dev/null and b/lib/iwo/__pycache__/region.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/service.cpython-310.pyc b/lib/iwo/__pycache__/service.cpython-310.pyc new file mode 100644 index 00000000..e409e46a Binary files /dev/null and b/lib/iwo/__pycache__/service.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/spec.cpython-310.pyc b/lib/iwo/__pycache__/spec.cpython-310.pyc new file mode 100644 index 00000000..586a949d Binary files /dev/null and b/lib/iwo/__pycache__/spec.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/storage.cpython-310.pyc b/lib/iwo/__pycache__/storage.cpython-310.pyc new file mode 100644 index 00000000..059877f7 Binary files /dev/null and b/lib/iwo/__pycache__/storage.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/switch.cpython-310.pyc b/lib/iwo/__pycache__/switch.cpython-310.pyc new file mode 100644 index 00000000..88412394 Binary files /dev/null and b/lib/iwo/__pycache__/switch.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/target.cpython-310.pyc b/lib/iwo/__pycache__/target.cpython-310.pyc new file mode 100644 index 00000000..6ba1642f Binary files /dev/null and b/lib/iwo/__pycache__/target.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/vdc.cpython-310.pyc b/lib/iwo/__pycache__/vdc.cpython-310.pyc new file mode 100644 index 00000000..62f7bcda Binary files /dev/null and b/lib/iwo/__pycache__/vdc.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/vm.cpython-310.pyc b/lib/iwo/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..faf858d3 Binary files /dev/null and b/lib/iwo/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/volume.cpython-310.pyc b/lib/iwo/__pycache__/volume.cpython-310.pyc new file mode 100644 index 00000000..73d5a8a0 Binary files /dev/null and b/lib/iwo/__pycache__/volume.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/workload.cpython-310.pyc b/lib/iwo/__pycache__/workload.cpython-310.pyc new file mode 100644 index 00000000..d4c0e30e Binary files /dev/null and b/lib/iwo/__pycache__/workload.cpython-310.pyc differ diff --git a/lib/iwo/__pycache__/zone.cpython-310.pyc b/lib/iwo/__pycache__/zone.cpython-310.pyc new file mode 100644 index 00000000..6cfadf8c Binary files /dev/null and b/lib/iwo/__pycache__/zone.cpython-310.pyc differ diff --git a/lib/iwo/action.py b/lib/iwo/action.py new file mode 100644 index 00000000..cd7554a1 --- /dev/null +++ b/lib/iwo/action.py @@ -0,0 +1,297 @@ +class IwoAction(): + def __init__(self): + self.mo_action = {} + + def initialize_action(self, related_class): + body = {} + body['environmentType'] = 'HYBRID' + body['detailLevel'] = 'EXECUTION' + if related_class != 'all': + body['relatedEntityTypes'] = [related_class] + + self.mo_action[related_class] = self.post( + '/wo/api/v3/markets/Market/actions', + body=body + ) + if self.mo_action[related_class] is None: + return False + + self.log.iwo_mo( + 'Action.%s.attributes' % (related_class), + self.mo_action[related_class] + ) + + return True + + def get_action_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def match_action(self, action_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + match = False + for match_rule in match_rules: + if match_rule.startswith('target_id:'): + if action_info['target']['uuid'] == match_rule[10:]: + match = True + break + + return match + + def get_actions(self, related_class='all', match_rules=None): + if related_class not in self.mo_action: + if not self.initialize_action(related_class): + self.log.error( + 'get_actions', + 'Managed objects must be initialized first' + ) + return None + + actions = [] + + for managed_object in self.mo_action[related_class]: + action_info = self.get_action_info( + managed_object + ) + if action_info is not None: + if not self.match_action(action_info, match_rules): + continue + + actions.append( + action_info + ) + + self.log.iwo_mo( + 'Action.%s.info' % (related_class), + actions + ) + + return actions + + def get_actions_summary(self, actions): + action_types = {} + for action_type in ['delete', 'move', 'provision', 'reconfigure', 'resize', 'scale', 'start', 'suspend']: + action_types[action_type] = {} + action_types[action_type]['count'] = 0 + + action_types[action_type]['severity'] = {} + action_types['severity'] = {} + for severity in ['minor', 'major', 'critical']: + action_types[action_type]['severity'][severity] = 0 + action_types['severity'][severity] = 0 + + action_types[action_type]['category'] = {} + action_types[action_type]['class'] = {} + action_types[action_type]['mode'] = {} + action_types[action_type]['environment'] = {} + + for action in actions: + action_type = action['actionType'].lower() + if action_type not in action_types: + self.log.error( + 'iwo.get_actions.summary', + 'Unsupported action type: %s' % (action_type) + ) + continue + + action_types[action_type]['count'] = action_types[action_type]['count'] + 1 + + class_name = action['target']['className'] + if class_name not in action_types[action_type]['class']: + action_types[action_type]['class'][class_name] = 0 + action_types[action_type]['class'][class_name] = action_types[action_type]['class'][class_name] + 1 + + environment_name = action['target']['environmentType'] + if environment_name not in action_types[action_type]['environment']: + action_types[action_type]['environment'][environment_name] = 0 + action_types[action_type]['environment'][environment_name] = action_types[action_type]['environment'][environment_name] + 1 + + action_mode = action['actionMode'] + if action_mode not in action_types[action_type]['mode']: + action_types[action_type]['mode'][action_mode] = 0 + action_types[action_type]['mode'][action_mode] = action_types[action_type]['mode'][action_mode] + 1 + + severity = action['risk']['severity'].lower() + action_types[action_type]['severity'][severity] = action_types[action_type]['severity'][severity] + 1 + action_types['severity'][severity] = action_types['severity'][severity] + 1 + + category = action['risk']['subCategory'] + if category not in action_types[action_type]['category']: + action_types[action_type]['category'][category] = 0 + action_types[action_type]['category'][category] = action_types[action_type]['category'][category] + 1 + + return action_types + + def get_actions_summary_list(self, actions): + action_types = self.get_actions_summary( + actions + ) + + summary = [] + for action_name in action_types: + if action_name in ['severity']: + continue + + item = {} + item['name'] = action_name + item['count'] = action_types[action_name]['count'] + for key in ['severity', 'category', 'class', 'mode', 'environment']: + item[key] = [] + for value in action_types[action_name][key]: + item[key].append( + '%s (%s)' % ( + value, + action_types[action_name][key][value] + ) + ) + if len(item[key]) == 0: + item[key].append('') + summary.append(item) + + return summary + + def get_actions_severity_flag(self, actions): + summary = self.get_actions_summary(actions) + + if summary['severity']['critical'] > 0: + flag = 'Critical (%s)' % (summary['severity']['critical']) + color = 'Red' + return (flag, color) + + if summary['severity']['major'] > 0: + flag = 'Major (%s)' % (summary['severity']['major']) + color = 'Yellow' + return (flag, color) + + if summary['severity']['minor'] > 0: + flag = 'Minor (%s)' % (summary['severity']['minor']) + color = 'Blue' + return (flag, color) + + return ('Normal', 'Green') + + def get_action_severity_summary(self, managed_objects, empty_if_zero=True): + if len(managed_objects) == 0: + return ('-', '.') + + critical = 0 + major = 0 + minor = 0 + normal = 0 + for managed_object in managed_objects: + if managed_object['risk']['severity'].lower() == 'critical': + critical = critical + 1 + + if managed_object['risk']['severity'].lower() == 'major': + major = major + 1 + + if managed_object['risk']['severity'].lower() == 'minor': + minor = minor + 1 + + if managed_object['risk']['severity'].lower() == 'normal': + normal = normal + 1 + + severity = '%s/%s/%s/%s' % ( + critical, + major, + minor, + normal + ) + + color = ':' + if critical == 0: + color = '%s.' % (color) + else: + color = '%s%s' % ( + color, + 'R'.rjust(len(str(critical)), 'R') + ) + color = '%s.' % (color) + + if major == 0: + color = '%s.' % (color) + else: + color = '%s%s' % ( + color, + 'Y'.rjust(len(str(major)), 'Y') + ) + color = '%s.' % (color) + + if minor == 0: + color = '%s.' % (color) + else: + color = '%s%s' % ( + color, + 'B'.rjust(len(str(minor)), 'B') + ) + color = '%s.' % (color) + + if normal == 0: + color = '%s.' % (color) + else: + color = '%s%s' % ( + color, + 'G'.rjust(len(str(normal)), 'G') + ) + + return (severity, color) + + def get_actions_list(self, actions): + actions_list = [] + for action in actions: + info = {} + info['__Output'] = {} + info['severity'] = action['risk']['severity'].lower() + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + info['description'] = action['risk']['description'] + info['subCategory'] = action['risk']['subCategory'] + info['details'] = action['details'] + actions_list.append(info) + return actions_list + + def print_actions_summary(self, actions): + summary = self.get_actions_summary_list( + actions + ) + + order = [ + 'name', + 'count', + 'severity', + 'category', + 'class', + 'mode', + 'environment' + ] + + headers = [ + 'Name', + 'Count', + 'Severity', + 'Category', + 'Class', + 'Mode', + 'Environment' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + summary, + order, + ['severity', 'category', 'class', 'mode', 'environment'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) diff --git a/lib/iwo/application.py b/lib/iwo/application.py new file mode 100644 index 00000000..abc0b0d8 --- /dev/null +++ b/lib/iwo/application.py @@ -0,0 +1,453 @@ +class IwoApplication(): + def __init__(self): + self.mo_application = None + self.application = None + + def initialize_application(self): + body = {} + body['className'] = 'ApplicationComponent' + + self.mo_application = self.search(body) + if self.mo_application is None: + return False + + self.log.iwo_mo( + 'ApplicationComponent.attributes', + self.mo_application + ) + + return True + + def get_application_info(self, managed_object, resolve_dependencies=False): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['severityFlag'] = self.map_severity_color( + info['severity'] + ) + + info['severityFlag'] = info['severity'] + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + info['isStale'] = False + if info['staleness'] == 'STALE': + info['isStale'] = True + + info['isActive'] = False + if info['state'] == 'ACTIVE': + info['isActive'] = True + + # Providers + + info['container'] = [] + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'Container': + info['container'].append( + provider + ) + + if provider['className'] not in ['Container']: + self.log.error( + 'iwo.get_application_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + info['container'] = sorted( + info['container'], + key=lambda i: i['displayName'] + ) + + # Consumers + + info['service'] = [] + if 'consumers' in managed_object: + for consumer in managed_object['consumers']: + if consumer['className'] == 'Service': + info['service'].append( + consumer + ) + + if consumer['className'] not in ['Service']: + self.log.error( + 'iwo.get_application_info', + 'Unrecognized provider class name: %s' % ( + consumer['className'] + ) + ) + + del info['consumers'] + + info['service'] = sorted( + info['service'], + key=lambda i: i['displayName'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='Service', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['actionsSeverity'], info['__Output']['actionsSeverity']) = self.get_action_severity_summary( + info['actions'] + ) + + if resolve_dependencies: + container_match_rules = [] + for container in info['container']: + container['__Output'] = {} + container['severity'] = self.get_container_severity( + container['uuid'] + ) + container['__Output']['displayName'] = self.map_severity_color( + container['severity'] + ) + container_match_rules.append( + 'uuid:%s' % (container['uuid']) + ) + + info['containerSummary'] = self.get_severity_summary( + info['container'] + ) + info['__Output']['containerSummary.severity'] = info['containerSummary']['__Output']['severity'] + + service_match_rules = [] + for service in info['service']: + service['__Output'] = {} + service['severity'] = self.get_service_severity( + service['uuid'] + ) + service['__Output']['displayName'] = self.map_severity_color( + service['severity'] + ) + service_match_rules.append( + 'uuid:%s' % (service['uuid']) + ) + + info['serviceSummary'] = self.get_severity_summary( + info['service'] + ) + info['__Output']['serviceSummary.severity'] = info['serviceSummary']['__Output']['severity'] + + return info + + def match_application(self, application_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + rules = {} + for match_rule in match_rules: + rules[match_rule] = False + + if match_rule.startswith('uuid:'): + if application_info['uuid'] == match_rule[5:]: + rules[match_rule] = True + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in application_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('cluster:'): + if match_rule[8:].lower() in application_info['discoveredBy']['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('service:'): + for service_info in application_info['service']: + if match_rule[8:].lower() in service_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('container:'): + for container_info in application_info['container']: + if match_rule[10:].lower() in container_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule == 'stale': + if application_info['isStale']: + rules[match_rule] = True + + if match_rule == 'inactive': + if not application_info['isActive']: + rules[match_rule] = True + + if match_rule == 'critical': + if application_info['severity'].lower() in ['critical']: + rules[match_rule] = True + + if match_rule == 'major': + if application_info['severity'].lower() in ['critical', 'major']: + rules[match_rule] = True + + if match_rule == 'minor': + if application_info['severity'].lower() in ['critical', 'major', 'minor']: + rules[match_rule] = True + + match = True + for rule in rules: + match = match and rules[rule] + + return match + + def get_applications(self, resolve_dependencies=False, match_rules=None): + if self.mo_application is None: + if not self.initialize_application(): + self.log.error( + 'get_applications', + 'Managed objects must be initialized first' + ) + return None + + applications = [] + + for managed_object in self.mo_application: + application_info = self.get_application_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if application_info is not None: + if not self.match_application(application_info, match_rules): + continue + + applications.append( + application_info + ) + + self.log.iwo_mo( + 'ApplicationComponent.info', + self.mo_application + ) + + return applications + + def get_application(self, application_uuid, resolve_dependencies=False): + if self.application is None: + self.application = self.get_applications(resolve_dependencies=resolve_dependencies) + + if self.application is not None: + for application in self.application: + if application['uuid'] == application_uuid: + return application + + return None + + def get_application_severity(self, application_uuid, resolve_dependencies=False): + application = self.get_application( + application_uuid, + resolve_dependencies=resolve_dependencies + ) + if application is not None: + return application['severity'] + return None + + def get_applications_summary(self, match_rules=None): + applications = self.get_applications( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if applications is not None: + summary = self.get_summary(applications) + + return summary + + def print_applications_base(self, applications): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Application Name' + ] + + self.my_output.my_table( + applications, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_applications_actions(self, applications): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'discoveredBy.displayName', + 'displayName', + 'environmentType', + 'serviceSummary.severity', + 'containerSummary.severity' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Kubernetes', + 'Application Name', + 'Location', + 'Service', + 'Container' + ] + + for application in applications: + if len(application['actionsList']) == 0: + continue + + self.my_output.my_table( + [application], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + action_order = [ + 'severity', + 'description', + 'subCategory', + 'details' + ] + + action_headers = [ + 'Severity', + 'Description', + 'Category', + 'Details' + ] + + self.my_output.my_table( + application['actionsList'], + order=action_order, + headers=action_headers, + allow_order_subkeys=True, + table=True + ) + + def print_applications_services(self, applications): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName', + 'serviceSummary.severity', + 'service.displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Application Name', + 'Service Severity', + 'Service' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + applications, + order, + ['service'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_applications_containers(self, applications): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName', + 'containerSummary.severity', + 'container.displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Application Name', + 'Container Severity', + 'Container' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + applications, + order, + ['container'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_applications(self, applications, show_actions=False, show_container=False, show_service=False, summary=True): + if summary: + self.print_summary(applications) + + if not show_actions and not show_container and not show_service: + self.print_applications_base(applications) + return + + if show_actions: + self.print_applications_actions(applications) + return + + if show_service: + self.print_applications_services(applications) + return + + if show_container: + self.print_applications_containers(applications) + return diff --git a/lib/iwo/chassis.py b/lib/iwo/chassis.py new file mode 100644 index 00000000..78d6bc18 --- /dev/null +++ b/lib/iwo/chassis.py @@ -0,0 +1,65 @@ +import json + + +class IwoChassis(): + def __init__(self): + self.mo_chassis = None + + def initialize_chassis(self): + body = {} + body['className'] = 'Chassis' + + self.mo_chassis = self.search(body) + if self.mo_chassis is None: + return False + + self.log.iwo_mo( + 'Chassis.attributes', + self.mo_chassis + ) + + return True + + def get_chassis_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_chassiss(self): + if self.mo_chassis is None: + if not self.initialize_chassis(): + self.log.error( + 'get_chassiss', + 'Managed objects must be initialized first' + ) + return None + + chassiss = [] + + for managed_object in self.mo_chassis: + chassis_info = self.get_chassis_info( + managed_object + ) + if chassis_info is not None: + chassiss.append( + chassis_info + ) + + self.log.iwo_mo( + 'Chassis.info', + self.mo_chassis + ) + + return chassiss + + def print_chassiss(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/client.py b/lib/iwo/client.py new file mode 100644 index 00000000..54112666 --- /dev/null +++ b/lib/iwo/client.py @@ -0,0 +1,199 @@ +import time +import json +import datetime +import traceback +import intersight + +from lib import iaccount_helper + + +class IwoClient(): + def __init__(self, iaccount): + self.iaccount = iaccount + self.api_client = None + self.iaccount_handler = iaccount_helper.IntersightAccount() + + def connect(self): + if self.api_client is not None: + return True + + iaccount_configuration = self.iaccount_handler.get_iaccount_configuration( + self.iaccount + ) + if iaccount_configuration is None: + self.log.error( + 'iwo_client.connect', + 'iaccount not found: %s' % (self.iaccount) + ) + return False + + start_time = int(time.time() * 1000) + + try: + client_configured = True + configuration = intersight.Configuration( + host='https://%s' % (iaccount_configuration['server']), + signing_info=intersight.HttpSigningConfiguration( + key_id=iaccount_configuration['keyid'], + private_key_path=iaccount_configuration['keyfile'], + signing_scheme=intersight.signing.SCHEME_RSA_SHA256, + signing_algorithm=intersight.signing.ALGORITHM_RSASSA_PKCS1v15, + hash_algorithm=intersight.signing.HASH_SHA256, + signed_headers=[intersight.signing.HEADER_REQUEST_TARGET, + intersight.signing.HEADER_CREATED, + intersight.signing.HEADER_EXPIRES, + intersight.signing.HEADER_HOST, + intersight.signing.HEADER_DATE, + intersight.signing.HEADER_DIGEST, + 'Content-Type', + 'User-Agent' + ], + signature_max_validity=datetime.timedelta(minutes=5) + ) + ) + + self.api_client = intersight.ApiClient(configuration) + self.api_client.set_default_header('referer', 'https://%s' % (iaccount_configuration['server'])) + self.api_client.set_default_header('x-requested-with', 'XMLHttpRequest') + self.api_client.set_default_header('Content-Type', 'application/json') + except BaseException: + client_configured = False + self.log.error( + 'iwo_client.connect', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.iwo( + 'connect', + None, + None, + client_configured, + duration_ms + ) + + return True + + def query(self, method, url, body=None, **kwargs): + header = {} + header['Accept'] = self.api_client.select_header_accept(['application/json']) + header['Content-Type'] = self.api_client.select_header_content_type(['application/json']) + auth_settings = ['cookieAuth', 'http_signature', 'oAuth2'] + query_parameters = [] + for key, value in kwargs.items(): + query_parameters.append((key, value)) + + start_time = int(time.time() * 1000) + + try: + success = True + + response = self.api_client.call_api( + url, + method, + header_params=header, + query_params=query_parameters, + body=body, + auth_settings=auth_settings, + _return_http_data_only=True, + _preload_content=False + ) + + output = [] + item_count = 0 + if response.data: + output = json.loads(response.data) + item_count = len(output) + + except Exception as exp: + success = False + output = None + item_count = 0 + + self.log.error( + 'iwo_client.query', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + + if body is None: + self.log.iwo( + method, + url, + None, + success, + duration_ms, + item_count=item_count + ) + else: + self.log.iwo( + method, + url, + json.dumps(body), + success, + duration_ms, + item_count=item_count + ) + + return output + + def get(self, url, limit=500, **kwargs): + if not self.connect(): + return None + + response = [] + cursor = 0 + while True: + batch = self.query('GET', url, cursor=cursor, limit=500, **kwargs) + if batch is None: + break + + response = response + batch + if len(batch) < limit: + break + + cursor = cursor + limit + + return response + + def post(self, url, body=None, limit=500, **kwargs): + if not self.connect(): + return None + + response = [] + cursor = 0 + while True: + batch = self.query('POST', url, body=body, cursor=cursor, limit=500, **kwargs) + if batch is None: + break + + response = response + batch + if len(batch) < limit: + break + + cursor = cursor + limit + + return response + + def search(self, body, limit=500, **kwargs): + if not self.connect(): + return None + + url = '/wo/api/v3/search' + response = [] + cursor = 0 + while True: + batch = self.query('POST', url, body=body, cursor=cursor, limit=500, **kwargs) + if batch is None: + break + + response = response + batch + if len(batch) < limit: + break + + cursor = cursor + limit + + return response diff --git a/lib/iwo/cluster.py b/lib/iwo/cluster.py new file mode 100644 index 00000000..7eff79a1 --- /dev/null +++ b/lib/iwo/cluster.py @@ -0,0 +1,65 @@ +import json + + +class IwoCluster(): + def __init__(self): + self.mo_cluster = None + + def initialize_cluster(self): + body = {} + body['className'] = 'ContainerPlatformCluster' + + self.mo_cluster = self.search(body) + if self.mo_cluster is None: + return False + + self.log.iwo_mo( + 'ContainerPlatformCluster.attributes', + self.mo_cluster + ) + + return True + + def get_cluster_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_clusters(self): + if self.mo_cluster is None: + if not self.initialize_cluster(): + self.log.error( + 'get_clusters', + 'Managed objects must be initialized first' + ) + return None + + clusters = [] + + for managed_object in self.mo_cluster: + cluster_info = self.get_cluster_info( + managed_object + ) + if cluster_info is not None: + clusters.append( + cluster_info + ) + + self.log.iwo_mo( + 'ContainerPlatformCluster.info', + self.mo_cluster + ) + + return clusters + + def print_clusters(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/container.py b/lib/iwo/container.py new file mode 100644 index 00000000..619576e6 --- /dev/null +++ b/lib/iwo/container.py @@ -0,0 +1,453 @@ +class IwoContainer(): + def __init__(self): + self.mo_container = None + self.container = None + + def initialize_container(self): + body = {} + body['className'] = 'Container' + + self.mo_container = self.search(body) + if self.mo_container is None: + return False + + self.log.iwo_mo( + 'Container.attributes', + self.mo_container + ) + + return True + + def get_container_info(self, managed_object, resolve_dependencies=False): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['severityFlag'] = self.map_severity_color( + info['severity'] + ) + + info['severityFlag'] = info['severity'] + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + info['isStale'] = False + if info['staleness'] == 'STALE': + info['isStale'] = True + + info['isActive'] = False + if info['state'] == 'ACTIVE': + info['isActive'] = True + + # Providers + + info['pod'] = [] + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'ContainerPod': + info['pod'].append( + provider + ) + + if provider['className'] not in ['ContainerPod']: + self.log.error( + 'iwo.get_container_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + info['pod'] = sorted( + info['pod'], + key=lambda i: i['displayName'] + ) + + # Consumers + + info['application'] = [] + if 'consumers' in managed_object: + for consumer in managed_object['consumers']: + if consumer['className'] == 'ApplicationComponent': + info['application'].append( + consumer + ) + + if consumer['className'] not in ['ApplicationComponent']: + self.log.error( + 'iwo.get_container_info', + 'Unrecognized provider class name: %s' % ( + consumer['className'] + ) + ) + + del info['consumers'] + + info['application'] = sorted( + info['application'], + key=lambda i: i['displayName'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='Service', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['actionsSeverity'], info['__Output']['actionsSeverity']) = self.get_action_severity_summary( + info['actions'] + ) + + if resolve_dependencies: + pod_match_rules = [] + for pod in info['pod']: + pod['__Output'] = {} + pod['severity'] = self.get_pod_severity( + pod['uuid'] + ) + pod['__Output']['displayName'] = self.map_severity_color( + pod['severity'] + ) + pod_match_rules.append( + 'uuid:%s' % (pod['uuid']) + ) + + info['podSummary'] = self.get_severity_summary( + info['pod'] + ) + info['__Output']['podSummary.severity'] = info['podSummary']['__Output']['severity'] + + application_match_rules = [] + for application in info['application']: + application['__Output'] = {} + application['severity'] = self.get_application_severity( + application['uuid'] + ) + application['__Output']['displayName'] = self.map_severity_color( + application['severity'] + ) + application_match_rules.append( + 'uuid:%s' % (application['uuid']) + ) + + info['applicationSummary'] = self.get_severity_summary( + info['application'] + ) + info['__Output']['applicationSummary.severity'] = info['applicationSummary']['__Output']['severity'] + + return info + + def match_container(self, container_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + rules = {} + for match_rule in match_rules: + rules[match_rule] = False + + if match_rule.startswith('uuid:'): + if container_info['uuid'] == match_rule[5:]: + rules[match_rule] = True + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in container_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('cluster:'): + if match_rule[8:].lower() in container_info['discoveredBy']['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('application:'): + for app_info in container_info['application']: + if match_rule[12:].lower() in app_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('pod:'): + for pod_info in container_info['pod']: + if match_rule[4:].lower() in pod_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule == 'stale': + if container_info['isStale']: + rules[match_rule] = True + + if match_rule == 'inactive': + if not container_info['isActive']: + rules[match_rule] = True + + if match_rule == 'critical': + if container_info['severity'].lower() in ['critical']: + rules[match_rule] = True + + if match_rule == 'major': + if container_info['severity'].lower() in ['critical', 'major']: + rules[match_rule] = True + + if match_rule == 'minor': + if container_info['severity'].lower() in ['critical', 'major', 'minor']: + rules[match_rule] = True + + match = True + for rule in rules: + match = match and rules[rule] + + return match + + def get_containers(self, resolve_dependencies=False, match_rules=None): + if self.mo_container is None: + if not self.initialize_container(): + self.log.error( + 'get_containers', + 'Managed objects must be initialized first' + ) + return None + + containers = [] + + for managed_object in self.mo_container: + container_info = self.get_container_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if container_info is not None: + if not self.match_container(container_info, match_rules): + continue + + containers.append( + container_info + ) + + self.log.iwo_mo( + 'Container.info', + self.mo_container + ) + + return containers + + def get_container(self, container_uuid, resolve_dependencies=False): + if self.container is None: + self.container = self.get_containers(resolve_dependencies=resolve_dependencies) + + if self.container is not None: + for container in self.container: + if container['uuid'] == container_uuid: + return container + + return None + + def get_container_severity(self, container_uuid, resolve_dependencies=False): + container = self.get_container( + container_uuid, + resolve_dependencies=resolve_dependencies + ) + if container is not None: + return container['severity'] + return None + + def get_containers_summary(self, match_rules=None): + containers = self.get_containers( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if containers is not None: + summary = self.get_summary(containers) + + return summary + + def print_containers_base(self, containers): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Container Name' + ] + + self.my_output.my_table( + containers, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_containers_actions(self, containers): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'discoveredBy.displayName', + 'displayName', + 'environmentType', + 'application.severity', + 'pod.severity' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Kubernetes', + 'Container Name', + 'Location', + 'Application', + 'Pod' + ] + + for container in containers: + if len(container['actionsList']) == 0: + continue + + self.my_output.my_table( + [container], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + action_order = [ + 'severity', + 'description', + 'subCategory', + 'details' + ] + + action_headers = [ + 'Severity', + 'Description', + 'Category', + 'Details' + ] + + self.my_output.my_table( + container['actionsList'], + order=action_order, + headers=action_headers, + allow_order_subkeys=True, + table=True + ) + + def print_containers_pods(self, containers): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName', + 'podSummary.severity', + 'pod.displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Container Name', + 'Pod Severity', + 'Pod' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + containers, + order, + ['pod'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_containers_apps(self, containers): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName', + 'applicationSummary.severity', + 'application.displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Container Name', + 'Application Severity', + 'Application' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + containers, + order, + ['application'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_containers(self, containers, show_actions=False, show_app=False, show_pod=False, summary=True): + if summary: + self.print_summary(containers) + + if not show_actions and not show_app and not show_pod: + self.print_containers_base(containers) + return + + if show_pod: + self.print_containers_pods(containers) + return + + if show_app: + self.print_containers_apps(containers) + return + + if show_actions: + self.print_containers_actions(containers) + return diff --git a/lib/iwo/dc.py b/lib/iwo/dc.py new file mode 100644 index 00000000..329de445 --- /dev/null +++ b/lib/iwo/dc.py @@ -0,0 +1,113 @@ +class IwoDataCenter(): + def __init__(self): + self.mo_data_center = None + + def initialize_data_center(self): + body = {} + body['className'] = 'DataCenter' + + self.mo_data_center = self.search(body) + if self.mo_data_center is None: + return False + + self.log.iwo_mo( + 'DataCenter.attributes', + self.mo_data_center + ) + + return True + + def get_data_center_info(self, managed_object): + # { + # "uuid": "74691878199569", + # "displayName": "Berlin Lab", + # "className": "DataCenter", + # "environmentType": "ONPREM", + # "discoveredBy": { + # "uuid": "74175664340512", + # "displayName": "6149828e6f72612d301327e8", + # "category": "Hypervisor", + # "type": "vCenter", + # "readonly": false + # }, + # "vendorIds": { + # "6149828e6f72612d301327e8": "datacenter-2" + # }, + # "state": "ACTIVE", + # "severity": "Normal", + # "severityBreakdown": { + # "NORMAL": 1 + # }, + # "consumers": [ + # { + # "uuid": "74691878199586", + # "displayName": "", + # "className": "PhysicalMachine" + # } + # ], + # "staleness": "CURRENT" + # } + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['physicalMachineCount'] = 0 + for consumer in managed_object['consumers']: + if consumer['className'] == 'PhysicalMachine': + info['physicalMachineCount'] = info['physicalMachineCount'] + 1 + + if info['state'] == 'ACTIVE': + info['__Output']['state'] = 'Green' + else: + info['__Output']['state'] = 'Red' + + return info + + def get_data_centers(self): + if self.mo_data_center is None: + if not self.initialize_data_center(): + self.log.error( + 'get_data_centers', + 'Managed objects must be initialized first' + ) + return None + + data_centers = [] + + for managed_object in self.mo_data_center: + data_center_info = self.get_data_center_info( + managed_object + ) + if data_center_info is not None: + data_centers.append( + data_center_info + ) + + return data_centers + + def print_data_centers(self, data_centers): + order = [ + 'state', + 'displayName', + 'environmentType', + 'discoveredBy.type', + 'physicalMachineCount' + ] + + headers = [ + 'State', + 'Name', + 'Location', + 'Type', + 'Physical Machines' + ] + + self.my_output.my_table( + data_centers, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) diff --git a/lib/iwo/disk.py b/lib/iwo/disk.py new file mode 100644 index 00000000..cbf4f9a1 --- /dev/null +++ b/lib/iwo/disk.py @@ -0,0 +1,65 @@ +import json + + +class IwoDisk(): + def __init__(self): + self.mo_disk = None + + def initialize_disk(self): + body = {} + body['className'] = 'DiskArray' + + self.mo_disk = self.search(body) + if self.mo_disk is None: + return False + + self.log.iwo_mo( + 'DiskArray.attributes', + self.mo_disk + ) + + return True + + def get_disk_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_disks(self): + if self.mo_disk is None: + if not self.initialize_disk(): + self.log.error( + 'get_disks', + 'Managed objects must be initialized first' + ) + return None + + disks = [] + + for managed_object in self.mo_disk: + disk_info = self.get_disk_info( + managed_object + ) + if disk_info is not None: + disks.append( + disk_info + ) + + self.log.iwo_mo( + 'DiskArray.info', + self.mo_disk + ) + + return disks + + def print_disks(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/lcm/__init__.py b/lib/iwo/lcm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/iwo/lcm/__pycache__/__init__.cpython-310.pyc b/lib/iwo/lcm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5ea357c4 Binary files /dev/null and b/lib/iwo/lcm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/iwo/lcm/__pycache__/main.cpython-310.pyc b/lib/iwo/lcm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..525af151 Binary files /dev/null and b/lib/iwo/lcm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/iwo/lcm/main.py b/lib/iwo/lcm/main.py new file mode 100644 index 00000000..67367c31 --- /dev/null +++ b/lib/iwo/lcm/main.py @@ -0,0 +1,19 @@ +from lib import log_helper +from lib import output_helper +from lib.iwo.lcm.ocp.main import IwoOcpLcm + + +class IwoLcm(IwoOcpLcm): + def __init__(self, verbose=False, debug=False, log_id=None): + self.verbose = verbose + self.debug = debug + self.log_id = log_id + + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + + IwoOcpLcm.__init__(self) diff --git a/lib/iwo/lcm/ocp/__init__.py b/lib/iwo/lcm/ocp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/iwo/lcm/ocp/__pycache__/__init__.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5cb5e909 Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/__pycache__/common.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..14ee9643 Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/common.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/__pycache__/create.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..5acc5405 Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/create.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/__pycache__/delete.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..354d6e2e Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/__pycache__/get.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/get.cpython-310.pyc new file mode 100644 index 00000000..0fd03d03 Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/get.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/__pycache__/main.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d2290da4 Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/__pycache__/template.cpython-310.pyc b/lib/iwo/lcm/ocp/__pycache__/template.cpython-310.pyc new file mode 100644 index 00000000..7ba33aad Binary files /dev/null and b/lib/iwo/lcm/ocp/__pycache__/template.cpython-310.pyc differ diff --git a/lib/iwo/lcm/ocp/create.py b/lib/iwo/lcm/ocp/create.py new file mode 100644 index 00000000..b76b0453 --- /dev/null +++ b/lib/iwo/lcm/ocp/create.py @@ -0,0 +1,240 @@ +import os +import json +import uuid +import tarfile +import traceback + +from lib import file_helper +from lib import ssh +from lib.intersight import asset_device_registration + + +class IwoOcpCreateLcm(): + def __init__(self): + pass + + def get_chart_values(self, chart_filename): + if not os.path.isfile(chart_filename): + self.log.error( + 'get_chart_values', + 'Chart file not found: %s' % (chart_filename) + ) + return None + + try: + with tarfile.open(chart_filename) as file_handler: + file_handler.extract('iwo-k8s-collector/values.yaml', '/tmp/') + file_handler.close() + except BaseException: + self.log.error( + 'get_chart_values', + 'Failed to extract values.yaml: %s' % (chart_filename) + ) + self.log.error( + 'get_chart_values', + traceback.format_exc() + ) + return None + + values_filename = '/tmp/iwo-k8s-collector/values.yaml' + content = file_helper.get_file_yaml( + values_filename + ) + if content is None: + self.log.error( + 'get_chart_values', + 'File read failed: %s' % (values_filename) + ) + return None + + self.log.debug( + 'get_chart_values', + json.dumps(content, indent=4) + ) + return content + + def upload_chart(self, chart_filename, cluster_parameters): + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + destination = '/root/iwo-chart.tgz' + success = ssh_handler.scp_file( + chart_filename, + destination + ) + + if not success: + self.log.error( + 'upload_chart', + 'IWO helm chart upload failed' + ) + return None + + self.log.debug( + 'upload_chart', + 'IWO helm chart uploaded: %s' % (destination) + ) + + return destination + + def generate_create_variables(self, destination_chart_filename, cluster_parameters, chart_values): + variables = {} + variables['CHART'] = destination_chart_filename + variables['NAMESPACE'] = 'iwo-collector' + variables['POD'] = 'my-iwo-k8s-collector' + variables['SERVER'] = chart_values['iwoServerVersion'] + variables['COLLECTOR'] = chart_values['collectorImage']['tag'] + variables['TARGET'] = 'my-k8s-cluster' + if cluster_parameters['proxy']['enabled']: + variables['HTTP_PROXY_ENABLED'] = 'True' + variables['HTTP_PROXY_SERVER'] = cluster_parameters['proxy']['https'].split(':')[1][2:] + variables['HTTP_PROXY_PORT'] = cluster_parameters['proxy']['https'].split(':')[2] + else: + variables['HTTP_PROXY_ENABLED'] = 'False' + + self.log.debug( + 'generate_create_variables', + json.dumps(variables, indent=4) + ) + + return variables + + def install_iwo(self, cluster_parameters, variables): + filename = self.get_template_filename('install.sh') + if filename is None: + self.log.error( + 'install_iwo', + 'Installation template not found' + ) + return False + + content = self.get_template_content(filename, variables) + if content is None: + self.log.error( + 'install_iwo', + 'Installation template preparation failed' + ) + return False + + script_source = '/tmp/%s' % (str(uuid.uuid4())) + with open(script_source, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + success = ssh_handler.run_file_upload( + script_source, + '/root/iwo_install.sh', + 744 + ) + if not success: + self.log.error( + 'install_iwo', + 'Installation script upload failed' + ) + + success, output, error = ssh_handler.run_cmd( + 'dos2unix /root/iwo_install.sh', + live_output=False + ) + if not success: + self.log.error( + 'install_iwo', + 'Installation script preparation failed' + ) + + success, output, error = ssh_handler.run_cmd( + './iwo_install.sh', + live_output=True + ) + if not success: + self.log.error( + 'install_iwo', + 'Installation script failed' + ) + self.log.error( + 'install_iwo', + output + ) + self.log.error( + 'install_iwo', + error + ) + + return True + + def create_intersight_target(self, iaccount, device_identifier, security_token): + asset_handler = asset_device_registration.AssetDeviceRegistration(iaccount, log_id=self.log_id) + success = asset_handler.create_target( + device_identifier, + security_token + ) + if not success: + self.my_output.error('Intersight target create failed') + return False + + self.my_output.default('Intersight target created') + return True + + def create(self, cluster_name, iaccount, chart_filename): + self.my_output.default('Check OCP cluster') + cluster_parameters = self.ocp_settings_handler.get_ocp_cluster_parameters(cluster_name) + if cluster_parameters is None: + return False + + if self.is_iwo_installed(cluster_parameters): + self.my_output.default('IWO is already installed') + else: + self.my_output.default('Check IWO chart') + chart_values = self.get_chart_values(chart_filename) + if chart_values is None: + return False + + self.my_output.default('Upload IWO chart') + destination_chart_filename = self.upload_chart(chart_filename, cluster_parameters) + if destination_chart_filename is None: + return False + + variables = self.generate_create_variables(destination_chart_filename, cluster_parameters, chart_values) + + self.my_output.default('Install IWO from chart') + if not self.install_iwo(cluster_parameters, variables): + return False + + self.my_output.default('Collect device identifier') + device_identifier = self.get_install_device_identifier(cluster_parameters) + if device_identifier is None: + return False + + self.my_output.default('Collect security token') + security_token = self.get_security_token(cluster_parameters) + if security_token is None: + return False + + self.my_output.default('Create Intersight Target') + if self.is_intersight_target(iaccount, device_identifier): + self.my_output.default('Intersight target already defined') + else: + if not self.create_intersight_target(iaccount, device_identifier, security_token): + return False + + iwo_parameters = {} + iwo_parameters['iaccount'] = iaccount + iwo_parameters['device_identifier'] = device_identifier + iwo_parameters['security_token'] = security_token + iwo_parameters['registration_id'] = self.get_intersight_target_moid(iaccount, device_identifier) + iwo_parameters['claim_id'] = self.get_intersight_target_claim(iaccount, device_identifier) + if not self.set_iwo_installed(cluster_parameters, iwo_parameters): + return False + + if not self.ocp_settings_handler.set_ocp_cluster_parameter(cluster_name, 'iwo', iwo_parameters): + self.my_output.error('OCP cluster iwo settings failed') + return False + self.my_output.default('OCP cluster iwo settings set') + + return True diff --git a/lib/iwo/lcm/ocp/delete.py b/lib/iwo/lcm/ocp/delete.py new file mode 100644 index 00000000..56118b43 --- /dev/null +++ b/lib/iwo/lcm/ocp/delete.py @@ -0,0 +1,141 @@ +import json +import uuid + +from lib.intersight import asset_device_registration +from lib import ssh + + +class IwoOcpDeleteLcm(): + def __init__(self): + pass + + def delete_iwo_install_finished(self, cluster_parameters): + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + filename = '/root/.iwo_installed' + if ssh_handler.is_file(filename): + if not ssh_handler.delete_file(filename): + self.my_output.error('Post installation flag delete failed') + return False + self.my_output.default('IWO installation complete flag deleted') + return True + + def uninstall_iwo(self, cluster_parameters, variables): + filename = self.get_template_filename('uninstall.sh') + if filename is None: + self.log.error( + 'uninstall_iwo', + 'Uninstallation template not found' + ) + return False + + content = self.get_template_content(filename, variables) + if content is None: + self.log.error( + 'uninstall_iwo', + 'Uninstallation template preparation failed' + ) + return False + + script_source = '/tmp/%s' % (str(uuid.uuid4())) + with open(script_source, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + success = ssh_handler.run_file_upload( + script_source, + '/root/iwo_uninstall.sh', + 744 + ) + if not success: + self.log.error( + 'uninstall_iwo', + 'Uninstallation script upload failed' + ) + + success, output, error = ssh_handler.run_cmd( + 'dos2unix /root/iwo_uninstall.sh', + live_output=False + ) + if not success: + self.log.error( + 'uninstall_iwo', + 'Unnstallation script preparation failed' + ) + + success, output, error = ssh_handler.run_cmd( + './iwo_uninstall.sh', + live_output=True + ) + if not success: + self.log.error( + 'uninstall_iwo', + 'Uninstallation script failed' + ) + + return True + + def generate_delete_variables(self, cluster_parameters): + variables = {} + variables['NAMESPACE'] = 'iwo-collector' + variables['POD'] = 'my-iwo-k8s-collector' + + self.log.debug( + 'generate_delete_variables', + json.dumps(variables, indent=4) + ) + + return variables + + def delete_intersight_target(self, iaccount, cluster_parameters): + device_identifier = self.get_install_device_identifier(cluster_parameters) + if device_identifier is None: + self.my_output.info('Target serial number not found - target is unlikely to exist') + return True + + target_moid = self.get_intersight_target_claim(iaccount, device_identifier) + if target_moid is None: + self.my_output.default('No target found with serial: %s' % (device_identifier)) + return True + + asset_handler = asset_device_registration.AssetDeviceRegistration(iaccount, log_id=self.log_id) + success = asset_handler.delete_target(target_moid) + if not success: + self.my_output.error('Target delete failed: %s' % (target_moid)) + return False + + self.my_output.default('Target deleted: %s' % (target_moid)) + return True + + def delete(self, cluster_name, iaccount): + self.my_output.default('Check OCP cluster') + cluster_parameters = self.ocp_settings_handler.get_ocp_cluster_parameters(cluster_name) + if cluster_parameters is None: + return False + + variables = self.generate_delete_variables(cluster_parameters) + + self.my_output.default('Uninstall') + if not self.uninstall_iwo(cluster_parameters, variables): + return False + + self.my_output.default('Delete Intersight Target') + if not self.delete_intersight_target(iaccount, cluster_parameters): + return False + + if not self.delete_iwo_install_finished(cluster_parameters): + return False + + if not self.ocp_settings_handler.set_ocp_cluster_parameter(cluster_name, 'iwo', None): + self.my_output.error('OCP cluster iwo settings failed') + return False + self.my_output.default('OCP cluster iwo settings cleared') + + return True diff --git a/lib/iwo/lcm/ocp/get.py b/lib/iwo/lcm/ocp/get.py new file mode 100644 index 00000000..92c82110 --- /dev/null +++ b/lib/iwo/lcm/ocp/get.py @@ -0,0 +1,212 @@ +import json +import uuid + +from lib import ssh +from lib.intersight import asset_device_registration + + +class IwoOcpGetLcm(): + def __init__(self): + pass + + def is_iwo_installed(self, cluster_parameters): + if self.get_iwo_installed(cluster_parameters) is None: + return False + return True + + def get_iwo_installed(self, cluster_parameters): + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + source = '/root/.iwo_installed.json' + if not ssh_handler.is_file(source): + return None + + destination = '/tmp/%s' % (str(uuid.uuid4())) + success = ssh_handler.scp_file(source, destination, put=False) + if not success: + self.my_output.error('IWO installation report download failed') + return False + + try: + with open(destination, 'r', encoding='utf-8') as file_handler: + report = json.loads(file_handler.read()) + except BaseException: + self.my_output.error('IWO installation report download failed') + return None + + self.my_output.debug( + 'get_iwo_installed', + json.dumps( + report, + indent=4 + ) + ) + return report + + def set_iwo_installed(self, cluster_parameters, iwo_parameters): + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + source = '/tmp/%s' % (str(uuid.uuid4())) + with open(source, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + iwo_parameters, + indent=4 + ) + ) + + destination = '/root/.iwo_installed.json' + success = ssh_handler.scp_file(source, destination) + if not success: + self.my_output.error('IWO installation report failed') + return False + + self.my_output.default('IWO installation report set') + return True + + def get_install_device_identifier(self, cluster_parameters): + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + filename = '/tmp/iwo_device_identifiers' + if not ssh_handler.is_file(filename): + self.my_output.error('IWO device identifier file not found: %s' % (filename)) + return None + + local_filename = '/tmp/%s' % (str(uuid.uuid4())) + success = ssh_handler.scp_file( + filename, + local_filename, + put=False + ) + if not success: + self.my_output.error('File download failed: %s' % (filename)) + return None + + try: + with open(local_filename, 'rb') as file_handler: + content = json.loads(file_handler.read()) + self.my_output.debug(content) + + except BaseException: + self.my_output.error('File read failed: %s' % (filename)) + return None + + try: + device_identifier = content[0]['Id'] + except BaseException: + self.my_output.error('Unsupported file content: %s' % (filename)) + self.my_output.default( + json.dumps(content, indent=4) + ) + return None + + self.my_output.default('Device identifier: %s' % (device_identifier)) + return device_identifier + + def get_security_token(self, cluster_parameters): + ssh_handler = ssh.Ssh( + cluster_parameters['installer']['vm']['ip'], + cluster_parameters['installer']['vm']['username'], + password=cluster_parameters['installer']['vm']['password'] + ) + filename = '/tmp/iwo_security_tokens' + if not ssh_handler.is_file(filename): + self.my_output.error('IWO security token file not found: %s' % (filename)) + return None + + local_filename = '/tmp/%s' % (str(uuid.uuid4())) + success = ssh_handler.scp_file( + filename, + local_filename, + put=False + ) + if not success: + self.my_output.error('File download failed: %s' % (filename)) + return None + + try: + with open(local_filename, 'rb') as file_handler: + content = json.loads(file_handler.read()) + self.my_output.debug(content) + + except BaseException: + self.my_output.error('File read failed: %s' % (filename)) + return None + + try: + security_token = content[0]['Token'] + except BaseException: + self.my_output.error('Unsupported file content: %s' % (filename)) + return None + + self.my_output.default('Security token: %s' % (security_token)) + return security_token + + def is_intersight_target(self, iaccount, device_identifier): + if self.get_intersight_target_claim(iaccount, device_identifier) is None: + return False + return True + + def get_intersight_target_moid(self, iaccount, device_identifier): + asset_handler = asset_device_registration.AssetDeviceRegistration(iaccount, log_id=self.log_id) + targets = asset_handler.get_all() + for target in targets: + for serial in target['Serial']: + if serial == device_identifier: + return target['Moid'] + return None + + def get_intersight_target_claim(self, iaccount, device_identifier): + asset_handler = asset_device_registration.AssetDeviceRegistration(iaccount, log_id=self.log_id) + targets = asset_handler.get_all() + for target in targets: + for serial in target['Serial']: + if serial == device_identifier: + return target['DeviceClaim']['Moid'] + return None + + def get_lcm_state(self, installation_report): + state = {} + state['__Output'] = {} + state['installed'] = False + state['installedTick'] = '\u2717' + state['__Output']['installedTick'] = 'Red' + state['connected'] = False + state['connectedTick'] = '\u2717' + state['__Output']['connectedTick'] = 'Red' + state['hostname'] = [] + state['ips'] = [] + + if installation_report is None: + return state + + state['installed'] = True + state['installedTick'] = '\u2713' + state['__Output']['installedTick'] = 'Green' + + asset_handler = asset_device_registration.AssetDeviceRegistration( + installation_report['iaccount'], + log_id=self.log_id + ) + device_registration = asset_handler.get( + installation_report['registration_id'] + ) + if device_registration is not None: + state['target'] = device_registration + if device_registration['ConnectionStatus'] == 'Connected': + state['connected'] = False + state['connectedTick'] = '\u2713' + state['__Output']['connectedTick'] = 'Green' + state['hostname'] = device_registration['DeviceHostname'] + state['ips'] = device_registration['DeviceIpAddress'] + + return state diff --git a/lib/iwo/lcm/ocp/main.py b/lib/iwo/lcm/ocp/main.py new file mode 100644 index 00000000..f78d8572 --- /dev/null +++ b/lib/iwo/lcm/ocp/main.py @@ -0,0 +1,16 @@ +from lib.ocp import settings as ocp_settings + +from lib.iwo.lcm.ocp.get import IwoOcpGetLcm +from lib.iwo.lcm.ocp.template import IwoOcpTemplateLcm +from lib.iwo.lcm.ocp.create import IwoOcpCreateLcm +from lib.iwo.lcm.ocp.delete import IwoOcpDeleteLcm + + +class IwoOcpLcm(IwoOcpTemplateLcm, IwoOcpGetLcm, IwoOcpCreateLcm, IwoOcpDeleteLcm): + def __init__(self): + IwoOcpGetLcm.__init__(self) + IwoOcpTemplateLcm.__init__(self) + IwoOcpCreateLcm.__init__(self) + IwoOcpDeleteLcm.__init__(self) + + self.ocp_settings_handler = ocp_settings.OcpSettings(log_id=self.log_id) diff --git a/lib/iwo/lcm/ocp/template.py b/lib/iwo/lcm/ocp/template.py new file mode 100644 index 00000000..604b3277 --- /dev/null +++ b/lib/iwo/lcm/ocp/template.py @@ -0,0 +1,53 @@ +import os +import sys + +from lib import file_helper +from lib import template + + +class IwoOcpTemplateLcm(): + def __init__(self): + self.template_handler = template.Template( + debug=False + ) + + def get_template_dir(self): + template_dir = os.path.join( + os.path.join( + os.path.join( + file_helper.get_main_dir(), + 'templates' + ), + 'iwo' + ), + 'ocp' + ) + return template_dir + + def get_template_filename(self, filename): + files_dir = os.path.join( + self.get_template_dir(), + 'files' + ) + template_filename = os.path.join(files_dir, filename) + if not os.path.isfile(template_filename): + self.my_output.error('Template file not found: %s' % (template_filename)) + return None + + return template_filename + + def get_template_content(self, filename, variables): + template_filename = self.get_template_filename(filename) + if template_filename is None: + return None + + content = self.template_handler.get_template( + template_filename, + variables, + check_remaining_variables=False + ) + if content is None: + self.my_output.error('Template failed: %s' % (template_filename)) + return None + + return content diff --git a/lib/iwo/main.py b/lib/iwo/main.py new file mode 100644 index 00000000..687787ff --- /dev/null +++ b/lib/iwo/main.py @@ -0,0 +1,303 @@ +from lib import log_helper +from lib import output_helper + +from lib.iwo.action import IwoAction +from lib.iwo.application import IwoApplication +from lib.iwo.chassis import IwoChassis +from lib.iwo.client import IwoClient +from lib.iwo.cluster import IwoCluster +from lib.iwo.container import IwoContainer +from lib.iwo.dc import IwoDataCenter +from lib.iwo.disk import IwoDisk +from lib.iwo.namespace import IwoNamespace +from lib.iwo.network import IwoNetwork +from lib.iwo.phy import IwoPhysicalMachine +from lib.iwo.pod import IwoPod +from lib.iwo.region import IwoRegion +from lib.iwo.service import IwoService +from lib.iwo.spec import IwoSpec +from lib.iwo.storage import IwoStorage +from lib.iwo.switch import IwoSwitch +from lib.iwo.target import IwoTarget +from lib.iwo.workload import IwoWorkload +from lib.iwo.vdc import IwoVirtualDataCenter +from lib.iwo.vm import IwoVirtualMachine +from lib.iwo.volume import IwoVolume +from lib.iwo.zone import IwoZone + + +class Iwo( + IwoAction, + IwoApplication, + IwoChassis, + IwoClient, + IwoCluster, + IwoContainer, + IwoDataCenter, + IwoDisk, + IwoNamespace, + IwoNetwork, + IwoPhysicalMachine, + IwoPod, + IwoRegion, + IwoService, + IwoSpec, + IwoStorage, + IwoSwitch, + IwoTarget, + IwoWorkload, + IwoVirtualDataCenter, + IwoVirtualMachine, + IwoVolume, + IwoZone + ): + def __init__(self, iaccount, verbose=False, debug=False, log_id=None): + self.verbose = verbose + self.debug = debug + self.log_id = log_id + + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + IwoAction.__init__(self) + IwoApplication.__init__(self) + IwoChassis.__init__(self) + IwoClient.__init__(self, iaccount) + IwoCluster.__init__(self) + IwoContainer.__init__(self) + IwoDataCenter.__init__(self) + IwoDisk.__init__(self) + IwoNamespace.__init__(self) + IwoNetwork.__init__(self) + IwoPhysicalMachine.__init__(self) + IwoPod.__init__(self) + IwoRegion.__init__(self) + IwoService.__init__(self) + IwoSpec.__init__(self) + IwoStorage.__init__(self) + IwoSwitch.__init__(self) + IwoTarget.__init__(self) + IwoWorkload.__init__(self) + IwoVirtualDataCenter.__init__(self) + IwoVirtualMachine.__init__(self) + IwoVolume.__init__(self) + IwoZone.__init__(self) + + def map_state_color(self, state): + if state.lower() == 'active': + return 'Green' + + if state.lower() == 'maintenance': + return 'Yellow' + + return 'Red' + + def map_severity_color(self, severity): + if severity.lower() == 'critical': + return 'Red' + + if severity.lower() == 'major': + return 'Yellow' + + if severity.lower() == 'minor': + return 'Blue' + + return 'Green' + + def map_staleness_color(self, staleness): + if staleness.lower() == 'stale': + return 'Red' + + if staleness.lower() == 'current': + return 'Green' + + return 'Yellow' + + def get_empty_summary(self): + summary = {} + summary['__Output'] = {} + summary['total'] = 0 + summary['active'] = 0 + summary['critical'] = 0 + summary['major'] = 0 + summary['minor'] = 0 + summary['normal'] = 0 + summary['current'] = 0 + summary['stale'] = 0 + summary['state'] = '' + summary['severity'] = '' + summary['connected'] = '' + return summary + + def get_summary(self, managed_objects): + summary = self.get_empty_summary() + summary['total'] = len(managed_objects) + + for managed_object in managed_objects: + if managed_object['state'] == 'ACTIVE': + summary['active'] = summary['active'] + 1 + + if managed_object['severity'] == 'Critical': + summary['critical'] = summary['critical'] + 1 + + if managed_object['severity'] == 'Major': + summary['major'] = summary['major'] + 1 + + if managed_object['severity'] == 'Minor': + summary['minor'] = summary['minor'] + 1 + + if managed_object['severity'] == 'Normal': + summary['normal'] = summary['normal'] + 1 + + if managed_object['staleness'] == 'CURRENT': + summary['current'] = summary['current'] + 1 + + summary['state'] = '%s/%s' % ( + summary['active'], + summary['total'] + ) + + summary['severity'] = '%s/%s/%s/%s' % ( + summary['critical'], + summary['major'], + summary['minor'], + summary['normal'] + ) + summary['__Output']['severity'] = ':' + + if summary['critical'] == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'R'.rjust(len(str(summary['critical'])), 'R') + ) + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + + if summary['major'] == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'Y'.rjust(len(str(summary['major'])), 'Y') + ) + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + + if summary['minor'] == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'B'.rjust(len(str(summary['minor'])), 'B') + ) + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + + if summary['normal'] == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'G'.rjust(len(str(summary['normal'])), 'G') + ) + + summary['connected'] = '%s/%s' % ( + summary['current'], + summary['total'] + ) + + return summary + + def get_severity_summary(self, managed_objects): + critical = 0 + major = 0 + minor = 0 + normal = 0 + for managed_object in managed_objects: + if managed_object['severity'].lower() == 'critical': + critical = critical + 1 + + if managed_object['severity'].lower() == 'major': + major = major + 1 + + if managed_object['severity'].lower() == 'minor': + minor = minor + 1 + + if managed_object['severity'].lower() == 'normal': + normal = normal + 1 + + summary = {} + summary['__Output'] = {} + + summary['severity'] = '%s/%s/%s/%s' % ( + critical, + major, + minor, + normal + ) + + summary['__Output']['severity'] = ':' + if critical == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'R'.rjust(len(str(critical)), 'R') + ) + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + + if major == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'Y'.rjust(len(str(major)), 'Y') + ) + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + + if minor == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'B'.rjust(len(str(minor)), 'B') + ) + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + + if normal == 0: + summary['__Output']['severity'] = '%s.' % (summary['__Output']['severity']) + else: + summary['__Output']['severity'] = '%s%s' % ( + summary['__Output']['severity'], + 'G'.rjust(len(str(normal)), 'G') + ) + + return summary + + def print_summary(self, managed_objects): + summary = self.get_summary(managed_objects) + + order = [ + 'state', + 'severity', + 'connected' + ] + + headers = [ + 'Active', + 'Severity', + 'Current' + ] + + self.my_output.dictionary( + summary, + title='Summary', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/iwo/namespace.py b/lib/iwo/namespace.py new file mode 100644 index 00000000..93f569ea --- /dev/null +++ b/lib/iwo/namespace.py @@ -0,0 +1,65 @@ +import json + + +class IwoNamespace(): + def __init__(self): + self.mo_namespace = None + + def initialize_namespace(self): + body = {} + body['className'] = 'Namespace' + + self.mo_namespace = self.search(body) + if self.mo_namespace is None: + return False + + self.log.iwo_mo( + 'Namespace.attributes', + self.mo_namespace + ) + + return True + + def get_namespace_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_namespaces(self): + if self.mo_namespace is None: + if not self.initialize_namespace(): + self.log.error( + 'get_namespaces', + 'Managed objects must be initialized first' + ) + return None + + namespaces = [] + + for managed_object in self.mo_namespace: + namespace_info = self.get_namespace_info( + managed_object + ) + if namespace_info is not None: + namespaces.append( + namespace_info + ) + + self.log.iwo_mo( + 'Namespace.info', + self.mo_namespace + ) + + return namespaces + + def print_namespaces(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/network.py b/lib/iwo/network.py new file mode 100644 index 00000000..db1be656 --- /dev/null +++ b/lib/iwo/network.py @@ -0,0 +1,65 @@ +import json + + +class IwoNetwork(): + def __init__(self): + self.mo_network = None + + def initialize_network(self): + body = {} + body['className'] = 'Network' + + self.mo_network = self.search(body) + if self.mo_network is None: + return False + + self.log.iwo_mo( + 'Network.attributes', + self.mo_network + ) + + return True + + def get_network_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_networks(self): + if self.mo_network is None: + if not self.initialize_network(): + self.log.error( + 'get_networks', + 'Managed objects must be initialized first' + ) + return None + + networks = [] + + for managed_object in self.mo_network: + network_info = self.get_network_info( + managed_object + ) + if network_info is not None: + networks.append( + network_info + ) + + self.log.iwo_mo( + 'Network.info', + self.mo_network + ) + + return networks + + def print_networks(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/phy.py b/lib/iwo/phy.py new file mode 100644 index 00000000..61ff5be0 --- /dev/null +++ b/lib/iwo/phy.py @@ -0,0 +1,570 @@ +import copy + + +class IwoPhysicalMachine(): + def __init__(self): + self.mo_physical_machine = None + self.physical_machine = None + + def initialize_physical_machine(self): + body = {} + body['className'] = 'PhysicalMachine' + + self.mo_physical_machine = self.search(body) + if self.mo_physical_machine is None: + return False + + self.log.iwo_mo( + 'PhysicalMachine.attributes', + self.mo_physical_machine + ) + + return True + + def get_physical_machine_info(self, managed_object, resolve_dependencies=True): + # { + # "uuid": "74691878199586", + # "displayName": "", + # "className": "PhysicalMachine", + # "environmentType": "ONPREM", + # "discoveredBy": { + # "uuid": "74175664340512", + # "displayName": "6149828e6f72612d301327e8", + # "category": "Hypervisor", + # "type": "vCenter", + # "readonly": false + # }, + # "vendorIds": { + # "6149828e6f72612d301327e8": "host-32744" + # }, + # "state": "ACTIVE", + # "severity": "Normal", + # "severityBreakdown": { + # "NORMAL": 1 + # }, + # "providers": [ + # { + # "uuid": "74691878199569", + # "displayName": "Berlin Lab", + # "className": "DataCenter" + # }, + # { + # "uuid": "74691878199581", + # "displayName": "disk (berlin-esxi-242)", + # "className": "Storage" + # } + # ], + # "consumers": [ + # { + # "uuid": "74691878199590", + # "displayName": "Resources-berlin-esxi-cluster", + # "className": "VirtualDataCenter" + # }, + # { + # "uuid": "74872469331928", + # "displayName": "vCLS-c054ea9e-77b0-4630-be60-759f7606649c", + # "className": "VirtualMachine" + # } + # ], + # "staleness": "STALE" + # }, + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='PhysicalMachine', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['severityFlag'], info['__Output']['severityFlag']) = self.get_actions_severity_flag( + info['actions'] + ) + + info['dataCenterName'] = '' + info['dataCenterId'] = None + info['storage'] = [] + info['switch'] = [] + info['chassis'] = [] + + # Providers + + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'DataCenter': + info['dataCenterName'] = provider['displayName'] + info['dataCenterId'] = provider['uuid'] + + if provider['className'] == 'Storage': + info['storage'].append(provider) + + if provider['className'] == 'Switch': + info['switch'].append(provider) + + if provider['className'] == 'Chassis': + info['chassis'].append(provider) + + if provider['className'] not in ['DataCenter', 'Storage', 'Switch', 'Chassis']: + self.log.error( + 'iwo.phy.get_physical_machine_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + info['storage'] = sorted( + info['storage'], + key=lambda i: i['displayName'] + ) + + # Consumers + + info['virtualMachine'] = [] + info['virtualDataCenter'] = [] + + if 'consumers' in managed_object: + for consumer in managed_object['consumers']: + if consumer['className'] == 'VirtualMachine': + info['virtualMachine'].append(consumer) + + if consumer['className'] == 'VirtualDataCenter': + info['virtualDataCenter'].append(consumer) + + if consumer['className'] not in ['VirtualMachine', 'VirtualDataCenter']: + self.log.error( + 'iwo.phy.get_physical_machine_info', + 'Unrecognized consumer class name: %s' % ( + consumer['className'] + ) + ) + + del info['consumers'] + + info['virtualMachine'] = sorted( + info['virtualMachine'], + key=lambda i: i['displayName'] + ) + + info['virtualDataCenter'] = sorted( + info['virtualDataCenter'], + key=lambda i: i['displayName'] + ) + + if resolve_dependencies: + virtual_machine_match_rules = [] + for virtual_machine in info['virtualMachine']: + virtual_machine['__Output'] = {} + virtual_machine['severity'] = self.get_virtual_machine_severity( + virtual_machine['uuid'] + ) + virtual_machine['__Output']['displayName'] = self.map_severity_color( + virtual_machine['severity'] + ) + virtual_machine_match_rules.append( + 'uuid:%s' % (virtual_machine['uuid']) + ) + + info['virtualMachineSummary'] = self.get_empty_summary() + if len(virtual_machine_match_rules) > 0: + summary = self.get_virtual_machines_summary( + match_rules=virtual_machine_match_rules + ) + + info['virtualMachineSummary'] = copy.deepcopy(summary) + info['__Output']['virtualMachineSummary.severity'] = summary['__Output']['severity'] + + virtual_data_center_rules = [] + for virtual_data_center in info['virtualDataCenter']: + virtual_data_center['__Output'] = {} + virtual_data_center['severity'] = self.get_virtual_data_center_severity( + virtual_data_center['uuid'] + ) + virtual_data_center['__Output']['displayName'] = self.map_severity_color( + virtual_data_center['severity'] + ) + virtual_data_center_rules.append( + 'uuid:%s' % (virtual_data_center['uuid']) + ) + + info['virtualDataCenterSummary'] = self.get_empty_summary() + if len(virtual_data_center_rules) > 0: + summary = self.get_virtual_data_centers_summary( + match_rules=virtual_data_center_rules + ) + + info['virtualDataCenterSummary'] = copy.deepcopy(summary) + info['__Output']['virtualDataCenterSummary.severity'] = summary['__Output']['severity'] + + storage_rules = [] + for storage in info['storage']: + storage['__Output'] = {} + storage['severity'] = self.get_storage_severity( + storage['uuid'] + ) + storage['__Output']['displayName'] = self.map_severity_color( + storage['severity'] + ) + storage_rules.append( + 'uuid:%s' % (storage['uuid']) + ) + + info['storageSummary'] = self.get_empty_summary() + if len(storage_rules) > 0: + summary = self.get_storages_summary( + match_rules=storage_rules + ) + + info['storageSummary'] = copy.deepcopy(summary) + info['__Output']['storageSummary.severity'] = summary['__Output']['severity'] + + return info + + def match_physical_machine(self, physical_machine_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + match = False + for match_rule in match_rules: + if match_rule.startswith('uuid:'): + if physical_machine_info['uuid'] == match_rule[5:]: + match = True + break + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in physical_machine_info['displayName'].lower(): + match = True + break + + if match_rule.startswith('vm:'): + for vm_info in physical_machine_info['virtualMachine']: + if match_rule[3:].lower() in vm_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule.startswith('vdc:'): + for vdc_info in physical_machine_info['virtualDataCenter']: + if match_rule[4:].lower() in vdc_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule.startswith('storage:'): + for storage_info in physical_machine_info['storage']: + if match_rule[8:].lower() in storage_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule == 'stale': + if physical_machine_info['isStale']: + match = True + break + + if match_rule == 'inactive': + if not physical_machine_info['isActive']: + match = True + break + + if match_rule == 'critical': + if physical_machine_info['severity'].lower() in ['critical']: + match = True + break + + if match_rule == 'major': + if physical_machine_info['severity'].lower() in ['critical', 'major']: + match = True + break + + if match_rule == 'minor': + if physical_machine_info['severity'].lower() in ['critical', 'major', 'minor']: + match = True + break + + return match + + def get_physical_machine(self, physical_machine_uuid, resolve_dependencies=False): + if self.physical_machine is None: + self.physical_machine = self.get_physical_machines(resolve_dependencies=resolve_dependencies) + + if self.physical_machine is not None: + for physical_machine in self.physical_machine: + if physical_machine['uuid'] == physical_machine_uuid: + return physical_machine + + return None + + def get_physical_machine_severity(self, physical_machine_uuid, resolve_dependencies=False): + physical_machine = self.get_physical_machine( + physical_machine_uuid, + resolve_dependencies=resolve_dependencies + ) + if physical_machine is not None: + return physical_machine['severity'] + return None + + def get_physical_machines(self, resolve_dependencies=False, match_rules=None): + if self.mo_physical_machine is None: + if not self.initialize_physical_machine(): + self.log.error( + 'get_physical_machines', + 'Managed objects must be initialized first' + ) + return None + + physical_machines = [] + + for managed_object in self.mo_physical_machine: + physical_machine_info = self.get_physical_machine_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if physical_machine_info is not None: + if not self.match_physical_machine(physical_machine_info, match_rules): + continue + + physical_machines.append( + physical_machine_info + ) + + self.log.iwo_mo( + 'PhysicalMachine.info', + physical_machines + ) + + return physical_machines + + def get_physical_machines_summary(self, match_rules=None): + physical_machines = self.get_physical_machines( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if physical_machines is not None: + summary = self.get_summary(physical_machines) + + return summary + + def print_physical_machines_actions(self, phys): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.type', + 'dataCenterName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Physical Machine Name', + 'Location', + 'Type', + 'Data Center' + ] + + for phy in phys: + if len(phy['actionsList']) == 0: + continue + + self.my_output.my_table( + [phy], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + action_order = [ + 'severity', + 'description', + 'subCategory', + 'details' + ] + + action_headers = [ + 'Severity', + 'Description', + 'Category', + 'Details' + ] + + self.my_output.my_table( + phy['actionsList'], + order=action_order, + headers=action_headers, + allow_order_subkeys=True, + table=True + ) + + def print_physical_machines_no_dep(self, phys): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.type', + 'dataCenterName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Physical Machine Name', + 'Location', + 'Type', + 'Data Center' + ] + + self.my_output.my_table( + phys, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_physical_machines(self, info, show_dep=False, show_actions=False, show_vm=False, show_vdc=False, show_storage=False, summary=True): + if summary: + self.print_summary(info) + + if not show_dep: + self.print_physical_machines_no_dep(info) + return + + if show_actions: + self.print_physical_machines_actions(info) + return + + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Name' + ] + + if not show_vm and not show_vdc and not show_storage: + order = order + [ + 'environmentType', + 'discoveredBy.type', + 'dataCenterName', + 'storageSummary.severity', + 'virtualMachineSummary.severity', + 'virtualDataCenterSummary.severity' + ] + + headers = headers + [ + 'Location', + 'Type', + 'Data Center', + 'Storage', + 'Virtual Machine', + 'Virtual Data Center' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + return + + expand_list = [] + + if show_vm: + order = order + [ + 'virtualMachineSummary.severity', + 'virtualMachine.displayName' + ] + + headers = headers + [ + 'Virtual Machine Severity', + 'Virtual Machine' + ] + + expand_list.append('virtualMachine') + + if show_vdc: + order = order + [ + 'virtualDataCenterSummary.severity', + 'virtualDataCenter.displayName' + ] + + headers = headers + [ + 'VDC Severity', + 'VDC' + ] + + expand_list.append('virtualDataCenter') + + if show_storage: + order = order + [ + 'storageSummary.severity', + 'storage.displayName' + ] + + headers = headers + [ + 'Storage Severity', + 'Storage' + ] + + expand_list.append('storage') + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + expand_list + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) diff --git a/lib/iwo/pod.py b/lib/iwo/pod.py new file mode 100644 index 00000000..7bea21c9 --- /dev/null +++ b/lib/iwo/pod.py @@ -0,0 +1,333 @@ +import json + + +class IwoPod(): + def __init__(self): + self.mo_pod = None + self.pod = None + + def initialize_pod(self): + body = {} + body['className'] = 'ContainerPod' + + self.mo_pod = self.search(body) + if self.mo_pod is None: + return False + + self.log.iwo_mo( + 'ContainerPod.attributes', + self.mo_pod + ) + + return True + + def get_pod_info(self, managed_object, resolve_dependencies=False): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['severityFlag'] = self.map_severity_color( + info['severity'] + ) + + info['severityFlag'] = info['severity'] + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + info['isStale'] = False + if info['staleness'] == 'STALE': + info['isStale'] = True + + info['isActive'] = False + if info['state'] == 'ACTIVE': + info['isActive'] = True + + # Providers + + info['workload'] = [] + info['vm'] = [] + info['namespace'] = [] + info['volume'] = [] + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'Namespace': + info['namespace'].append( + provider + ) + + if provider['className'] == 'WorkloadController': + info['workload'].append( + provider + ) + + if provider['className'] == 'VirtualMachine': + info['vm'].append( + provider + ) + + if provider['className'] == 'VirtualVolume': + info['volume'].append( + provider + ) + + if provider['className'] not in ['WorkloadController', 'VirtualMachine', 'Namespace', 'VirtualVolume']: + self.log.error( + 'iwo.get_pod_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + # Consumers + + info['container'] = [] + if 'consumers' in managed_object: + for consumer in managed_object['consumers']: + if consumer['className'] == 'Container': + info['container'].append( + consumer + ) + + if consumer['className'] == 'WorkloadController': + found = False + for workload in info['workload']: + if workload['uuid'] == consumer['uuid']: + found = True + + if not found: + info['workload'].append( + consumer + ) + + if consumer['className'] == 'VirtualMachine': + found = False + for vm_info in info['vm']: + if vm_info['uuid'] == consumer['uuid']: + found = True + + if not found: + info['vm'].append( + consumer + ) + + if consumer['className'] not in ['WorkloadController', 'VirtualMachine', 'Container']: + self.log.error( + 'iwo.get_pod_info', + 'Unrecognized consumer class name: %s' % ( + consumer['className'] + ) + ) + + del info['consumers'] + + info['container'] = sorted( + info['container'], + key=lambda i: i['displayName'] + ) + + info['namespace'] = sorted( + info['namespace'], + key=lambda i: i['displayName'] + ) + + info['volume'] = sorted( + info['volume'], + key=lambda i: i['displayName'] + ) + + info['workload'] = sorted( + info['workload'], + key=lambda i: i['displayName'] + ) + + info['vm'] = sorted( + info['vm'], + key=lambda i: i['displayName'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='Service', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['actionsSeverity'], info['__Output']['actionsSeverity']) = self.get_action_severity_summary( + info['actions'] + ) + + if resolve_dependencies: + workload_match_rules = [] + for workload in info['workload']: + workload['__Output'] = {} + workload['severity'] = self.get_workload_severity( + workload['uuid'] + ) + workload['__Output']['displayName'] = self.map_severity_color( + workload['severity'] + ) + workload_match_rules.append( + 'uuid:%s' % (workload['uuid']) + ) + + info['workloadSummary'] = self.get_severity_summary( + info['workload'] + ) + info['__Output']['workloadSummary.severity'] = info['workloadSummary']['__Output']['severity'] + + vm_match_rules = [] + for vm_info in info['vm']: + vm_info['__Output'] = {} + vm_info['severity'] = self.get_virtual_machine_severity( + vm_info['uuid'] + ) + vm_info['__Output']['displayName'] = self.map_severity_color( + vm_info['severity'] + ) + vm_match_rules.append( + 'uuid:%s' % (vm_info['uuid']) + ) + + info['vmSummary'] = self.get_severity_summary( + info['vm'] + ) + info['__Output']['vmSummary.severity'] = info['vmSummary']['__Output']['severity'] + + return info + + def match_pod(self, pod_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + rules = {} + for match_rule in match_rules: + rules[match_rule] = False + + if match_rule.startswith('uuid:'): + if pod_info['uuid'] == match_rule[5:]: + rules[match_rule] = True + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in pod_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('cluster:'): + if match_rule[8:].lower() in pod_info['discoveredBy']['displayName'].lower(): + rules[match_rule] = True + + if match_rule == 'stale': + if pod_info['isStale']: + rules[match_rule] = True + + if match_rule == 'inactive': + if not pod_info['isActive']: + rules[match_rule] = True + + if match_rule == 'critical': + if pod_info['severity'].lower() in ['critical']: + rules[match_rule] = True + + if match_rule == 'major': + if pod_info['severity'].lower() in ['critical', 'major']: + rules[match_rule] = True + + if match_rule == 'minor': + if pod_info['severity'].lower() in ['critical', 'major', 'minor']: + rules[match_rule] = True + + match = True + for rule in rules: + match = match and rules[rule] + + return match + + def get_pods(self, resolve_dependencies=False, match_rules=None): + if self.mo_pod is None: + if not self.initialize_pod(): + self.log.error( + 'get_pods', + 'Managed objects must be initialized first' + ) + return None + + pods = [] + + for managed_object in self.mo_pod: + pod_info = self.get_pod_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if pod_info is not None: + if not self.match_pod(pod_info, match_rules): + continue + + pods.append( + pod_info + ) + + self.log.iwo_mo( + 'ContainerPod.info', + self.mo_pod + ) + + return pods + + def get_pod(self, pod_uuid, resolve_dependencies=False): + if self.pod is None: + self.pod = self.get_pods(resolve_dependencies=resolve_dependencies) + + if self.pod is not None: + for pod in self.pod: + if pod['uuid'] == pod_uuid: + return pod + + return None + + def get_pod_severity(self, pod_uuid, resolve_dependencies=False): + pod = self.get_pod( + pod_uuid, + resolve_dependencies=resolve_dependencies + ) + if pod is not None: + return pod['severity'] + return None + + def get_pods_summary(self, match_rules=None): + pods = self.get_pods( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if pods is not None: + summary = self.get_summary(pods) + + return summary + + def print_pods(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/region.py b/lib/iwo/region.py new file mode 100644 index 00000000..dafade20 --- /dev/null +++ b/lib/iwo/region.py @@ -0,0 +1,65 @@ +import json + + +class IwoRegion(): + def __init__(self): + self.mo_region = None + + def initialize_region(self): + body = {} + body['className'] = 'Region' + + self.mo_region = self.search(body) + if self.mo_region is None: + return False + + self.log.iwo_mo( + 'Region.attributes', + self.mo_region + ) + + return True + + def get_region_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_regions(self): + if self.mo_region is None: + if not self.initialize_region(): + self.log.error( + 'get_regions', + 'Managed objects must be initialized first' + ) + return None + + regions = [] + + for managed_object in self.mo_region: + region_info = self.get_region_info( + managed_object + ) + if region_info is not None: + regions.append( + region_info + ) + + self.log.iwo_mo( + 'Region.info', + self.mo_region + ) + + return regions + + def print_regions(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/service.py b/lib/iwo/service.py new file mode 100644 index 00000000..0b63c300 --- /dev/null +++ b/lib/iwo/service.py @@ -0,0 +1,363 @@ +class IwoService(): + def __init__(self): + self.mo_service = None + self.service = None + + def initialize_service(self): + body = {} + body['className'] = 'Service' + + self.mo_service = self.search(body) + if self.mo_service is None: + return False + + self.log.iwo_mo( + 'Service.attributes', + self.mo_service + ) + + return True + + def get_service_info(self, managed_object, resolve_dependencies=False): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['severityFlag'] = self.map_severity_color( + info['severity'] + ) + + info['severityFlag'] = info['severity'] + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + info['isStale'] = False + if info['staleness'] == 'STALE': + info['isStale'] = True + + info['isActive'] = False + if info['state'] == 'ACTIVE': + info['isActive'] = True + + # Providers + + info['application'] = [] + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'ApplicationComponent': + info['application'].append( + provider + ) + + if provider['className'] not in ['ApplicationComponent']: + self.log.error( + 'iwo.get_service_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + info['application'] = sorted( + info['application'], + key=lambda i: i['displayName'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='Service', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['actionsSeverity'], info['__Output']['actionsSeverity']) = self.get_action_severity_summary( + info['actions'] + ) + + if resolve_dependencies: + application_match_rules = [] + for application in info['application']: + application['__Output'] = {} + application['severity'] = self.get_application_severity( + application['uuid'] + ) + application['__Output']['displayName'] = self.map_severity_color( + application['severity'] + ) + application_match_rules.append( + 'uuid:%s' % (application['uuid']) + ) + + info['applicationSummary'] = self.get_severity_summary( + info['application'] + ) + info['__Output']['applicationSummary.severity'] = info['applicationSummary']['__Output']['severity'] + + return info + + def match_service(self, service_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + rules = {} + for match_rule in match_rules: + rules[match_rule] = False + + if match_rule.startswith('uuid:'): + if service_info['uuid'] == match_rule[5:]: + rules[match_rule] = True + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in service_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('cluster:'): + if match_rule[8:].lower() in service_info['discoveredBy']['displayName'].lower(): + rules[match_rule] = True + + if match_rule.startswith('app:'): + for app_info in service_info['application']: + if match_rule[4:].lower() in app_info['displayName'].lower(): + rules[match_rule] = True + + if match_rule == 'stale': + if service_info['isStale']: + rules[match_rule] = True + + if match_rule == 'inactive': + if not service_info['isActive']: + rules[match_rule] = True + + if match_rule == 'critical': + if service_info['severity'].lower() in ['critical']: + rules[match_rule] = True + + if match_rule == 'major': + if service_info['severity'].lower() in ['critical', 'major']: + rules[match_rule] = True + + if match_rule == 'minor': + if service_info['severity'].lower() in ['critical', 'major', 'minor']: + rules[match_rule] = True + + match = True + for rule in rules: + match = match and rules[rule] + + return match + + def get_services(self, resolve_dependencies=False, match_rules=None): + if self.mo_service is None: + if not self.initialize_service(): + self.log.error( + 'get_services', + 'Managed objects must be initialized first' + ) + return None + + services = [] + + for managed_object in self.mo_service: + service_info = self.get_service_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if service_info is not None: + if not self.match_service(service_info, match_rules): + continue + + services.append( + service_info + ) + + self.log.iwo_mo( + 'Service.info', + services + ) + + return services + + def get_service(self, service_uuid, resolve_dependencies=False): + if self.service is None: + self.service = self.get_services(resolve_dependencies=resolve_dependencies) + + if self.service is not None: + for service in self.service: + if service['uuid'] == service_uuid: + return service + + return None + + def get_service_severity(self, service_uuid, resolve_dependencies=False): + service = self.get_service( + service_uuid, + resolve_dependencies=resolve_dependencies + ) + if service is not None: + return service['severity'] + return None + + def get_services_summary(self, match_rules=None): + services = self.get_services( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if services is not None: + summary = self.get_summary(services) + + return summary + + def print_services_base(self, services): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Service Name' + ] + + self.my_output.my_table( + services, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_services_actions(self, services): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.displayName', + 'applicationSummary.severity' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Service Name', + 'Location', + 'Kubernetes', + 'Application' + ] + + for service in services: + if len(service['actionsList']) == 0: + continue + + self.my_output.my_table( + [service], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + action_order = [ + 'severity', + 'description', + 'subCategory', + 'details' + ] + + action_headers = [ + 'Severity', + 'Description', + 'Category', + 'Details' + ] + + self.my_output.my_table( + service['actionsList'], + order=action_order, + headers=action_headers, + allow_order_subkeys=True, + table=True + ) + + def print_services_apps(self, services): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'actionsSeverity', + 'discoveredBy.displayName', + 'displayName', + 'applicationSummary.severity', + 'application.displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Actions', + 'Cluster', + 'Service Name', + 'Application Severity', + 'Application' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + services, + order, + ['application'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_services(self, services, show_actions=False, show_app=False, summary=True): + if summary: + self.print_summary(services) + + if not show_actions and not show_app: + self.print_services_base(services) + return + + if show_actions: + self.print_services_actions(services) + return + + if show_app: + self.print_services_apps(services) + return diff --git a/lib/iwo/spec.py b/lib/iwo/spec.py new file mode 100644 index 00000000..7aeeebf8 --- /dev/null +++ b/lib/iwo/spec.py @@ -0,0 +1,65 @@ +import json + + +class IwoSpec(): + def __init__(self): + self.mo_spec = None + + def initialize_spec(self): + body = {} + body['className'] = 'ContainerSpec' + + self.mo_spec = self.search(body) + if self.mo_spec is None: + return False + + self.log.iwo_mo( + 'ContainerSpec.attributes', + self.mo_spec + ) + + return True + + def get_spec_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_specs(self): + if self.mo_spec is None: + if not self.initialize_spec(): + self.log.error( + 'get_specs', + 'Managed objects must be initialized first' + ) + return None + + specs = [] + + for managed_object in self.mo_spec: + spec_info = self.get_spec_info( + managed_object + ) + if spec_info is not None: + specs.append( + spec_info + ) + + self.log.iwo_mo( + 'ContainerSpec.info', + self.mo_spec + ) + + return specs + + def print_specs(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/storage.py b/lib/iwo/storage.py new file mode 100644 index 00000000..68beb58c --- /dev/null +++ b/lib/iwo/storage.py @@ -0,0 +1,506 @@ +import copy + + +class IwoStorage(): + def __init__(self): + self.mo_storage = None + self.storage = None + + def initialize_storage(self): + body = {} + body['className'] = 'Storage' + + self.mo_storage = self.search(body) + if self.mo_storage is None: + return False + + self.log.iwo_mo( + 'Storage.attributes', + self.mo_storage + ) + + return True + + def get_storage_info(self, managed_object, resolve_dependencies=False): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + info['isStale'] = False + if info['staleness'] == 'STALE': + info['isStale'] = True + + info['isActive'] = False + if info['state'] == 'ACTIVE': + info['isActive'] = True + + # Providers + + info['diskArray'] = [] + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'DiskArray': + info['diskArray'].append( + provider + ) + + if provider['className'] not in ['DiskArray']: + self.log.error( + 'iwo.get_storage_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + info['diskArrayCount'] = len( + info['diskArray'] + ) + + # Consumers + + info['virtualMachine'] = [] + info['physicalMachine'] = [] + if 'consumers' in managed_object: + for consumer in managed_object['consumers']: + if consumer['className'] == 'VirtualMachine': + info['virtualMachine'].append(consumer) + + if consumer['className'] == 'PhysicalMachine': + info['physicalMachine'].append(consumer) + + if consumer['className'] not in ['VirtualMachine', 'PhysicalMachine']: + self.log.error( + 'iwo.get_storage_info', + 'Unrecognized consumer class name: %s' % ( + consumer['className'] + ) + ) + + del info['consumers'] + + info['virtualMachine'] = sorted( + info['virtualMachine'], + key=lambda i: i['displayName'] + ) + + info['physicalMachine'] = sorted( + info['physicalMachine'], + key=lambda i: i['displayName'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='Storage', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['severityFlag'], info['__Output']['severityFlag']) = self.get_actions_severity_flag( + info['actions'] + ) + + if resolve_dependencies: + physical_machine_match_rules = [] + for physical_machine in info['physicalMachine']: + physical_machine['__Output'] = {} + physical_machine['severity'] = self.get_physical_machine_severity( + physical_machine['uuid'] + ) + physical_machine['__Output']['displayName'] = self.map_severity_color( + physical_machine['severity'] + ) + physical_machine_match_rules.append( + 'uuid:%s' % (physical_machine['uuid']) + ) + + info['physicalMachineSummary'] = self.get_empty_summary() + if len(physical_machine_match_rules) > 0: + summary = self.get_physical_machines_summary( + match_rules=physical_machine_match_rules + ) + + info['physicalMachineSummary'] = copy.deepcopy(summary) + info['__Output']['physicalMachineSummary.severity'] = summary['__Output']['severity'] + + virtual_machine_match_rules = [] + for virtual_machine in info['virtualMachine']: + virtual_machine['__Output'] = {} + virtual_machine['severity'] = self.get_virtual_machine_severity( + virtual_machine['uuid'] + ) + virtual_machine['__Output']['displayName'] = self.map_severity_color( + virtual_machine['severity'] + ) + virtual_machine_match_rules.append( + 'uuid:%s' % (virtual_machine['uuid']) + ) + + info['virtualMachineSummary'] = self.get_empty_summary() + if len(virtual_machine_match_rules) > 0: + summary = self.get_virtual_machines_summary( + match_rules=virtual_machine_match_rules + ) + + info['virtualMachineSummary'] = copy.deepcopy(summary) + info['__Output']['virtualMachineSummary.severity'] = summary['__Output']['severity'] + + return info + + def match_storage(self, storage_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + match = False + for match_rule in match_rules: + if match_rule.startswith('uuid:'): + if storage_info['uuid'] == match_rule[5:]: + match = True + break + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in storage_info['displayName'].lower(): + match = True + break + + if match_rule.startswith('vm:'): + for vm_info in storage_info['virtualMachine']: + if match_rule[3:].lower() in vm_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule.startswith('phy:'): + for phy_info in storage_info['physicalMachine']: + if match_rule[4:].lower() in phy_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule == 'stale': + if storage_info['isStale']: + match = True + break + + if match_rule == 'inactive': + if not storage_info['isActive']: + match = True + break + + if match_rule == 'critical': + if storage_info['severity'].lower() in ['critical']: + match = True + break + + if match_rule == 'major': + if storage_info['severity'].lower() in ['critical', 'major']: + match = True + break + + if match_rule == 'minor': + if storage_info['severity'].lower() in ['critical', 'major', 'minor']: + match = True + break + + return match + + def get_storages(self, resolve_dependencies=False, match_rules=None): + if self.mo_storage is None: + if not self.initialize_storage(): + self.log.error( + 'get_storages', + 'Managed objects must be initialized first' + ) + return None + + storages = [] + + for managed_object in self.mo_storage: + storage_info = self.get_storage_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if storage_info is not None: + if not self.match_storage(storage_info, match_rules): + continue + + storages.append( + storage_info + ) + + self.log.iwo_mo( + 'Storage.info', + storages + ) + + return storages + + def get_storage(self, storage_uuid, resolve_dependencies=False): + if self.storage is None: + self.storage = self.get_storages(resolve_dependencies=resolve_dependencies) + + if self.storage is not None: + for storage in self.storage: + if storage['uuid'] == storage_uuid: + return storage + + return None + + def get_storage_severity(self, storage_uuid, resolve_dependencies=False): + storage = self.get_storage( + storage_uuid, + resolve_dependencies=resolve_dependencies + ) + if storage is not None: + return storage['severity'] + return None + + def get_storages_summary(self, match_rules=None): + storages = self.get_storages( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if storages is not None: + summary = self.get_summary(storages) + + return summary + + def print_storages_no_dep(self, storages): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.type' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Storage Device Name', + 'Location', + 'Type' + ] + + self.my_output.my_table( + storages, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_storages_actions(self, storages): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.type', + 'diskArrayCount', + 'virtualMachineSummary.severity', + 'physicalMachineSummary.severity' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Storage Device Name', + 'Location', + 'Type', + 'Disk Array', + 'Virtual Machine', + 'Physical Machine' + ] + + for storage in storages: + if len(storage['actionsList']) == 0: + continue + + self.my_output.my_table( + [storage], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + action_order = [ + 'severity', + 'description', + 'subCategory', + 'details' + ] + + action_headers = [ + 'Severity', + 'Description', + 'Category', + 'Details' + ] + + self.my_output.my_table( + storage['actionsList'], + order=action_order, + headers=action_headers, + allow_order_subkeys=True, + table=True + ) + + def print_storages(self, storages, show_dep=False, show_actions=False, show_vm=False, show_phy=False, summary=True): + if summary: + self.print_summary(storages) + + if not show_dep: + self.print_storages_no_dep(storages) + return + + if show_actions: + self.print_storages_actions(storages) + return + + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Name' + ] + + if not show_vm and not show_phy: + order = order + [ + 'environmentType', + 'discoveredBy.type', + 'diskArrayCount', + 'virtualMachineSummary.severity', + 'physicalMachineSummary.severity' + ] + + headers = headers + [ + 'Location', + 'Type', + 'Disk Array', + 'Virtual Machine', + 'Physical Machine' + ] + + self.my_output.my_table( + storages, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + if show_vm and not show_phy: + order = order + [ + 'virtualMachineSummary.severity', + 'virtualMachine.displayName' + ] + + headers = headers + [ + 'Virtual Machine Severity', + 'Virtual Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + storages, + order, + ['virtualMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + if not show_vm and show_phy: + order = order + [ + 'physicalMachineSummary.severity', + 'physicalMachine.displayName' + ] + + headers = headers + [ + 'Physical Machine Severity', + 'Physical Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + storages, + order, + ['physicalMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + if show_vm and show_phy: + order = order + [ + 'physicalMachineSummary.severity', + 'physicalMachine.displayName', + 'virtualMachineSummary.severity', + 'virtualMachine.displayName' + ] + + headers = headers + [ + 'Physical Machine Severity', + 'Physical Machine', + 'Virtual Machine Severity', + 'Virtual Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + storages, + order, + ['physicalMachine', 'virtualMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) diff --git a/lib/iwo/switch.py b/lib/iwo/switch.py new file mode 100644 index 00000000..fea1b5f0 --- /dev/null +++ b/lib/iwo/switch.py @@ -0,0 +1,65 @@ +import json + + +class IwoSwitch(): + def __init__(self): + self.mo_switch = None + + def initialize_switch(self): + body = {} + body['className'] = 'Switch' + + self.mo_switch = self.search(body) + if self.mo_switch is None: + return False + + self.log.iwo_mo( + 'Switch.attributes', + self.mo_switch + ) + + return True + + def get_switch_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_switchs(self): + if self.mo_switch is None: + if not self.initialize_switch(): + self.log.error( + 'get_switchs', + 'Managed objects must be initialized first' + ) + return None + + switchs = [] + + for managed_object in self.mo_switch: + switch_info = self.get_switch_info( + managed_object + ) + if switch_info is not None: + switchs.append( + switch_info + ) + + self.log.iwo_mo( + 'Switch.info', + self.mo_switch + ) + + return switchs + + def print_switchs(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/target.py b/lib/iwo/target.py new file mode 100644 index 00000000..75c214c5 --- /dev/null +++ b/lib/iwo/target.py @@ -0,0 +1,18 @@ +import json + + +class IwoTarget(): + def __init__(self): + pass + + def get_targets(self): + url = '/wo/api/v3/targets' + return self.get(url) + + def print_targets(self, targets): + self.my_output.default( + json.dumps( + targets, + indent=4 + ) + ) diff --git a/lib/iwo/vdc.py b/lib/iwo/vdc.py new file mode 100644 index 00000000..462cd937 --- /dev/null +++ b/lib/iwo/vdc.py @@ -0,0 +1,525 @@ +import copy + + +class IwoVirtualDataCenter(): + def __init__(self): + self.mo_virtual_data_center = None + self.virtual_data_center = None + + def initialize_virtual_data_center(self): + body = {} + body['className'] = 'VirtualDataCenter' + + self.mo_virtual_data_center = self.search(body) + if self.mo_virtual_data_center is None: + return False + + self.log.iwo_mo( + 'VirtualDataCenter.attributes', + self.mo_virtual_data_center + ) + + return True + + def get_virtual_data_center_info(self, managed_object, resolve_dependencies=False): + # { + # "uuid": "74691878199569", + # "displayName": "Berlin Lab", + # "className": "DataCenter", + # "environmentType": "ONPREM", + # "discoveredBy": { + # "uuid": "74175664340512", + # "displayName": "6149828e6f72612d301327e8", + # "category": "Hypervisor", + # "type": "vCenter", + # "readonly": false + # }, + # "vendorIds": { + # "6149828e6f72612d301327e8": "datacenter-2" + # }, + # "state": "ACTIVE", + # "severity": "Normal", + # "severityBreakdown": { + # "NORMAL": 1 + # }, + # "consumers": [ + # { + # "uuid": "74691878199586", + # "displayName": "", + # "className": "PhysicalMachine" + # } + # ], + # "staleness": "CURRENT" + # } + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + info['isStale'] = False + if info['staleness'] == 'STALE': + info['isStale'] = True + + info['isActive'] = False + if info['state'] == 'ACTIVE': + info['isActive'] = True + + # Providers + + info['physicalMachine'] = [] + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'PhysicalMachine': + info['physicalMachine'].append(provider) + + if provider['className'] not in ['PhysicalMachine', 'VirtualDataCenter']: + self.log.error( + 'iwo.get_virtual_data_center_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + del info['providers'] + + info['physicalMachine'] = sorted( + info['physicalMachine'], + key=lambda i: i['displayName'] + ) + + # Consumers + + info['virtualMachine'] = [] + if 'consumers' in managed_object: + for consumer in managed_object['consumers']: + if consumer['className'] == 'VirtualMachine': + info['virtualMachine'].append(consumer) + + if consumer['className'] not in ['VirtualMachine', 'VirtualDataCenter']: + self.log.error( + 'iwo.get_vdc_info', + 'Unrecognized consumer class name: %s' % ( + consumer['className'] + ) + ) + + del info['consumers'] + + info['virtualMachine'] = sorted( + info['virtualMachine'], + key=lambda i: i['displayName'] + ) + + # Actions + + action_rules = [] + action_rules.append( + 'target_id:%s' % (info['uuid']) + ) + info['actions'] = self.get_actions( + related_class='Storage', + match_rules=action_rules + ) + info['actionsList'] = self.get_actions_list( + info['actions'] + ) + (info['severityFlag'], info['__Output']['severityFlag']) = self.get_actions_severity_flag( + info['actions'] + ) + + if resolve_dependencies: + physical_machine_match_rules = [] + for physical_machine in info['physicalMachine']: + physical_machine['__Output'] = {} + physical_machine['severity'] = self.get_physical_machine_severity( + physical_machine['uuid'] + ) + physical_machine['__Output']['displayName'] = self.map_severity_color( + physical_machine['severity'] + ) + physical_machine_match_rules.append( + 'uuid:%s' % (physical_machine['uuid']) + ) + + info['physicalMachineSummary'] = self.get_empty_summary() + if len(physical_machine_match_rules) > 0: + summary = self.get_physical_machines_summary( + match_rules=physical_machine_match_rules + ) + + info['physicalMachineSummary'] = copy.deepcopy(summary) + info['__Output']['physicalMachineSummary.severity'] = summary['__Output']['severity'] + + virtual_machine_match_rules = [] + for virtual_machine in info['virtualMachine']: + virtual_machine['__Output'] = {} + virtual_machine['severity'] = self.get_virtual_machine_severity( + virtual_machine['uuid'] + ) + virtual_machine['__Output']['displayName'] = self.map_severity_color( + virtual_machine['severity'] + ) + virtual_machine_match_rules.append( + 'uuid:%s' % (virtual_machine['uuid']) + ) + + info['virtualMachineSummary'] = self.get_empty_summary() + if len(virtual_machine_match_rules) > 0: + summary = self.get_virtual_machines_summary( + match_rules=virtual_machine_match_rules + ) + + info['virtualMachineSummary'] = copy.deepcopy(summary) + info['__Output']['virtualMachineSummary.severity'] = summary['__Output']['severity'] + + return info + + def match_virtual_data_center(self, vdc_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + match = False + for match_rule in match_rules: + if match_rule.startswith('uuid:'): + if vdc_info['uuid'] == match_rule[5:]: + match = True + break + + if match_rule.startswith('name:'): + if match_rule[5:].lower() in vdc_info['displayName'].lower(): + match = True + break + + if match_rule.startswith('vm:'): + for vm_info in vdc_info['virtualMachine']: + if match_rule[3:].lower() in vm_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule.startswith('phy:'): + for phy_info in vdc_info['physicalMachine']: + if match_rule[4:].lower() in phy_info['displayName'].lower(): + match = True + break + + if match: + break + + if match_rule == 'stale': + if vdc_info['isStale']: + match = True + break + + if match_rule == 'inactive': + if not vdc_info['isActive']: + match = True + break + + if match_rule == 'critical': + if vdc_info['severity'].lower() in ['critical']: + match = True + break + + if match_rule == 'major': + if vdc_info['severity'].lower() in ['critical', 'major']: + match = True + break + + if match_rule == 'minor': + if vdc_info['severity'].lower() in ['critical', 'major', 'minor']: + match = True + break + + return match + + def get_virtual_data_centers(self, resolve_dependencies=False, match_rules=None): + if self.mo_virtual_data_center is None: + if not self.initialize_virtual_data_center(): + self.log.error( + 'get_virtual_data_centers', + 'Managed objects must be initialized first' + ) + return None + + virtual_data_centers = [] + + for managed_object in self.mo_virtual_data_center: + virtual_data_center_info = self.get_virtual_data_center_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if virtual_data_center_info is not None: + if not self.match_virtual_data_center(virtual_data_center_info, match_rules): + continue + + virtual_data_centers.append( + virtual_data_center_info + ) + + self.log.iwo_mo( + 'VirtualDataCenter.info', + virtual_data_centers + ) + + return virtual_data_centers + + def get_virtual_data_center(self, virtual_data_center_uuid, resolve_dependencies=False): + if self.virtual_data_center is None: + self.virtual_data_center = self.get_virtual_data_centers(resolve_dependencies=resolve_dependencies) + + if self.virtual_data_center is not None: + for virtual_data_center in self.virtual_data_center: + if virtual_data_center['uuid'] == virtual_data_center_uuid: + return virtual_data_center + + return None + + def get_virtual_data_center_severity(self, virtual_data_center_uuid, resolve_dependencies=False): + virtual_data_center = self.get_virtual_data_center( + virtual_data_center_uuid, + resolve_dependencies=resolve_dependencies + ) + if virtual_data_center is not None: + return virtual_data_center['severity'] + return None + + def get_virtual_data_centers_summary(self, match_rules=None): + virtual_data_centers = self.get_virtual_data_centers( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if virtual_data_centers is not None: + summary = self.get_summary(virtual_data_centers) + + return summary + + def print_virtual_data_centers_no_dep(self, vdcs): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.type' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Storage Device Name', + 'Location', + 'Type' + ] + + self.my_output.my_table( + vdcs, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_virtual_data_centers_actions(self, vdcs): + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName', + 'environmentType', + 'discoveredBy.type', + 'diskArrayCount', + 'virtualMachineSummary.severity', + 'physicalMachineSummary.severity' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Storage Device Name', + 'Location', + 'Type', + 'Disk Array', + 'Virtual Machine', + 'Physical Machine' + ] + + for vdc in vdcs: + if len(vdc['actionsList']) == 0: + continue + + self.my_output.my_table( + [vdc], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + action_order = [ + 'severity', + 'description', + 'subCategory', + 'details' + ] + + action_headers = [ + 'Severity', + 'Description', + 'Category', + 'Details' + ] + + self.my_output.my_table( + vdc['actionsList'], + order=action_order, + headers=action_headers, + allow_order_subkeys=True, + table=True + ) + + def print_virtual_data_centers(self, vdcs, show_dep=False, show_actions=False, show_vm=False, show_phy=False, summary=True): + if summary: + self.print_summary(vdcs) + + if not show_dep: + self.print_virtual_data_centers_no_dep(vdcs) + return + + if show_actions: + self.print_virtual_data_centers_actions(vdcs) + return + + order = [ + 'state', + 'severityFlag', + 'staleness', + 'displayName' + ] + + headers = [ + 'State', + 'Severity', + 'Staleness', + 'Name' + ] + + if not show_vm and not show_phy: + order = order + [ + 'environmentType', + 'discoveredBy.type', + 'diskArrayCount', + 'virtualMachineSummary.severity', + 'physicalMachineSummary.severity' + ] + + headers = headers + [ + 'Location', + 'Type', + 'Disk Array', + 'Virtual Machine', + 'Physical Machine' + ] + + self.my_output.my_table( + vdcs, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + if show_vm and not show_phy: + order = order + [ + 'virtualMachineSummary.severity', + 'virtualMachine.displayName' + ] + + headers = headers + [ + 'Virtual Machine Severity', + 'Virtual Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + vdcs, + order, + ['virtualMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + if not show_vm and show_phy: + order = order + [ + 'physicalMachineSummary.severity', + 'physicalMachine.displayName' + ] + + headers = headers + [ + 'Physical Machine Severity', + 'Physical Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + vdcs, + order, + ['physicalMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + if show_vm and show_phy: + order = order + [ + 'physicalMachineSummary.severity', + 'physicalMachine.displayName', + 'virtualMachineSummary.severity', + 'virtualMachine.displayName' + ] + + headers = headers + [ + 'Physical Machine Severity', + 'Physical Machine', + 'Virtual Machine Severity', + 'Virtual Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + vdcs, + order, + ['physicalMachine', 'virtualMachine'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) diff --git a/lib/iwo/vm.py b/lib/iwo/vm.py new file mode 100644 index 00000000..5bcbfb5c --- /dev/null +++ b/lib/iwo/vm.py @@ -0,0 +1,192 @@ +import json + + +class IwoVirtualMachine(): + def __init__(self): + self.mo_virtual_machine = None + + def initialize_virtual_machine(self): + body = {} + body['className'] = 'VirtualMachine' + + self.mo_virtual_machine = self.search(body) + if self.mo_virtual_machine is None: + return False + + self.log.iwo_mo( + 'VirtualMachine.attributes', + self.mo_virtual_machine + ) + + return True + + def get_virtual_machine_info(self, managed_object, resolve_dependencies=True): + # { + # "uuid": "74691878216315", + # "displayName": "client2", + # "className": "VirtualMachine", + # "environmentType": "ONPREM", + # "discoveredBy": { + # "uuid": "74869892680816", + # "displayName": "63fa369b6f72612d31e82971", + # "category": "Hypervisor", + # "type": "vCenter", + # "readonly": false + # }, + # "vendorIds": { + # "63fa369b6f72612d31e82971": "vm-3456" + # }, + # "state": "IDLE", + # "severity": "Normal", + # "severityBreakdown": { + # "NORMAL": 1 + # }, + # "providers": [ + # { + # "uuid": "74857429819607", + # "displayName": "Resources-eu-spdc-dc-A-racks", + # "className": "VirtualDataCenter" + # }, + # { + # "uuid": "74691878215438", + # "displayName": "EU-SPDC-Datastore-TNAS-DO-NOT-USE", + # "className": "Storage" + # }, + # { + # "uuid": "74691878215486", + # "displayName": "esx8", + # "className": "PhysicalMachine" + # }, + # { + # "uuid": "74691878215455", + # "displayName": "EU-SPDC-Datastore-WNAS", + # "className": "Storage" + # } + # ], + # "staleness": "CURRENT" + # } + + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + info['__Output']['state'] = self.map_state_color( + info['state'] + ) + + info['__Output']['severity'] = self.map_severity_color( + info['severity'] + ) + + info['__Output']['staleness'] = self.map_staleness_color( + info['staleness'] + ) + + if resolve_dependencies: + info['virtualDataCenterName'] = '' + info['virtualDataCenterId'] = None + info['storageCount'] = 0 + info['phyCount'] = 0 + + if 'providers' in managed_object: + for provider in managed_object['providers']: + if provider['className'] == 'VirtualDataCenter': + info['virtualDataCenterName'] = provider['displayName'] + info['virtualDataCenterId'] = provider['uuid'] + + if provider['className'] == 'Storage': + info['storageCount'] = info['storageCount'] + 1 + + if provider['className'] == 'PhysicalMachine': + info['phyCount'] = info['phyCount'] + 1 + + if provider['className'] not in ['VirtualDataCenter', 'Storage', 'PhysicalMachine']: + self.log.error( + 'iwo.get_virtual_machine_info', + 'Unrecognized provider class name: %s' % ( + provider['className'] + ) + ) + + return info + + def match_virtual_machine(self, virtual_machine_info, match_rules): + if match_rules is None or len(match_rules) == 0: + return True + + match = False + for match_rule in match_rules: + if match_rule.startswith('uuid:'): + if virtual_machine_info['uuid'] == match_rule[5:]: + match = True + break + + return match + + def get_virtual_machine(self, virtual_machine_uuid, resolve_dependencies=True): + virtual_machines = self.get_virtual_machines(resolve_dependencies=resolve_dependencies) + if virtual_machines is not None: + for virtual_machine in self.mo_virtual_machine: + if virtual_machine['uuid'] == virtual_machine_uuid: + return virtual_machine + return None + + def get_virtual_machine_severity(self, virtual_machine_uuid, resolve_dependencies=False): + virtual_machine = self.get_virtual_machine( + virtual_machine_uuid, + resolve_dependencies=resolve_dependencies + ) + if virtual_machine is not None: + return virtual_machine['severity'] + return None + + def get_virtual_machines(self, resolve_dependencies=True, match_rules=None): + if self.mo_virtual_machine is None: + if not self.initialize_virtual_machine(): + self.log.error( + 'get_virtual_machines', + 'Managed objects must be initialized first' + ) + return None + + virtual_machines = [] + + for managed_object in self.mo_virtual_machine: + virtual_machine_info = self.get_virtual_machine_info( + managed_object, + resolve_dependencies=resolve_dependencies + ) + if virtual_machine_info is not None: + if not self.match_virtual_machine(virtual_machine_info, match_rules): + continue + + virtual_machines.append( + virtual_machine_info + ) + + return virtual_machines + + def get_virtual_machines_summary(self, match_rules=None): + virtual_machines = self.get_virtual_machines( + resolve_dependencies=False, + match_rules=match_rules + ) + + summary = None + if virtual_machines is not None: + summary = self.get_summary(virtual_machines) + + return summary + + def print_virtual_machines(self, info, summary=True): + if summary: + self.print_summary(info) + + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/volume.py b/lib/iwo/volume.py new file mode 100644 index 00000000..8b9e2f88 --- /dev/null +++ b/lib/iwo/volume.py @@ -0,0 +1,65 @@ +import json + + +class IwoVolume(): + def __init__(self): + self.mo_volume = None + + def initialize_volume(self): + body = {} + body['className'] = 'VirtualVolume' + + self.mo_volume = self.search(body) + if self.mo_volume is None: + return False + + self.log.iwo_mo( + 'VirtualVolume.attributes', + self.mo_volume + ) + + return True + + def get_volume_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_volumes(self): + if self.mo_volume is None: + if not self.initialize_volume(): + self.log.error( + 'get_volumes', + 'Managed objects must be initialized first' + ) + return None + + volumes = [] + + for managed_object in self.mo_volume: + volume_info = self.get_volume_info( + managed_object + ) + if volume_info is not None: + volumes.append( + volume_info + ) + + self.log.iwo_mo( + 'VirtualVolume.info', + self.mo_volume + ) + + return volumes + + def print_volumes(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/workload.py b/lib/iwo/workload.py new file mode 100644 index 00000000..5766966e --- /dev/null +++ b/lib/iwo/workload.py @@ -0,0 +1,65 @@ +import json + + +class IwoWorkload(): + def __init__(self): + self.mo_workload = None + + def initialize_workload(self): + body = {} + body['className'] = 'WorkloadController' + + self.mo_workload = self.search(body) + if self.mo_workload is None: + return False + + self.log.iwo_mo( + 'WorkloadController.attributes', + self.mo_workload + ) + + return True + + def get_workload_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_workloads(self): + if self.mo_workload is None: + if not self.initialize_workload(): + self.log.error( + 'get_workloads', + 'Managed objects must be initialized first' + ) + return None + + workloads = [] + + for managed_object in self.mo_workload: + workload_info = self.get_workload_info( + managed_object + ) + if workload_info is not None: + workloads.append( + workload_info + ) + + self.log.iwo_mo( + 'WorkloadController.info', + self.mo_workload + ) + + return workloads + + def print_workloads(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/iwo/zone.py b/lib/iwo/zone.py new file mode 100644 index 00000000..042962ce --- /dev/null +++ b/lib/iwo/zone.py @@ -0,0 +1,65 @@ +import json + + +class IwoZone(): + def __init__(self): + self.mo_zone = None + + def initialize_zone(self): + body = {} + body['className'] = 'AvailabilityZone' + + self.mo_zone = self.search(body) + if self.mo_zone is None: + return False + + self.log.iwo_mo( + 'AvailabilityZone.attributes', + self.mo_zone + ) + + return True + + def get_zone_info(self, managed_object): + info = {} + info['__Output'] = {} + + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_zones(self): + if self.mo_zone is None: + if not self.initialize_zone(): + self.log.error( + 'get_zones', + 'Managed objects must be initialized first' + ) + return None + + zones = [] + + for managed_object in self.mo_zone: + zone_info = self.get_zone_info( + managed_object + ) + if zone_info is not None: + zones.append( + zone_info + ) + + self.log.iwo_mo( + 'AvailabilityZone.info', + self.mo_zone + ) + + return zones + + def print_zones(self, info): + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) diff --git a/lib/k8s/README.md b/lib/k8s/README.md new file mode 100644 index 00000000..99725433 --- /dev/null +++ b/lib/k8s/README.md @@ -0,0 +1,49 @@ +important fix in windows + +C:\Users\>\AppData\Local\Programs\Python\Python39\Lib\site-packages\kubevirt\api_client.py + + def __call_api(self, resource_path, method, + path_params=None, query_params=None, header_params=None, + body=None, post_params=None, files=None, + response_type=None, auth_settings=None, callback=None, + _return_http_data_only=None, collection_formats=None, _preload_content=True, + _request_timeout=None): + + config = Configuration() + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params['Cookie'] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict(self.parameters_to_tuples(header_params, + collection_formats)) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples(path_params, + collection_formats) + for k, v in path_params: + # THIS NEEDS TO BE CHANGED + resource_path = resource_path.replace( + '{%s}' % k, quote(str(v), safe=config.safe_chars_for_path_param)) + resource_path = resource_path.replace( + '{%s:[a-z0-9][a-z0-9\-]*}' % k, quote(str(v), safe=config.safe_chars_for_path_param)) + +C:\Users\\AppData\Local\Programs\Python\Python39\Lib\site-packages\kubevirt\rest.py + + def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): + if headers['Content-Type'] == 'application/json-patch+json': + headers['Content-Type'] = 'application/merge-patch+json' + + return self.request("PATCH", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) diff --git a/lib/k8s/__init__.py b/lib/k8s/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/__pycache__/__init__.cpython-310.pyc b/lib/k8s/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9071c2d2 Binary files /dev/null and b/lib/k8s/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/__pycache__/common.cpython-310.pyc b/lib/k8s/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..fb90a20f Binary files /dev/null and b/lib/k8s/__pycache__/common.cpython-310.pyc differ diff --git a/lib/k8s/__pycache__/main.cpython-310.pyc b/lib/k8s/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c2efbb3f Binary files /dev/null and b/lib/k8s/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/__pycache__/nodes.cpython-310.pyc b/lib/k8s/__pycache__/nodes.cpython-310.pyc new file mode 100644 index 00000000..a5e79d33 Binary files /dev/null and b/lib/k8s/__pycache__/nodes.cpython-310.pyc differ diff --git a/lib/k8s/alert_manager/__init__.py b/lib/k8s/alert_manager/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/alert_manager/api.py b/lib/k8s/alert_manager/api.py new file mode 100644 index 00000000..46b8158c --- /dev/null +++ b/lib/k8s/alert_manager/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sAlertManagerApi(): + def __init__(self): + self.alert_manager_mo = None + + def get_alert_manager_mo(self, cache_enabled=True): + if cache_enabled: + if self.alert_manager_mo is not None: + return self.alert_manager_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='Alertmanager' + ) + self.alert_manager_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'alert_manager', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_alert_manager_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'alert_manager', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'alert_manager', + self.alert_manager_mo + ) + + return self.alert_manager_mo diff --git a/lib/k8s/alert_manager/info.py b/lib/k8s/alert_manager/info.py new file mode 100644 index 00000000..34e98eff --- /dev/null +++ b/lib/k8s/alert_manager/info.py @@ -0,0 +1,93 @@ +from lib import filter_helper + + +class K8sAlertManagerInfo(): + def __init__(self): + self.alert_manager = None + + def get_alert_manager_info(self, alert_manager_mo): + if alert_manager_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + alert_manager_mo + ) + info.update(metadata_info) + + info['version'] = self.get( + alert_manager_mo, + 'metadata:labels:app.kubernetes.io/version' + ) + + info['replicas'] = self.get( + alert_manager_mo, + 'spec:replicas' + ) + + return info + + def get_alert_managers_info(self, cache_enabled=True): + if cache_enabled: + if self.alert_manager is not None: + return self.alert_manager + + managed_objects = self.get_alert_manager_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.alert_manager = [] + for managed_object in managed_objects: + alert_manager_info = {} + alert_manager_info['info'] = self.get_alert_manager_info( + managed_object + ) + alert_manager_info['mo'] = managed_object + self.alert_manager.append( + alert_manager_info + ) + + return self.alert_manager + + def match_alert_manager(self, alert_manager_info, alert_manager_filter): + if alert_manager_filter is None or len(alert_manager_filter) == 0: + return True + + for ap_rule in alert_manager_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_alert_manager', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_alert_managers(self, object_filter=None, return_mo=False, cache_enabled=True): + all_alert_managers = self.get_alert_managers_info(cache_enabled=cache_enabled) + if all_alert_managers is None: + return None + + alert_managers = [] + + for alert_manager_info in all_alert_managers: + if not self.match_alert_manager(alert_manager_info['info'], object_filter): + continue + + if return_mo: + alert_managers.append( + alert_manager_info['mo'] + ) + continue + + alert_managers.append( + alert_manager_info['info'] + ) + + return alert_managers diff --git a/lib/k8s/alert_manager/main.py b/lib/k8s/alert_manager/main.py new file mode 100644 index 00000000..e4f8b035 --- /dev/null +++ b/lib/k8s/alert_manager/main.py @@ -0,0 +1,11 @@ +from lib.k8s.alert_manager.api import K8sAlertManagerApi +from lib.k8s.alert_manager.info import K8sAlertManagerInfo + + +class K8sAlertManager( + K8sAlertManagerApi, + K8sAlertManagerInfo + ): + def __init__(self): + K8sAlertManagerApi.__init__(self) + K8sAlertManagerInfo.__init__(self) diff --git a/lib/k8s/alert_manager/output.py b/lib/k8s/alert_manager/output.py new file mode 100644 index 00000000..2c5c7800 --- /dev/null +++ b/lib/k8s/alert_manager/output.py @@ -0,0 +1,41 @@ +class K8sAlertManagerOutput(): + def __init__(self): + pass + + def print_alert_managers(self, info, title=False): + if title: + self.my_output.default( + 'Alert Manager [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'version', + 'replicas', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Version', + 'Replicas', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/alert_manager_config/__init__.py b/lib/k8s/alert_manager_config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/alert_manager_config/api.py b/lib/k8s/alert_manager_config/api.py new file mode 100644 index 00000000..dd588e7e --- /dev/null +++ b/lib/k8s/alert_manager_config/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sAlertManagerConfigApi(): + def __init__(self): + self.alert_manager_config_mo = None + + def get_alert_manager_config_mo(self, cache_enabled=True): + if cache_enabled: + if self.alert_manager_config_mo is not None: + return self.alert_manager_config_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1beta1', + kind='AlertmanagerConfig' + ) + self.alert_manager_config_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'alert_manager_config', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_alert_manager_config_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'alert_manager_config', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'alert_manager_config', + self.alert_manager_config_mo + ) + + return self.alert_manager_config_mo diff --git a/lib/k8s/alert_manager_config/info.py b/lib/k8s/alert_manager_config/info.py new file mode 100644 index 00000000..412f4db2 --- /dev/null +++ b/lib/k8s/alert_manager_config/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sAlertManagerConfigInfo(): + def __init__(self): + self.alert_manager_config = None + + def get_alert_manager_config_info(self, alert_manager_config_mo): + if alert_manager_config_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + alert_manager_config_mo + ) + info.update(metadata_info) + + return info + + def get_alert_manager_configs_info(self, cache_enabled=True): + if cache_enabled: + if self.alert_manager_config is not None: + return self.alert_manager_config + + managed_objects = self.get_alert_manager_config_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.alert_manager_config = [] + for managed_object in managed_objects: + alert_manager_config_info = {} + alert_manager_config_info['info'] = self.get_alert_manager_config_info( + managed_object + ) + alert_manager_config_info['mo'] = managed_object + self.alert_manager_config.append( + alert_manager_config_info + ) + + return self.alert_manager_config + + def match_alert_manager_config(self, alert_manager_config_info, alert_manager_config_filter): + if alert_manager_config_filter is None or len(alert_manager_config_filter) == 0: + return True + + for ap_rule in alert_manager_config_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_alert_manager_config', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_alert_manager_configs(self, object_filter=None, return_mo=False, cache_enabled=True): + all_alert_manager_configs = self.get_alert_manager_configs_info(cache_enabled=cache_enabled) + if all_alert_manager_configs is None: + return None + + alert_manager_configs = [] + + for alert_manager_config_info in all_alert_manager_configs: + if not self.match_alert_manager_config(alert_manager_config_info['info'], object_filter): + continue + + if return_mo: + alert_manager_configs.append( + alert_manager_config_info['mo'] + ) + continue + + alert_manager_configs.append( + alert_manager_config_info['info'] + ) + + return alert_manager_configs diff --git a/lib/k8s/alert_manager_config/main.py b/lib/k8s/alert_manager_config/main.py new file mode 100644 index 00000000..dddf5f36 --- /dev/null +++ b/lib/k8s/alert_manager_config/main.py @@ -0,0 +1,11 @@ +from lib.k8s.alert_manager_config.api import K8sAlertManagerConfigApi +from lib.k8s.alert_manager_config.info import K8sAlertManagerConfigInfo + + +class K8sAlertManagerConfig( + K8sAlertManagerConfigApi, + K8sAlertManagerConfigInfo + ): + def __init__(self): + K8sAlertManagerConfigApi.__init__(self) + K8sAlertManagerConfigInfo.__init__(self) diff --git a/lib/k8s/alert_manager_config/output.py b/lib/k8s/alert_manager_config/output.py new file mode 100644 index 00000000..a9b731bc --- /dev/null +++ b/lib/k8s/alert_manager_config/output.py @@ -0,0 +1,33 @@ +class K8sAlertManagerConfigOutput(): + def __init__(self): + pass + + def print_alert_manager_configs(self, info, title=False): + if title: + self.my_output.default( + 'Alert Manager [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/api.py b/lib/k8s/api.py new file mode 100644 index 00000000..fd66368a --- /dev/null +++ b/lib/k8s/api.py @@ -0,0 +1,196 @@ +import os +import time +import traceback +import yaml + +from kubernetes import config +from kubernetes import client +from kubernetes.config import kube_config + +from openshift.dynamic import DynamicClient +from urllib3.exceptions import MaxRetryError + + +class K8sApi(): + def __init__(self, kubeconfig_filename, cluster_type='standard'): + self.kubeconfig_filename = kubeconfig_filename + self.cluster_type = cluster_type + self.api = {} + self.api_timeout_seconds = 3 + self.connect_timeout_seconds = 3 + self.api_retries = 1 + + def get_api(self, cluster_type='standard', api_type='v1'): + if cluster_type not in ['standard', 'ocp']: + self.log.error( + 'get_api', + 'Unsupported cluster type: %s' % (cluster_type) + ) + return None + + if cluster_type == 'standard': + if api_type == 'v1': + return self.get_api_standard() + + if api_type == 'version': + return self.get_api_version() + + if cluster_type == 'ocp': + return self.get_api_ocp() + + return None + + def get_api_standard(self): + if 'standard' in self.api and self.api['standard'] is not None: + return self.api['standard'] + + if not os.path.isfile(self.kubeconfig_filename): + self.log.error( + 'k8s.get_api_standard', + 'Kubeconfig file not found: %s' % (self.kubeconfig_filename) + ) + return None + + try: + start_time = int(time.time() * 1000) + + my_config = client.Configuration() + my_config.verify_ssl = False + my_config.retries = self.api_retries + + with open(self.kubeconfig_filename, 'r', encoding='utf-8') as file_handler: + configuration_yaml = yaml.safe_load(file_handler.read()) + + k8_loader = kube_config.KubeConfigLoader( + configuration_yaml + ) + k8_loader.load_and_set(my_config) + + my_client = client.ApiClient( + configuration=my_config + ) + self.api['standard'] = client.CoreV1Api( + api_client=my_client + ) + + response = self.api['standard'].list_namespace( + timeout_seconds=self.api_timeout_seconds, + _request_timeout=self.connect_timeout_seconds + ) + + self.log.k8s( + 'connect.standard', + '-', + True, + int(time.time() * 1000) - start_time + ) + + except MaxRetryError: + self.log.error( + 'k8s.get_api_standard', + 'Connection timed out' + ) + return None + + except BaseException: + self.log.error( + 'k8s.get_api_standard', + 'Kubeconfig file failed: %s' % (self.kubeconfig_filename) + ) + self.log.error('k8s.get_api_standard', traceback.format_exc()) + return None + + return self.api['standard'] + + def get_api_version(self): + if 'version' in self.api and self.api['version'] is not None: + return self.api['version'] + + if not os.path.isfile(self.kubeconfig_filename): + self.log.error( + 'k8s.get_api_version', + 'Kubeconfig file not found: %s' % (self.kubeconfig_filename) + ) + return None + + try: + start_time = int(time.time() * 1000) + + config.load_kube_config(self.kubeconfig_filename) + self.api['version'] = client.VersionApi() + + self.log.k8s( + 'connect.version', + '-', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error( + 'k8s.get_api_version', + 'Kubeconfig file failed: %s' % (self.kubeconfig_filename) + ) + self.log.error('k8s.get_api_version', traceback.format_exc()) + return None + + return self.api['version'] + + def get_api_ocp(self): + if 'ocp' in self.api and self.api['ocp'] is not None: + return self.api['ocp'] + + if not os.path.isfile(self.kubeconfig_filename): + self.log.error( + 'k8s.get_api_ocp', + 'Kubeconfig file not found: %s' % (self.kubeconfig_filename) + ) + return None + + try: + start_time = int(time.time() * 1000) + + my_config = client.Configuration() + my_config.retries = self.api_retries + + with open(self.kubeconfig_filename, 'r', encoding='utf-8') as file_handler: + configuration_yaml = yaml.safe_load(file_handler.read()) + + k8_loader = kube_config.KubeConfigLoader( + configuration_yaml + ) + k8_loader.load_and_set(my_config) + + my_client = client.ApiClient( + configuration=my_config + ) + self.api['ocp'] = DynamicClient(my_client) + + # response = self.api['ocp'].resources.get( + # api_version='v1', + # kind='Namespace' + # ) + + self.log.k8s( + 'connect.ocp', + '-', + True, + int(time.time() * 1000) - start_time + ) + + except MaxRetryError: + self.log.error( + 'k8s.get_api_standard', + 'Connection timed out' + ) + return None + + except BaseException: + self.log.error( + 'k8s.get_api_ocp', + 'Kubeconfig file failed: %s' % (self.kubeconfig_filename) + ) + self.log.error('k8s.get_api_standard', traceback.format_exc()) + return None + + return self.api['ocp'] diff --git a/lib/k8s/cluster_operator/__init__.py b/lib/k8s/cluster_operator/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/cluster_operator/api.py b/lib/k8s/cluster_operator/api.py new file mode 100644 index 00000000..6b64faab --- /dev/null +++ b/lib/k8s/cluster_operator/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sClusterOperatorApi(): + def __init__(self): + self.cluster_operator_mo = None + + def get_cluster_operator_mo(self, cache_enabled=True): + if cache_enabled: + if self.cluster_operator_mo is not None: + return self.cluster_operator_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='config.openshift.io/v1', + kind='ClusterOperator' + ) + self.cluster_operator_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'cluster_operator', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_cluster_operator_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'cluster_operator', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'cluster_operator', + self.cluster_operator_mo + ) + + return self.cluster_operator_mo diff --git a/lib/k8s/cluster_operator/info.py b/lib/k8s/cluster_operator/info.py new file mode 100644 index 00000000..3582de11 --- /dev/null +++ b/lib/k8s/cluster_operator/info.py @@ -0,0 +1,253 @@ +from lib import filter_helper + + +class K8sClusterOperatorInfo(): + def __init__(self): + self.cluster_operator = None + + def get_cluster_operator_info(self, cluster_operator_mo): + if cluster_operator_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + cluster_operator_mo + ) + info.update(metadata_info) + + info['manager'] = None + managed_fields = self.get( + cluster_operator_mo, + 'metadata:managedFields' + ) + if managed_fields is not None: + for managed_field in managed_fields: + try: + if len(managed_field['fieldsV1']['f:status']['f:conditions']) >= 0: + info['manager'] = managed_field['manager'] + except BaseException: + pass + + info['available'] = False + info['availableSince'] = '--' + info['availableTick'] = '\u2717' + info['__Output']['availableTick'] = 'Red' + + info['progressing'] = False + info['progressingTick'] = '\u2713' + + info['degraded'] = False + info['degradedTick'] = '\u2713' + + info['upgradeable'] = False + info['upgradeableTick'] = '\u2713' + + conditions_mo = self.get( + cluster_operator_mo, + 'status:conditions' + ) + if conditions_mo is not None: + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Available': + if condition_mo['status'] == 'True': + info['available'] = True + info['availableTick'] = '\u2713' + info['__Output']['availableTick'] = 'Green' + info['availableSince'] = self.convert_timestamp_to_age( + self.get( + condition_mo, + 'lastTransitionTime' + ), + on_error='--' + ) + + if condition_mo['type'] == 'Degraded': + if condition_mo['status'] == 'True': + info['degraded'] = True + info['degradedTick'] = '\u2713' + + if condition_mo['type'] == 'Progressing': + if condition_mo['status'] == 'True': + info['progressing'] = True + info['progressingTick'] = '\u2713' + + if condition_mo['type'] == 'Upgradeable': + if condition_mo['status'] == 'True': + info['upgradeable'] = True + info['upgradeableTick'] = '\u2713' + + versions = self.get( + cluster_operator_mo, + 'status:versions' + ) + info['version'] = None + if versions is not None: + for version in versions: + if version['name'] == 'operator': + info['version'] = version['version'] + + info['related'] = self.get( + cluster_operator_mo, + 'status:relatedObjects' + ) + + return info + + def get_cluster_operators_info(self, cache_enabled=True): + if cache_enabled: + if self.cluster_operator is not None: + return self.cluster_operator + + managed_objects = self.get_cluster_operator_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cluster_operator = [] + for managed_object in managed_objects: + cluster_operator_info = {} + cluster_operator_info['info'] = self.get_cluster_operator_info( + managed_object + ) + cluster_operator_info['mo'] = managed_object + self.cluster_operator.append( + cluster_operator_info + ) + + return self.cluster_operator + + def match_cluster_operator(self, cluster_operator_info, cluster_operator_filter): + if cluster_operator_filter is None or len(cluster_operator_filter) == 0: + return True + + for ap_rule in cluster_operator_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cluster_operator_info['name']): + return False + + if not key_found: + self.log.error( + 'match_cluster_operator', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cluster_operator_deployment(self, cluster_operator_info, deployments): + if cluster_operator_info['related'] is None: + return None + + namespaces = [] + for related in cluster_operator_info['related']: + if related['resource'] == 'namespaces': + namespaces.append( + related['name'] + ) + + names = [] + names.append(cluster_operator_info['name']) + names.append('openshift-%s' % (cluster_operator_info['name'])) + names.append('%s-operator' % (cluster_operator_info['name'])) + names.append('openshift-%s-operator' % (cluster_operator_info['name'])) + names.append('cluster-%s-operator' % (cluster_operator_info['name'])) + + if cluster_operator_info['name'] == 'openshift-samples': + names.append('cluster-samples-operator') + + app_label_map = {} + app_label_map['operator-lifecycle-manager'] = 'olm-operator' + app_label_map['operator-lifecycle-manager-catalog'] = 'catalog-operator' + app_label_map['operator-lifecycle-manager-packageserver'] = 'package-server-manager' + + for deployment in deployments: + if deployment['owner_kind'] != 'ClusterVersion': + continue + + if cluster_operator_info['name'] in app_label_map: + for label in deployment['label']: + if label == 'app': + if deployment['label'][label] == app_label_map[cluster_operator_info['name']]: + return deployment + + if deployment['namespace'] not in namespaces: + continue + + if deployment['name'] not in names: + continue + + return deployment + + return None + + def get_cluster_operator_related_deployments(self, cluster_operator_info, deployments): + related = [] + + for deployment in deployments: + for label in deployment['label']: + if label == 'app.kubernetes.io/managed-by': + if deployment['label'][label] == cluster_operator_info['co_deployment']['name']: + related.append( + deployment + ) + continue + + return related + + def get_cluster_operators(self, object_filter=None, return_mo=False, deployment_info=False, cache_enabled=True): + all_cluster_operators = self.get_cluster_operators_info(cache_enabled=cache_enabled) + if all_cluster_operators is None: + return None + + cluster_operators = [] + + if deployment_info: + deployments = self.get_deployments() + + for cluster_operator_info in all_cluster_operators: + if not self.match_cluster_operator(cluster_operator_info['info'], object_filter): + continue + + if return_mo: + cluster_operators.append( + cluster_operator_info['mo'] + ) + continue + + if deployment_info: + cluster_operator_info['info']['co_deployment'] = None + cluster_operator_info['info']['related_deployment'] = None + + cluster_operator_deployment = self.get_cluster_operator_deployment( + cluster_operator_info['info'], + deployments + ) + if cluster_operator_deployment is not None: + cluster_operator_info['info']['co_deployment'] = {} + cluster_operator_info['info']['co_deployment']['namespace'] = cluster_operator_deployment['namespace'] + cluster_operator_info['info']['co_deployment']['name'] = cluster_operator_deployment['name'] + cluster_operator_related_deployments = self.get_cluster_operator_related_deployments( + cluster_operator_info['info'], + deployments + ) + if cluster_operator_related_deployments is not None: + cluster_operator_info['info']['related_deployment'] = [] + for related_deployment in cluster_operator_related_deployments: + item = {} + item['namespace'] = related_deployment['namespace'] + item['name'] = related_deployment['name'] + cluster_operator_info['info']['related_deployment'].append( + item + ) + + cluster_operators.append( + cluster_operator_info['info'] + ) + + return cluster_operators diff --git a/lib/k8s/cluster_operator/main.py b/lib/k8s/cluster_operator/main.py new file mode 100644 index 00000000..75a899e2 --- /dev/null +++ b/lib/k8s/cluster_operator/main.py @@ -0,0 +1,11 @@ +from lib.k8s.cluster_operator.api import K8sClusterOperatorApi +from lib.k8s.cluster_operator.info import K8sClusterOperatorInfo + + +class K8sClusterOperator( + K8sClusterOperatorApi, + K8sClusterOperatorInfo + ): + def __init__(self): + K8sClusterOperatorApi.__init__(self) + K8sClusterOperatorInfo.__init__(self) diff --git a/lib/k8s/cluster_operator/output.py b/lib/k8s/cluster_operator/output.py new file mode 100644 index 00000000..05622132 --- /dev/null +++ b/lib/k8s/cluster_operator/output.py @@ -0,0 +1,123 @@ +class K8sClusterOperatorOutput(): + def __init__(self): + pass + + def print_cluster_operators(self, info, title=False): + if title: + self.my_output.default( + 'Cluster Operator [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['version'] is None: + item['version'] = '--' + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'name', + 'version', + 'ownerT', + 'availableTick', + 'progressingTick', + 'degradedTick', + 'upgradeableTick', + 'availableSince', + 'age' + ] + + headers = [ + 'Name', + 'Version', + 'Owner', + 'Available', + 'Progressing', + 'Degraded', + 'Upgradeable', + 'Since', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ownerT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cluster_operators_deployment(self, info, title=False): + if title: + self.my_output.default( + 'Cluster Operator - Deployment [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['deploymentT'] = [] + if item['co_deployment'] is not None: + item['deploymentT'].append( + item['co_deployment']['namespace'] + ) + item['deploymentT'].append( + item['co_deployment']['name'] + ) + + item['relatedT'] = [] + if item['related_deployment'] is not None: + for related in item['related_deployment']: + item['relatedT'].append( + '%s/%s' % ( + related['namespace'], + related['name'] + ) + ) + + if len(item['relatedT']) == 0: + item['relatedT'].append('--') + + order = [ + 'name', + 'deploymentT', + 'relatedT' + ] + + headers = [ + 'Name', + 'Operator Deployment', + 'Managed Deployments' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['deploymentT', 'relatedT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/cluster_quota/__init__.py b/lib/k8s/cluster_quota/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/cluster_quota/api.py b/lib/k8s/cluster_quota/api.py new file mode 100644 index 00000000..899bc0d0 --- /dev/null +++ b/lib/k8s/cluster_quota/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sClusterQuotaApi(): + def __init__(self): + self.cluster_quota_mo = None + + def get_cluster_quota_mo(self, cache_enabled=True): + if cache_enabled: + if self.cluster_quota_mo is not None: + return self.cluster_quota_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='quota.openshift.io/v1', + kind='ClusterResourceQuota' + ) + self.cluster_quota_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'cluster_quota', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_cluster_quota_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'cluster_quota', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'cluster_quota', + self.cluster_quota_mo + ) + + return self.cluster_quota_mo diff --git a/lib/k8s/cluster_quota/info.py b/lib/k8s/cluster_quota/info.py new file mode 100644 index 00000000..423fbf40 --- /dev/null +++ b/lib/k8s/cluster_quota/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sClusterQuotaInfo(): + def __init__(self): + self.cluster_quota = None + + def get_cluster_quota_info(self, cluster_quota_mo): + if cluster_quota_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + cluster_quota_mo + ) + info.update(metadata_info) + + return info + + def get_cluster_quotas_info(self, cache_enabled=True): + if cache_enabled: + if self.cluster_quota is not None: + return self.cluster_quota + + managed_objects = self.get_cluster_quota_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cluster_quota = [] + for managed_object in managed_objects: + cluster_quota_info = {} + cluster_quota_info['info'] = self.get_cluster_quota_info( + managed_object + ) + cluster_quota_info['mo'] = managed_object + self.cluster_quota.append( + cluster_quota_info + ) + + return self.cluster_quota + + def match_cluster_quota(self, cluster_quota_info, cluster_quota_filter): + if cluster_quota_filter is None or len(cluster_quota_filter) == 0: + return True + + for ap_rule in cluster_quota_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_cluster_quota', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cluster_quotas(self, object_filter=None, return_mo=False, cache_enabled=True): + all_cluster_quotas = self.get_cluster_quotas_info(cache_enabled=cache_enabled) + if all_cluster_quotas is None: + return None + + cluster_quotas = [] + + for cluster_quota_info in all_cluster_quotas: + if not self.match_cluster_quota(cluster_quota_info['info'], object_filter): + continue + + if return_mo: + cluster_quotas.append( + cluster_quota_info['mo'] + ) + continue + + cluster_quotas.append( + cluster_quota_info['info'] + ) + + return cluster_quotas diff --git a/lib/k8s/cluster_quota/main.py b/lib/k8s/cluster_quota/main.py new file mode 100644 index 00000000..a158adc2 --- /dev/null +++ b/lib/k8s/cluster_quota/main.py @@ -0,0 +1,11 @@ +from lib.k8s.cluster_quota.api import K8sClusterQuotaApi +from lib.k8s.cluster_quota.info import K8sClusterQuotaInfo + + +class K8sClusterQuota( + K8sClusterQuotaApi, + K8sClusterQuotaInfo + ): + def __init__(self): + K8sClusterQuotaApi.__init__(self) + K8sClusterQuotaInfo.__init__(self) diff --git a/lib/k8s/cluster_quota/output.py b/lib/k8s/cluster_quota/output.py new file mode 100644 index 00000000..9510a94c --- /dev/null +++ b/lib/k8s/cluster_quota/output.py @@ -0,0 +1,33 @@ +class K8sClusterQuotaOutput(): + def __init__(self): + pass + + def print_cluster_quotas(self, info, title=False): + if title: + self.my_output.default( + 'Cluster Quota [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/cluster_role_binding/__init__.py b/lib/k8s/cluster_role_binding/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/cluster_role_binding/api.py b/lib/k8s/cluster_role_binding/api.py new file mode 100644 index 00000000..ffa0d703 --- /dev/null +++ b/lib/k8s/cluster_role_binding/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sClusterRoleBindingApi(): + def __init__(self): + self.cluster_role_binding_mo = None + + def get_cluster_role_binding_mo(self, cache_enabled=True): + if cache_enabled: + if self.cluster_role_binding_mo is not None: + return self.cluster_role_binding_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='rbac.authorization.k8s.io/v1', + kind='ClusterRoleBinding' + ) + self.cluster_role_binding_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'cluster_role_binding', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_cluster_role_binding_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'cluster_role_binding', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'cluster_role_binding', + self.cluster_role_binding_mo + ) + + return self.cluster_role_binding_mo diff --git a/lib/k8s/cluster_role_binding/info.py b/lib/k8s/cluster_role_binding/info.py new file mode 100644 index 00000000..5ee61a47 --- /dev/null +++ b/lib/k8s/cluster_role_binding/info.py @@ -0,0 +1,119 @@ +from lib import filter_helper + + +class K8sClusterRoleBindingInfo(): + def __init__(self): + self.cluster_role_binding = None + + def get_cluster_role_binding_info(self, cluster_role_binding_mo): + if cluster_role_binding_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + cluster_role_binding_mo + ) + info.update(metadata_info) + + info['role'] = self.get(cluster_role_binding_mo, 'roleRef') + info['subject'] = self.get(cluster_role_binding_mo, 'subjects', on_error=[], on_none=[]) + for subject in info['subject']: + if 'namespace' in subject: + subject['description'] = '%s:%s/%s' % ( + subject['kind'], + subject['namespace'], + subject['name'] + ) + else: + subject['description'] = '%s:%s' % ( + subject['kind'], + subject['name'] + ) + + return info + + def get_cluster_role_bindings_info(self, cache_enabled=True): + if cache_enabled: + if self.cluster_role_binding is not None: + return self.cluster_role_binding + + managed_objects = self.get_cluster_role_binding_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cluster_role_binding = [] + for managed_object in managed_objects: + cluster_role_binding_info = {} + cluster_role_binding_info['info'] = self.get_cluster_role_binding_info( + managed_object + ) + cluster_role_binding_info['mo'] = managed_object + self.cluster_role_binding.append( + cluster_role_binding_info + ) + + return self.cluster_role_binding + + def match_cluster_role_binding(self, cluster_role_binding_info, cluster_role_binding_filter): + if cluster_role_binding_filter is None or len(cluster_role_binding_filter) == 0: + return True + + for ap_rule in cluster_role_binding_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cluster_role_binding_info['name']): + return False + + if key == 'role': + key_found = True + if not filter_helper.match_string(value, cluster_role_binding_info['role']): + return False + + if key == 'subject': + key_found = True + found = False + for subject in cluster_role_binding_info['subject']: + if filter_helper.match_string(value, subject['description']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_cluster_role_binding', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cluster_role_bindings(self, object_filter=None, return_mo=False, cache_enabled=True): + all_cluster_role_bindings = self.get_cluster_role_bindings_info(cache_enabled=cache_enabled) + if all_cluster_role_bindings is None: + return None + + cluster_role_bindings = [] + + for cluster_role_binding_info in all_cluster_role_bindings: + if not self.match_cluster_role_binding(cluster_role_binding_info['info'], object_filter): + continue + + if return_mo: + cluster_role_bindings.append( + cluster_role_binding_info['mo'] + ) + continue + + cluster_role_bindings.append( + cluster_role_binding_info['info'] + ) + + return cluster_role_bindings diff --git a/lib/k8s/cluster_role_binding/main.py b/lib/k8s/cluster_role_binding/main.py new file mode 100644 index 00000000..f9691ed4 --- /dev/null +++ b/lib/k8s/cluster_role_binding/main.py @@ -0,0 +1,11 @@ +from lib.k8s.cluster_role_binding.api import K8sClusterRoleBindingApi +from lib.k8s.cluster_role_binding.info import K8sClusterRoleBindingInfo + + +class K8sClusterRoleBinding( + K8sClusterRoleBindingApi, + K8sClusterRoleBindingInfo + ): + def __init__(self): + K8sClusterRoleBindingApi.__init__(self) + K8sClusterRoleBindingInfo.__init__(self) diff --git a/lib/k8s/cluster_role_binding/output.py b/lib/k8s/cluster_role_binding/output.py new file mode 100644 index 00000000..44c843f4 --- /dev/null +++ b/lib/k8s/cluster_role_binding/output.py @@ -0,0 +1,43 @@ +class K8sClusterRoleBindingOutput(): + def __init__(self): + pass + + def print_cluster_role_bindings(self, info, title=False): + if title: + self.my_output.default( + 'Cluster Role Binding [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'role.name', + 'subject.description', + 'age' + ] + + headers = [ + 'Name', + 'Role', + 'Subject', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['subject'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/cluster_service_version/__init__.py b/lib/k8s/cluster_service_version/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/cluster_service_version/api.py b/lib/k8s/cluster_service_version/api.py new file mode 100644 index 00000000..4e26784d --- /dev/null +++ b/lib/k8s/cluster_service_version/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sClusterServiceVersionApi(): + def __init__(self): + self.cluster_service_version_mo = None + + def get_cluster_service_version_mo(self, cache_enabled=True): + if cache_enabled: + if self.cluster_service_version_mo is not None: + return self.cluster_service_version_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='operators.coreos.com/v1alpha1', + kind='ClusterServiceVersion' + ) + self.cluster_service_version_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'cluster_service_version', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_cluster_service_version_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'cluster_service_version', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'cluster_service_version', + self.cluster_service_version_mo + ) + + return self.cluster_service_version_mo diff --git a/lib/k8s/cluster_service_version/info.py b/lib/k8s/cluster_service_version/info.py new file mode 100644 index 00000000..72c89ff2 --- /dev/null +++ b/lib/k8s/cluster_service_version/info.py @@ -0,0 +1,133 @@ +from lib import filter_helper + + +class K8sClusterServiceVersionInfo(): + def __init__(self): + self.cluster_service_version = None + + def get_cluster_service_version_info(self, cluster_service_version_mo): + if cluster_service_version_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + cluster_service_version_mo + ) + info.update(metadata_info) + + info['phase'] = self.get(cluster_service_version_mo, 'status:phase') + if info['phase'] is not None and info['phase'] == 'Succeeded': + info['__Output']['phase'] = 'Green' + else: + info['__Output']['phase'] = 'Red' + + info['display_name'] = self.get(cluster_service_version_mo, 'spec:displayName') + info['provider_name'] = self.get(cluster_service_version_mo, 'spec:provider:name') + info['maturity'] = self.get(cluster_service_version_mo, 'spec:maturity') + info['maturityT'] = info['maturity'] + if info['maturityT'] is None: + info['maturityT'] = '--' + info['replaces'] = self.get(cluster_service_version_mo, 'spec:replaces') + info['version'] = self.get(cluster_service_version_mo, 'spec:version') + + return info + + def get_cluster_service_versions_info(self, cache_enabled=True): + if cache_enabled: + if self.cluster_service_version is not None: + return self.cluster_service_version + + managed_objects = self.get_cluster_service_version_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cluster_service_version = [] + for managed_object in managed_objects: + cluster_service_version_info = {} + cluster_service_version_info['info'] = self.get_cluster_service_version_info( + managed_object + ) + cluster_service_version_info['mo'] = managed_object + self.cluster_service_version.append( + cluster_service_version_info + ) + + return self.cluster_service_version + + def match_cluster_service_version(self, cluster_service_version_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, cluster_service_version_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (cluster_service_version_info['namespace'], cluster_service_version_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_cluster_service_version', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cluster_service_versions(self, object_filter=None, return_mo=False, cache_enabled=True): + all_cluster_service_versions = self.get_cluster_service_versions_info(cache_enabled=cache_enabled) + if all_cluster_service_versions is None: + return None + + cluster_service_versions = [] + + for cluster_service_version_info in all_cluster_service_versions: + if not self.match_cluster_service_version(cluster_service_version_info['info'], object_filter): + continue + + if return_mo: + cluster_service_versions.append( + cluster_service_version_info['mo'] + ) + continue + + cluster_service_versions.append( + cluster_service_version_info['info'] + ) + + return cluster_service_versions + + def is_cluster_service_version(self, namespace, name, cache_enabled=True): + if self.get_cluster_service_version(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_cluster_service_version(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + cluster_service_versions = self.get_cluster_service_versions( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if cluster_service_versions is None: + return None + + if len(cluster_service_versions) == 1: + return cluster_service_versions[0] + + return None diff --git a/lib/k8s/cluster_service_version/main.py b/lib/k8s/cluster_service_version/main.py new file mode 100644 index 00000000..db6677c1 --- /dev/null +++ b/lib/k8s/cluster_service_version/main.py @@ -0,0 +1,11 @@ +from lib.k8s.cluster_service_version.api import K8sClusterServiceVersionApi +from lib.k8s.cluster_service_version.info import K8sClusterServiceVersionInfo + + +class K8sClusterServiceVersion( + K8sClusterServiceVersionApi, + K8sClusterServiceVersionInfo + ): + def __init__(self): + K8sClusterServiceVersionApi.__init__(self) + K8sClusterServiceVersionInfo.__init__(self) diff --git a/lib/k8s/cluster_service_version/output.py b/lib/k8s/cluster_service_version/output.py new file mode 100644 index 00000000..19bb9ba4 --- /dev/null +++ b/lib/k8s/cluster_service_version/output.py @@ -0,0 +1,47 @@ +class K8sClusterServiceVersionOutput(): + def __init__(self): + pass + + def print_cluster_service_versions(self, info, title=False): + if title: + self.my_output.default( + 'Cluster Service Version - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'provider_name', + 'display_name', + 'version', + 'maturityT', + 'phase', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Provider', + 'Type', + 'Version', + 'Maturity', + 'Phase', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/cni/__init__.py b/lib/k8s/cni/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/cni/api.py b/lib/k8s/cni/api.py new file mode 100644 index 00000000..103a6114 --- /dev/null +++ b/lib/k8s/cni/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sCniApi(): + def __init__(self): + self.cni_mo = None + + def get_cni_mo(self, cache_enabled=True): + if cache_enabled: + if self.cni_mo is not None: + return self.cni_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='config.openshift.io/v1', + kind='Network' + ) + self.cni_mo = response.get().to_dict()['items'] + + self.log.k8s( + 'get', + 'cni', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_cni_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'cni', + False, + int(time.time() * 1000) - start_time + ) + return None + + self.log.k8s_mo( + 'cni', + self.cni_mo + ) + + return self.cni_mo diff --git a/lib/k8s/cni/info.py b/lib/k8s/cni/info.py new file mode 100644 index 00000000..c98e19f6 --- /dev/null +++ b/lib/k8s/cni/info.py @@ -0,0 +1,88 @@ +from lib import filter_helper + + +class K8sCniInfo(): + def __init__(self): + self.cni = None + + def get_cni_info(self, cni_mo): + if cni_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['cni'] = self.get(cni_mo, 'status:networkType', on_error='--', on_none='--') + info['cluster'] = self.get(cni_mo, 'status:clusterNetwork', on_error=[], on_none=[]) + info['service'] = self.get(cni_mo, 'status:serviceNetwork', on_error=[], on_none=[]) + + return info + + def get_cnis_info(self, cache_enabled=True): + if cache_enabled: + if self.cni is not None: + return self.cni + + managed_objects = self.get_cni_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cni = [] + for managed_object in managed_objects: + cni_info = {} + cni_info['info'] = self.get_cni_info( + managed_object + ) + cni_info['mo'] = managed_object + self.cni.append( + cni_info + ) + + return self.cni + + def match_cni(self, cni_info, cni_filter): + if cni_filter is None or len(cni_filter) == 0: + return True + + for ap_rule in cni_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_cni', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnis(self, object_filter=None, return_mo=False, cache_enabled=True): + all_cnis = self.get_cnis_info(cache_enabled=cache_enabled) + if all_cnis is None: + return None + + cnis = [] + + for cni_info in all_cnis: + if not self.match_cni(cni_info['info'], object_filter): + continue + + if return_mo: + cnis.append( + cni_info['mo'] + ) + continue + + cnis.append( + cni_info['info'] + ) + + return cnis + + def get_cni(self): + cnis = self.get_cnis() + if cnis is None or len(cnis) != 1: + return None + return cnis[0] diff --git a/lib/k8s/cni/main.py b/lib/k8s/cni/main.py new file mode 100644 index 00000000..e25ec7f0 --- /dev/null +++ b/lib/k8s/cni/main.py @@ -0,0 +1,11 @@ +from lib.k8s.cni.api import K8sCniApi +from lib.k8s.cni.info import K8sCniInfo + + +class K8sCni( + K8sCniApi, + K8sCniInfo + ): + def __init__(self): + K8sCniApi.__init__(self) + K8sCniInfo.__init__(self) diff --git a/lib/k8s/cni/output.py b/lib/k8s/cni/output.py new file mode 100644 index 00000000..a9fff888 --- /dev/null +++ b/lib/k8s/cni/output.py @@ -0,0 +1,43 @@ +class K8sCniOutput(): + def __init__(self): + pass + + def print_cnis(self, info, title=False): + if title: + self.my_output.default( + 'K8s Cluster CNI [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'cni', + 'cluster.cidr', + 'cluster.hostPrefix', + 'service' + ] + + headers = [ + 'Network Type', + 'Cluster CIDR', + 'Cluster Host Prefix', + 'Service CIDR' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cluster', 'service'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/common.py b/lib/k8s/common.py new file mode 100644 index 00000000..65024fc0 --- /dev/null +++ b/lib/k8s/common.py @@ -0,0 +1,303 @@ +import json +import time +import datetime + +from lib import filter_helper + + +class K8sCommon(): + def __init__(self): + pass + + def _get(self, value, key): + if value is None: + return '__ERROR' + + if ':' in key: + subkey = key.split(':')[0] + if subkey not in value: + return '__ERROR' + + new_key = ':'.join(key.split(':')[1:]) + return self._get(value[subkey], new_key) + + if key in value: + return value[key] + + return '__ERROR' + + def get(self, managed_object, key, on_error=None, on_none=None): + if managed_object is None: + return on_error + + if not isinstance(managed_object, dict): + return on_error + + value = self._get(managed_object, key) + if value == '__ERROR': + return on_error + + if value is None: + return on_none + + return value + + def convert_object(self, item): + if item is None: + return None + + if isinstance(item, str): + return item + + if isinstance(item, int): + return item + + if isinstance(item, dict): + converted = {} + for key in item: + converted[key] = self.convert_object( + item[key] + ) + return converted + + if isinstance(item, list): + converted = [] + for key in item: + converted.append( + self.convert_object( + key + ) + ) + return converted + + converted = str( + item + ) + + return converted + + def convert_age(self, seconds): + if seconds > 60 * 60 * 24: + return '%sd' % (int(seconds / (60 * 60 * 24))) + + if seconds > 60 * 60: + hours = 0 + while True: + if seconds < 60 * 60: + break + + hours = hours + 1 + seconds = seconds - 60 * 60 + + return '%sh%sm' % ( + hours, + int(seconds / 60) + ) + + if seconds > 60: + return '%sm' % (int(seconds / 60)) + + return '%ss' % (seconds) + + def convert_timestamp(self, timestamp): + if timestamp is None: + return None + + new_timestamp = None + if isinstance(timestamp, str): + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S%z').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp.rstrip('Z'), '%Y-%m-%dT%H:%M:%S').timetuple())) + except BaseException: + pass + + return new_timestamp + + try: + new_timestamp = int(timestamp.timestamp()) + except BaseException: + pass + + return new_timestamp + + def convert_timestamp_to_age(self, timestamp, on_error=None): + timestamp = self.convert_timestamp(timestamp) + if timestamp is None: + return on_error + + return self.convert_age(int(time.time()) - timestamp) + + def get_metadata_info(self, managed_object, exclude_labels=[], exclude_annotations=[]): + info = {} + + if 'metadata' not in managed_object: + return info + + info['name'] = self.get(managed_object, 'metadata:name') + namespace = self.get(managed_object, 'metadata:namespace') + if namespace is not None: + info['namespace'] = namespace + info['namespace_name'] = '%s/%s' % ( + info['namespace'], + info['name'] + ) + + labels = self.get_metadata_label_info( + managed_object, + 'metadata:labels', + exclude_labels=exclude_labels + ) + info.update(labels) + + annotations = self.get_metadata_annotation_info( + managed_object, + 'metadata:annotations', + exclude_annotations=exclude_annotations + ) + info.update(annotations) + + owner_property_name = 'owner_references' + if owner_property_name not in managed_object['metadata']: + owner_property_name = 'ownerReferences' + + owner_references = self.get_metadata_owner_info( + managed_object, + 'metadata:%s' % (owner_property_name) + ) + info.update(owner_references) + + timestamp_name = 'creation_timestamp' + if timestamp_name not in managed_object['metadata']: + timestamp_name = 'creationTimestamp' + + info['age'] = self.convert_timestamp_to_age( + self.get( + managed_object, + 'metadata:%s' % (timestamp_name) + ), + on_error='--' + ) + + return info + + def get_metadata_label_info(self, managed_object, property_name, exclude_labels=[], chunk=60): + info = {} + info['label'] = self.get(managed_object, property_name, on_error={}, on_none={}) + info['labelT'] = [] + for key in info['label']: + if key in exclude_labels: + continue + + line = '%s = %s' % ( + key, + info['label'][key] + ) + + if chunk is not None: + lines = filter_helper.get_string_chunks( + line, + chunk + ) + info['labelT'] = info['labelT'] + lines + else: + info['labelT'].append( + line + ) + + return info + + def get_metadata_annotation_info(self, managed_object, property_name, exclude_annotations=[], chunk=60): + info = {} + info['annotation'] = self.get(managed_object, property_name, on_error={}, on_none={}) + info['annotationT'] = [] + + exclude_annotations.append( + 'kubectl.kubernetes.io/last-applied-configuration' + ) + exclude_annotations.append( + 'operator.cdi.kubevirt.io/lastAppliedConfiguration' + ) + + for key in info['annotation']: + if key in exclude_annotations: + continue + + line = '%s = %s' % ( + key, + info['annotation'][key] + ) + + if chunk is not None: + if len(line.split('\n')) == 1: + lines = filter_helper.get_string_chunks( + line, + chunk + ) + + info['annotationT'] = info['annotationT'] + lines + + else: + for item in line.split('\n'): + lines = filter_helper.get_string_chunks( + item, + chunk, + separator=',', + extra_separator='-' + ) + + info['annotationT'] = info['annotationT'] + lines + + else: + info['annotationT'].append( + line + ) + + return info + + def get_metadata_owner_info(self, managed_object, property_name): + owner_kind = None + owner_name = None + + owner_references = self.get( + managed_object, + property_name, + on_error=[], + on_none=[] + ) + + if len(owner_references) == 1: + owner_kind = self.get( + owner_references[0], + 'kind' + ) + + owner_name = self.get( + owner_references[0], + 'name' + ) + + if owner_kind is None or owner_name is None: + owner = None + else: + owner = '%s/%s' % ( + owner_kind, + owner_name + ) + + info = {} + info['owner_kind'] = owner_kind + info['owner_name'] = owner_name + info['owner'] = owner + + return info diff --git a/lib/k8s/config_map/__init__.py b/lib/k8s/config_map/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/config_map/api.py b/lib/k8s/config_map/api.py new file mode 100644 index 00000000..36e4dd0f --- /dev/null +++ b/lib/k8s/config_map/api.py @@ -0,0 +1,53 @@ +import time +import traceback + + +class K8sConfigMapApi(): + def __init__(self): + self.config_map_mo = None + + def get_config_map_mo(self, cache_enabled=True): + if cache_enabled: + if self.config_map_mo is not None: + return self.config_map_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_config_map_for_all_namespaces + try: + start_time = int(time.time() * 1000) + response = api_handler.list_config_map_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'config_map', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_config_map_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'config_map', + True, + int(time.time() * 1000) - start_time + ) + return False + + self.config_map_mo = [] + for item in response.items: + config_map_mo = self.convert_object(item.to_dict()) + self.config_map_mo.append( + config_map_mo + ) + + self.log.k8s_mo( + 'config_map', + self.config_map_mo + ) + + return self.config_map_mo diff --git a/lib/k8s/config_map/info.py b/lib/k8s/config_map/info.py new file mode 100644 index 00000000..246463a8 --- /dev/null +++ b/lib/k8s/config_map/info.py @@ -0,0 +1,161 @@ +from lib import filter_helper + + +class K8sConfigMapInfo(): + def __init__(self): + self.config_map = None + + def get_config_map_info(self, config_map_mo): + if config_map_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + config_map_mo + ) + info.update(metadata_info) + + info['namespace'] = self.get(config_map_mo, 'metadata:namespace') + info['name'] = self.get(config_map_mo, 'metadata:name') + + info['data'] = self.get(config_map_mo, 'data', on_error={}, on_none={}) + info['dataCount'] = len(info['data']) + + return info + + def get_config_maps_info(self, cache_enabled=True): + if cache_enabled: + if self.config_map is not None: + return self.config_map + + managed_objects = self.get_config_map_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.config_map = [] + for managed_object in managed_objects: + config_map_info = {} + config_map_info['info'] = self.get_config_map_info( + managed_object + ) + config_map_info['mo'] = managed_object + self.config_map.append( + config_map_info + ) + + return self.config_map + + def match_config_map(self, config_map_info, config_map_filter): + if config_map_filter is None or len(config_map_filter) == 0: + return True + + for ap_rule in config_map_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, config_map_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (config_map_info['namespace'], config_map_info['name'])): + return False + + if key == 'cm-name': + key_found = True + found = False + for key in config_map_info['data']: + if filter_helper.match_string(value, key): + found = True + + if not found: + return False + + if key == 'cm-data': + key_found = True + found = False + for key in config_map_info['data']: + if filter_helper.match_string(value, config_map_info['data'][key]): + found = True + + if not found: + return False + + if not key_found: + self.log.error( + 'match_config_map', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_config_maps(self, object_filter=None, pod_info=False, return_mo=False, cache_enabled=True): + all_config_maps = self.get_config_maps_info(cache_enabled=cache_enabled) + if all_config_maps is None: + return None + + config_maps = [] + + for config_map_info in all_config_maps: + if not self.match_config_map(config_map_info['info'], object_filter): + continue + + if return_mo: + config_maps.append( + config_map_info['mo'] + ) + continue + + if pod_info: + config_map_info['info']['pod'] = [] + pods_info = self.get_pods( + object_filter=[ + 'cm:%s:%s' % ( + config_map_info['info']['namespace'], + config_map_info['info']['name'] + ) + ] + ) + if pods_info is not None: + for pod in pods_info: + cm_pod_info = {} + cm_pod_info['namespace'] = pod['namespace'] + cm_pod_info['name'] = pod['name'] + config_map_info['info']['pod'].append( + cm_pod_info + ) + + config_maps.append( + config_map_info['info'] + ) + + if not return_mo: + config_maps = sorted( + config_maps, + key=lambda i: ( + i['namespace'], + i['name'] + ) + ) + + return config_maps + + def get_config_map(self, namespace, name): + config_map_filter = [] + config_map_filter.append('namespace:%s' % (namespace)) + config_map_filter.append('name:%s' % (name)) + + config_maps = self.get_config_maps( + object_filter=config_map_filter + ) + + if config_maps is None or len(config_maps) != 1: + return None + + return config_maps[0] diff --git a/lib/k8s/config_map/main.py b/lib/k8s/config_map/main.py new file mode 100644 index 00000000..71aa67d9 --- /dev/null +++ b/lib/k8s/config_map/main.py @@ -0,0 +1,11 @@ +from lib.k8s.config_map.api import K8sConfigMapApi +from lib.k8s.config_map.info import K8sConfigMapInfo + + +class K8sConfigMap( + K8sConfigMapApi, + K8sConfigMapInfo + ): + def __init__(self): + K8sConfigMapApi.__init__(self) + K8sConfigMapInfo.__init__(self) diff --git a/lib/k8s/config_map/output.py b/lib/k8s/config_map/output.py new file mode 100644 index 00000000..bade7d6d --- /dev/null +++ b/lib/k8s/config_map/output.py @@ -0,0 +1,199 @@ +class K8sConfigMapOutput(): + def __init__(self): + pass + + def print_config_maps(self, info, title=False): + if title: + self.my_output.default( + 'Config Map - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'dataCount', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Data', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_config_maps_name(self, info, title=False): + if title: + self.my_output.default( + 'Config Map - Data Name [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + + for item in info: + item['dataName'] = [] + for key in item['data']: + item['dataName'].append( + key + ) + + item['dataName'] = sorted(item['dataName']) + if len(item['dataName']) == 0: + item['dataName'].append('--') + + if len(item['dataName']) > 1: + row_separator = True + + order = [ + 'namespace', + 'name', + 'dataName', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Data Name', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['dataName'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=row_separator, + table=True + ) + + def print_config_maps_data(self, info, title=False): + if title: + self.my_output.default( + 'Config Map - Data [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'dataCount', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Data', + 'Age' + ] + + for item in info: + self.my_output.my_table( + [item], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + if len(item['data']) > 0: + for key in item['data']: + self.my_output.default('') + self.my_output.default('Data: %s' % (key), underline=True) + self.my_output.default(item['data'][key]) + + def print_config_maps_pod(self, info, title=False): + if title: + self.my_output.default( + 'Config Map - Pod [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + + for item in info: + for pod in item['pod']: + pod['namespace_name'] = '%s/%s' % ( + pod['namespace'], + pod['name'] + ) + + if len(item['pod']) > 1: + row_separator = True + + if len(item['pod']) == 0: + item['pod'].append( + dict( + namespace_name='--' + ) + ) + + order = [ + 'namespace', + 'name', + 'dataCount', + 'pod.namespace_name' + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Data Name', + 'Pod', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['pod'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=row_separator, + table=True + ) diff --git a/lib/k8s/configmap.py b/lib/k8s/configmap.py new file mode 100644 index 00000000..538e98c8 --- /dev/null +++ b/lib/k8s/configmap.py @@ -0,0 +1,34 @@ +import time +import traceback + + +class K8sConfigMap(): + def __init__(self): + pass + + def get_configmap(self, name, namespace): + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_secret_for_all_namespaces + try: + start_time = int(time.time() * 1000) + response = self.api.read_namespaced_config_map( + name=name, + namespace=namespace + ) + self.log.k8s( + 'get', + 'read_namespaced_config_map:%s:%s' % (namespace, name), + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s_configmap.get_configmap', traceback.format_exc()) + self.log.k8s( + 'get', + 'read_namespaced_config_map:%s:%s' % (namespace, name), + False, + int(time.time() * 1000) - start_time + ) + return None + + return response diff --git a/lib/k8s/custom_resource_definition/__init__.py b/lib/k8s/custom_resource_definition/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/custom_resource_definition/api.py b/lib/k8s/custom_resource_definition/api.py new file mode 100644 index 00000000..ca0d6e90 --- /dev/null +++ b/lib/k8s/custom_resource_definition/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sCustomResourceDefinitionApi(): + def __init__(self): + self.custom_resource_definition_mo = None + + def get_custom_resource_definition_mo(self, cache_enabled=True): + if cache_enabled: + if self.custom_resource_definition_mo is not None: + return self.custom_resource_definition_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='apiextensions.k8s.io/v1', + kind='CustomResourceDefinition' + ) + self.custom_resource_definition_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'custom_resource_definition', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_custom_resource_definition_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'custom_resource_definition', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'custom_resource_definition', + self.custom_resource_definition_mo + ) + + return self.custom_resource_definition_mo diff --git a/lib/k8s/custom_resource_definition/info.py b/lib/k8s/custom_resource_definition/info.py new file mode 100644 index 00000000..d489fa5a --- /dev/null +++ b/lib/k8s/custom_resource_definition/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sCustomResourceDefinitionInfo(): + def __init__(self): + self.custom_resource_definition = None + + def get_custom_resource_definition_info(self, custom_resource_definition_mo): + if custom_resource_definition_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_custom_resource_definitions_info(self, cache_enabled=True): + if cache_enabled: + if self.custom_resource_definition is not None: + return self.custom_resource_definition + + managed_objects = self.get_custom_resource_definition_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.custom_resource_definition = [] + for managed_object in managed_objects: + custom_resource_definition_info = {} + custom_resource_definition_info['info'] = self.get_custom_resource_definition_info( + managed_object + ) + custom_resource_definition_info['mo'] = managed_object + self.custom_resource_definition.append( + custom_resource_definition_info + ) + + return self.custom_resource_definition + + def match_custom_resource_definition(self, custom_resource_definition_info, custom_resource_definition_filter): + if custom_resource_definition_filter is None or len(custom_resource_definition_filter) == 0: + return True + + for ap_rule in custom_resource_definition_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_custom_resource_definition', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_custom_resource_definitions(self, object_filter=None, return_mo=False, cache_enabled=True): + all_custom_resource_definitions = self.get_custom_resource_definitions_info(cache_enabled=cache_enabled) + if all_custom_resource_definitions is None: + return None + + custom_resource_definitions = [] + + for custom_resource_definition_info in all_custom_resource_definitions: + if not self.match_custom_resource_definition(custom_resource_definition_info['info'], object_filter): + continue + + if return_mo: + custom_resource_definitions.append( + custom_resource_definition_info['mo'] + ) + continue + + custom_resource_definitions.append( + custom_resource_definition_info['info'] + ) + + return custom_resource_definitions diff --git a/lib/k8s/custom_resource_definition/main.py b/lib/k8s/custom_resource_definition/main.py new file mode 100644 index 00000000..c2b0a533 --- /dev/null +++ b/lib/k8s/custom_resource_definition/main.py @@ -0,0 +1,11 @@ +from lib.k8s.custom_resource_definition.api import K8sCustomResourceDefinitionApi +from lib.k8s.custom_resource_definition.info import K8sCustomResourceDefinitionInfo + + +class K8sCustomResourceDefinition( + K8sCustomResourceDefinitionApi, + K8sCustomResourceDefinitionInfo + ): + def __init__(self): + K8sCustomResourceDefinitionApi.__init__(self) + K8sCustomResourceDefinitionInfo.__init__(self) diff --git a/lib/k8s/custom_resource_definition/output.py b/lib/k8s/custom_resource_definition/output.py new file mode 100644 index 00000000..e88f46b8 --- /dev/null +++ b/lib/k8s/custom_resource_definition/output.py @@ -0,0 +1,33 @@ +class K8sCustomResourceDefinitionOutput(): + def __init__(self): + pass + + def print_custom_resource_definitions(self, info, title=False): + if title: + self.my_output.default( + 'Custom Resource Definition [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/daemon_set/__init__.py b/lib/k8s/daemon_set/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/daemon_set/api.py b/lib/k8s/daemon_set/api.py new file mode 100644 index 00000000..ca15b525 --- /dev/null +++ b/lib/k8s/daemon_set/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sDaemonSetApi(): + def __init__(self): + self.daemon_set_mo = None + + def get_daemon_set_mo(self, cache_enabled=True): + if cache_enabled: + if self.daemon_set_mo is not None: + return self.daemon_set_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='apps/v1', + kind='DaemonSet' + ) + self.daemon_set_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'daemon_set', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_daemon_set_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'daemon_set', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'daemon_set', + self.daemon_set_mo + ) + + return self.daemon_set_mo diff --git a/lib/k8s/daemon_set/info.py b/lib/k8s/daemon_set/info.py new file mode 100644 index 00000000..766091b4 --- /dev/null +++ b/lib/k8s/daemon_set/info.py @@ -0,0 +1,140 @@ +from lib import filter_helper + + +class K8sDaemonSetInfo(): + def __init__(self): + self.daemon_set = None + + def get_daemon_set_info(self, daemon_set_mo): + if daemon_set_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + daemon_set_mo + ) + info.update(metadata_info) + + keys = [ + 'currentNumberScheduled', + 'numberMisscheduled', + 'desiredNumberScheduled', + 'numberReady', + 'observedGeneration', + 'updatedNumberScheduled', + 'numberAvailable' + ] + for key in keys: + info[key] = self.get( + daemon_set_mo, + 'status:%s' % (key), + on_error=0, + on_none=0 + ) + + info['scheduled_summary'] = '%s/%s' % ( + info['desiredNumberScheduled'], + info['currentNumberScheduled'] + ) + if info['desiredNumberScheduled'] == info['currentNumberScheduled']: + info['__Output']['scheduled_summary'] = 'Green' + else: + info['__Output']['scheduled_summary'] = 'Red' + + info['available_summary'] = '%s/%s' % ( + info['numberReady'], + info['numberAvailable'] + ) + if info['numberAvailable'] == info['numberAvailable']: + info['__Output']['available_summary'] = 'Green' + else: + info['__Output']['available_summary'] = 'Red' + + info['node_selector'] = self.get( + daemon_set_mo, + 'spec:template:spec:nodeSelector', + on_error={}, + on_none={} + ) + + return info + + def get_daemon_sets_info(self, cache_enabled=True): + if cache_enabled: + if self.daemon_set is not None: + return self.daemon_set + + managed_objects = self.get_daemon_set_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.daemon_set = [] + for managed_object in managed_objects: + daemon_set_info = {} + daemon_set_info['info'] = self.get_daemon_set_info( + managed_object + ) + daemon_set_info['mo'] = managed_object + self.daemon_set.append( + daemon_set_info + ) + + return self.daemon_set + + def match_daemon_set(self, daemon_set_info, daemon_set_filter): + if daemon_set_filter is None or len(daemon_set_filter) == 0: + return True + + for ap_rule in daemon_set_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, daemon_set_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (daemon_set_info['namespace'], daemon_set_info['name'])): + return False + + if key == 'owner': + key_found = True + if not filter_helper.match_namespace_name(value, daemon_set_info['owner']): + return False + + if not key_found: + self.log.error( + 'match_daemon_set', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_daemon_sets(self, object_filter=None, return_mo=False, cache_enabled=True): + all_daemon_sets = self.get_daemon_sets_info(cache_enabled=cache_enabled) + if all_daemon_sets is None: + return None + + daemon_sets = [] + + for daemon_set_info in all_daemon_sets: + if not self.match_daemon_set(daemon_set_info['info'], object_filter): + continue + + if return_mo: + daemon_sets.append( + daemon_set_info['mo'] + ) + continue + + daemon_sets.append( + daemon_set_info['info'] + ) + + return daemon_sets diff --git a/lib/k8s/daemon_set/main.py b/lib/k8s/daemon_set/main.py new file mode 100644 index 00000000..f940fad3 --- /dev/null +++ b/lib/k8s/daemon_set/main.py @@ -0,0 +1,11 @@ +from lib.k8s.daemon_set.api import K8sDaemonSetApi +from lib.k8s.daemon_set.info import K8sDaemonSetInfo + + +class K8sDaemonSet( + K8sDaemonSetApi, + K8sDaemonSetInfo + ): + def __init__(self): + K8sDaemonSetApi.__init__(self) + K8sDaemonSetInfo.__init__(self) diff --git a/lib/k8s/daemon_set/output.py b/lib/k8s/daemon_set/output.py new file mode 100644 index 00000000..5ab05f5f --- /dev/null +++ b/lib/k8s/daemon_set/output.py @@ -0,0 +1,118 @@ +class K8sDaemonSetOutput(): + def __init__(self): + pass + + def print_daemon_sets(self, info, title=False): + if title: + self.my_output.default( + 'Daemon Set [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['node_selectorT'] = [] + for key in item['node_selector']: + item['node_selectorT'].append( + '%s: %s' % ( + key, + item['node_selector'][key] + ) + ) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace', + 'name', + 'ownerT', + 'scheduled_summary', + 'available_summary', + 'node_selectorT', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Owner', + 'Scheduled', + 'Available', + 'Node Selector', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ownerT', 'node_selectorT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_daemon_sets_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Daemon Set - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'Daemon Set', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'annotationT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/data_volume/__init__.py b/lib/k8s/data_volume/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/data_volume/api.py b/lib/k8s/data_volume/api.py new file mode 100644 index 00000000..1082eee3 --- /dev/null +++ b/lib/k8s/data_volume/api.py @@ -0,0 +1,108 @@ +import time +import json +import traceback + + +class K8sDataVolumeApi(): + def __init__(self): + self.data_volume_mo = None + + def get_data_volume_mo(self, cache_enabled=True): + if cache_enabled: + if self.data_volume_mo is not None: + return self.data_volume_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='cdi.kubevirt.io/v1beta1', + kind='DataVolume' + ) + self.data_volume_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'data_volume', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_data_volume_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'data_volume', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'data_volume', + self.data_volume_mo + ) + + return self.data_volume_mo + + def create_data_volume(self, data_volume): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='cdi.kubevirt.io/v1beta1', kind='DataVolume') + success = True + response = obj_list.create( + body=data_volume, + namespace=data_volume['metadata']['namespace'], + ) + except BaseException: + success = False + self.log.error( + 'k8s.create_data_volume', + 'PVC create failed: %s' % (json.dumps(data_volume, indent=4)) + ) + self.log.error( + 'k8s.create_data_volume', + traceback.format_exc() + ) + + self.log.ocp( + 'create', + 'dv', + success, + int(time.time() * 1000) - start_time + ) + + return success + + def delete_data_volume(self, namespace, name): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + success = True + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='cdi.kubevirt.io/v1beta1', kind='DataVolume') + success = obj_list.delete( + namespace=namespace, + name=name + ) + except BaseException: + success = False + self.log.error('k8s.create_data_volume', traceback.format_exc()) + + self.log.ocp( + 'delete', + 'dv', + success, + int(time.time() * 1000) - start_time + ) + + return success diff --git a/lib/k8s/data_volume/info.py b/lib/k8s/data_volume/info.py new file mode 100644 index 00000000..aa8eb0a4 --- /dev/null +++ b/lib/k8s/data_volume/info.py @@ -0,0 +1,190 @@ +import time + +from lib import filter_helper + + +class K8sDataVolumeInfo(): + def __init__(self): + self.data_volume = None + + def get_data_volume_info(self, data_volume_mo): + if data_volume_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + data_volume_mo + ) + info.update(metadata_info) + + info['access_modes'] = self.get(data_volume_mo, 'spec:pvc:accessModes', on_error=[], on_none=[]) + info['storage'] = self.get(data_volume_mo, 'spec:pvc:resources:requests:storage') + + info['claim_name'] = self.get(data_volume_mo, 'status:claimName') + info['phase'] = self.get(data_volume_mo, 'status:phase') + info['progress'] = self.get(data_volume_mo, 'status:progress') + + conditions = self.get(data_volume_mo, 'status:conditions', on_error=[], on_none=[]) + + info['bound'] = False + info['ready'] = False + info['running'] = False + + for condition in conditions: + if condition['type'] == 'Bound': + if condition['status'] == 'True': + info['bound'] = True + + if condition['type'] == 'Ready': + if condition['status'] == 'True': + info['ready'] = True + + if condition['type'] == 'Running': + if condition['status'] == 'True': + info['running'] = True + + if info['ready']: + info['readyTick'] = '\u2713' + info['__Output']['readyTick'] = 'Green' + else: + info['readyTick'] = '\u2717' + info['__Output']['readyTick'] = 'Red' + + if info['running']: + info['runningTick'] = '\u2713' + info['__Output']['runningTick'] = 'Green' + else: + info['runningTick'] = '\u2717' + info['__Output']['runningTick'] = 'Red' + + if info['bound']: + info['boundTick'] = '\u2713' + info['__Output']['boundTick'] = 'Green' + else: + info['boundTick'] = '\u2717' + info['__Output']['boundTick'] = 'Red' + + return info + + def get_data_volumes_info(self, cache_enabled=True): + if cache_enabled: + if self.data_volume is not None: + return self.data_volume + + managed_objects = self.get_data_volume_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.data_volume = [] + for managed_object in managed_objects: + data_volume_info = {} + data_volume_info['info'] = self.get_data_volume_info( + managed_object + ) + data_volume_info['mo'] = managed_object + self.data_volume.append( + data_volume_info + ) + + return self.data_volume + + def match_data_volume(self, data_volume_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, data_volume_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (data_volume_info['namespace'], data_volume_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_data_volume', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_data_volumes(self, object_filter=None, return_mo=False, cache_enabled=True): + all_data_volumes = self.get_data_volumes_info(cache_enabled=cache_enabled) + if all_data_volumes is None: + return None + + data_volumes = [] + + for data_volume_info in all_data_volumes: + if not self.match_data_volume(data_volume_info['info'], object_filter): + continue + + if return_mo: + data_volumes.append( + data_volume_info['mo'] + ) + continue + + data_volumes.append( + data_volume_info['info'] + ) + + return data_volumes + + def is_data_volume(self, namespace, name, cache_enabled=True): + if self.get_data_volume(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_data_volume(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + data_volumes = self.get_data_volumes( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if data_volumes is None: + return None + + if len(data_volumes) == 1: + return data_volumes[0] + + return None + + def wait_data_volume_upload_ready(self, namespace, name, max_time=60, log_error_on_timeout=True): + start_time = int(time.time()) + while True: + pvc_info = self.get_data_volume( + namespace, + name, + cache_enabled=False + ) + if pvc_info is not None: + if pvc_info['phase'] == 'UploadReady': + return True + + duration = int(time.time()) - start_time + if duration > max_time: + if log_error_on_timeout: + self.log.error( + 'k8s.wait_data_volume_upload_ready', + 'Max time reached: %s/%s' % (namespace, name) + ) + return False + + time.sleep(5) diff --git a/lib/k8s/data_volume/main.py b/lib/k8s/data_volume/main.py new file mode 100644 index 00000000..90cec19b --- /dev/null +++ b/lib/k8s/data_volume/main.py @@ -0,0 +1,11 @@ +from lib.k8s.data_volume.api import K8sDataVolumeApi +from lib.k8s.data_volume.info import K8sDataVolumeInfo + + +class K8sDataVolume( + K8sDataVolumeApi, + K8sDataVolumeInfo + ): + def __init__(self): + K8sDataVolumeApi.__init__(self) + K8sDataVolumeInfo.__init__(self) diff --git a/lib/k8s/data_volume/output.py b/lib/k8s/data_volume/output.py new file mode 100644 index 00000000..5e686509 --- /dev/null +++ b/lib/k8s/data_volume/output.py @@ -0,0 +1,62 @@ +class K8sDataVolumeOutput(): + def __init__(self): + pass + + def print_data_volumes(self, info, title=False): + if title: + self.my_output.default( + 'Data Volume - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + for item in info: + if len(item['access_modes']) > 1: + row_separator = True + + order = [ + 'namespace', + 'name', + 'runningTick', + 'boundTick', + 'readyTick', + 'access_modes', + 'storage', + 'claim_name', + 'phase', + 'progress', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'POD Running', + 'Bound', + 'Ready', + 'Access Mode', + 'Storage', + 'PVC', + 'Phase', + 'Progress', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['access_modes'] + ), + order=order, + headers=headers, + row_separator=row_separator, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/deployment/__init__.py b/lib/k8s/deployment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/deployment/api.py b/lib/k8s/deployment/api.py new file mode 100644 index 00000000..e29f2633 --- /dev/null +++ b/lib/k8s/deployment/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sDeploymentApi(): + def __init__(self): + self.deployment_mo = None + + def get_deployment_mo(self, cache_enabled=True): + if cache_enabled: + if self.deployment_mo is not None: + return self.deployment_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='apps/v1', + kind='Deployment' + ) + self.deployment_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'deployment', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_deployment_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'deployment', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'deployment', + self.deployment_mo + ) + + return self.deployment_mo diff --git a/lib/k8s/deployment/info.py b/lib/k8s/deployment/info.py new file mode 100644 index 00000000..72fcc84c --- /dev/null +++ b/lib/k8s/deployment/info.py @@ -0,0 +1,118 @@ +from lib import filter_helper + + +class K8sDeploymentInfo(): + def __init__(self): + self.deployment = None + + def get_deployment_info(self, deployment_mo): + if deployment_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + deployment_mo + ) + info.update(metadata_info) + + keys = [ + 'observedGeneration', + 'replicas', + 'updatedReplicas', + 'readyReplicas', + 'availableReplicas', + 'conditions' + ] + for key in keys: + info[key] = self.get(deployment_mo, 'status:%s' % (key)) + + info['readyT'] = '%s/%s' % ( + info['replicas'], + info['readyReplicas'] + ) + if info['replicas'] > 0 and info['replicas'] == info['readyReplicas']: + info['__Output']['readyT'] = 'Green' + else: + info['__Output']['readyT'] = 'Red' + + return info + + def get_deployments_info(self, cache_enabled=True): + if cache_enabled: + if self.deployment is not None: + return self.deployment + + managed_objects = self.get_deployment_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.deployment = [] + for managed_object in managed_objects: + deployment_info = {} + deployment_info['info'] = self.get_deployment_info( + managed_object + ) + deployment_info['mo'] = managed_object + self.deployment.append( + deployment_info + ) + + return self.deployment + + def match_deployment(self, deployment_info, deployment_filter): + if deployment_filter is None or len(deployment_filter) == 0: + return True + + for ap_rule in deployment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, deployment_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (deployment_info['namespace'], deployment_info['name'])): + return False + + if key == 'owner': + key_found = True + if not filter_helper.match_namespace_name(value, deployment_info['owner']): + return False + + if not key_found: + self.log.error( + 'match_deployment', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_deployments(self, object_filter=None, return_mo=False, cache_enabled=True): + all_deployments = self.get_deployments_info(cache_enabled=cache_enabled) + if all_deployments is None: + return None + + deployments = [] + + for deployment_info in all_deployments: + if not self.match_deployment(deployment_info['info'], object_filter): + continue + + if return_mo: + deployments.append( + deployment_info['mo'] + ) + continue + + deployments.append( + deployment_info['info'] + ) + + return deployments diff --git a/lib/k8s/deployment/main.py b/lib/k8s/deployment/main.py new file mode 100644 index 00000000..d3747022 --- /dev/null +++ b/lib/k8s/deployment/main.py @@ -0,0 +1,11 @@ +from lib.k8s.deployment.api import K8sDeploymentApi +from lib.k8s.deployment.info import K8sDeploymentInfo + + +class K8sDeployment( + K8sDeploymentApi, + K8sDeploymentInfo + ): + def __init__(self): + K8sDeploymentApi.__init__(self) + K8sDeploymentInfo.__init__(self) diff --git a/lib/k8s/deployment/output.py b/lib/k8s/deployment/output.py new file mode 100644 index 00000000..108205a1 --- /dev/null +++ b/lib/k8s/deployment/output.py @@ -0,0 +1,96 @@ +class K8sDeploymentOutput(): + def __init__(self): + pass + + def print_deployments(self, info, title=False): + if title: + self.my_output.default( + 'Deployment [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'readyT', + 'updatedReplicas', + 'availableReplicas', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Ready', + 'Up-To-Date', + 'Available', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_deployments_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Deployment - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'Deployment', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'annotationT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/deployment_config/__init__.py b/lib/k8s/deployment_config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/deployment_config/api.py b/lib/k8s/deployment_config/api.py new file mode 100644 index 00000000..78bbfa52 --- /dev/null +++ b/lib/k8s/deployment_config/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sDeploymentConfigApi(): + def __init__(self): + self.deployment_config_mo = None + + def get_deployment_config_mo(self, cache_enabled=True): + if cache_enabled: + if self.deployment_config_mo is not None: + return self.deployment_config_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='apps.openshift.io/v1', + kind='DeploymentConfig' + ) + self.deployment_config_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'deployment_config', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_deployment_config_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'deployment_config', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'deployment_config', + self.deployment_config_mo + ) + + return self.deployment_config_mo diff --git a/lib/k8s/deployment_config/info.py b/lib/k8s/deployment_config/info.py new file mode 100644 index 00000000..b5777493 --- /dev/null +++ b/lib/k8s/deployment_config/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sDeploymentConfigInfo(): + def __init__(self): + self.deployment_config = None + + def get_deployment_config_info(self, deployment_config_mo): + if deployment_config_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + deployment_config_mo + ) + info.update(metadata_info) + + return info + + def get_deployment_configs_info(self, cache_enabled=True): + if cache_enabled: + if self.deployment_config is not None: + return self.deployment_config + + managed_objects = self.get_deployment_config_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.deployment_config = [] + for managed_object in managed_objects: + deployment_config_info = {} + deployment_config_info['info'] = self.get_deployment_config_info( + managed_object + ) + deployment_config_info['mo'] = managed_object + self.deployment_config.append( + deployment_config_info + ) + + return self.deployment_config + + def match_deployment_config(self, deployment_config_info, deployment_config_filter): + if deployment_config_filter is None or len(deployment_config_filter) == 0: + return True + + for ap_rule in deployment_config_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_deployment_config', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_deployment_configs(self, object_filter=None, return_mo=False, cache_enabled=True): + all_deployment_configs = self.get_deployment_configs_info(cache_enabled=cache_enabled) + if all_deployment_configs is None: + return None + + deployment_configs = [] + + for deployment_config_info in all_deployment_configs: + if not self.match_deployment_config(deployment_config_info['info'], object_filter): + continue + + if return_mo: + deployment_configs.append( + deployment_config_info['mo'] + ) + continue + + deployment_configs.append( + deployment_config_info['info'] + ) + + return deployment_configs diff --git a/lib/k8s/deployment_config/main.py b/lib/k8s/deployment_config/main.py new file mode 100644 index 00000000..89cdde4e --- /dev/null +++ b/lib/k8s/deployment_config/main.py @@ -0,0 +1,11 @@ +from lib.k8s.deployment_config.api import K8sDeploymentConfigApi +from lib.k8s.deployment_config.info import K8sDeploymentConfigInfo + + +class K8sDeploymentConfig( + K8sDeploymentConfigApi, + K8sDeploymentConfigInfo + ): + def __init__(self): + K8sDeploymentConfigApi.__init__(self) + K8sDeploymentConfigInfo.__init__(self) diff --git a/lib/k8s/deployment_config/output.py b/lib/k8s/deployment_config/output.py new file mode 100644 index 00000000..d2b74063 --- /dev/null +++ b/lib/k8s/deployment_config/output.py @@ -0,0 +1,33 @@ +class K8sDeploymentConfigOutput(): + def __init__(self): + pass + + def print_deployment_configs(self, info, title=False): + if title: + self.my_output.default( + 'Deployment Config [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/egress_ip/__init__.py b/lib/k8s/egress_ip/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/egress_ip/api.py b/lib/k8s/egress_ip/api.py new file mode 100644 index 00000000..4f2bb4cc --- /dev/null +++ b/lib/k8s/egress_ip/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sEgressIpApi(): + def __init__(self): + self.egress_ip_mo = None + + def get_egress_ip_mo(self, cache_enabled=True): + if cache_enabled: + if self.egress_ip_mo is not None: + return self.egress_ip_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='k8s.ovn.org/v1', + kind='EgressIP' + ) + self.egress_ip_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'egress_ip', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_egress_ip_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'egress_ip', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'egress_ip', + self.egress_ip_mo + ) + + return self.egress_ip_mo diff --git a/lib/k8s/egress_ip/info.py b/lib/k8s/egress_ip/info.py new file mode 100644 index 00000000..9238bd40 --- /dev/null +++ b/lib/k8s/egress_ip/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sEgressIpInfo(): + def __init__(self): + self.egress_ip = None + + def get_egress_ip_info(self, egress_ip_mo): + if egress_ip_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + egress_ip_mo + ) + info.update(metadata_info) + + return info + + def get_egress_ips_info(self, cache_enabled=True): + if cache_enabled: + if self.egress_ip is not None: + return self.egress_ip + + managed_objects = self.get_egress_ip_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.egress_ip = [] + for managed_object in managed_objects: + egress_ip_info = {} + egress_ip_info['info'] = self.get_egress_ip_info( + managed_object + ) + egress_ip_info['mo'] = managed_object + self.egress_ip.append( + egress_ip_info + ) + + return self.egress_ip + + def match_egress_ip(self, egress_ip_info, egress_ip_filter): + if egress_ip_filter is None or len(egress_ip_filter) == 0: + return True + + for ap_rule in egress_ip_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_egress_ip', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_egress_ips(self, object_filter=None, return_mo=False, cache_enabled=True): + all_egress_ips = self.get_egress_ips_info(cache_enabled=cache_enabled) + if all_egress_ips is None: + return None + + egress_ips = [] + + for egress_ip_info in all_egress_ips: + if not self.match_egress_ip(egress_ip_info['info'], object_filter): + continue + + if return_mo: + egress_ips.append( + egress_ip_info['mo'] + ) + continue + + egress_ips.append( + egress_ip_info['info'] + ) + + return egress_ips diff --git a/lib/k8s/egress_ip/main.py b/lib/k8s/egress_ip/main.py new file mode 100644 index 00000000..9287b06b --- /dev/null +++ b/lib/k8s/egress_ip/main.py @@ -0,0 +1,11 @@ +from lib.k8s.egress_ip.api import K8sEgressIpApi +from lib.k8s.egress_ip.info import K8sEgressIpInfo + + +class K8sEgressIp( + K8sEgressIpApi, + K8sEgressIpInfo + ): + def __init__(self): + K8sEgressIpApi.__init__(self) + K8sEgressIpInfo.__init__(self) diff --git a/lib/k8s/egress_ip/output.py b/lib/k8s/egress_ip/output.py new file mode 100644 index 00000000..5029a77f --- /dev/null +++ b/lib/k8s/egress_ip/output.py @@ -0,0 +1,33 @@ +class K8sEgressIpOutput(): + def __init__(self): + pass + + def print_egress_ips(self, info, title=False): + if title: + self.my_output.default( + 'Egress IP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/egress_router/__init__.py b/lib/k8s/egress_router/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/egress_router/api.py b/lib/k8s/egress_router/api.py new file mode 100644 index 00000000..800e06dd --- /dev/null +++ b/lib/k8s/egress_router/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sEgressRouterApi(): + def __init__(self): + self.egress_router_mo = None + + def get_egress_router_mo(self, cache_enabled=True): + if cache_enabled: + if self.egress_router_mo is not None: + return self.egress_router_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='k8s.ovn.org/v1', + kind='EgressIP' + ) + self.egress_router_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'egress_router', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_egress_router_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'egress_router', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'egress_router', + self.egress_router_mo + ) + + return self.egress_router_mo diff --git a/lib/k8s/egress_router/info.py b/lib/k8s/egress_router/info.py new file mode 100644 index 00000000..8aa8e344 --- /dev/null +++ b/lib/k8s/egress_router/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sEgressRouterInfo(): + def __init__(self): + self.egress_router = None + + def get_egress_router_info(self, egress_router_mo): + if egress_router_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + egress_router_mo + ) + info.update(metadata_info) + + return info + + def get_egress_routers_info(self, cache_enabled=True): + if cache_enabled: + if self.egress_router is not None: + return self.egress_router + + managed_objects = self.get_egress_router_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.egress_router = [] + for managed_object in managed_objects: + egress_router_info = {} + egress_router_info['info'] = self.get_egress_router_info( + managed_object + ) + egress_router_info['mo'] = managed_object + self.egress_router.append( + egress_router_info + ) + + return self.egress_router + + def match_egress_router(self, egress_router_info, egress_router_filter): + if egress_router_filter is None or len(egress_router_filter) == 0: + return True + + for ap_rule in egress_router_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_egress_router', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_egress_routers(self, object_filter=None, return_mo=False, cache_enabled=True): + all_egress_routers = self.get_egress_routers_info(cache_enabled=cache_enabled) + if all_egress_routers is None: + return None + + egress_routers = [] + + for egress_router_info in all_egress_routers: + if not self.match_egress_router(egress_router_info['info'], object_filter): + continue + + if return_mo: + egress_routers.append( + egress_router_info['mo'] + ) + continue + + egress_routers.append( + egress_router_info['info'] + ) + + return egress_routers diff --git a/lib/k8s/egress_router/main.py b/lib/k8s/egress_router/main.py new file mode 100644 index 00000000..50ad9a9b --- /dev/null +++ b/lib/k8s/egress_router/main.py @@ -0,0 +1,11 @@ +from lib.k8s.egress_router.api import K8sEgressRouterApi +from lib.k8s.egress_router.info import K8sEgressRouterInfo + + +class K8sEgressRouter( + K8sEgressRouterApi, + K8sEgressRouterInfo + ): + def __init__(self): + K8sEgressRouterApi.__init__(self) + K8sEgressRouterInfo.__init__(self) diff --git a/lib/k8s/egress_router/output.py b/lib/k8s/egress_router/output.py new file mode 100644 index 00000000..e22344b1 --- /dev/null +++ b/lib/k8s/egress_router/output.py @@ -0,0 +1,33 @@ +class K8sEgressRouterOutput(): + def __init__(self): + pass + + def print_egress_routers(self, info, title=False): + if title: + self.my_output.default( + 'Egress Router [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/endpoint/__init__.py b/lib/k8s/endpoint/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/endpoint/api.py b/lib/k8s/endpoint/api.py new file mode 100644 index 00000000..770e91cc --- /dev/null +++ b/lib/k8s/endpoint/api.py @@ -0,0 +1,53 @@ +import time +import traceback + + +class K8sEndpointApi(): + def __init__(self): + self.endpoint_mo = None + + def get_endpoint_mo(self, cache_enabled=True): + if cache_enabled: + if self.endpoint_mo is not None: + return self.endpoint_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_endpoints_for_all_namespaces + try: + start_time = int(time.time() * 1000) + response = api_handler.list_endpoints_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'endpoint', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s_endpoints.get_endpoints', traceback.format_exc()) + self.log.k8s( + 'get', + 'endpoint', + True, + int(time.time() * 1000) - start_time + ) + return False + + self.endpoint_mo = [] + for item in response.items: + endpoint_mo = self.convert_object(item.to_dict()) + self.endpoint_mo.append( + endpoint_mo + ) + + self.log.k8s_mo( + 'endpoint', + self.endpoint_mo + ) + + return self.endpoint_mo diff --git a/lib/k8s/endpoint/info.py b/lib/k8s/endpoint/info.py new file mode 100644 index 00000000..755c92a4 --- /dev/null +++ b/lib/k8s/endpoint/info.py @@ -0,0 +1,115 @@ +from lib import filter_helper + + +class K8sEndpointInfo(): + def __init__(self): + self.endpoint = None + + def get_endpoint_info(self, endpoint_mo): + if endpoint_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + endpoint_mo + ) + info.update(metadata_info) + + return info + + def get_endpoints_info(self, cache_enabled=True): + if cache_enabled: + if self.endpoint is not None: + return self.endpoint + + managed_objects = self.get_endpoint_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.endpoint = [] + for managed_object in managed_objects: + endpoint_info = {} + endpoint_info['info'] = self.get_endpoint_info( + managed_object + ) + endpoint_info['mo'] = managed_object + self.endpoint.append( + endpoint_info + ) + + return self.endpoint + + def match_endpoint(self, endpoint_info, endpoint_filter): + if endpoint_filter is None or len(endpoint_filter) == 0: + return True + + for ap_rule in endpoint_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, endpoint_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (endpoint_info['namespace'], endpoint_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_endpoint', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_endpoints(self, object_filter=None, return_mo=False, cache_enabled=True): + all_endpoints = self.get_endpoints_info(cache_enabled=cache_enabled) + if all_endpoints is None: + return None + + endpoints = [] + + for endpoint_info in all_endpoints: + if not self.match_endpoint(endpoint_info['info'], object_filter): + continue + + if return_mo: + endpoints.append( + endpoint_info['mo'] + ) + continue + + endpoints.append( + endpoint_info['info'] + ) + + endpoints = sorted( + endpoints, + key=lambda i: ( + i['namespace'], + i['name'] + ) + ) + + return endpoints + + def get_endpoint(self, namespace, name): + endpoint_filter = [] + endpoint_filter.append('namespace:%s' % (namespace)) + endpoint_filter.append('name:%s' % (name)) + + endpoints = self.get_endpoints( + object_filter=endpoint_filter + ) + + if endpoints is None or len(endpoints) != 1: + return None + + return endpoints[0] diff --git a/lib/k8s/endpoint/main.py b/lib/k8s/endpoint/main.py new file mode 100644 index 00000000..2ecbaf37 --- /dev/null +++ b/lib/k8s/endpoint/main.py @@ -0,0 +1,11 @@ +from lib.k8s.endpoint.api import K8sEndpointApi +from lib.k8s.endpoint.info import K8sEndpointInfo + + +class K8sEndpoint( + K8sEndpointApi, + K8sEndpointInfo + ): + def __init__(self): + K8sEndpointApi.__init__(self) + K8sEndpointInfo.__init__(self) diff --git a/lib/k8s/endpoint/output.py b/lib/k8s/endpoint/output.py new file mode 100644 index 00000000..c90cd4f7 --- /dev/null +++ b/lib/k8s/endpoint/output.py @@ -0,0 +1,37 @@ +class K8sEndpointOutput(): + def __init__(self): + pass + + def print_endpoints(self, info, title=False): + if title: + self.my_output.default( + 'Endpoint - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/event/__init__.py b/lib/k8s/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/event/api.py b/lib/k8s/event/api.py new file mode 100644 index 00000000..272c4399 --- /dev/null +++ b/lib/k8s/event/api.py @@ -0,0 +1,53 @@ +import time +import traceback + + +class K8sEventApi(): + def __init__(self): + self.event_mo = None + + def get_event_mo(self, cache_enabled=True): + if cache_enabled: + if self.event_mo is not None: + return self.event_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_event_for_all_namespaces + try: + start_time = int(time.time() * 1000) + response = api_handler.list_event_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'event', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s_events.get_events', traceback.format_exc()) + self.log.k8s( + 'get', + 'event', + True, + int(time.time() * 1000) - start_time + ) + return False + + self.event_mo = [] + for item in response.items: + event_mo = self.convert_object(item.to_dict()) + self.event_mo.append( + event_mo + ) + + self.log.k8s_mo( + 'event', + self.event_mo + ) + + return self.event_mo diff --git a/lib/k8s/event/info.py b/lib/k8s/event/info.py new file mode 100644 index 00000000..f0b75752 --- /dev/null +++ b/lib/k8s/event/info.py @@ -0,0 +1,141 @@ +from lib import filter_helper + + +class K8sEventInfo(): + def __init__(self): + self.event = None + + def get_event_info(self, event_mo): + if event_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['message'] = self.get(event_mo, 'message') + info['count'] = self.get(event_mo, 'count') + info['action'] = self.get(event_mo, 'action') + info['reason'] = self.get(event_mo, 'reason') + info['type'] = self.get(event_mo, 'type') + info['obj_kind'] = self.get(event_mo, 'involved_object:kind') + info['obj_namespace'] = self.get(event_mo, 'involved_object:namespace') + if info['obj_namespace'] is None: + info['obj_namespace'] = self.get(event_mo, 'metadata:namespace') + info['obj_name'] = self.get(event_mo, 'involved_object:name') + info['obj_uid'] = self.get(event_mo, 'involved_object:uid') + info['src_component'] = self.get(event_mo, 'source:component') + info['src_host'] = self.get(event_mo, 'source:host') + + info['first_timestamp'] = self.get(event_mo, 'first_timestamp') + info['first_timestamp_epoch'] = self.convert_timestamp( + self.get(event_mo, 'first_timestamp') + ) + info['first_timestamp_age'] = self.convert_timestamp_to_age( + info['first_timestamp'], + on_error='--' + ) + + info['last_timestamp'] = self.get(event_mo, 'last_timestamp') + info['last_timestamp_epoch'] = self.convert_timestamp( + self.get(event_mo, 'last_timestamp') + ) + info['last_timestamp_age'] = self.convert_timestamp_to_age( + info['last_timestamp'], + on_error='--' + ) + + return info + + def get_events_info(self, cache_enabled=True): + if cache_enabled: + if self.event is not None: + return self.event + + managed_objects = self.get_event_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.event = [] + for managed_object in managed_objects: + event_info = {} + event_info['info'] = self.get_event_info( + managed_object + ) + event_info['mo'] = managed_object + self.event.append( + event_info + ) + + return self.event + + def match_event(self, event_info, event_filter): + if event_filter is None or len(event_filter) == 0: + return True + + for ap_rule in event_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'kind': + key_found = True + if not filter_helper.match_string(value, event_info['obj_kind']): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, event_info['obj_namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, event_info['obj_name']): + return False + + if key == 'uid': + key_found = True + if not filter_helper.match_string(value, event_info['obj_uid']): + return False + + if key == 'message': + key_found = True + if not filter_helper.match_string(value, event_info['message']): + return False + + if not key_found: + self.log.error( + 'match_event', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_events(self, object_filter=None, return_mo=False, cache_enabled=True): + all_events = self.get_events_info(cache_enabled=cache_enabled) + if all_events is None: + return None + + events = [] + + for event_info in all_events: + if not self.match_event(event_info['info'], object_filter): + continue + + if return_mo: + events.append( + event_info['mo'] + ) + continue + + events.append( + event_info['info'] + ) + + if not return_mo: + events = sorted( + events, + key=lambda i: i['last_timestamp_epoch'] + ) + + return events diff --git a/lib/k8s/event/main.py b/lib/k8s/event/main.py new file mode 100644 index 00000000..124c3a8e --- /dev/null +++ b/lib/k8s/event/main.py @@ -0,0 +1,11 @@ +from lib.k8s.event.api import K8sEventApi +from lib.k8s.event.info import K8sEventInfo + + +class K8sEvent( + K8sEventApi, + K8sEventInfo + ): + def __init__(self): + K8sEventApi.__init__(self) + K8sEventInfo.__init__(self) diff --git a/lib/k8s/event/output.py b/lib/k8s/event/output.py new file mode 100644 index 00000000..0d59442e --- /dev/null +++ b/lib/k8s/event/output.py @@ -0,0 +1,68 @@ +from lib import filter_helper + + +class K8sEventOutput(): + def __init__(self): + pass + + def print_events(self, info, title=False): + if title: + self.my_output.default( + 'Event [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['ageT'] = [] + item['ageT'].append('First: %s' % (item['first_timestamp_age'])) + item['ageT'].append('Last: %s' % (item['last_timestamp_age'])) + + order = [ + 'objT', + 'ageT', + 'count', + 'messageT', + 'type', + 'reason', + 'action' + ] + + headers = [ + 'Object', + 'When', + 'Count', + 'Message', + 'Type', + 'Reason', + 'Action' + ] + + chunk = {} + chunk['message'] = 40 + empty = ['type', 'reason', 'action'] + collapse = {} + collapse['objT'] = ['obj_kind', 'obj_namespace', 'obj_name', 'obj_uid'] + + self.my_output.my_table( + self.my_output.expand_lists( + self.my_output.prepare_list( + info, + chunk=chunk, + empty=empty, + collapse=collapse + ), + order, + ['objT', 'ageT', 'messageT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/ingress/__init__.py b/lib/k8s/ingress/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/ingress/api.py b/lib/k8s/ingress/api.py new file mode 100644 index 00000000..11e34f7b --- /dev/null +++ b/lib/k8s/ingress/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sIngressApi(): + def __init__(self): + self.ingress_mo = None + + def get_ingress_mo(self, cache_enabled=True): + if cache_enabled: + if self.ingress_mo is not None: + return self.ingress_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='networking.k8s.io/v1', + kind='Ingress' + ) + self.ingress_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'ingress', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_ingress_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'ingress', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'ingress', + self.ingress_mo + ) + + return self.ingress_mo diff --git a/lib/k8s/ingress/info.py b/lib/k8s/ingress/info.py new file mode 100644 index 00000000..fb1ad568 --- /dev/null +++ b/lib/k8s/ingress/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sIngressInfo(): + def __init__(self): + self.ingress = None + + def get_ingress_info(self, ingress_mo): + if ingress_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + ingress_mo + ) + info.update(metadata_info) + + return info + + def get_ingresses_info(self, cache_enabled=True): + if cache_enabled: + if self.ingress is not None: + return self.ingress + + managed_objects = self.get_ingress_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.ingress = [] + for managed_object in managed_objects: + ingress_info = {} + ingress_info['info'] = self.get_ingress_info( + managed_object + ) + ingress_info['mo'] = managed_object + self.ingress.append( + ingress_info + ) + + return self.ingress + + def match_ingress(self, ingress_info, ingress_filter): + if ingress_filter is None or len(ingress_filter) == 0: + return True + + for ap_rule in ingress_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_ingress', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_ingresses(self, object_filter=None, return_mo=False, cache_enabled=True): + all_ingresses = self.get_ingresses_info(cache_enabled=cache_enabled) + if all_ingresses is None: + return None + + ingresses = [] + + for ingress_info in all_ingresses: + if not self.match_ingress(ingress_info['info'], object_filter): + continue + + if return_mo: + ingresses.append( + ingress_info['mo'] + ) + continue + + ingresses.append( + ingress_info['info'] + ) + + return ingresses diff --git a/lib/k8s/ingress/main.py b/lib/k8s/ingress/main.py new file mode 100644 index 00000000..35c3ba47 --- /dev/null +++ b/lib/k8s/ingress/main.py @@ -0,0 +1,11 @@ +from lib.k8s.ingress.api import K8sIngressApi +from lib.k8s.ingress.info import K8sIngressInfo + + +class K8sIngress( + K8sIngressApi, + K8sIngressInfo + ): + def __init__(self): + K8sIngressApi.__init__(self) + K8sIngressInfo.__init__(self) diff --git a/lib/k8s/ingress/output.py b/lib/k8s/ingress/output.py new file mode 100644 index 00000000..072b2e1d --- /dev/null +++ b/lib/k8s/ingress/output.py @@ -0,0 +1,33 @@ +class K8sIngressOutput(): + def __init__(self): + pass + + def print_ingresses(self, info, title=False): + if title: + self.my_output.default( + 'Ingress [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/kubevirt/__init__.py b/lib/k8s/kubevirt/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/kubevirt/api.py b/lib/k8s/kubevirt/api.py new file mode 100644 index 00000000..67abb27f --- /dev/null +++ b/lib/k8s/kubevirt/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sKubevirtApi(): + def __init__(self): + self.kubevirt_mo = None + + def get_kubevirt_mo(self, cache_enabled=True): + if cache_enabled: + if self.kubevirt_mo is not None: + return self.kubevirt_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='KubeVirt' + ) + self.kubevirt_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'kubevirt', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_kubevirt_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'kubevirt', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'kubevirt', + self.kubevirt_mo + ) + + return self.kubevirt_mo diff --git a/lib/k8s/kubevirt/info.py b/lib/k8s/kubevirt/info.py new file mode 100644 index 00000000..84a9deb4 --- /dev/null +++ b/lib/k8s/kubevirt/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sKubevirtInfo(): + def __init__(self): + self.kubevirt = None + + def get_kubevirt_info(self, kubevirt_mo): + if kubevirt_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_kubevirts_info(self, cache_enabled=True): + if cache_enabled: + if self.kubevirt is not None: + return self.kubevirt + + managed_objects = self.get_kubevirt_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.kubevirt = [] + for managed_object in managed_objects: + kubevirt_info = {} + kubevirt_info['info'] = self.get_kubevirt_info( + managed_object + ) + kubevirt_info['mo'] = managed_object + self.kubevirt.append( + kubevirt_info + ) + + return self.kubevirt + + def match_kubevirt(self, kubevirt_info, kubevirt_filter): + if kubevirt_filter is None or len(kubevirt_filter) == 0: + return True + + for ap_rule in kubevirt_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_kubevirt', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_kubevirts(self, object_filter=None, return_mo=False, cache_enabled=True): + all_kubevirts = self.get_kubevirts_info(cache_enabled=cache_enabled) + if all_kubevirts is None: + return None + + kubevirts = [] + + for kubevirt_info in all_kubevirts: + if not self.match_kubevirt(kubevirt_info['info'], object_filter): + continue + + if return_mo: + kubevirts.append( + kubevirt_info['mo'] + ) + continue + + kubevirts.append( + kubevirt_info['info'] + ) + + return kubevirts diff --git a/lib/k8s/kubevirt/main.py b/lib/k8s/kubevirt/main.py new file mode 100644 index 00000000..84d9a5dd --- /dev/null +++ b/lib/k8s/kubevirt/main.py @@ -0,0 +1,11 @@ +from lib.k8s.kubevirt.api import K8sKubevirtApi +from lib.k8s.kubevirt.info import K8sKubevirtInfo + + +class K8sKubevirt( + K8sKubevirtApi, + K8sKubevirtInfo + ): + def __init__(self): + K8sKubevirtApi.__init__(self) + K8sKubevirtInfo.__init__(self) diff --git a/lib/k8s/kubevirt/output.py b/lib/k8s/kubevirt/output.py new file mode 100644 index 00000000..eeb80787 --- /dev/null +++ b/lib/k8s/kubevirt/output.py @@ -0,0 +1,33 @@ +class K8sKubevirtOutput(): + def __init__(self): + pass + + def print_kubevirts(self, info, title=False): + if title: + self.my_output.default( + 'Kubevirt [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/limit/__init__.py b/lib/k8s/limit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/limit/api.py b/lib/k8s/limit/api.py new file mode 100644 index 00000000..2f77f51c --- /dev/null +++ b/lib/k8s/limit/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sLimitApi(): + def __init__(self): + self.limit_mo = None + + def get_limit_mo(self, cache_enabled=True): + if cache_enabled: + if self.limit_mo is not None: + return self.limit_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='v1', + kind='LimitRange' + ) + self.limit_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'limit', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_limit_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'limit', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'limit', + self.limit_mo + ) + + return self.limit_mo diff --git a/lib/k8s/limit/info.py b/lib/k8s/limit/info.py new file mode 100644 index 00000000..bac62b7f --- /dev/null +++ b/lib/k8s/limit/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sLimitInfo(): + def __init__(self): + self.limit = None + + def get_limit_info(self, limit_mo): + if limit_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_limits_info(self, cache_enabled=True): + if cache_enabled: + if self.limit is not None: + return self.limit + + managed_objects = self.get_limit_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.limit = [] + for managed_object in managed_objects: + limit_info = {} + limit_info['info'] = self.get_limit_info( + managed_object + ) + limit_info['mo'] = managed_object + self.limit.append( + limit_info + ) + + return self.limit + + def match_limit(self, limit_info, limit_filter): + if limit_filter is None or len(limit_filter) == 0: + return True + + for ap_rule in limit_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_limit', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_limits(self, object_filter=None, return_mo=False, cache_enabled=True): + all_limits = self.get_limits_info(cache_enabled=cache_enabled) + if all_limits is None: + return None + + limits = [] + + for limit_info in all_limits: + if not self.match_limit(limit_info['info'], object_filter): + continue + + if return_mo: + limits.append( + limit_info['mo'] + ) + continue + + limits.append( + limit_info['info'] + ) + + return limits diff --git a/lib/k8s/limit/main.py b/lib/k8s/limit/main.py new file mode 100644 index 00000000..f7b34de9 --- /dev/null +++ b/lib/k8s/limit/main.py @@ -0,0 +1,11 @@ +from lib.k8s.limit.api import K8sLimitApi +from lib.k8s.limit.info import K8sLimitInfo + + +class K8sLimit( + K8sLimitApi, + K8sLimitInfo + ): + def __init__(self): + K8sLimitApi.__init__(self) + K8sLimitInfo.__init__(self) diff --git a/lib/k8s/limit/output.py b/lib/k8s/limit/output.py new file mode 100644 index 00000000..04eebfc0 --- /dev/null +++ b/lib/k8s/limit/output.py @@ -0,0 +1,33 @@ +class K8sLimitOutput(): + def __init__(self): + pass + + def print_limits(self, info, title=False): + if title: + self.my_output.default( + 'Limit [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/machine_config/__init__.py b/lib/k8s/machine_config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/machine_config/api.py b/lib/k8s/machine_config/api.py new file mode 100644 index 00000000..48637cad --- /dev/null +++ b/lib/k8s/machine_config/api.py @@ -0,0 +1,79 @@ +import time +import traceback + + +class K8sMachineConfigApi(): + def __init__(self): + self.machine_config_mo = None + + def get_machine_config_mo(self, cache_enabled=True): + if cache_enabled: + if self.machine_config_mo is not None: + return self.machine_config_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='machineconfiguration.openshift.io/v1', + kind='MachineConfig' + ) + self.machine_config_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'machine_config', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_machine_config_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'machine_config', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'machine_config', + self.machine_config_mo + ) + + return self.machine_config_mo + + def set_machine_config_mo(self, body): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='machineconfiguration.openshift.io/v1', kind='MachineConfig') + response = obj_list.replace( + body=body + ) + self.log.k8s( + 'set', + 'machine_config', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_machine_config_mo', traceback.format_exc()) + self.log.k8s( + 'set', + 'machine_config', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return False + + return True diff --git a/lib/k8s/machine_config/info.py b/lib/k8s/machine_config/info.py new file mode 100644 index 00000000..adabd1d3 --- /dev/null +++ b/lib/k8s/machine_config/info.py @@ -0,0 +1,384 @@ +import base64 +import gzip + +from lib import file_helper +from lib import filter_helper + + +class K8sMachineConfigInfo(): + def __init__(self): + self.machine_config = None + + def get_machine_config_info(self, machine_config_mo): + if machine_config_mo is None: + return None + + info = {} + info['__Output'] = {} + info['name'] = self.get(machine_config_mo, 'metadata:name') + + info['generated_by'] = self.get(machine_config_mo, 'metadata:annotations:machineconfiguration.openshift.io/generated-by-controller-version', on_error='--', on_none='--') + + owner = self.get_metadata_owner_info( + machine_config_mo, + 'metadata:ownerReferences' + ) + info.update(owner) + + info['label'] = self.get(machine_config_mo, 'metadata:labels', on_error={}, on_none={}) + info['node'] = [] + if info['owner_kind'] != 'MachineConfigPool': + if 'machineconfiguration.openshift.io/role' not in info['label']: + self.log.error( + 'get_machine_config_info', + 'Unexpected machine config label: %s' % (info['name']) + ) + else: + node_role = info['label']['machineconfiguration.openshift.io/role'] + if node_role not in ['master', 'worker']: + self.log.error( + 'get_machine_config_info', + 'Unexpected machine config node role: %s' % (info['name']) + ) + else: + if node_role == 'master': + info['node'] = self.get_master_nodes_name() + + if node_role == 'worker': + info['node'] = self.get_worker_nodes_name() + + # https://coreos.github.io/ignition/configuration-v3_2/ + info['ignition_version'] = self.get(machine_config_mo, 'spec:config:ignition:version') + + info['file'] = [] + files_mo = self.get(machine_config_mo, 'spec:config:storage:files', on_error=[], on_none=[]) + for file_mo in files_mo: + file_info = {} + file_info['path'] = self.get(file_mo, 'path') + file_info['overwrite'] = self.get(file_mo, 'overwrite', on_error=False, on_none=False) + file_info['mode'] = self.get(file_mo, 'mode', on_error=420, on_none=420) + file_info['umode'] = oct(file_info['mode']).replace('0o', '0x') + + file_source = self.get(file_mo, 'contents:source') + compression = self.get(file_mo, 'contents:compression', on_error=None, on_none=None) + if file_source is None: + file_info['content'] = 'Undefined' + else: + file_info['content'] = 'Unsupported format' + if file_source.startswith('data:text/plain;charset=utf-8;base64,'): + file_info['content'] = base64.b64decode( + file_source.split('data:text/plain;charset=utf-8;base64,')[1] + ).decode('utf-8') + if file_source.startswith('data:;base64,'): + if compression is not None and compression == 'gzip': + file_info['content'] = gzip.decompress( + base64.b64decode( + file_source.split('data:;base64,')[1].encode('utf-8') + ) + ).decode('utf-8') + + if file_source.startswith('data:,'): + if len(file_source.split('data:,')) == 1: + file_info['content'] = '' + else: + file_info['content'] = file_helper.decode_ascii( + file_source.split('data:,')[1] + ) + + info['file'].append( + file_info + ) + + info['file'] = sorted( + info['file'], + key=lambda i: i['path'] + ) + info['fileCount'] = len(info['file']) + + info['systemd'] = [] + systemds_mo = self.get(machine_config_mo, 'spec:config:systemd:units', on_error=[], on_none=[]) + for systemd_mo in systemds_mo: + systemd_info = {} + systemd_info['name'] = self.get(systemd_mo, 'name') + systemd_info['enabled'] = str(self.get(systemd_mo, 'enabled', on_error='--', on_none='--')) + systemd_info['content'] = self.get(systemd_mo, 'contents') + systemd_info['dropin'] = self.get(systemd_mo, 'dropins', on_error=[], on_none=[]) + info['systemd'].append( + systemd_info + ) + + info['systemd'] = sorted( + info['systemd'], + key=lambda i: i['name'] + ) + info['systemdCount'] = len(info['systemd']) + + info['users'] = [] + users_mo = self.get(machine_config_mo, 'spec:config:passwd:users', on_error=[], on_none=[]) + for user_mo in users_mo: + user_info = {} + user_info['username'] = self.get(user_mo, 'name') + user_info['keys'] = self.get(user_mo, 'sshAuthorizedKeys') + info['users'].append( + user_info + ) + + info['users'] = sorted( + info['users'], + key=lambda i: i['username'] + ) + info['usersCount'] = len(info['users']) + + info['age'] = self.convert_timestamp_to_age( + self.get(machine_config_mo, 'metadata:creationTimestamp'), + on_error='--' + ) + + return info + + def get_machine_configs_info(self, cache_enabled=True): + if cache_enabled: + if self.machine_config is not None: + return self.machine_config + + managed_objects = self.get_machine_config_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.machine_config = [] + for managed_object in managed_objects: + machine_config_info = {} + machine_config_info['info'] = self.get_machine_config_info( + managed_object + ) + machine_config_info['mo'] = managed_object + self.machine_config.append( + machine_config_info + ) + + return self.machine_config + + def filter_machine_config_label(self, labels, label_filter): + new_labels = {} + + if len(label_filter.split(':')) > 2: + return new_labels + + if len(label_filter.split(':')) == 1: + label_filter_key = label_filter + label_filter_value = None + + if len(label_filter.split(':')) == 2: + (label_filter_key, label_filter_value) = label_filter.split(':') + + for lkey in labels: + if filter_helper.match_string(label_filter_key, lkey): + if label_filter_value is None: + new_labels[lkey] = labels[lkey] + continue + + if filter_helper.match_string(label_filter_value, labels[lkey]): + new_labels[lkey] = labels[lkey] + continue + + return new_labels + + def match_machine_config(self, machine_config_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, machine_config_info['name']): + return False + + if key == 'path': + key_found = True + + if key == 'systemd': + key_found = True + + if key == 'content': + key_found = True + + if key == 'label': + key_found = True + filtered_labels = self.filter_machine_config_label( + machine_config_info['label'], + value + ) + if len(filtered_labels) == 0: + return False + + if not key_found: + self.log.error( + 'match_machine_config', + 'Unsupported key: %s' % (key) + ) + + return True + + def match_machine_config_file(self, machine_config_file_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + + if key == 'path': + key_found = True + if not filter_helper.match_string(value, machine_config_file_info['path']): + return False + + if key == 'systemd': + key_found = True + + if key == 'content': + key_found = True + if not filter_helper.match_string(value, machine_config_file_info['content']): + return False + + if key == 'label': + key_found = True + + if not key_found: + self.log.error( + 'match_machine_config_file', + 'Unsupported key: %s' % (key) + ) + + return True + + def match_machine_config_systemd(self, machine_config_systemd_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + + if key == 'path': + key_found = True + found = False + for dropin in machine_config_systemd_info['dropin']: + if filter_helper.match_string(value, dropin['name']): + found = True + break + + if not found: + return False + + if key == 'systemd': + key_found = True + if not filter_helper.match_string(value, machine_config_systemd_info['name']): + return False + + if key == 'content': + key_found = True + + if machine_config_systemd_info['content'] is not None: + if not filter_helper.match_string(value, machine_config_systemd_info['content']): + return False + + if len(machine_config_systemd_info['dropin']) > 0: + found = False + for dropin in machine_config_systemd_info['dropin']: + if filter_helper.match_string(value, dropin['contents']): + found = True + break + + if not found: + return False + + if machine_config_systemd_info['content'] is None and len(machine_config_systemd_info['dropin']) == 0: + return False + + if key == 'label': + key_found = True + + if not key_found: + self.log.error( + 'match_machine_config_file', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_machine_configs(self, object_filter=None, return_mo=False, cache_enabled=True): + all_machine_configs = self.get_machine_configs_info(cache_enabled=cache_enabled) + if all_machine_configs is None: + return None + + machine_configs = [] + + for machine_config_info in all_machine_configs: + if not self.match_machine_config(machine_config_info['info'], object_filter): + continue + + if return_mo: + machine_configs.append( + machine_config_info['mo'] + ) + continue + + files_info = [] + for file_info in machine_config_info['info']['file']: + if self.match_machine_config_file(file_info, object_filter): + files_info.append( + file_info + ) + machine_config_info['info']['file'] = files_info + + systemsd_info = [] + for systemd_info in machine_config_info['info']['systemd']: + if self.match_machine_config_systemd(systemd_info, object_filter): + systemsd_info.append( + systemd_info + ) + machine_config_info['info']['systemd'] = systemsd_info + + machine_configs.append( + machine_config_info['info'] + ) + + return machine_configs + + def is_machine_config(self, name, cache_enabled=True): + if self.get_machine_config(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_machine_config(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + machine_configs = self.get_machine_configs( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if machine_configs is None: + return None + + if len(machine_configs) == 1: + return machine_configs[0] + + return None diff --git a/lib/k8s/machine_config/main.py b/lib/k8s/machine_config/main.py new file mode 100644 index 00000000..c2f7318e --- /dev/null +++ b/lib/k8s/machine_config/main.py @@ -0,0 +1,11 @@ +from lib.k8s.machine_config.api import K8sMachineConfigApi +from lib.k8s.machine_config.info import K8sMachineConfigInfo + + +class K8sMachineConfig( + K8sMachineConfigApi, + K8sMachineConfigInfo + ): + def __init__(self): + K8sMachineConfigApi.__init__(self) + K8sMachineConfigInfo.__init__(self) diff --git a/lib/k8s/machine_config/output.py b/lib/k8s/machine_config/output.py new file mode 100644 index 00000000..e757d97b --- /dev/null +++ b/lib/k8s/machine_config/output.py @@ -0,0 +1,329 @@ +class K8sMachineConfigOutput(): + def __init__(self): + pass + + def print_machine_configs(self, info, title=False): + if title: + self.my_output.default( + 'Machine Config (MC) - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['labelT'] = [] + for key in item['label']: + item['labelT'].append( + '%s:%s' % ( + key.replace('machineconfiguration.openshift.io/', ''), + item['label'][key] + ) + ) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + info = self.my_output.prepare_list( + info, + empty=['labelT'] + ) + + order = [ + 'name', + 'ownerT', + 'labelT', + 'generated_by', + 'ignition_version', + 'fileCount', + 'systemdCount', + 'usersCount', + 'age' + ] + + headers = [ + 'Name', + 'Owner', + 'Label', + 'Generated By', + 'Ignition', + 'File', + 'Systemd', + 'User', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ownerT', 'labelT'] + ), + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_machine_configs_file(self, info, title=False): + new_info = [] + for item in info: + for file_info in item['file']: + new_item = {} + new_item['name'] = item['name'] + for key in file_info: + new_item[key] = file_info[key] + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'Machine Config (MC) - File [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'path', + 'overwrite', + 'umode' + ] + + headers = [ + 'Name', + 'Path', + 'Overwrite', + 'Mode' + ] + + self.my_output.my_table( + new_info, + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_machine_configs_systemd(self, info, title=False): + new_info = [] + for item in info: + for systemd_info in item['systemd']: + new_item = {} + new_item['mcname'] = item['name'] + for key in systemd_info: + new_item[key] = systemd_info[key] + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'Machine Config (MC) - Systemd [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + order = [ + 'mcname', + 'name', + 'enabled' + ] + + headers = [ + 'Name', + 'Systemd', + 'Enabled' + ] + + self.my_output.my_table( + new_info, + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_machine_configs_content_file(self, info, title=False): + new_info = [] + for item in info: + for file_info in item['file']: + new_item = {} + new_item['name'] = item['name'] + for key in file_info: + new_item[key] = file_info[key] + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'Machine Config (MC) - File Content [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + for item in new_info: + order = [ + 'name', + 'path', + 'overwrite', + 'umode' + ] + + headers = [ + 'Name', + 'Path', + 'Overwrite', + 'Mode' + ] + + self.my_output.dictionary( + item, + title='Machine Config File', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + self.my_output.default( + item['content'] + ) + + def print_machine_configs_content_systemd(self, info, title=False): + new_info = [] + for item in info: + for file_info in item['systemd']: + new_item = {} + new_item['mc_name'] = item['name'] + for key in file_info: + new_item[key] = file_info[key] + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'Machine Config (MC) - Systemd Content [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + for item in new_info: + order = [ + 'mc_name', + 'name', + 'enabled' + ] + + headers = [ + 'Name', + 'Systemd', + 'Enabled' + ] + + self.my_output.dictionary( + item, + title='Machine Config Systemd', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + self.my_output.default('') + if item['content'] is not None: + self.my_output.default( + item['content'] + ) + + for dropin in item['dropin']: + self.my_output.default('Name: %s' % (dropin['name']), underline=True) + self.my_output.default( + dropin['contents'] + ) + + def print_machine_configs_user(self, info, title=False): + new_info = [] + for item in info: + for user_info in item['users']: + new_item = {} + new_item['name'] = item['name'] + for key in user_info: + new_item[key] = user_info[key] + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'Machine Config (MC) - Users [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'username', + 'keys' + ] + + headers = [ + 'Name', + 'Username', + 'Authorized Key' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['keys'] + ), + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/machine_config_pool/__init__.py b/lib/k8s/machine_config_pool/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/machine_config_pool/api.py b/lib/k8s/machine_config_pool/api.py new file mode 100644 index 00000000..36784ae0 --- /dev/null +++ b/lib/k8s/machine_config_pool/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sMachineConfigPoolApi(): + def __init__(self): + self.machine_config_pool_mo = None + + def get_machine_config_pool_mo(self, cache_enabled=True): + if cache_enabled: + if self.machine_config_pool_mo is not None: + return self.machine_config_pool_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='machineconfiguration.openshift.io/v1', + kind='MachineConfigPool' + ) + self.machine_config_pool_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'machine_config_pool', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_machine_config_pool_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'machine_config_pool', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'machine_config_pool', + self.machine_config_pool_mo + ) + + return self.machine_config_pool_mo diff --git a/lib/k8s/machine_config_pool/info.py b/lib/k8s/machine_config_pool/info.py new file mode 100644 index 00000000..bfaa77f8 --- /dev/null +++ b/lib/k8s/machine_config_pool/info.py @@ -0,0 +1,299 @@ +import time + +from lib import filter_helper + + +class K8sMachineConfigPoolInfo(): + def __init__(self): + self.machine_config_pool = None + + def get_machine_config_pool_info(self, machine_config_pool_mo): + if machine_config_pool_mo is None: + return None + + info = {} + info['__Output'] = {} + info['name'] = self.get(machine_config_pool_mo, 'metadata:name') + + conditions_mo = self.get(machine_config_pool_mo, 'status:conditions', on_error=[], on_none=[]) + + info['updated'] = None + info['updatedTick'] = '--' + info['__Output']['updatedTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Updated': + if condition_mo['status'] == 'True': + info['updated'] = True + info['updatedTick'] = '\u2713' + info['__Output']['updatedTick'] = 'Green' + + if condition_mo['status'] == 'False': + info['updated'] = False + info['updatedTick'] = '\u2717' + info['__Output']['updatedTick'] = 'Red' + + info['updating'] = None + info['updatingTick'] = '--' + info['__Output']['updatingTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Updating': + if condition_mo['status'] == 'True': + info['updating'] = True + info['updatingTick'] = '\u2713' + info['__Output']['updatingTick'] = 'Red' + + if condition_mo['status'] == 'False': + info['updating'] = False + info['updatingTick'] = '\u2717' + info['__Output']['updatingTick'] = 'Green' + + info['degraded'] = None + info['degradedTick'] = '--' + info['__Output']['degradedTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Degraded': + if condition_mo['status'] == 'True': + info['degraded'] = True + info['degradedTick'] = '\u2713' + info['__Output']['degradedTick'] = 'Red' + + if condition_mo['status'] == 'False': + info['degraded'] = False + info['degradedTick'] = '\u2717' + info['__Output']['degradedTick'] = 'Green' + + keys = [ + 'degradedMachineCount', + 'machineCount', + 'observedGeneration', + 'readyMachineCount', + 'unavailableMachineCount', + 'updatedMachineCount' + ] + for key in keys: + info[key] = self.get(machine_config_pool_mo, 'status:%s' % (key), on_error=-1, on_none=-1) + + info['target_configuration'] = self.get(machine_config_pool_mo, 'spec:configuration:name') + info['current_configuration'] = self.get(machine_config_pool_mo, 'status:configuration:name') + + info['source'] = self.get(machine_config_pool_mo, 'status:configuration:source', on_error=[], on_none=[]) + + info['machine_config_selector'] = self.get(machine_config_pool_mo, 'spec:machineConfigSelector', on_error={}, on_none={}) + info['node_selector'] = self.get(machine_config_pool_mo, 'spec:nodeSelector', on_error={}, on_none={}) + + info['ready'] = True + if info['degraded']: + info['ready'] = False + if info['updating']: + info['ready'] = False + + info['age'] = self.convert_timestamp_to_age( + self.get(machine_config_pool_mo, 'metadata:creationTimestamp'), + on_error='--' + ) + + return info + + def add_machine_config_pool_selector_info(self, machine_config_pool_info): + machine_config_pool_info['candidate_machine_configs'] = [] + if 'matchLabels' in machine_config_pool_info['machine_config_selector']: + machine_config_filter = [] + for machine_config_match_label in machine_config_pool_info['machine_config_selector']['matchLabels']: + machine_config_filter.append( + 'label:%s:%s' % ( + machine_config_match_label, + machine_config_pool_info['machine_config_selector']['matchLabels'][machine_config_match_label] + ) + ) + + machine_configs = self.get_machine_configs( + object_filter=machine_config_filter + ) + if machine_configs is not None: + for machine_config in machine_configs: + machine_config_pool_info['candidate_machine_configs'].append( + machine_config['name'] + ) + + machine_config_pool_info['candidate_nodes'] = [] + if 'matchLabels' in machine_config_pool_info['node_selector']: + node_filter = [] + for node_match_label in machine_config_pool_info['node_selector']['matchLabels']: + node_filter.append( + 'label:%s:%s' % ( + node_match_label, + machine_config_pool_info['node_selector']['matchLabels'][node_match_label] + ) + ) + + nodes = self.get_nodes( + object_filter=node_filter + ) + if nodes is not None: + for node in nodes: + machine_config_pool_info['candidate_nodes'].append( + node['name'] + ) + + return machine_config_pool_info + + def get_machine_config_pools_info(self, cache_enabled=True): + if cache_enabled: + if self.machine_config_pool is not None: + return self.machine_config_pool + + managed_objects = self.get_machine_config_pool_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.machine_config_pool = [] + for managed_object in managed_objects: + machine_config_pool_info = {} + machine_config_pool_info['info'] = self.get_machine_config_pool_info( + managed_object + ) + machine_config_pool_info['mo'] = managed_object + self.machine_config_pool.append( + machine_config_pool_info + ) + + return self.machine_config_pool + + def match_machine_config_pool(self, machine_config_pool_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, machine_config_pool_info['name']): + return False + + if not key_found: + self.log.error( + 'match_machine_config_pool', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_machine_config_pools(self, object_filter=None, return_mo=False, cache_enabled=True, selector_info=False): + all_machine_config_pools = self.get_machine_config_pools_info(cache_enabled=cache_enabled) + if all_machine_config_pools is None: + return None + + machine_config_pools = [] + + for machine_config_pool_info in all_machine_config_pools: + if not self.match_machine_config_pool(machine_config_pool_info['info'], object_filter): + continue + + if return_mo: + machine_config_pools.append( + machine_config_pool_info['mo'] + ) + continue + + if selector_info: + machine_config_pool_info['info'] = self.add_machine_config_pool_selector_info( + machine_config_pool_info['info'] + ) + + machine_config_pools.append( + machine_config_pool_info['info'] + ) + + return machine_config_pools + + def is_machine_config_pool(self, name, cache_enabled=True): + if self.get_machine_config_pool(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_machine_config_pool(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + machine_config_pools = self.get_machine_config_pools( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if machine_config_pools is None: + return None + + if len(machine_config_pools) == 1: + return machine_config_pools[0] + + return None + + def wait_machine_config_pool_update(self, machine_config_pools, machine_configs, output_handler=None, max_time=3600): + target_mcp = [] + mcp_configurations = {} + for machine_config_pool in machine_config_pools: + mcp_configurations[machine_config_pool['name']] = machine_config_pool['current_configuration'] + for source in machine_config_pool['source']: + if source['name'] in machine_configs: + if machine_config_pool['name'] not in target_mcp: + target_mcp.append(machine_config_pool['name']) + + if len(target_mcp) == 0: + if output_handler is not None: + output_handler.default('No machine config pool update expected') + return True + + if output_handler is not None: + output_handler.default('Wait for machine config pool update...') + for name in target_mcp: + output_handler.default('- %s' % (name)) + + finished_mcp = [] + start_time = int(time.time()) + while True: + for mcp in target_mcp: + if mcp in finished_mcp: + continue + + mcp_info = self.get_machine_config_pool( + mcp, + cache_enabled=False + ) + if mcp_info is None: + continue + + if mcp_info['updating']: + continue + + if mcp_info['current_configuration'] == mcp_configurations[mcp]: + continue + + finished_mcp.append(mcp) + + if len(target_mcp) == len(finished_mcp): + break + + if int(time.time()) - start_time > max_time: + if output_handler is not None: + output_handler.error('Max waiting time elapsed [%s seconds]' % (max_time)) + return False + + time.sleep(5) + + return True + + def is_machine_config_pools_ready(self, machine_config_pools=None, cache_enabled=False): + if machine_config_pools is None: + machine_config_pools = self.get_machine_config_pools(cache_enabled=cache_enabled) + if machine_config_pools is None: + return False + + ready = True + for pool in machine_config_pools: + ready = ready and pool['ready'] + + return ready diff --git a/lib/k8s/machine_config_pool/main.py b/lib/k8s/machine_config_pool/main.py new file mode 100644 index 00000000..23794b1f --- /dev/null +++ b/lib/k8s/machine_config_pool/main.py @@ -0,0 +1,11 @@ +from lib.k8s.machine_config_pool.api import K8sMachineConfigPoolApi +from lib.k8s.machine_config_pool.info import K8sMachineConfigPoolInfo + + +class K8sMachineConfigPool( + K8sMachineConfigPoolApi, + K8sMachineConfigPoolInfo + ): + def __init__(self): + K8sMachineConfigPoolApi.__init__(self) + K8sMachineConfigPoolInfo.__init__(self) diff --git a/lib/k8s/machine_config_pool/output.py b/lib/k8s/machine_config_pool/output.py new file mode 100644 index 00000000..78ea3a80 --- /dev/null +++ b/lib/k8s/machine_config_pool/output.py @@ -0,0 +1,112 @@ +import json + + +class K8sMachineConfigPoolOutput(): + def __init__(self): + pass + + def print_machine_config_pools(self, info, title=False): + if title: + self.my_output.default( + 'Machine Config Pool (MCP) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'current_configuration', + 'updatedTick', + 'updatingTick', + 'degradedTick', + 'machineCount', + 'readyMachineCount', + 'updatedMachineCount', + 'degradedMachineCount', + 'unavailableMachineCount', + 'source.name', + 'age' + ] + + headers = [ + 'Name', + 'Config', + 'Updated', + 'Updating', + 'Degraded', + 'Machines', + 'Ready', + 'Updated', + 'Degraded', + 'Unavail', + 'Machine Config', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['source'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_machine_config_pools_selector(self, info, title=False): + if title: + self.my_output.default( + 'Machine Config Pool (MCP) Selector [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['machine_config_selectorT'] = json.dumps(item['machine_config_selector'], indent=4).split('\n') + item['node_selectorT'] = json.dumps(item['node_selector'], indent=4).split('\n') + if len(item['candidate_machine_configs']) == 0: + item['candidate_machine_configs'].append('--') + if len(item['candidate_nodes']) == 0: + item['candidate_nodes'].append('--') + + order = [ + 'name', + 'machine_config_selectorT', + 'candidate_machine_configs', + 'node_selectorT', + 'candidate_nodes' + ] + + headers = [ + 'Name', + 'Machine Config Selector', + 'Candidate Machine Configs', + 'Node Selector', + 'Candidate Nodes' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['machine_config_selectorT', 'node_selectorT', 'candidate_machine_configs', 'candidate_nodes'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/main.py b/lib/k8s/main.py new file mode 100644 index 00000000..c0f92bf8 --- /dev/null +++ b/lib/k8s/main.py @@ -0,0 +1,245 @@ +from lib import log_helper + +from lib.k8s.api import K8sApi +from lib.k8s.common import K8sCommon + +from lib.k8s.alert_manager.main import K8sAlertManager +from lib.k8s.alert_manager_config.main import K8sAlertManagerConfig +from lib.k8s.cluster_operator.main import K8sClusterOperator +from lib.k8s.cluster_quota.main import K8sClusterQuota +from lib.k8s.cluster_role_binding.main import K8sClusterRoleBinding +from lib.k8s.cluster_service_version.main import K8sClusterServiceVersion +from lib.k8s.cni.main import K8sCni +from lib.k8s.config_map.main import K8sConfigMap +from lib.k8s.custom_resource_definition.main import K8sCustomResourceDefinition +from lib.k8s.daemon_set.main import K8sDaemonSet +from lib.k8s.data_volume.main import K8sDataVolume +from lib.k8s.deployment.main import K8sDeployment +from lib.k8s.deployment_config.main import K8sDeploymentConfig +from lib.k8s.egress_ip.main import K8sEgressIp +from lib.k8s.egress_router.main import K8sEgressRouter +from lib.k8s.endpoint.main import K8sEndpoint +from lib.k8s.event.main import K8sEvent +from lib.k8s.ingress.main import K8sIngress +from lib.k8s.kubevirt.main import K8sKubevirt +from lib.k8s.limit.main import K8sLimit +from lib.k8s.machine_config.main import K8sMachineConfig +from lib.k8s.machine_config_pool.main import K8sMachineConfigPool +from lib.k8s.namespace.main import K8sNamespace +from lib.k8s.network_attachment_definition.main import K8sNetworkAttachmentDefinition +from lib.k8s.node.main import K8sNode +from lib.k8s.node_network_configuration_enactment.main import K8sNodeNetworkConfigurationEnactment +from lib.k8s.node_network_configuration_policy.main import K8sNodeNetworkConfigurationPolicy +from lib.k8s.node_network_state.main import K8sNodeNetworkState +from lib.k8s.operator_group.main import K8sOperatorGroup +from lib.k8s.performance_profile.main import K8sPerformanceProfile +from lib.k8s.pod.main import K8sPod +from lib.k8s.pod_monitor.main import K8sPodMonitor +from lib.k8s.priority_class.main import K8sPriorityClass +from lib.k8s.probe.main import K8sProbe +from lib.k8s.profile.main import K8sProfile +from lib.k8s.prometheus.main import K8sPrometheus +from lib.k8s.prometheus_rule.main import K8sPrometheusRule +from lib.k8s.pv.main import K8sPv +from lib.k8s.pvc.main import K8sPvc +from lib.k8s.replication_controller.main import K8sReplicationController +from lib.k8s.replica_set.main import K8sReplicaSet +from lib.k8s.resource_quota.main import K8sResourceQuota +from lib.k8s.role_binding.main import K8sRoleBinding +from lib.k8s.route.main import K8sRoute +from lib.k8s.secret.main import K8sSecret +from lib.k8s.security_context_constraint.main import K8sSecurityContextConstraint +from lib.k8s.service.main import K8sService +from lib.k8s.service_account.main import K8sServiceAccount +from lib.k8s.service_monitor.main import K8sServiceMonitor +from lib.k8s.sriov_network.main import K8sSriovNetwork +from lib.k8s.sriov_network_node_policy.main import K8sSriovNetworkNodePolicy +from lib.k8s.sriov_network_node_state.main import K8sSriovNetworkNodeState +from lib.k8s.stateful_set.main import K8sStatefulSet +from lib.k8s.storage_class.main import K8sStorageClass +from lib.k8s.subscription.main import K8sSubscription +from lib.k8s.thanos_ruler.main import K8sThanosRuler +from lib.k8s.tuned.main import K8sTuned +from lib.k8s.version.main import K8sVersion +from lib.k8s.virtual_machine.main import K8sVirtualMachine +from lib.k8s.virtual_machine_clone.main import K8sVirtualMachineClone +from lib.k8s.virtual_machine_cluster_instance_type.main import K8sVirtualMachineClusterInstanceType +from lib.k8s.virtual_machine_cluster_preference.main import K8sVirtualMachineClusterPreference +from lib.k8s.virtual_machine_export.main import K8sVirtualMachineExport +from lib.k8s.virtual_machine_instance.main import K8sVirtualMachineInstance +from lib.k8s.virtual_machine_instance_migration.main import K8sVirtualMachineInstanceMigration +from lib.k8s.virtual_machine_instance_preset.main import K8sVirtualMachineInstancePreset +from lib.k8s.virtual_machine_instance_replica_set.main import K8sVirtualMachineInstanceReplicaSet +from lib.k8s.virtual_machine_preference.main import K8sVirtualMachinePreference +from lib.k8s.virtual_machine_restore.main import K8sVirtualMachineRestore +from lib.k8s.virtual_machine_snapshot.main import K8sVirtualMachineSnapshot +from lib.k8s.virtual_machine_snapshot_content.main import K8sVirtualMachineSnapshotContent +from lib.k8s.volume_attachment.main import K8sVolumeAttachment +from lib.k8s.volume_snapshot.main import K8sVolumeSnapshot +from lib.k8s.volume_snapshot_class.main import K8sVolumeSnapshotClass +from lib.k8s.volume_snapshot_content.main import K8sVolumeSnapshotContent + + +class K8s( + K8sApi, + K8sCommon, + K8sAlertManager, + K8sAlertManagerConfig, + K8sClusterOperator, + K8sClusterQuota, + K8sClusterRoleBinding, + K8sClusterServiceVersion, + K8sCni, + K8sConfigMap, + K8sCustomResourceDefinition, + K8sDaemonSet, + K8sDataVolume, + K8sDeployment, + K8sDeploymentConfig, + K8sEgressIp, + K8sEgressRouter, + K8sEndpoint, + K8sEvent, + K8sIngress, + K8sKubevirt, + K8sLimit, + K8sMachineConfig, + K8sMachineConfigPool, + K8sNamespace, + K8sNetworkAttachmentDefinition, + K8sNode, + K8sNodeNetworkConfigurationEnactment, + K8sNodeNetworkConfigurationPolicy, + K8sNodeNetworkState, + K8sOperatorGroup, + K8sPerformanceProfile, + K8sPod, + K8sPodMonitor, + K8sPriorityClass, + K8sProbe, + K8sProfile, + K8sPrometheus, + K8sPrometheusRule, + K8sPv, + K8sPvc, + K8sReplicaSet, + K8sReplicationController, + K8sResourceQuota, + K8sRoleBinding, + K8sRoute, + K8sSecret, + K8sSecurityContextConstraint, + K8sService, + K8sServiceAccount, + K8sServiceMonitor, + K8sSriovNetwork, + K8sSriovNetworkNodePolicy, + K8sSriovNetworkNodeState, + K8sStatefulSet, + K8sStorageClass, + K8sSubscription, + K8sThanosRuler, + K8sTuned, + K8sVersion, + K8sVirtualMachine, + K8sVirtualMachineClone, + K8sVirtualMachineClusterInstanceType, + K8sVirtualMachineClusterPreference, + K8sVirtualMachineExport, + K8sVirtualMachineInstance, + K8sVirtualMachineInstanceMigration, + K8sVirtualMachineInstancePreset, + K8sVirtualMachineInstanceReplicaSet, + K8sVirtualMachinePreference, + K8sVirtualMachineRestore, + K8sVirtualMachineSnapshot, + K8sVirtualMachineSnapshotContent, + K8sVolumeAttachment, + K8sVolumeSnapshot, + K8sVolumeSnapshotClass, + K8sVolumeSnapshotContent + ): + def __init__(self, kubeconfig_filename, cluster_type='standard', verbose=False, debug=False, log_id=None): + K8sApi.__init__(self, kubeconfig_filename, cluster_type=cluster_type) + K8sCommon.__init__(self) + + K8sAlertManager.__init__(self) + K8sAlertManagerConfig.__init__(self) + K8sClusterOperator.__init__(self) + K8sClusterQuota.__init__(self) + K8sClusterRoleBinding.__init__(self) + K8sClusterServiceVersion.__init__(self) + K8sCni.__init__(self) + K8sConfigMap.__init__(self) + K8sCustomResourceDefinition.__init__(self) + K8sDaemonSet.__init__(self) + K8sDataVolume.__init__(self) + K8sDeployment.__init__(self) + K8sDeploymentConfig.__init__(self) + K8sEgressIp.__init__(self) + K8sEgressRouter.__init__(self) + K8sEndpoint.__init__(self) + K8sEvent.__init__(self) + K8sIngress.__init__(self) + K8sKubevirt.__init__(self) + K8sLimit.__init__(self) + K8sMachineConfig.__init__(self) + K8sMachineConfigPool.__init__(self) + K8sNamespace.__init__(self) + K8sNetworkAttachmentDefinition.__init__(self) + K8sNode.__init__(self) + K8sNodeNetworkConfigurationEnactment.__init__(self) + K8sNodeNetworkConfigurationPolicy.__init__(self) + K8sNodeNetworkState.__init__(self) + K8sOperatorGroup.__init__(self) + K8sPerformanceProfile.__init__(self) + K8sPod.__init__(self) + K8sPodMonitor.__init__(self) + K8sPriorityClass.__init__(self) + K8sProbe.__init__(self) + K8sProfile.__init__(self) + K8sPrometheus.__init__(self) + K8sPrometheusRule.__init__(self) + K8sPv.__init__(self) + K8sPvc.__init__(self) + K8sReplicaSet.__init__(self) + K8sReplicationController.__init__(self) + K8sResourceQuota.__init__(self) + K8sRoleBinding.__init__(self) + K8sRoute.__init__(self) + K8sSecret.__init__(self) + K8sSecurityContextConstraint.__init__(self) + K8sService.__init__(self) + K8sServiceAccount.__init__(self) + K8sServiceMonitor.__init__(self) + K8sSriovNetwork.__init__(self) + K8sSriovNetworkNodePolicy.__init__(self) + K8sSriovNetworkNodeState.__init__(self) + K8sStatefulSet.__init__(self) + K8sStorageClass.__init__(self) + K8sSubscription.__init__(self) + K8sThanosRuler.__init__(self) + K8sTuned.__init__(self) + K8sVersion.__init__(self) + K8sVirtualMachine.__init__(self) + K8sVirtualMachineClone.__init__(self) + K8sVirtualMachineClusterInstanceType.__init__(self) + K8sVirtualMachineClusterPreference.__init__(self) + K8sVirtualMachineExport.__init__(self) + K8sVirtualMachineInstance.__init__(self) + K8sVirtualMachineInstanceMigration.__init__(self) + K8sVirtualMachineInstancePreset.__init__(self) + K8sVirtualMachineInstanceReplicaSet.__init__(self) + K8sVirtualMachinePreference.__init__(self) + K8sVirtualMachineRestore.__init__(self) + K8sVirtualMachineSnapshot.__init__(self) + K8sVirtualMachineSnapshotContent.__init__(self) + K8sVolumeAttachment.__init__(self) + K8sVolumeSnapshot.__init__(self) + K8sVolumeSnapshotClass.__init__(self) + K8sVolumeSnapshotContent.__init__(self) + + self.verbose = verbose + self.debug = debug + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) diff --git a/lib/k8s/namespace/__init__.py b/lib/k8s/namespace/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/namespace/__pycache__/__init__.cpython-310.pyc b/lib/k8s/namespace/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3fa46a76 Binary files /dev/null and b/lib/k8s/namespace/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/namespace/__pycache__/api.cpython-310.pyc b/lib/k8s/namespace/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..cd61edb3 Binary files /dev/null and b/lib/k8s/namespace/__pycache__/api.cpython-310.pyc differ diff --git a/lib/k8s/namespace/__pycache__/info.cpython-310.pyc b/lib/k8s/namespace/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..849c1bd1 Binary files /dev/null and b/lib/k8s/namespace/__pycache__/info.cpython-310.pyc differ diff --git a/lib/k8s/namespace/__pycache__/main.cpython-310.pyc b/lib/k8s/namespace/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ae7031c8 Binary files /dev/null and b/lib/k8s/namespace/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/namespace/__pycache__/object.cpython-310.pyc b/lib/k8s/namespace/__pycache__/object.cpython-310.pyc new file mode 100644 index 00000000..23dd8f4d Binary files /dev/null and b/lib/k8s/namespace/__pycache__/object.cpython-310.pyc differ diff --git a/lib/k8s/namespace/__pycache__/task.cpython-310.pyc b/lib/k8s/namespace/__pycache__/task.cpython-310.pyc new file mode 100644 index 00000000..54ffc6c9 Binary files /dev/null and b/lib/k8s/namespace/__pycache__/task.cpython-310.pyc differ diff --git a/lib/k8s/namespace/api.py b/lib/k8s/namespace/api.py new file mode 100644 index 00000000..7e50c4e6 --- /dev/null +++ b/lib/k8s/namespace/api.py @@ -0,0 +1,52 @@ +import time +import traceback + + +class K8sNamespaceApi(): + def __init__(self): + self.namespace_mo = None + + def get_namespace_mo(self, cache_enabled=True): + if cache_enabled: + if self.namespace_mo is not None: + return self.namespace_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.list_namespace( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'namespace', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_namespace_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'namespace', + True, + int(time.time() * 1000) - start_time + ) + return None + + self.namespace_mo = [] + for item in response.items: + namespace_mo = self.convert_object(item.to_dict()) + self.namespace_mo.append( + namespace_mo + ) + + self.log.k8s_mo( + 'namespace', + self.namespace_mo + ) + + return self.namespace_mo diff --git a/lib/k8s/namespace/info.py b/lib/k8s/namespace/info.py new file mode 100644 index 00000000..171810f9 --- /dev/null +++ b/lib/k8s/namespace/info.py @@ -0,0 +1,116 @@ +from lib import filter_helper + + +class K8sNamespaceInfo(): + def __init__(self): + self.namespace = None + + def get_namespace_info(self, namespace_mo): + if namespace_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + namespace_mo + ) + info.update(metadata_info) + + info['phase'] = self.get(namespace_mo, 'status:phase') + if info['phase'] is not None and info['phase'] == 'Active': + info['__Output']['phase'] = 'Green' + else: + info['__Output']['phase'] = 'Red' + + return info + + def get_namespaces_info(self, cache_enabled=True): + if cache_enabled: + if self.namespace is not None: + return self.namespace + + managed_objects = self.get_namespace_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.namespace = [] + for managed_object in managed_objects: + namespace_info = {} + namespace_info['info'] = self.get_namespace_info( + managed_object + ) + namespace_info['mo'] = managed_object + self.namespace.append( + namespace_info + ) + + return self.namespace + + def match_namespace(self, namespace_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, namespace_info['name']): + return False + + if not key_found: + self.log.error( + 'match_namespace', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_namespaces(self, object_filter=None, return_mo=False, cache_enabled=True): + all_namespaces = self.get_namespaces_info(cache_enabled=cache_enabled) + if all_namespaces is None: + return None + + namespaces = [] + + for namespace_info in all_namespaces: + if not self.match_namespace(namespace_info['info'], object_filter): + continue + + if return_mo: + namespaces.append( + namespace_info['mo'] + ) + continue + + namespaces.append( + namespace_info['info'] + ) + + return namespaces + + def is_namespace(self, name, cache_enabled=True): + if self.get_namespace(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_namespace(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + namespaces = self.get_namespaces( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if namespaces is None: + return None + + if len(namespaces) == 1: + return namespaces[0] + + return None diff --git a/lib/k8s/namespace/main.py b/lib/k8s/namespace/main.py new file mode 100644 index 00000000..77e735ae --- /dev/null +++ b/lib/k8s/namespace/main.py @@ -0,0 +1,11 @@ +from lib.k8s.namespace.api import K8sNamespaceApi +from lib.k8s.namespace.info import K8sNamespaceInfo + + +class K8sNamespace( + K8sNamespaceApi, + K8sNamespaceInfo + ): + def __init__(self): + K8sNamespaceApi.__init__(self) + K8sNamespaceInfo.__init__(self) diff --git a/lib/k8s/namespace/output.py b/lib/k8s/namespace/output.py new file mode 100644 index 00000000..289bc402 --- /dev/null +++ b/lib/k8s/namespace/output.py @@ -0,0 +1,83 @@ +import copy + + +class K8sNamespaceOutput(): + def __init__(self): + pass + + def print_namespaces(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Namespace [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'name', + 'phase', + 'age' + ] + + headers = headers + [ + 'Name', + 'Status', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def select_namespace(self, info): + self.my_output.default( + 'Select Namespace [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No namespace found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_namespaces(new_info, title=False, select=True) + + while True: + answer = input("Select namespace using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/k8s/network_attachment_definition/__init__.py b/lib/k8s/network_attachment_definition/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/network_attachment_definition/api.py b/lib/k8s/network_attachment_definition/api.py new file mode 100644 index 00000000..cb652b43 --- /dev/null +++ b/lib/k8s/network_attachment_definition/api.py @@ -0,0 +1,100 @@ +import time +import traceback + + +class K8sNetworkAttachmentDefinitionApi(): + def __init__(self): + self.nad_mo = None + + def get_nad_mo(self, cache_enabled=True): + if cache_enabled: + if self.nad_mo is not None: + return self.nad_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='k8s.cni.cncf.io/v1', + kind='NetworkAttachmentDefinition' + ) + self.nad_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'nad', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_nad_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'nad', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'nad', + self.nad_mo + ) + + return self.nad_mo + + def create_nad(self, policy): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='k8s.cni.cncf.io/v1', kind='NetworkAttachmentDefinition') + success = True + response = obj_list.create( + body=policy, + namespace=policy['metadata']['namespace'], + ) + except BaseException: + success = False + self.log.error('ocp.create_ocp_nad', traceback.format_exc()) + + self.log.ocp( + 'create', + 'nad', + success, + int(time.time() * 1000) - start_time + ) + + return success + + def delete_nad(self, namespace, name): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='k8s.cni.cncf.io/v1', kind='NetworkAttachmentDefinition') + success = True + response = obj_list.delete( + namespace=namespace, + name=name + ) + except BaseException: + success = False + self.log.error('ocp.delete_ocp_nad', traceback.format_exc()) + + self.log.ocp( + 'delete', + 'delete_ocp_nad', + success, + int(time.time() * 1000) - start_time + ) + + return success diff --git a/lib/k8s/network_attachment_definition/info.py b/lib/k8s/network_attachment_definition/info.py new file mode 100644 index 00000000..c35772b1 --- /dev/null +++ b/lib/k8s/network_attachment_definition/info.py @@ -0,0 +1,148 @@ +import json + +from lib import filter_helper + + +class K8sNetworkAttachmentDefinitionInfo(): + def __init__(self): + self.nad = None + + def get_nad_info(self, nad_mo): + if nad_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + nad_mo + ) + info.update(metadata_info) + + info['resource_name'] = self.get(nad_mo, 'metadata:annotations:k8s.v1.cni.cncf.io/resourceName') + info['config'] = json.loads( + self.get(nad_mo, 'spec:config') + ) + + return info + + def get_nads_info(self, cache_enabled=True): + if cache_enabled: + if self.nad is not None: + return self.nad + + managed_objects = self.get_nad_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.nad = [] + for managed_object in managed_objects: + nad_info = {} + nad_info['info'] = self.get_nad_info( + managed_object + ) + nad_info['mo'] = managed_object + self.nad.append( + nad_info + ) + + return self.nad + + def match_nad(self, nad_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, nad_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (nad_info['namespace'], nad_info['name'])): + return False + + if key == 'resource': + key_found = True + if not filter_helper.match_string(value, nad_info['resource_name']): + return False + + if not key_found: + self.log.error( + 'match_nad', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_nads(self, object_filter=None, return_mo=False, cache_enabled=True): + all_nads = self.get_nads_info(cache_enabled=cache_enabled) + if all_nads is None: + return None + + nads = [] + + for nad_info in all_nads: + if not self.match_nad(nad_info['info'], object_filter): + continue + + if return_mo: + nads.append( + nad_info['mo'] + ) + continue + + nads.append( + nad_info['info'] + ) + + return nads + + def is_nad(self, namespace, name, cache_enabled=True): + if self.get_nad(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_nad(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + nads = self.get_nads( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if nads is None: + return None + + if len(nads) == 1: + return nads[0] + + return None + + def get_nad_with_resource_name(self, resource_name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'resource:%s' % (resource_name) + ) + nads = self.get_nads( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if nads is None: + return None + + if len(nads) == 1: + return nads[0] + + return None diff --git a/lib/k8s/network_attachment_definition/main.py b/lib/k8s/network_attachment_definition/main.py new file mode 100644 index 00000000..5ebf071c --- /dev/null +++ b/lib/k8s/network_attachment_definition/main.py @@ -0,0 +1,11 @@ +from lib.k8s.network_attachment_definition.api import K8sNetworkAttachmentDefinitionApi +from lib.k8s.network_attachment_definition.info import K8sNetworkAttachmentDefinitionInfo + + +class K8sNetworkAttachmentDefinition( + K8sNetworkAttachmentDefinitionApi, + K8sNetworkAttachmentDefinitionInfo + ): + def __init__(self): + K8sNetworkAttachmentDefinitionApi.__init__(self) + K8sNetworkAttachmentDefinitionInfo.__init__(self) diff --git a/lib/k8s/network_attachment_definition/output.py b/lib/k8s/network_attachment_definition/output.py new file mode 100644 index 00000000..114b0607 --- /dev/null +++ b/lib/k8s/network_attachment_definition/output.py @@ -0,0 +1,59 @@ +import json + + +class K8sNetworkAttachmentDefinitionOutput(): + def __init__(self): + pass + + def print_nads(self, info, title=False): + if title: + self.my_output.default( + 'Network Attachment Definition [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['resource_name'] is None: + item['resource_name'] = '--' + + item['configT'] = json.dumps( + item['config'], + indent=2 + ).split('\n') + + order = [ + 'namespace', + 'name', + 'config.type', + 'resource_name', + 'configT', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Type', + 'SR-IOV Resource', + 'Config', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['configT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/node/__init__.py b/lib/k8s/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/node/__pycache__/__init__.cpython-310.pyc b/lib/k8s/node/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..38a3002d Binary files /dev/null and b/lib/k8s/node/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/node/__pycache__/api.cpython-310.pyc b/lib/k8s/node/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..6b891c60 Binary files /dev/null and b/lib/k8s/node/__pycache__/api.cpython-310.pyc differ diff --git a/lib/k8s/node/__pycache__/info.cpython-310.pyc b/lib/k8s/node/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..110b063c Binary files /dev/null and b/lib/k8s/node/__pycache__/info.cpython-310.pyc differ diff --git a/lib/k8s/node/__pycache__/main.cpython-310.pyc b/lib/k8s/node/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c49d067a Binary files /dev/null and b/lib/k8s/node/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/node/__pycache__/object.cpython-310.pyc b/lib/k8s/node/__pycache__/object.cpython-310.pyc new file mode 100644 index 00000000..4314d10b Binary files /dev/null and b/lib/k8s/node/__pycache__/object.cpython-310.pyc differ diff --git a/lib/k8s/node/__pycache__/task.cpython-310.pyc b/lib/k8s/node/__pycache__/task.cpython-310.pyc new file mode 100644 index 00000000..cbd094ca Binary files /dev/null and b/lib/k8s/node/__pycache__/task.cpython-310.pyc differ diff --git a/lib/k8s/node/api.py b/lib/k8s/node/api.py new file mode 100644 index 00000000..0ad96eb2 --- /dev/null +++ b/lib/k8s/node/api.py @@ -0,0 +1,53 @@ +import time +import traceback + + +class K8sNodeApi(): + def __init__(self): + self.node_mo = None + + def get_node_mo(self, cache_enabled=True): + if cache_enabled: + if self.node_mo is not None: + return self.node_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/V1NodeList.md + try: + start_time = int(time.time() * 1000) + response = api_handler.list_node( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'node', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s_nodes.get_nodes', traceback.format_exc()) + self.log.k8s( + 'get', + 'node', + True, + int(time.time() * 1000) - start_time + ) + return False + + self.node_mo = [] + for item in response.items: + node_mo = self.convert_object(item.to_dict()) + self.node_mo.append( + node_mo + ) + + self.log.k8s_mo( + 'node', + self.node_mo + ) + + return self.node_mo diff --git a/lib/k8s/node/info.py b/lib/k8s/node/info.py new file mode 100644 index 00000000..881c8885 --- /dev/null +++ b/lib/k8s/node/info.py @@ -0,0 +1,811 @@ +from lib import filter_helper +from lib import ip_helper + + +class K8sNodeInfo(): + def __init__(self): + self.node = None + + def get_node_info(self, node_mo): + if node_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = self.get(node_mo, 'metadata:name') + info['node_info'] = self.get(node_mo, 'status:node_info') + + conditions = self.get(node_mo, 'status:conditions', on_error=[], on_none=[]) + + info['ready'] = False + for condition in conditions: + if condition['type'] == 'Ready': + if condition['status'] == 'True': + info['ready'] = True + + if info['ready']: + info['readyTick'] = '\u2713' + info['__Output']['readyTick'] = 'Green' + else: + info['readyTick'] = '\u2717' + info['__Output']['readyTick'] = 'Red' + + info['memory_pressure'] = False + for condition in conditions: + if condition['type'] == 'MemoryPressure': + if condition['status'] == 'True': + info['memory_pressure'] = True + + if info['memory_pressure']: + info['memoryTick'] = '\u2717' + info['__Output']['memoryTick'] = 'Red' + else: + info['memoryTick'] = '\u2713' + info['__Output']['memoryTick'] = 'Green' + + info['disk_pressure'] = False + for condition in conditions: + if condition['type'] == 'MemoryPressure': + if condition['status'] == 'True': + info['disk_pressure'] = True + + if info['disk_pressure']: + info['diskTick'] = '\u2717' + info['__Output']['diskTick'] = 'Red' + else: + info['diskTick'] = '\u2713' + info['__Output']['diskTick'] = 'Green' + + info['pid_pressure'] = False + for condition in conditions: + if condition['type'] == 'PIDPressure': + if condition['status'] == 'True': + info['pid_pressure'] = True + + if info['pid_pressure']: + info['pidTick'] = '\u2717' + info['__Output']['pidTick'] = 'Red' + else: + info['pidTick'] = '\u2713' + info['__Output']['pidTick'] = 'Green' + + info['label'] = self.get(node_mo, 'metadata:labels', on_error={}, on_none={}) + + info['role'] = [] + info['master'] = False + for label in info['label']: + if label == 'node-role.kubernetes.io/master': + info['master'] = True + info['role'].append('Master') + + info['worker'] = False + for label in info['label']: + if label == 'node-role.kubernetes.io/worker': + info['worker'] = True + info['role'].append('Worker') + + info['cnv'] = False + info['cnvTick'] = '\u2717' + info['__Output']['cnvTick'] = 'Red' + for label in info['label']: + if label == 'kubevirt.io/schedulable' and info['label'][label] == 'true': + info['cnv'] = True + info['cnvTick'] = '\u2713' + info['__Output']['cnvTick'] = 'Green' + + annotations_mo = self.get(node_mo, 'metadata:annotations', on_error={}, on_none={}) + info['mcp_current_config'] = None + info['mcp_desired_config'] = None + info['mcpTick'] = '--' + if 'machineconfiguration.openshift.io/currentConfig' in annotations_mo: + info['mcp_current_config'] = annotations_mo['machineconfiguration.openshift.io/currentConfig'] + if 'machineconfiguration.openshift.io/desiredConfig' in annotations_mo: + info['mcp_desired_config'] = annotations_mo['machineconfiguration.openshift.io/desiredConfig'] + if info['mcp_current_config'] is not None and info['mcp_desired_config'] is not None: + if info['mcp_current_config'] == info['mcp_desired_config']: + info['mcpTick'] = '\u2713' + info['__Output']['mcpTick'] = 'Green' + else: + info['mcpTick'] = '\u2717' + info['__Output']['mcpTick'] = 'Red' + + info['capacity'] = self.get(node_mo, 'status:capacity', on_error={}, on_none={}) + info['capacityT'] = [] + for key in info['capacity']: + info['capacityT'].append( + '%s:%s' % ( + key, + info['capacity'][key] + ) + ) + + info['capacity_cpu'] = self.get(node_mo, 'status:capacity:cpu') + info['capacity_pod'] = self.get(node_mo, 'status:capacity:pods') + info['capacity_memory'] = self.get(node_mo, 'status:capacity:memory') + info['capacity_storage'] = self.get(node_mo, 'status:capacity:ephemeral-storage') + info['capacity_hp2m'] = self.get(node_mo, 'status:capacity:hugepages-2Mi') + info['capacity_hp1g'] = self.get(node_mo, 'status:capacity:hugepages-1Gi') + info['capacity_kubevirt'] = [] + info['capacity_vendor'] = [] + + for key in info['capacity']: + if key not in ['cpu', 'pods', 'memory', 'ephemeral-storage', 'hugepages-2Mi', 'hugepages-1Gi']: + if key.startswith('devices.kubevirt.io'): + info['capacity_kubevirt'].append( + '%s: %s' % ( + key, + info['capacity'][key] + ) + ) + else: + info['capacity_vendor'].append( + '%s: %s' % ( + key, + info['capacity'][key] + ) + ) + + info['capacity_vendor'] = sorted(info['capacity_vendor']) + info['capacity_kubevirt'] = sorted(info['capacity_kubevirt']) + + info['internal_ip'] = None + info['external_ip'] = None + info['ip'] = [] + info['ipT'] = [] + + addresses = self.get(node_mo, 'status:addresses', on_error=[], on_none=[]) + for address in addresses: + if address['type'] == 'InternalIP': + info['internal_ip'] = address['address'] + info['ip'].append( + address['address'] + ) + info['ipT'].append( + '%s (int)' % ( + address['address'] + ) + ) + + if address['type'] == 'ExternalIP': + info['external_ip'] = address['address'] + info['ip'].append( + address['address'] + ) + info['ipT'].append( + '%s (int)' % ( + address['address'] + ) + ) + + info['ssh_ip'] = info['external_ip'] + if info['external_ip'] is None: + info['ssh_ip'] = info['internal_ip'] + + info['age'] = self.convert_timestamp_to_age( + self.get(node_mo, 'metadata:creation_timestamp'), + on_error='--' + ) + + return info + + def get_nodes_info(self, cache_enabled=True): + if cache_enabled: + if self.node is not None: + return self.node + + managed_objects = self.get_node_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.node = [] + for managed_object in managed_objects: + node_info = {} + node_info['info'] = self.get_node_info( + managed_object + ) + node_info['mo'] = managed_object + self.node.append( + node_info + ) + + return self.node + + def filter_node_label(self, labels, label_filter): + new_labels = {} + + if len(label_filter.split(':')) > 2: + return new_labels + + if len(label_filter.split(':')) == 1: + label_filter_key = label_filter + label_filter_value = None + + if len(label_filter.split(':')) == 2: + (label_filter_key, label_filter_value) = label_filter.split(':') + + for lkey in labels: + if filter_helper.match_string(label_filter_key, lkey): + if label_filter_value is None: + new_labels[lkey] = labels[lkey] + continue + + if filter_helper.match_string(label_filter_value, labels[lkey]): + new_labels[lkey] = labels[lkey] + continue + + return new_labels + + def get_node_filter_value(self, node_filter, filter_key): + if node_filter is not None: + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == filter_key: + return value + + return None + + def match_node(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, node_info['name']): + return False + + if key == 'ip': + key_found = True + found = False + for address in node_info['ip']: + if address == value: + found = True + break + + if not found: + return False + + if key == 'worker': + key_found = True + if value == 'true' and not node_info['worker']: + return False + if value == 'false' and node_info['worker']: + return False + + if key == 'master': + key_found = True + if value == 'true' and not node_info['master']: + return False + if value == 'false' and node_info['master']: + return False + + if key == 'label': + key_found = True + filtered_labels = self.filter_node_label( + node_info['label'], + value + ) + if len(filtered_labels) == 0: + return False + + if not key_found: + self.log.error( + 'match_node', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_nodes(self, object_filter=None, sriov_phy_info=False, sriov_policy_info=False, sriov_network_info=False, sriov_vf_info=False, return_mo=False, cache_enabled=True): + all_nodes = self.get_nodes_info(cache_enabled=cache_enabled) + if all_nodes is None: + return None + + nodes = [] + + for node_info in all_nodes: + if not self.match_node(node_info['info'], object_filter): + continue + + if return_mo: + nodes.append( + node_info['mo'] + ) + continue + + label_filter = self.get_node_filter_value(object_filter, 'label') + if label_filter is not None: + node_info['info']['label'] = self.filter_node_label( + node_info['info']['label'], + label_filter + ) + + if sriov_policy_info: + node_info['info']['sriov_policy'] = self.get_ocp_node_sriov_policy( + node_info['info']['name'] + ) + + nodes.append( + node_info['info'] + ) + + if not return_mo: + nodes = sorted( + nodes, + key=lambda i: i['name'] + ) + + return nodes + + def get_node(self, node_name): + node_filter = ['name:%s' % (node_name)] + nodes = self.get_nodes( + object_filter=node_filter + ) + + if nodes is None or len(nodes) != 1: + return None + + return nodes[0] + + def get_node_name(self, ip_address): + node_info = self.get_node_with_ip(ip_address) + if node_info is None: + return None + return node_info['name'] + + def get_node_with_ip(self, ip_address): + node_filter = ['ip:%s' % (ip_address)] + nodes = self.get_nodes( + object_filter=node_filter + ) + + if nodes is None or len(nodes) != 1: + return None + + return nodes[0] + + def get_node_internal_ip(self, node_name, address_type='ipv4'): + node_info = self.get_node(node_name) + if node_info is None: + return None + + if len(node_info['internal_ip']) == 0: + return None + + for internal_ip in node_info['internal_ip']: + if address_type == 'ipv4': + if ip_helper.is_valid_ipv4_address(internal_ip): + return internal_ip + if address_type == 'ipv6': + if ip_helper.is_valid_ipv6_address(internal_ip): + return internal_ip + + return None + + def get_node_external_ip(self, node_name, address_type='ipv4'): + node_info = self.get_node(node_name) + if node_info is None: + return None + + if len(node_info['external_ip']) == 0: + return None + + for external_ip in node_info['external_ip']: + if address_type == 'ipv4': + if ip_helper.is_valid_ipv4_address(external_ip): + return external_ip + if address_type == 'ipv6': + if ip_helper.is_valid_ipv6_address(external_ip): + return external_ip + + return None + + def get_node_ip(self, node_name, address_type='ipv4'): + node_info = self.get_node(node_name) + if node_info is None: + return None + + if len(node_info['ip']) == 0: + return None + + for ip_address in node_info['ip']: + if address_type == 'ipv4': + if ip_helper.is_valid_ipv4_address(ip_address): + return ip_address + if address_type == 'ipv6': + if ip_helper.is_valid_ipv6_address(ip_address): + return ip_address + + return None + + def get_master_nodes(self): + node_filter = ['master:true'] + return self.get_nodes(object_filter=node_filter) + + def get_worker_nodes(self): + node_filter = ['worker:true'] + return self.get_nodes(object_filter=node_filter) + + def get_worker_nodes_name(self): + names = [] + for node_info in self.get_worker_nodes(): + names.append( + node_info['name'] + ) + return names + + def get_worker_nodes_ip(self, ready=True): + node_ips = [] + for node_info in self.get_worker_nodes(): + if ready and not node_info['ready']: + continue + node_ips = node_ips + node_info['ip'] + + return node_ips + + def get_any_worker_node_ip(self): + node_ips = self.get_worker_nodes_ip() + if len(node_ips) == 0: + return None + return node_ips[0] + + def get_master_nodes_name(self): + names = [] + for node_info in self.get_master_nodes(): + names.append( + node_info['name'] + ) + return names + + # def get_node_pods(self, node_name): + # try: + # node_pods = [] + # for pod in self.pods: + # if pod['node'] == node_name: + # node_pods.append(pod) + + # except BaseException: + # self.log.error('k8s_nodes.get_node_pods', traceback.format_exc()) + # return None + + # return node_pods + + # def get_node_pods_ip(self, node_name): + # try: + # ips = {} + # for pod in self.pods: + # try: + # pod_ip = pod['status']['pod_ip'] + # ips[pod_ip] = {} + # ips[pod_ip]['uid'] = pod['metadata']['uid'] + # ips[pod_ip]['name'] = pod['metadata']['name'] + # except BaseException: + # pass + + # except BaseException: + # self.log.error('k8s_nodes.get_node_pods_ip', traceback.format_exc()) + # return None + + # return ips + + # def get_node_status(self, node_mo): + # status = [] + # for condition in node_mo['status']['conditions']: + # if condition['status'] == 'True': + # status.append( + # condition['type'] + # ) + # return ','.join(status) + + # def get_node_ready_status(self, node_mo): + # for condition in node_mo['status']['conditions']: + # if condition['type'] == 'Ready': + # if condition['status'] == 'True': + # return 'Ready' + # return 'NotReady' + + # def is_node_ready(self, node_mo): + # for condition in node_mo['status']['conditions']: + # if condition['type'] == 'Ready': + # if condition['status'] == 'True': + # return True + # return False + + # def is_node_memory_pressure(self, node): + # for condition in node['status']['conditions']: + # if condition['type'] == 'MemoryPressure': + # if condition['status'] == 'True': + # return True + # return False + + # def is_node_disk_pressure(self, node): + # for condition in node['status']['conditions']: + # if condition['type'] == 'DiskPressure': + # if condition['status'] == 'True': + # return True + # return False + + # def is_node_pid_pressure(self, node): + # for condition in node['status']['conditions']: + # if condition['type'] == 'PIDPressure': + # if condition['status'] == 'True': + # return True + # return False + + # def get_nodes_ready_count(self): + # count = 0 + # for node in self.nodes: + # if self.is_node_ready(node): + # count = count + 1 + # return count + + # def get_nodes_status_summary(self): + # status = {} + # status['Ready'] = 0 + # status['Memory Pressure'] = 0 + # status['Disk Pressure'] = 0 + # status['PID Pressure'] = 0 + + # for node in self.nodes: + # if self.is_node_ready(node): + # status['Ready'] = status['Ready'] + 1 + # if self.is_node_memory_pressure(node): + # status['Memory Pressure'] = status['Memory Pressure'] + 1 + # if self.is_node_disk_pressure(node): + # status['Disk Pressure'] = status['Disk Pressure'] + 1 + # if self.is_node_pid_pressure(node): + # status['PID Pressure'] = status['PID Pressure'] + 1 + + # summary = [] + # for field in status: + # summary.append(dict(status=field, count=status[field])) + + # return summary + + # def get_node_name(self, node_mo): + # return node_mo['metadata']['name'] + + # def get_node_ip(self, node_mo, address_type): + # addresses = node_mo['status']['addresses'] + # if addresses is not None: + # for address in addresses: + # if address['type'] == address_type: + # return address['address'] + # return None + + # def get_node_machine_id(self, node): + # try: + # return node['status']['node_info']['machine_id'] + # except BaseException: + # self.log.error('k8s_nodes.get_node_machine_id', traceback.format_exc()) + # return None + + # def get_node_roles(self, node): + # roles = [] + # for label in node['metadata']['labels']: + # if label == 'node-role.kubernetes.io/master': + # roles.append('Master') + # if label == 'node-role.kubernetes.io/worker': + # roles.append('Worker') + + # return ','.join(roles) + + # def get_node_vm_name(self, node_mo): + # for annotation in node_mo['metadata']['annotations']: + # if annotation == 'csi.volume.kubernetes.io/nodeid': + # for csi in node_mo['metadata']['annotations'][annotation]: + # if csi == 'csi.vsphere.vmware.com': + # return node_mo['metadata']['annotations'][annotation][csi] + # return None + + # def is_node_vm(self, node_mo): + # if self.get_node_vm_name(node_mo) is None: + # return False + # return True + + # def is_node_bm(self, node): + # return False + + # def is_node(self, node_name): + # if self.get_node_mo(node_name) is None: + # return False + # return True + + # def get_worker_nodes_name(self): + # if not self.get_nodes(): + # return None + + # names = [] + # for node_mo in self.nodes: + # if self.is_node_worker(node_mo): + # names.append( + # node_mo['metadata']['name'] + # ) + + # return names + + # def get_nodes_name(self): + # if not self.get_nodes(): + # return None + + # names = [] + # for node_mo in self.nodes: + # names.append( + # node_mo['metadata']['name'] + # ) + + # return names + + # def get_node_info(self, node_mo): + # info = {} + # info['__Output'] = {} + + # info['uid'] = node_mo['metadata']['uid'] + # info['name'] = node_mo['metadata']['name'] + # info['namespace'] = node_mo['metadata']['namespace'] + # info['age'] = self.convert_age( + # int(time.time()) - node_mo['metadata']['creation_timestamp'] + # ) + # info['node_info'] = node_mo['status']['node_info'] + # info['internal_ip'] = self.get_node_ip(node_mo, 'InternalIP') + # info['external_ip'] = self.get_node_ip(node_mo, 'ExternalIP') + # info['labels'] = node_mo['metadata']['labels'] + # info['roles'] = self.get_node_roles(node_mo) + # info['master'] = self.is_node_master(node_mo) + # info['worker'] = self.is_node_worker(node_mo) + # info['ready'] = self.get_node_ready_status(node_mo) + # if info['ready'] == 'Ready': + # info['__Output']['ready'] = 'Green' + # else: + # info['__Output']['ready'] = 'Red' + + # info['conditions'] = {} + # info['conditions']['Memory Pressure'] = self.is_node_memory_pressure(node_mo) + # info['conditions']['Disk Pressure'] = self.is_node_disk_pressure(node_mo) + # info['conditions']['PID Pressure'] = self.is_node_pid_pressure(node_mo) + + # info['is_vm'] = self.is_node_vm(node_mo) + # info['is_bm'] = self.is_node_bm(node_mo) + # info['type'] = '' + # if info['is_vm']: + # info['type'] = 'VM' + # if info['is_bm']: + # info['type'] = 'BM' + + # return info + + # def get_nodes_info(self): + # if not self.get_nodes(): + # return None + + # info = [] + # for node_mo in self.nodes: + # node_info = self.get_node_info(node_mo) + # if node_info is not None: + # info.append(node_info) + + # info = sorted( + # info, + # key=lambda i: i['name'] + # ) + + # return info + + # def get_nodes_state(self, summary_only=False): + # try: + # state = {} + # state['summary'] = {} + # state['summary']['count'] = len(self.nodes) + # state['summary']['ready'] = self.get_nodes_ready_count() + # state['summary']['functional'] = False + # if state['summary']['count'] > 0 and state['summary']['count'] == state['summary']['ready']: + # state['summary']['functional'] = True + # state['summary']['status'] = self.get_nodes_status_summary() + + # if summary_only: + # return state['summary'] + + # state['nodes'] = self.get_nodes_info() + + # except BaseException: + # self.log.error('k8s_nodes.get_nodes_state', traceback.format_exc()) + # return None + + # return state + + # def get_nodes_health_summary(self): + # ''' + # { + # "nodes_count": 5, + # "nodes_ready": 5, + # "nodes_healthy": true, + # "nodes_status": [ + # { + # "status": "Ready", + # "count": 5 + # }, + # { + # "status": "Memory Pressure", + # "count": 0 + # }, + # { + # "status": "Disk Pressure", + # "count": 0 + # }, + # { + # "status": "PID Pressure", + # "count": 0 + # } + # ] + # } + # ''' + # summary = {} + # summary['nodes_count'] = len(self.nodes) + # summary['nodes_ready'] = self.get_nodes_ready_count() + # summary['nodes_healthy'] = False + # if summary['nodes_count'] > 0 and summary['nodes_count'] == summary['nodes_ready']: + # summary['nodes_healthy'] = True + # summary['nodes_status'] = self.get_nodes_status_summary() + # return summary + + # def get_nodes_labels(self): + # try: + # labels = [] + # for node in self.nodes: + # try: + # node_labels = node['metadata']['labels'] + # if node_labels is not None: + # for key in node_labels: + # labels.append( + # dict( + # key=key, + # value=node_labels[key] + # ) + # ) + + # except BaseException: + # self.log.error('k8s_nodes.get_nodes_labels', traceback.format_exc()) + + # except BaseException: + # self.log.error('k8s_nodes.get_nodes_labels', traceback.format_exc()) + # return None + + # return labels + + # def get_node_mo(self, node_name, cache=True): + # if not self.get_nodes(cache=cache): + # return False + + # for node in self.nodes: + # if node['metadata']['name'] == node_name: + # return node + + # return None + + # def get_node(self, name): + # try: + # for node_mo in self.nodes: + # if node_mo['metadata']['name'] == name: + # info = {} + # info['node'] = node_mo + # info['summary'] = self.get_node_info(node_mo) + # info['pods'] = self.get_node_pods(name) + # info['age'] = int(time.time() * 1000) - info['timestamp'] + # return info + + # except BaseException: + # self.log.error( + # 'k8s_nodes.get_node', + # traceback.format_exc() + # ) + + # return None diff --git a/lib/k8s/node/main.py b/lib/k8s/node/main.py new file mode 100644 index 00000000..66388054 --- /dev/null +++ b/lib/k8s/node/main.py @@ -0,0 +1,14 @@ +from lib.k8s.node.api import K8sNodeApi +from lib.k8s.node.info import K8sNodeInfo +from lib.k8s.node.task import K8sNodeTask + + +class K8sNode( + K8sNodeApi, + K8sNodeInfo, + K8sNodeTask + ): + def __init__(self): + K8sNodeApi.__init__(self) + K8sNodeInfo.__init__(self) + K8sNodeTask.__init__(self) diff --git a/lib/k8s/node/output.py b/lib/k8s/node/output.py new file mode 100644 index 00000000..b9aac76d --- /dev/null +++ b/lib/k8s/node/output.py @@ -0,0 +1,380 @@ +class K8sNodeOutput(): + def __init__(self): + pass + + def print_nodes_state(self, info, title=False): + if title: + self.my_output.default( + 'Node - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'readyTick', + 'memoryTick', + 'diskTick', + 'pidTick', + 'cnvTick', + 'mcpTick', + 'role', + 'ipT', + 'age' + ] + + headers = [ + 'Name', + 'Ready', + 'Memory', + 'Disk', + 'PID', + 'CNV', + 'MCP', + 'Role', + 'IP', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ipT', 'role'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_nodes_version(self, info, title=False): + if title: + self.my_output.default( + 'Node - Versions [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'node_info.kubelet_version', + 'node_info.os_image', + 'node_info.kernel_version', + 'node_info.container_runtime_version' + ] + + headers = [ + 'Name', + 'Version', + 'OS Image', + 'Kernel Version', + 'Container Runtime' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_nodes_capacity(self, info, title=False): + if title: + self.my_output.default( + 'Node - Capacity [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'capacity_pod', + 'capacity_cpu', + 'capacity_memory', + 'capacity_storage', + 'capacity_hp2m', + 'capacity_hp1g', + 'capacity_kubevirt', + 'capacity_vendor' + ] + + headers = [ + 'Name', + 'POD', + 'CPU', + 'Memory', + 'Storage', + 'HP 2Mi', + 'HP 1Gi', + 'Kubevirt', + 'Vendor' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['capacity_vendor', 'capacity_kubevirt'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_nodes_label(self, info, title=False): + if title: + self.my_output.default( + 'Node - Label [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['labelT'] = [] + for key in item['label']: + label_info = {} + label_info['key'] = key + label_info['value'] = item['label'][key] + if label_info['value'] == '': + label_info['value'] = '--' + + item['labelT'].append( + label_info + ) + + order = [ + 'name', + 'labelT.key', + 'labelT.value' + ] + + headers = [ + 'Name', + 'Label Key', + 'Label Value' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['labelT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_ocp_nodes_sriov_phy(self, info, title=False): + if title: + self.my_output.default('SR-IOV Node Interfaces', underline=True, before_newline=True) + + order = [ + 'cluster', + 'name', + 'sriov_phy.name', + 'sriov_phy.state', + 'sriov_phy.flags', + 'sriov_phy.mtu', + 'sriov_phy.mac', + 'sriov_phy.numa', + 'sriov_phy.pci.driver', + 'sriov_phy.pci.slot', + 'sriov_phy.policyCount', + 'sriov_phy.numVfs', + 'sriov_phy.vfUsage' + ] + + headers = [ + 'Cluster', + 'Node', + 'Interface', + 'State', + 'Flags', + 'MTU', + 'MAC', + 'Numa', + 'Driver', + 'PCI', + 'Policies', + 'Num VFs', + 'Policies VF Usage' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['sriov_phy'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_ocp_nodes_sriov_policy(self, info, title=False): + if title: + self.my_output.default('SR-IOV Node Policy', underline=True, before_newline=True) + + order = [ + 'cluster', + 'name', + 'sriov_policy.policyName', + 'sriov_policy.selector', + 'sriov_policy.name', + 'sriov_policy.deviceType', + 'sriov_policy.resourceName', + 'sriov_policy.numVfs', + 'sriov_policy.vfUsage' + ] + + headers = [ + 'Cluster', + 'Node', + 'Policy', + 'Selector', + 'Interface', + 'Device Type', + 'Resource Name', + 'Num VFs', + 'Policy VF Usage' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['sriov_policy'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_ocp_nodes_sriov_network(self, info, title=False): + if title: + self.my_output.default('SR-IOV Network', underline=True, before_newline=True) + + order = [ + 'cluster', + 'name', + 'sriov_network.namespace_name', + 'sriov_network.policyName', + 'sriov_network.deviceType', + 'sriov_network.interfaceName', + 'sriov_network.vf', + 'sriov_network.ipamTick', + 'sriov_network.vlan', + 'sriov_network.usedBy' + ] + + headers = [ + 'Cluster', + 'Node', + 'SR-IOV Network', + 'Policy Name', + 'Device Type', + 'Interface', + 'VF', + 'IPAM', + 'VLAN', + 'Used By' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['sriov_network'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_ocp_nodes_sriov_vf(self, info, title=False): + if title: + self.my_output.default('SR-IOV Node Interface VFs', underline=True, before_newline=True) + + order = [ + 'cluster', + 'name', + 'sriov_vf.name', + 'sriov_vf.index', + 'sriov_vf.mac', + 'sriov_vf.vlan', + 'sriov_vf.spoof', + 'sriov_vf.link', + 'sriov_vf.trust', + 'sriov_vf.policyName', + 'sriov_vf.usedTick', + 'sriov_vf.networkName', + 'sriov_vf.usedBy' + ] + + headers = [ + 'Cluster', + 'Node', + 'Interface', + 'VF Index', + 'MAC', + 'VLAN', + 'Spoof', + 'Link', + 'Trust', + 'Policy Name', + 'Used', + 'Network Name', + 'Used By' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['sriov_vf'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/node/task.py b/lib/k8s/node/task.py new file mode 100644 index 00000000..47567197 --- /dev/null +++ b/lib/k8s/node/task.py @@ -0,0 +1,48 @@ +import time + + +class K8sNodeTask(): + def __init__(self): + pass + + def wait_node_ready(self, node_name, max_time=360): + start_time = int(time.time()) + while True: + node_mo = self.get_node_mo( + node_name, + cache=False + ) + if node_mo is not None: + if self.is_node_ready(node_mo): + return True + + duration = int(time.time()) - start_time + if duration > max_time: + self.log.error( + 'k8s.wait_node_ready', + 'Max time reached' + ) + return False + + time.sleep(5) + + def wait_node_not_ready(self, node_name, max_time=360): + start_time = int(time.time()) + while True: + node_mo = self.get_node_mo( + node_name, + cache=False + ) + if node_mo is not None: + if not self.is_node_ready(node_mo): + return True + + duration = int(time.time()) - start_time + if duration > max_time: + self.log.error( + 'k8s.wait_node_ready', + 'Max time reached' + ) + return False + + time.sleep(5) diff --git a/lib/k8s/node_network_configuration_enactment/__init__.py b/lib/k8s/node_network_configuration_enactment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/node_network_configuration_enactment/api.py b/lib/k8s/node_network_configuration_enactment/api.py new file mode 100644 index 00000000..6e53f25c --- /dev/null +++ b/lib/k8s/node_network_configuration_enactment/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sNodeNetworkConfigurationEnactmentApi(): + def __init__(self): + self.node_network_configuration_enactment_mo = None + + def get_node_network_configuration_enactment_mo(self, cache_enabled=True): + if cache_enabled: + if self.node_network_configuration_enactment_mo is not None: + return self.node_network_configuration_enactment_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='nmstate.io/v1beta1', + kind='NodeNetworkConfigurationEnactment' + ) + self.node_network_configuration_enactment_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'node_network_configuration_enactment', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_node_network_configuration_enactment_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'node_network_configuration_enactment', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'node_network_configuration_enactment', + self.node_network_configuration_enactment_mo + ) + + return self.node_network_configuration_enactment_mo diff --git a/lib/k8s/node_network_configuration_enactment/info.py b/lib/k8s/node_network_configuration_enactment/info.py new file mode 100644 index 00000000..d2af8064 --- /dev/null +++ b/lib/k8s/node_network_configuration_enactment/info.py @@ -0,0 +1,130 @@ +from lib import filter_helper + + +class K8sNodeNetworkConfigurationEnactmentInfo(): + def __init__(self): + self.node_network_configuration_enactment = None + + def get_node_network_configuration_enactment_info(self, node_network_configuration_enactment_mo): + if node_network_configuration_enactment_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + node_network_configuration_enactment_mo + ) + info.update(metadata_info) + + return info + + def get_node_network_configuration_enactments_info(self, cache_enabled=True): + if cache_enabled: + if self.node_network_configuration_enactment is not None: + return self.node_network_configuration_enactment + + managed_objects = self.get_node_network_configuration_enactment_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.node_network_configuration_enactment = [] + for managed_object in managed_objects: + node_network_configuration_enactment_info = {} + node_network_configuration_enactment_info['info'] = self.get_node_network_configuration_enactment_info( + managed_object + ) + node_network_configuration_enactment_info['mo'] = managed_object + self.node_network_configuration_enactment.append( + node_network_configuration_enactment_info + ) + + return self.node_network_configuration_enactment + + def match_node_network_interface_state_state(self, node_network_interface_state_state_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + + if not key_found: + self.log.error( + 'match_node_network_interface_state_state', + 'Unsupported key: %s' % (key) + ) + + return True + + def match_node_network_configuration_enactment(self, node_network_configuration_enactment_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, node_network_configuration_enactment_info['name']): + return False + + if not key_found: + self.log.error( + 'match_node_network_configuration_enactment', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_node_network_configuration_enactments(self, object_filter=None, return_mo=False, cache_enabled=True): + all_node_network_configuration_enactments = self.get_node_network_configuration_enactments_info(cache_enabled=cache_enabled) + if all_node_network_configuration_enactments is None: + return None + + node_network_configuration_enactments = [] + + for node_network_configuration_enactment_info in all_node_network_configuration_enactments: + if not self.match_node_network_configuration_enactment(node_network_configuration_enactment_info['info'], object_filter): + continue + + if return_mo: + node_network_configuration_enactments.append( + node_network_configuration_enactment_info['mo'] + ) + continue + + node_network_configuration_enactments.append( + node_network_configuration_enactment_info['info'] + ) + + return node_network_configuration_enactments + + def is_node_network_configuration_enactment(self, name, cache_enabled=True): + if self.get_node_network_configuration_enactment(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_node_network_configuration_enactment(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + node_network_configuration_enactments = self.get_node_network_configuration_enactments( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if node_network_configuration_enactments is None: + return None + + if len(node_network_configuration_enactments) == 1: + return node_network_configuration_enactments[0] + + return None diff --git a/lib/k8s/node_network_configuration_enactment/main.py b/lib/k8s/node_network_configuration_enactment/main.py new file mode 100644 index 00000000..fc046cae --- /dev/null +++ b/lib/k8s/node_network_configuration_enactment/main.py @@ -0,0 +1,11 @@ +from lib.k8s.node_network_configuration_enactment.api import K8sNodeNetworkConfigurationEnactmentApi +from lib.k8s.node_network_configuration_enactment.info import K8sNodeNetworkConfigurationEnactmentInfo + + +class K8sNodeNetworkConfigurationEnactment( + K8sNodeNetworkConfigurationEnactmentApi, + K8sNodeNetworkConfigurationEnactmentInfo + ): + def __init__(self): + K8sNodeNetworkConfigurationEnactmentApi.__init__(self) + K8sNodeNetworkConfigurationEnactmentInfo.__init__(self) diff --git a/lib/k8s/node_network_configuration_enactment/output.py b/lib/k8s/node_network_configuration_enactment/output.py new file mode 100644 index 00000000..43cba8a5 --- /dev/null +++ b/lib/k8s/node_network_configuration_enactment/output.py @@ -0,0 +1,11 @@ +class K8sNodeNetworkConfigurationEnactmentOutput(): + def __init__(self): + pass + + def print_node_network_configuration_enactment(self, info, title=False): + if title: + self.my_output.default( + 'Node Network Configuration Enactment [#%s]' % (len(info)), + underline=True, + before_newline=True + ) diff --git a/lib/k8s/node_network_configuration_policy/__init__.py b/lib/k8s/node_network_configuration_policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/node_network_configuration_policy/api.py b/lib/k8s/node_network_configuration_policy/api.py new file mode 100644 index 00000000..8288a04a --- /dev/null +++ b/lib/k8s/node_network_configuration_policy/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sNodeNetworkConfigurationPolicyApi(): + def __init__(self): + self.node_network_configuration_policy_mo = None + + def get_node_network_configuration_policy_mo(self, cache_enabled=True): + if cache_enabled: + if self.node_network_configuration_policy_mo is not None: + return self.node_network_configuration_policy_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='nmstate.io/v1', + kind='NodeNetworkConfigurationPolicy' + ) + self.node_network_configuration_policy_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'node_network_configuration_policy', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_node_network_configuration_policy_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'node_network_configuration_policy', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'node_network_configuration_policy', + self.node_network_configuration_policy_mo + ) + + return self.node_network_configuration_policy_mo diff --git a/lib/k8s/node_network_configuration_policy/info.py b/lib/k8s/node_network_configuration_policy/info.py new file mode 100644 index 00000000..c0b3ac7a --- /dev/null +++ b/lib/k8s/node_network_configuration_policy/info.py @@ -0,0 +1,110 @@ +from lib import filter_helper + + +class K8sNodeNetworkConfigurationPolicyInfo(): + def __init__(self): + self.node_network_configuration_policy = None + + def get_node_network_configuration_policy_info(self, node_network_configuration_policy_mo): + if node_network_configuration_policy_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + node_network_configuration_policy_mo + ) + info.update(metadata_info) + + return info + + def get_node_network_configuration_policies_info(self, cache_enabled=True): + if cache_enabled: + if self.node_network_configuration_policy is not None: + return self.node_network_configuration_policy + + managed_objects = self.get_node_network_configuration_policy_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.node_network_configuration_policy = [] + for managed_object in managed_objects: + node_network_configuration_policy_info = {} + node_network_configuration_policy_info['info'] = self.get_node_network_configuration_policy_info( + managed_object + ) + node_network_configuration_policy_info['mo'] = managed_object + self.node_network_configuration_policy.append( + node_network_configuration_policy_info + ) + + return self.node_network_configuration_policy + + def match_node_network_configuration_policy(self, node_network_configuration_policy_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, node_network_configuration_policy_info['name']): + return False + + if not key_found: + self.log.error( + 'match_node_network_configuration_policy', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_node_network_configuration_policies(self, object_filter=None, return_mo=False, cache_enabled=True): + all_node_network_configuration_policies = self.get_node_network_configuration_policies_info(cache_enabled=cache_enabled) + if all_node_network_configuration_policies is None: + return None + + node_network_configuration_policies = [] + + for node_network_configuration_policy_info in all_node_network_configuration_policies: + if not self.match_node_network_configuration_policy(node_network_configuration_policy_info['info'], object_filter): + continue + + if return_mo: + node_network_configuration_policies.append( + node_network_configuration_policy_info['mo'] + ) + continue + + node_network_configuration_policies.append( + node_network_configuration_policy_info['info'] + ) + + return node_network_configuration_policies + + def is_node_network_configuration_policy(self, name, cache_enabled=True): + if self.get_node_network_configuration_policy(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_node_network_configuration_policy(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + node_network_configuration_policies = self.get_node_network_configuration_policies( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if node_network_configuration_policies is None: + return None + + if len(node_network_configuration_policies) == 1: + return node_network_configuration_policies[0] + + return None diff --git a/lib/k8s/node_network_configuration_policy/main.py b/lib/k8s/node_network_configuration_policy/main.py new file mode 100644 index 00000000..4e1c5e72 --- /dev/null +++ b/lib/k8s/node_network_configuration_policy/main.py @@ -0,0 +1,11 @@ +from lib.k8s.node_network_configuration_policy.api import K8sNodeNetworkConfigurationPolicyApi +from lib.k8s.node_network_configuration_policy.info import K8sNodeNetworkConfigurationPolicyInfo + + +class K8sNodeNetworkConfigurationPolicy( + K8sNodeNetworkConfigurationPolicyApi, + K8sNodeNetworkConfigurationPolicyInfo + ): + def __init__(self): + K8sNodeNetworkConfigurationPolicyApi.__init__(self) + K8sNodeNetworkConfigurationPolicyInfo.__init__(self) diff --git a/lib/k8s/node_network_configuration_policy/output.py b/lib/k8s/node_network_configuration_policy/output.py new file mode 100644 index 00000000..3ed2739f --- /dev/null +++ b/lib/k8s/node_network_configuration_policy/output.py @@ -0,0 +1,11 @@ +class K8sNodeNetworkConfigurationPolicyOutput(): + def __init__(self): + pass + + def print_node_network_configuration_policy(self, info, title=False): + if title: + self.my_output.default( + 'Node Network Configuration Policy [#%s]' % (len(info)), + underline=True, + before_newline=True + ) diff --git a/lib/k8s/node_network_state/__init__.py b/lib/k8s/node_network_state/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/node_network_state/api.py b/lib/k8s/node_network_state/api.py new file mode 100644 index 00000000..208f7970 --- /dev/null +++ b/lib/k8s/node_network_state/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sNodeNetworkStateApi(): + def __init__(self): + self.node_network_state_mo = None + + def get_node_network_state_mo(self, cache_enabled=True): + if cache_enabled: + if self.node_network_state_mo is not None: + return self.node_network_state_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='nmstate.io/v1beta1', + kind='NodeNetworkState' + ) + self.node_network_state_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'node_network_state', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_node_network_state_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'node_network_state', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'node_network_state', + self.node_network_state_mo + ) + + return self.node_network_state_mo diff --git a/lib/k8s/node_network_state/info.py b/lib/k8s/node_network_state/info.py new file mode 100644 index 00000000..b1585567 --- /dev/null +++ b/lib/k8s/node_network_state/info.py @@ -0,0 +1,591 @@ +from lib import filter_helper + + +class K8sNodeNetworkStateInfo(): + def __init__(self): + self.node_network_state = None + + def get_node_network_state_interface_ipv4_info(self, interface_mo): + info = {} + + info['v4dhcp'] = self.get(interface_mo, 'ipv4:dhcp', on_error=False, on_none=False) + info['v4enabled'] = self.get(interface_mo, 'ipv4:enabled', on_error=False, on_none=False) + info['v4address'] = [] + + addresses_mo = self.get(interface_mo, 'ipv4:address', on_error=[], on_none=[]) + for address_mo in addresses_mo: + address_ip = self.get(address_mo, 'ip') + prefix_length = self.get(address_mo, 'prefix-length') + if address_ip is None or prefix_length is None: + self.log.error( + 'get_node_network_state_interface_ipv4_info', + 'Failed to parse v4 address mo: %s' % (address_mo) + ) + continue + + info['v4address'].append( + '%s/%s' % ( + address_ip, + prefix_length + ) + ) + + return info + + def get_node_network_state_interface_ipv6_info(self, interface_mo): + info = {} + + info['v6dhcp'] = self.get(interface_mo, 'ipv6:dhcp', on_error=False, on_none=False) + info['v6enabled'] = self.get(interface_mo, 'ipv6:enabled', on_error=False, on_none=False) + info['v6autoconf'] = self.get(interface_mo, 'ipv6:autoconf', on_error=False, on_none=False) + info['v6address'] = [] + + addresses_mo = self.get(interface_mo, 'ipv6:address', on_error=[], on_none=[]) + for address_mo in addresses_mo: + address_ip = self.get(address_mo, 'ip') + prefix_length = self.get(address_mo, 'prefix-length') + if address_ip is None or prefix_length is None: + self.log.error( + 'get_node_network_state_interface_ipv6_info', + 'Failed to parse v6 address mo: %s' % (address_mo) + ) + continue + + info['v6address'].append( + '%s/%s' % ( + address_ip, + prefix_length + ) + ) + + return info + + def get_node_network_state_interface_ethtool_info(self, interface_mo): + info = {} + info['ethtool'] = {} + + ethtool_mo = self.get(interface_mo, 'ethtool', on_error={}, on_none={}) + for key in ethtool_mo: + if key not in ['feature', 'coalesce', 'pause', 'ring']: + self.log.error( + 'get_node_network_state_interface_ethtool_info', + 'Unsupported ethtool section: %s' % (key) + ) + + ethtool_mo = self.get(interface_mo, 'ethtool:feature', on_error={}, on_none={}) + for key in ethtool_mo: + info['ethtool']['feature:%s' % (key)] = ethtool_mo[key] + + ethtool_mo = self.get(interface_mo, 'ethtool:coalesce', on_error={}, on_none={}) + for key in ethtool_mo: + info['ethtool']['coalesce:%s' % (key)] = ethtool_mo[key] + + ethtool_mo = self.get(interface_mo, 'ethtool:pause', on_error={}, on_none={}) + for key in ethtool_mo: + info['ethtool']['pause:%s' % (key)] = ethtool_mo[key] + + ethtool_mo = self.get(interface_mo, 'ethtool:ring', on_error={}, on_none={}) + for key in ethtool_mo: + info['ethtool']['ring:%s' % (key)] = ethtool_mo[key] + + return info + + def get_node_network_state_interface_lacp_info(self, interface_mo): + info = {} + lacp_mo = self.get(interface_mo, 'link-aggregation', on_error=None, on_none=None) + if lacp_mo is None: + info['lacp_enabled'] = False + else: + info['lacp_enabled'] = True + info['lacp_mode'] = self.get(interface_mo, 'link-aggregation:mode') + info['lacp_port'] = self.get(interface_mo, 'link-aggregation:port', on_error=[], on_none=[]) + info['lacp_option'] = self.get(interface_mo, 'link-aggregation:options', on_error={}, on_none={}) + + return info + + def get_node_network_state_interface_lldp_info(self, interface_mo): + info = {} + lldp_mo = self.get(interface_mo, 'lldp', on_error=None, on_none=None) + if lldp_mo is None: + info['lldp_enabled'] = False + else: + info['lldp_enabled'] = self.get(interface_mo, 'lldp:enabled', on_error=False, on_none=False) + + if info['lldp_enabled']: + info['lldp_enabledTick'] = '\u2713' + else: + info['lldp_enabledTick'] = '\u2717' + + return info + + def get_node_network_state_interface_bridge_info(self, interface_mo): + info = {} + bridge_mo = self.get(interface_mo, 'bridge', on_error=None, on_none=None) + if bridge_mo is None: + info['bridge_enabled'] = False + else: + info['bridge_enabled'] = True + info['bridge_port'] = [] + ports_mo = self.get(interface_mo, 'bridge:port', on_error=[], on_none=[]) + for port_mo in ports_mo: + port_info = {} + port_info['name'] = self.get(port_mo, 'name') + port_info['stp-hairpin-mode'] = self.get(port_mo, 'stp-hairpin-mode') + port_info['stp-path-cost'] = self.get(port_mo, 'stp-path-cost') + port_info['stp-priority'] = self.get(port_mo, 'stp-priority') + port_vlan_mo = self.get(port_mo, 'vlan') + if port_vlan_mo is None: + port_info['vlan_enabled'] = False + else: + port_info['vlan_enabled'] = True + port_info['vlan_native'] = self.get(port_vlan_mo, 'enable-native', on_error=False, on_none=False) + port_info['vlan_mode'] = self.get(port_vlan_mo, 'mode') + if port_info['vlan_mode'] == 'trunk': + trunk_range_mo = self.get(port_vlan_mo, 'trunk-tags') + port_info['vlan_range'] = [] + for range_mo in trunk_range_mo: + if 'id-range' in range_mo: + port_info['vlan_range'].append( + '%s-%s' % ( + range_mo['id-range']['min'], + range_mo['id-range']['max'] + ) + ) + + if port_info['vlan_mode'] == 'access': + port_info['vlan_range'] = [] + access_vlan = str(self.get(port_vlan_mo, 'tag')) + if access_vlan is not None: + port_info['vlan_range'].append( + access_vlan + ) + + info['bridge_port'].append( + port_info + ) + + info['bridge_option'] = {} + options_mo = self.get(interface_mo, 'bridge:options', on_error={}, on_none={}) + for key in options_mo: + if key == 'stp' and isinstance(options_mo[key], dict): + for stp_key in options_mo[key]: + info['bridge_option']['stp:%s' % (stp_key)] = options_mo[key][stp_key] + else: + info['bridge_option'][key] = options_mo[key] + + return info + + def get_node_network_state_interface_ethernet_info(self, interface_mo): + info = {} + ethernet_mo = self.get(interface_mo, 'ethernet', on_error=None, on_none=None) + if ethernet_mo is not None: + info['ethernet_auto'] = self.get(interface_mo, 'ethernet:auto-negotiation') + info['ethernet_duplex'] = self.get(interface_mo, 'ethernet:duplex') + info['ethernet_speed'] = self.get(interface_mo, 'ethernet:speed') + sriov_mo = self.get(interface_mo, 'ethernet:sr-iov') + if sriov_mo is None: + info['ethernet_sriov_enabled'] = False + info['ethernet_sriov_vfs_count'] = 0 + info['ethernet_sriov_vfs_summary'] = '--' + else: + info['ethernet_sriov_enabled'] = True + info['ethernet_sriov_num_vfs'] = self.get(sriov_mo, 'total-vfs') + info['ethernet_sriov_vfs'] = self.get(sriov_mo, 'vfs', on_error=[], on_none=[]) + + info['ethernet_sriov_vfs_count'] = 0 + for vf_info in info['ethernet_sriov_vfs']: + if vf_info['_vf_iface_name'] is not None: + info['ethernet_sriov_vfs_count'] = info['ethernet_sriov_vfs_count'] + 1 + + info['ethernet_sriov_vfs_summary'] = '%s/%s' % ( + info['ethernet_sriov_vfs_count'], + info['ethernet_sriov_num_vfs'] + ) + + return info + + def get_node_network_state_interface_vlan_info(self, interface_mo): + info = {} + vlan_mo = self.get(interface_mo, 'vlan', on_error=None, on_none=None) + if vlan_mo is not None: + info['vlan_base'] = self.get(vlan_mo, 'base-iface') + info['vlan_id'] = self.get(vlan_mo, 'id') + + return info + + def get_node_network_state_interface_info(self, interface_mo): + info = {} + info['__Output'] = {} + + keys = [ + 'name', + 'state', + 'type', + 'mtu' + ] + for key in keys: + info[key] = self.get(interface_mo, key) + + if info['state'] == 'up': + info['stateTick'] = '\u2713' + info['__Output']['stateTick'] = 'Green' + info['__Output']['state'] = 'Green' + + if info['state'] == 'ignore': + info['stateTick'] = '--' + + if info['state'] not in ['up', 'ignore']: + info['stateTick'] = '\u2717' + info['__Output']['stateTick'] = 'Red' + info['__Output']['state'] = 'Red' + + if info['type'] not in ['bond', 'vlan', 'ethernet', 'ovs-interface', 'ovs-bridge', 'linux-bridge', 'loopback']: + if interface_mo['type'] != 'unknown' and interface_mo['name'] == 'lo': + self.log.error( + 'get_node_network_state_interface_info', + 'Unsupported interface: %s' % (interface_mo) + ) + return None + + if interface_mo['type'] == 'unknown' and interface_mo['name'] != 'lo': + self.log.error( + 'get_node_network_state_interface_info', + 'Unsupported interface: %s' % (interface_mo) + ) + return None + + info['accept'] = self.get(interface_mo, 'accept-all-mac-addresses', on_error=False, on_none=False) + info['mac'] = self.get(interface_mo, 'mac-address') + + ethtool_info = self.get_node_network_state_interface_ethtool_info( + interface_mo + ) + info.update(ethtool_info) + + ipv4_info = self.get_node_network_state_interface_ipv4_info( + interface_mo + ) + info.update(ipv4_info) + + ipv6_info = self.get_node_network_state_interface_ipv6_info( + interface_mo + ) + info.update(ipv6_info) + + info['address'] = info['v4address'] + info['v6address'] + + lacp_info = self.get_node_network_state_interface_lacp_info( + interface_mo + ) + info.update(lacp_info) + + lldp_info = self.get_node_network_state_interface_lldp_info( + interface_mo + ) + info.update(lldp_info) + + bridge_info = self.get_node_network_state_interface_bridge_info( + interface_mo + ) + info.update(bridge_info) + + ethernet_info = self.get_node_network_state_interface_ethernet_info( + interface_mo + ) + info.update(ethernet_info) + + if 'ethernet_sriov_enabled' in ethernet_info: + if ethernet_info['ethernet_sriov_enabled']: + info['ethernet_sriov_enabledTick'] = '\u2713' + else: + info['ethernet_sriov_enabledTick'] = '\u2717' + + if 'ethernet_auto' in ethernet_info: + if ethernet_info['ethernet_auto']: + info['ethernet_autoTick'] = '\u2713' + else: + info['ethernet_autoTick'] = '\u2717' + + vlan_info = self.get_node_network_state_interface_vlan_info( + interface_mo + ) + info.update(vlan_info) + + return info + + def get_node_network_state_interfaces_info(self, interfaces_mo): + interfaces_info = [] + for interface_mo in interfaces_mo: + interface_info = self.get_node_network_state_interface_info(interface_mo) + if interface_info is not None: + interfaces_info.append( + interface_info + ) + + bridge_interface_names = {} + for interface_info in interfaces_info: + if interface_info['type'] == 'linux-bridge': + if 'bridge_port' in interface_info: + for port_info in interface_info['bridge_port']: + bridge_interface_names[port_info['name']] = interface_info['name'] + + ovs_interface_names = {} + for interface_info in interfaces_info: + if interface_info['type'] == 'ovs-bridge': + if 'bridge_port' in interface_info: + for port_info in interface_info['bridge_port']: + ovs_interface_names[port_info['name']] = interface_info['name'] + + vlan_interface_names = {} + for interface_info in interfaces_info: + if interface_info['type'] == 'vlan': + vlan_interface_names[interface_info['vlan_base']] = True + if interface_info['name'] in bridge_interface_names: + bridge_interface_names[interface_info['vlan_base']] = bridge_interface_names[interface_info['name']] + if interface_info['name'] in ovs_interface_names: + ovs_interface_names[interface_info['vlan_base']] = ovs_interface_names[interface_info['name']] + + vf_interface_names = [] + vf_interface_state = {} + for interface_info in interfaces_info: + if interface_info['type'] == 'ethernet' and interface_info['ethernet_sriov_enabled']: + for vf_info in interface_info['ethernet_sriov_vfs']: + if vf_info['_vf_iface_name'] is not None: + if vf_info['_vf_iface_name'] not in vf_interface_names: + vf_interface_names.append( + vf_info['_vf_iface_name'] + ) + vf_interface_state[vf_info['_vf_iface_name']] = vf_info + + bond_interface_names = {} + for interface_info in interfaces_info: + if interface_info['type'] == 'bond': + interface_info['vlan'] = False + interface_info['vlanTick'] = '\u2717' + if interface_info['name'] in vlan_interface_names: + interface_info['vlan'] = True + interface_info['vlanTick'] = '\u2713' + + for port_name in interface_info['lacp_port']: + bond_interface_names[port_name] = interface_info['name'] + + for interface_info in interfaces_info: + if interface_info['type'] == 'ethernet': + if interface_info['name'] in vf_interface_names: + interface_info['type'] = 'vf' + interface_info['vf'] = vf_interface_state[interface_info['name']] + continue + + interface_info['lacp_parent'] = None + if interface_info['name'] in bond_interface_names: + interface_info['lacp_parent'] = bond_interface_names[interface_info['name']] + + interface_info['bridge'] = None + if interface_info['name'] in bridge_interface_names: + interface_info['bridge'] = bridge_interface_names[interface_info['name']] + if interface_info['lacp_parent'] is not None and interface_info['lacp_parent'] in bridge_interface_names: + interface_info['bridge'] = bridge_interface_names[interface_info['lacp_parent']] + + interface_info['ovs'] = False + interface_info['ovsTick'] = '\u2717' + interface_info['__Output']['ovsTick'] = 'Red' + if interface_info['name'] in ovs_interface_names: + interface_info['ovs'] = True + interface_info['ovsTick'] = '\u2713' + interface_info['__Output']['ovsTick'] = 'Green' + if interface_info['lacp_parent'] is not None and interface_info['lacp_parent'] in ovs_interface_names: + interface_info['ovs'] = True + interface_info['ovsTick'] = '\u2713' + interface_info['__Output']['ovsTick'] = 'Green' + + interface_info['vlan'] = False + interface_info['vlanTick'] = '\u2717' + interface_info['__Output']['vlanTick'] = 'Red' + if interface_info['name'] in vlan_interface_names: + interface_info['vlan'] = True + interface_info['vlanTick'] = '\u2713' + interface_info['__Output']['vlanTick'] = 'Green' + if interface_info['lacp_parent'] is not None and interface_info['lacp_parent'] in vlan_interface_names: + interface_info['vlan'] = True + interface_info['vlanTick'] = '\u2713' + interface_info['__Output']['vlanTick'] = 'Green' + + interfaces_info = sorted( + interfaces_info, + key=lambda i: i['name'] + ) + + return interfaces_info + + def get_node_network_state_info(self, node_network_state_mo): + if node_network_state_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + node_network_state_mo + ) + info.update(metadata_info) + + info['interface'] = self.get_node_network_state_interfaces_info( + self.get( + node_network_state_mo, + 'status:currentState:interfaces' + ) + ) + + info['dns'] = {} + info['dns']['search'] = self.get( + node_network_state_mo, + 'status:currentState:dns-resolver:running:search' + ) + info['dns']['server'] = self.get( + node_network_state_mo, + 'status:currentState:dns-resolver:running:server' + ) + + info['route'] = [] + routes_mo = self.get( + node_network_state_mo, + 'status:currentState:routes:running' + ) + for route_mo in routes_mo: + route_info = {} + for key in route_mo: + route_info[key] = route_mo[key] + info['route'].append( + route_info + ) + + return info + + def get_node_network_states_info(self, cache_enabled=True): + if cache_enabled: + if self.node_network_state is not None: + return self.node_network_state + + managed_objects = self.get_node_network_state_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.node_network_state = [] + for managed_object in managed_objects: + node_network_state_info = {} + node_network_state_info['info'] = self.get_node_network_state_info( + managed_object + ) + node_network_state_info['mo'] = managed_object + self.node_network_state.append( + node_network_state_info + ) + + return self.node_network_state + + def match_node_network_state(self, node_network_state_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, node_network_state_info['name']): + return False + + if key.startswith('interface-'): + key_found = True + + if not key_found: + self.log.error( + 'match_node_network_state', + 'Unsupported key: %s' % (key) + ) + + return True + + def match_node_network_state_interface(self, node_network_state_interface_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + + if key == 'interface-type': + key_found = True + if not filter_helper.match_string(value, node_network_state_interface_info['interface']): + return False + + if not key_found: + self.log.error( + 'match_node_network_state_interface', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_node_network_states(self, object_filter=None, return_mo=False, cache_enabled=True): + all_node_network_states = self.get_node_network_states_info(cache_enabled=cache_enabled) + if all_node_network_states is None: + return None + + node_network_states = [] + + for node_network_state_info in all_node_network_states: + if not self.match_node_network_state(node_network_state_info['info'], object_filter): + continue + + if return_mo: + node_network_states.append( + node_network_state_info['mo'] + ) + continue + + interfaces_info = [] + for node_network_state_interface_info in node_network_state_info['info']['interface']: + if not self.match_node_network_state_interface(node_network_state_interface_info, object_filter): + continue + + interfaces_info.append( + node_network_state_interface_info + ) + + node_network_state_info['info']['interface'] = interfaces_info + + node_network_states.append( + node_network_state_info['info'] + ) + + return node_network_states + + def is_node_network_state(self, name, cache_enabled=True): + if self.get_node_network_state(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_node_network_state(self, node_name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (node_name) + ) + node_network_states = self.get_node_network_states( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if node_network_states is None: + return None + + if len(node_network_states) == 1: + return node_network_states[0] + + return None diff --git a/lib/k8s/node_network_state/main.py b/lib/k8s/node_network_state/main.py new file mode 100644 index 00000000..014e5413 --- /dev/null +++ b/lib/k8s/node_network_state/main.py @@ -0,0 +1,11 @@ +from lib.k8s.node_network_state.api import K8sNodeNetworkStateApi +from lib.k8s.node_network_state.info import K8sNodeNetworkStateInfo + + +class K8sNodeNetworkState( + K8sNodeNetworkStateApi, + K8sNodeNetworkStateInfo + ): + def __init__(self): + K8sNodeNetworkStateApi.__init__(self) + K8sNodeNetworkStateInfo.__init__(self) diff --git a/lib/k8s/node_network_state/output.py b/lib/k8s/node_network_state/output.py new file mode 100644 index 00000000..e8a0c500 --- /dev/null +++ b/lib/k8s/node_network_state/output.py @@ -0,0 +1,954 @@ +import copy + + +class K8sNodeNetworkStateOutput(): + def __init__(self): + pass + + def print_node_network_state(self, info, title=False): + if title: + self.my_output.default( + 'Node Network State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + def print_node_network_state_dns(self, state, title=False): + if title: + self.my_output.default( + 'Node Network State - DNS [#%s]' % (len(state)), + underline=True, + before_newline=True + ) + + order = [ + 'name', + 'dns.search', + 'dns.server' + ] + + headers = [ + 'Node', + 'Search', + 'Server' + ] + + self.my_output.my_table( + state, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_route(self, state, title=False): + if title: + self.my_output.default( + 'Node Network State - Route [#%s]' % (len(state)), + underline=True, + before_newline=True + ) + + order = [ + 'name', + 'route.destination', + 'route.next-hop-address', + 'route.next-hop-interface', + 'route.metric', + 'route.table-id' + ] + + headers = [ + 'Node', + 'Destination', + 'NH', + 'Interface', + 'Metric', + 'Table' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + state, + order, + ['route'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_bond(self, state, options=False, ethtool=False, title=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'bond': + continue + + interface['node_name'] = item['name'] + + interface['ipv4'] = [] + if interface['v4enabled']: + interface['ipv4'].append('Enabled') + if interface['v4dhcp']: + interface['ipv4'].append('DHCPv4: yes') + else: + interface['ipv4'].append('DHCPv4: no') + interface['ipv4'] = interface['ipv4'] + interface['v4address'] + if len(interface['ipv4']) == 0: + interface['ipv4'] = ['--'] + + interface['ipv6'] = [] + if interface['v4enabled']: + interface['ipv6'].append('Enabled') + if interface['v6dhcp']: + interface['ipv6'].append('DHCPv6: yes') + else: + interface['ipv6'].append('DHCPv6: no') + interface['ipv6'] = interface['ipv6'] + interface['v6address'] + if len(interface['ipv6']) == 0: + interface['ipv6'] = ['--'] + + interface['ethtoolT'] = [] + for key in interface['ethtool']: + interface['ethtoolT'].append( + '%s = %s' % ( + key, + interface['ethtool'][key] + ) + ) + + interface['lacp_optionT'] = [] + for key in interface['lacp_option']: + interface['lacp_optionT'].append( + '%s = %s' % ( + key, + interface['lacp_option'][key] + ) + ) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if title: + self.my_output.default( + 'Node Network State - Bond Interface [#%s]' % (len(interfaces)), + underline=True, + before_newline=True + ) + + order = [ + 'node_name', + 'name', + 'stateTick', + 'mtu', + 'mac', + 'lacp_mode', + 'lacp_port', + 'lldp_enabledTick', + 'vlanTick', + 'ipv4', + 'ipv6' + ] + + headers = [ + 'Node', + 'Interface', + 'State', + 'MTU', + 'MAC', + 'Mode', + 'Port', + 'LLDP', + 'VLAN', + 'IPv4', + 'IPv6' + ] + + to_expand = ['ipv4', 'ipv6', 'lacp_port'] + + if options: + order.append('lacp_optionT') + headers.append('LACP Options') + to_expand.append('lacp_optionT') + + if ethtool: + order.append('ethtoolT') + headers.append('Ethtool') + to_expand.append('ethtoolT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_ethernet(self, state, ethtool=False, title=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'ethernet': + continue + + interface['node_name'] = item['name'] + + if interface['ethernet_duplex'] is None: + interface['ethernet_duplex'] = '--' + + if interface['ethernet_speed'] is None: + interface['ethernet_speed'] = '--' + + if interface['lacp_parent'] is None: + interface['lacp_parent'] = '--' + + if interface['bridge'] is None: + interface['bridge'] = '--' + + interface['ipv4'] = [] + if interface['v4enabled']: + interface['ipv4'].append('Enabled') + if interface['v4dhcp']: + interface['ipv4'].append('DHCPv4: yes') + else: + interface['ipv4'].append('DHCPv4: no') + interface['ipv4'] = interface['ipv4'] + interface['v4address'] + if len(interface['ipv4']) == 0: + interface['ipv4'] = ['--'] + + interface['ipv6'] = [] + if interface['v4enabled']: + interface['ipv6'].append('Enabled') + if interface['v6dhcp']: + interface['ipv6'].append('DHCPv6: yes') + else: + interface['ipv6'].append('DHCPv6: no') + interface['ipv6'] = interface['ipv6'] + interface['v6address'] + if len(interface['ipv6']) == 0: + interface['ipv6'] = ['--'] + + interface['ethtoolT'] = [] + for key in interface['ethtool']: + interface['ethtoolT'].append( + '%s = %s' % ( + key, + interface['ethtool'][key] + ) + ) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if title: + self.my_output.default( + 'Node Network State - Ethernet Interface [#%s]' % (len(interfaces)), + underline=True, + before_newline=True + ) + + order = [ + 'node_name', + 'name', + 'stateTick', + 'mtu', + 'mac', + 'ethernet_autoTick', + 'ethernet_duplex', + 'ethernet_speed', + 'ethernet_sriov_vfs_summary', + 'lldp_enabledTick', + 'lacp_parent', + 'vlanTick', + 'ovsTick', + 'bridge', + 'ipv4', + 'ipv6' + ] + + headers = [ + 'Node', + 'Interface', + 'State', + 'MTU', + 'MAC', + 'Auto', + 'Duplex', + 'Speed', + 'SR-IOV', + 'LLDP', + 'LACP', + 'VLAN', + 'OVS', + 'LB', + 'IPv4', + 'IPv6' + ] + + to_expand = ['ipv4', 'ipv6'] + if ethtool: + order.append('ethtoolT') + headers.append('Ethtool') + to_expand.append('ethtoolT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_vf(self, state, ethtool=False, title=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'vf': + continue + + interface['node_name'] = item['name'] + + if interface['ethernet_duplex'] is None: + interface['ethernet_duplex'] = '--' + + if interface['ethernet_speed'] is None: + interface['ethernet_speed'] = '--' + + interface['ipv4'] = [] + if interface['v4enabled']: + interface['ipv4'].append('Enabled') + if interface['v4dhcp']: + interface['ipv4'].append('DHCPv4: yes') + else: + interface['ipv4'].append('DHCPv4: no') + interface['ipv4'] = interface['ipv4'] + interface['v4address'] + if len(interface['ipv4']) == 0: + interface['ipv4'] = ['--'] + + interface['ipv6'] = [] + if interface['v4enabled']: + interface['ipv6'].append('Enabled') + if interface['v6dhcp']: + interface['ipv6'].append('DHCPv6: yes') + else: + interface['ipv6'].append('DHCPv6: no') + interface['ipv6'] = interface['ipv6'] + interface['v6address'] + if len(interface['ipv6']) == 0: + interface['ipv6'] = ['--'] + + interface['ethtoolT'] = [] + for key in interface['ethtool']: + interface['ethtoolT'].append( + '%s = %s' % ( + key, + interface['ethtool'][key] + ) + ) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if title: + self.my_output.default( + 'Node Network State - SR-IOV VF [#%s]' % (len(interfaces)), + underline=True, + before_newline=True + ) + + if len(interfaces) == 0: + self.my_output.default('None') + return + + order = [ + 'node_name', + 'name', + 'stateTick', + 'mtu', + 'mac', + 'ethernet_autoTick', + 'ethernet_duplex', + 'ethernet_speed', + 'ipv4', + 'ipv6', + 'vf.spoof-check', + 'vf.trust', + 'vf.vlan-id' + ] + + headers = [ + 'Node', + 'Interface', + 'State', + 'MTU', + 'MAC', + 'Auto', + 'Duplex', + 'Speed', + 'IPv4', + 'IPv6', + 'Spoof', + 'Trust', + 'VLAN' + ] + + to_expand = ['ipv4', 'ipv6'] + if ethtool: + order.append('ethtoolT') + headers.append('Ethtool') + to_expand.append('ethtoolT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_vlan(self, state, ethtool=False, title=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'vlan': + continue + + interface['node_name'] = item['name'] + + interface['ipv4'] = [] + if interface['v4enabled']: + interface['ipv4'].append('Enabled') + if interface['v4dhcp']: + interface['ipv4'].append('DHCPv4: yes') + else: + interface['ipv4'].append('DHCPv4: no') + interface['ipv4'] = interface['ipv4'] + interface['v4address'] + if len(interface['ipv4']) == 0: + interface['ipv4'] = ['--'] + + interface['ipv6'] = [] + if interface['v4enabled']: + interface['ipv6'].append('Enabled') + if interface['v6dhcp']: + interface['ipv6'].append('DHCPv6: yes') + else: + interface['ipv6'].append('DHCPv6: no') + interface['ipv6'] = interface['ipv6'] + interface['v6address'] + if len(interface['ipv6']) == 0: + interface['ipv6'] = ['--'] + + interface['ethtoolT'] = [] + for key in interface['ethtool']: + interface['ethtoolT'].append( + '%s = %s' % ( + key, + interface['ethtool'][key] + ) + ) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if title: + self.my_output.default( + 'Node Network State - VLAN Interface [#%s]' % (len(interfaces)), + underline=True, + before_newline=True + ) + + if len(interfaces) == 0: + self.my_output.default('None') + return + + order = [ + 'node_name', + 'name', + 'stateTick', + 'mtu', + 'mac', + 'ipv4', + 'ipv6', + 'vlan_base', + 'vlan_id' + ] + + headers = [ + 'Node', + 'Interface', + 'State', + 'MTU', + 'MAC', + 'IPv4', + 'IPv6', + 'Base Intf', + 'VLAN ID' + ] + + to_expand = ['ipv4', 'ipv6'] + if ethtool: + order.append('ethtoolT') + headers.append('Ethtool') + to_expand.append('ethtoolT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_lb(self, state, options=False, ethtool=False, title=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'linux-bridge': + continue + + interface['node_name'] = item['name'] + + interface['ipv4'] = [] + if interface['v4enabled']: + interface['ipv4'].append('Enabled') + if interface['v4dhcp']: + interface['ipv4'].append('DHCPv4: yes') + else: + interface['ipv4'].append('DHCPv4: no') + interface['ipv4'] = interface['ipv4'] + interface['v4address'] + if len(interface['ipv4']) == 0: + interface['ipv4'] = ['--'] + + interface['ipv6'] = [] + if interface['v4enabled']: + interface['ipv6'].append('Enabled') + if interface['v6dhcp']: + interface['ipv6'].append('DHCPv6: yes') + else: + interface['ipv6'].append('DHCPv6: no') + interface['ipv6'] = interface['ipv6'] + interface['v6address'] + if len(interface['ipv6']) == 0: + interface['ipv6'] = ['--'] + + interface['ethtoolT'] = [] + for key in interface['ethtool']: + interface['ethtoolT'].append( + '%s = %s' % ( + key, + interface['ethtool'][key] + ) + ) + + interface['bridge_optionT'] = [] + for key in interface['bridge_option']: + interface['bridge_optionT'].append( + '%s = %s' % ( + key, + interface['bridge_option'][key] + ) + ) + + if len(interface['bridge_port']) == 0: + interface['bridge_port'].append(dict(name='--')) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if title: + self.my_output.default( + 'Node Network State - Linux Bridge [#%s]' % (len(interfaces)), + underline=True, + before_newline=True + ) + + if len(interfaces) == 0: + self.my_output.default('None') + return + + order = [ + 'node_name', + 'name', + 'stateTick', + 'mtu', + 'mac', + 'bridge_port.name', + 'lldp_enabledTick', + 'ipv4', + 'ipv6' + ] + + headers = [ + 'Node', + 'Bridge', + 'State', + 'MTU', + 'MAC', + 'Interface', + 'LLDP', + 'IPv4', + 'IPv6' + ] + + to_expand = ['ipv4', 'ipv6', 'bridge_port'] + + if options: + order.append('bridge_optionT') + headers.append('Bridge Options') + to_expand.append('bridge_optionT') + + if ethtool: + order.append('ethtoolT') + headers.append('Ethtool') + to_expand.append('ethtoolT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_lb_interfaces(self, state): + ports = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'linux-bridge': + continue + + for lb_port_info in interface['bridge_port']: + port_info = lb_port_info + port_info['node_name'] = item['name'] + port_info['lb_name'] = interface['name'] + port_info['vlan_rangeT'] = '--' + if 'vlan_range' in port_info: + port_info['vlan_rangeT'] = ','.join(port_info['vlan_range']) + + ports.append( + port_info + ) + + ports = sorted( + ports, + key=lambda i: ( + i['node_name'].lower(), + i['lb_name'].lower(), + i['name'].lower() + ) + ) + + if len(ports) == 0: + return + + order = [ + 'node_name', + 'lb_name', + 'name', + 'stp-hairpin-mode', + 'stp-path-cost', + 'stp-priority', + 'vlan_enabled', + 'vlan_native', + 'vlan_mode', + 'vlan_rangeT' + ] + + headers = [ + 'Node', + 'Bridge', + 'Interface', + 'STP Hairpin', + 'STP Cost', + 'STP Prio', + 'VLAN', + 'Native', + 'Mode', + 'Range' + ] + + self.my_output.my_table( + ports, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_ovs(self, state, options=False, ethtool=False, title=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'ovs-bridge': + continue + + interface['node_name'] = item['name'] + + interface['bridge_optionT'] = [] + for key in interface['bridge_option']: + interface['bridge_optionT'].append( + '%s = %s' % ( + key, + interface['bridge_option'][key] + ) + ) + + if len(interface['bridge_port']) == 0: + interface['bridge_port'].append(dict(name='--')) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if title: + self.my_output.default( + 'Node Network State - OVS [#%s]' % (len(interfaces)), + underline=True, + before_newline=True + ) + + if len(interfaces) == 0: + self.my_output.default('None') + return + + order = [ + 'node_name', + 'name', + 'state', + 'bridge_port.name', + 'lldp_enabledTick' + ] + + headers = [ + 'Node', + 'Bridge', + 'State', + 'Interface', + 'LLDP' + ] + + to_expand = ['bridge_port'] + + if options: + order.append('bridge_optionT') + headers.append('Bridge Options') + to_expand.append('bridge_optionT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_node_network_state_ovs_interfaces(self, state, ethtool=False): + interfaces = [] + + info = copy.deepcopy(state) + for item in info: + for interface in item['interface']: + if interface['type'] != 'ovs-interface': + continue + + interface['node_name'] = item['name'] + + if interface['mtu'] is None: + interface['mtu'] = '--' + + if interface['mac'] is None: + interface['mac'] = '--' + + interface['ipv4'] = [] + if interface['v4enabled']: + interface['ipv4'].append('Enabled') + if interface['v4dhcp']: + interface['ipv4'].append('DHCPv4: yes') + else: + interface['ipv4'].append('DHCPv4: no') + interface['ipv4'] = interface['ipv4'] + interface['v4address'] + if len(interface['ipv4']) == 0: + interface['ipv4'] = ['--'] + + interface['ipv6'] = [] + if interface['v4enabled']: + interface['ipv6'].append('Enabled') + if interface['v6dhcp']: + interface['ipv6'].append('DHCPv6: yes') + else: + interface['ipv6'].append('DHCPv6: no') + interface['ipv6'] = interface['ipv6'] + interface['v6address'] + if len(interface['ipv6']) == 0: + interface['ipv6'] = ['--'] + + interface['ethtoolT'] = [] + for key in interface['ethtool']: + interface['ethtoolT'].append( + '%s = %s' % ( + key, + interface['ethtool'][key] + ) + ) + + interfaces.append( + interface + ) + + interfaces = sorted( + interfaces, + key=lambda i: ( + i['node_name'].lower(), + i['name'].lower() + ) + ) + + if len(interfaces) == 0: + return + + order = [ + 'node_name', + 'name', + 'stateTick', + 'mtu', + 'mac', + 'ipv4', + 'ipv6' + ] + + headers = [ + 'Node', + 'Interface', + 'State', + 'MTU', + 'MAC', + 'IPv4', + 'IPv6' + ] + + to_expand = ['ipv4', 'ipv6'] + + if ethtool: + order.append('ethtoolT') + headers.append('Ethtool') + to_expand.append('ethtoolT') + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + to_expand + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/operator_group/__init__.py b/lib/k8s/operator_group/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/operator_group/api.py b/lib/k8s/operator_group/api.py new file mode 100644 index 00000000..1446c609 --- /dev/null +++ b/lib/k8s/operator_group/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sOperatorGroupApi(): + def __init__(self): + self.operator_group_mo = None + + def get_operator_group_mo(self, cache_enabled=True): + if cache_enabled: + if self.operator_group_mo is not None: + return self.operator_group_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='operators.coreos.com/v1', + kind='OperatorGroup' + ) + self.operator_group_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'operator_group', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_operator_group_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'operator_group', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'operator_group', + self.operator_group_mo + ) + + return self.operator_group_mo diff --git a/lib/k8s/operator_group/info.py b/lib/k8s/operator_group/info.py new file mode 100644 index 00000000..04bdeeca --- /dev/null +++ b/lib/k8s/operator_group/info.py @@ -0,0 +1,137 @@ +from lib import filter_helper + + +class K8sOperatorGroupInfo(): + def __init__(self): + self.operator_group = None + + def get_operator_group_info(self, operator_group_mo): + if operator_group_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + operator_group_mo + ) + info.update(metadata_info) + + actual_namespaces = self.get(operator_group_mo, 'status:namespaces', on_error=[], on_none=[]) + info['ns'] = [] + for namespace_name in actual_namespaces: + if len(namespace_name) == 0: + continue + + ns_info = {} + ns_info['__Output'] = {} + ns_info['name'] = namespace_name + info['ns'].append( + ns_info + ) + + info['ns'] = sorted( + info['ns'], + key=lambda i: i['name'] + ) + info['nsCount'] = len(info['ns']) + + return info + + def get_operator_groups_info(self, cache_enabled=True): + if cache_enabled: + if self.operator_group is not None: + return self.operator_group + + managed_objects = self.get_operator_group_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.operator_group = [] + for managed_object in managed_objects: + operator_group_info = {} + operator_group_info['info'] = self.get_operator_group_info( + managed_object + ) + operator_group_info['mo'] = managed_object + self.operator_group.append( + operator_group_info + ) + + return self.operator_group + + def match_operator_group(self, operator_group_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, operator_group_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (operator_group_info['namespace'], operator_group_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_operator_group', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_operator_groups(self, object_filter=None, return_mo=False, cache_enabled=True): + all_operator_groups = self.get_operator_groups_info(cache_enabled=cache_enabled) + if all_operator_groups is None: + return None + + operator_groups = [] + + for operator_group_info in all_operator_groups: + if not self.match_operator_group(operator_group_info['info'], object_filter): + continue + + if return_mo: + operator_groups.append( + operator_group_info['mo'] + ) + continue + + operator_groups.append( + operator_group_info['info'] + ) + + return operator_groups + + def is_operator_group(self, namespace, name, cache_enabled=True): + if self.get_operator_group(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_operator_group(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + operator_groups = self.get_operator_groups( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if operator_groups is None: + return None + + if len(operator_groups) == 1: + return operator_groups[0] + + return None diff --git a/lib/k8s/operator_group/main.py b/lib/k8s/operator_group/main.py new file mode 100644 index 00000000..f241381f --- /dev/null +++ b/lib/k8s/operator_group/main.py @@ -0,0 +1,11 @@ +from lib.k8s.operator_group.api import K8sOperatorGroupApi +from lib.k8s.operator_group.info import K8sOperatorGroupInfo + + +class K8sOperatorGroup( + K8sOperatorGroupApi, + K8sOperatorGroupInfo + ): + def __init__(self): + K8sOperatorGroupApi.__init__(self) + K8sOperatorGroupInfo.__init__(self) diff --git a/lib/k8s/operator_group/output.py b/lib/k8s/operator_group/output.py new file mode 100644 index 00000000..15548dd7 --- /dev/null +++ b/lib/k8s/operator_group/output.py @@ -0,0 +1,83 @@ +class K8sOperatorGroupOutput(): + def __init__(self): + pass + + def print_operator_groups(self, info, title=False): + if title: + self.my_output.default( + 'Operator Group - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'nsCount', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Target Namespaces', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_operator_groups_ns(self, info, title=False): + if title: + self.my_output.default( + 'Operator Group - Target Namespace [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'ns.name', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Target Namespace', + 'Age' + ] + + for item in info: + if len(item['ns']) == 0: + item['ns'].append(dict(name='--')) + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ns'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/output.py b/lib/k8s/output.py new file mode 100644 index 00000000..75a7e3c3 --- /dev/null +++ b/lib/k8s/output.py @@ -0,0 +1,338 @@ +from lib import output_helper + +from lib.k8s.alert_manager.output import K8sAlertManagerOutput +from lib.k8s.alert_manager_config.output import K8sAlertManagerConfigOutput +from lib.k8s.cluster_operator.output import K8sClusterOperatorOutput +from lib.k8s.cluster_quota.output import K8sClusterQuotaOutput +from lib.k8s.cluster_role_binding.output import K8sClusterRoleBindingOutput +from lib.k8s.cluster_service_version.output import K8sClusterServiceVersionOutput +from lib.k8s.cni.output import K8sCniOutput +from lib.k8s.config_map.output import K8sConfigMapOutput +from lib.k8s.custom_resource_definition.output import K8sCustomResourceDefinitionOutput +from lib.k8s.daemon_set.output import K8sDaemonSetOutput +from lib.k8s.data_volume.output import K8sDataVolumeOutput +from lib.k8s.deployment.output import K8sDeploymentOutput +from lib.k8s.deployment_config.output import K8sDeploymentConfigOutput +from lib.k8s.egress_ip.output import K8sEgressIpOutput +from lib.k8s.egress_router.output import K8sEgressRouterOutput +from lib.k8s.endpoint.output import K8sEndpointOutput +from lib.k8s.event.output import K8sEventOutput +from lib.k8s.ingress.output import K8sIngressOutput +from lib.k8s.kubevirt.output import K8sKubevirtOutput +from lib.k8s.limit.output import K8sLimitOutput +from lib.k8s.machine_config.output import K8sMachineConfigOutput +from lib.k8s.machine_config_pool.output import K8sMachineConfigPoolOutput +from lib.k8s.namespace.output import K8sNamespaceOutput +from lib.k8s.network_attachment_definition.output import K8sNetworkAttachmentDefinitionOutput +from lib.k8s.node.output import K8sNodeOutput +from lib.k8s.node_network_configuration_enactment.output import K8sNodeNetworkConfigurationEnactmentOutput +from lib.k8s.node_network_configuration_policy.output import K8sNodeNetworkConfigurationPolicyOutput +from lib.k8s.node_network_state.output import K8sNodeNetworkStateOutput +from lib.k8s.operator_group.output import K8sOperatorGroupOutput +from lib.k8s.performance_profile.output import K8sPerformanceProfileOutput +from lib.k8s.pod.output import K8sPodOutput +from lib.k8s.pod_monitor.output import K8sPodMonitorOutput +from lib.k8s.priority_class.output import K8sPriorityClassOutput +from lib.k8s.probe.output import K8sProbeOutput +from lib.k8s.profile.output import K8sProfileOutput +from lib.k8s.prometheus.output import K8sPrometheusOutput +from lib.k8s.prometheus_rule.output import K8sPrometheusRuleOutput +from lib.k8s.pv.output import K8sPvOutput +from lib.k8s.pvc.output import K8sPvcOutput +from lib.k8s.replica_set.output import K8sReplicaSetOutput +from lib.k8s.replication_controller.output import K8sReplicationControllerOutput +from lib.k8s.resource_quota.output import K8sResourceQuotaOutput +from lib.k8s.role_binding.output import K8sRoleBindingOutput +from lib.k8s.route.output import K8sRouteOutput +from lib.k8s.secret.output import K8sSecretOutput +from lib.k8s.security_context_constraint.output import K8sSecurityContextConstraintOutput +from lib.k8s.service.output import K8sServiceOutput +from lib.k8s.service_account.output import K8sServiceAccountOutput +from lib.k8s.service_monitor.output import K8sServiceMonitorOutput +from lib.k8s.sriov_network.output import K8sSriovNetworkOutput +from lib.k8s.sriov_network_node_policy.output import K8sSriovNetworkNodePolicyOutput +from lib.k8s.sriov_network_node_state.output import K8sSriovNetworkNodeStateOutput +from lib.k8s.stateful_set.output import K8sStatefulSetOutput +from lib.k8s.storage_class.output import K8sStorageClassOutput +from lib.k8s.subscription.output import K8sSubscriptionOutput +from lib.k8s.thanos_ruler.output import K8sThanosRulerOutput +from lib.k8s.tuned.output import K8sTunedOutput +from lib.k8s.version.output import K8sVersionOutput +from lib.k8s.virtual_machine.output import K8sVirtualMachineOutput +from lib.k8s.virtual_machine_clone.output import K8sVirtualMachineCloneOutput +from lib.k8s.virtual_machine_cluster_instance_type.output import K8sVirtualMachineClusterInstanceTypeOutput +from lib.k8s.virtual_machine_cluster_preference.output import K8sVirtualMachineClusterPreferenceOutput +from lib.k8s.virtual_machine_export.output import K8sVirtualMachineExportOutput +from lib.k8s.virtual_machine_instance.output import K8sVirtualMachineInstanceOutput +from lib.k8s.virtual_machine_instance_migration.output import K8sVirtualMachineInstanceMigrationOutput +from lib.k8s.virtual_machine_instance_preset.output import K8sVirtualMachineInstancePresetOutput +from lib.k8s.virtual_machine_instance_replica_set.output import K8sVirtualMachineInstanceReplicaSetOutput +from lib.k8s.virtual_machine_preference.output import K8sVirtualMachinePreferenceOutput +from lib.k8s.virtual_machine_restore.output import K8sVirtualMachineRestoreOutput +from lib.k8s.virtual_machine_snapshot.output import K8sVirtualMachineSnapshotOutput +from lib.k8s.virtual_machine_snapshot_content.output import K8sVirtualMachineSnapshotContentOutput +from lib.k8s.volume_attachment.output import K8sVolumeAttachmentOutput +from lib.k8s.volume_snapshot.output import K8sVolumeSnapshotOutput +from lib.k8s.volume_snapshot_class.output import K8sVolumeSnapshotClassOutput +from lib.k8s.volume_snapshot_content.output import K8sVolumeSnapshotContentOutput + + +class K8sOutput( + K8sAlertManagerOutput, + K8sAlertManagerConfigOutput, + K8sClusterOperatorOutput, + K8sClusterQuotaOutput, + K8sClusterRoleBindingOutput, + K8sClusterServiceVersionOutput, + K8sCniOutput, + K8sConfigMapOutput, + K8sCustomResourceDefinitionOutput, + K8sDaemonSetOutput, + K8sDataVolumeOutput, + K8sDeploymentOutput, + K8sDeploymentConfigOutput, + K8sEgressIpOutput, + K8sEgressRouterOutput, + K8sEndpointOutput, + K8sEventOutput, + K8sIngressOutput, + K8sKubevirtOutput, + K8sLimitOutput, + K8sMachineConfigOutput, + K8sMachineConfigPoolOutput, + K8sNamespaceOutput, + K8sNetworkAttachmentDefinitionOutput, + K8sNodeOutput, + K8sNodeNetworkConfigurationEnactmentOutput, + K8sNodeNetworkConfigurationPolicyOutput, + K8sNodeNetworkStateOutput, + K8sOperatorGroupOutput, + K8sPerformanceProfileOutput, + K8sPodOutput, + K8sPodMonitorOutput, + K8sPriorityClassOutput, + K8sProbeOutput, + K8sProfileOutput, + K8sPrometheusOutput, + K8sPrometheusRuleOutput, + K8sPvOutput, + K8sPvcOutput, + K8sReplicaSetOutput, + K8sReplicationControllerOutput, + K8sResourceQuotaOutput, + K8sRoleBindingOutput, + K8sRouteOutput, + K8sSecretOutput, + K8sSecurityContextConstraintOutput, + K8sServiceOutput, + K8sServiceAccountOutput, + K8sServiceMonitorOutput, + K8sSriovNetworkOutput, + K8sSriovNetworkNodePolicyOutput, + K8sSriovNetworkNodeStateOutput, + K8sStatefulSetOutput, + K8sStorageClassOutput, + K8sSubscriptionOutput, + K8sThanosRulerOutput, + K8sTunedOutput, + K8sVersionOutput, + K8sVirtualMachineOutput, + K8sVirtualMachineCloneOutput, + K8sVirtualMachineClusterInstanceTypeOutput, + K8sVirtualMachineClusterPreferenceOutput, + K8sVirtualMachineExportOutput, + K8sVirtualMachineInstanceOutput, + K8sVirtualMachineInstanceMigrationOutput, + K8sVirtualMachineInstancePresetOutput, + K8sVirtualMachineInstanceReplicaSetOutput, + K8sVirtualMachinePreferenceOutput, + K8sVirtualMachineRestoreOutput, + K8sVirtualMachineSnapshotOutput, + K8sVirtualMachineSnapshotContentOutput, + K8sVolumeAttachmentOutput, + K8sVolumeSnapshotOutput, + K8sVolumeSnapshotClassOutput, + K8sVolumeSnapshotContentOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + K8sAlertManagerOutput.__init__(self) + K8sAlertManagerConfigOutput.__init__(self) + K8sClusterOperatorOutput.__init__(self) + K8sClusterQuotaOutput.__init__(self) + K8sClusterRoleBindingOutput.__init__(self) + K8sClusterServiceVersionOutput.__init__(self) + K8sCniOutput.__init__(self) + K8sConfigMapOutput.__init__(self) + K8sCustomResourceDefinitionOutput.__init__(self) + K8sDaemonSetOutput.__init__(self) + K8sDataVolumeOutput.__init__(self) + K8sDeploymentOutput.__init__(self) + K8sDeploymentConfigOutput.__init__(self) + K8sEgressIpOutput.__init__(self) + K8sEgressRouterOutput.__init__(self) + K8sEndpointOutput.__init__(self) + K8sEventOutput.__init__(self) + K8sIngressOutput.__init__(self) + K8sKubevirtOutput.__init__(self) + K8sLimitOutput.__init__(self) + K8sMachineConfigOutput.__init__(self) + K8sMachineConfigPoolOutput.__init__(self) + K8sNamespaceOutput.__init__(self) + K8sNetworkAttachmentDefinitionOutput.__init__(self) + K8sNodeOutput.__init__(self) + K8sNodeNetworkConfigurationEnactmentOutput.__init__(self) + K8sNodeNetworkConfigurationPolicyOutput.__init__(self) + K8sNodeNetworkStateOutput.__init__(self) + K8sOperatorGroupOutput.__init__(self) + K8sPerformanceProfileOutput.__init__(self) + K8sPodOutput.__init__(self) + K8sPodMonitorOutput.__init__(self) + K8sPriorityClassOutput.__init__(self) + K8sProbeOutput.__init__(self) + K8sProfileOutput.__init__(self) + K8sPrometheusOutput.__init__(self) + K8sPrometheusRuleOutput.__init__(self) + K8sPvOutput.__init__(self) + K8sPvcOutput.__init__(self) + K8sReplicaSetOutput.__init__(self) + K8sReplicationControllerOutput.__init__(self) + K8sResourceQuotaOutput.__init__(self) + K8sRoleBindingOutput.__init__(self) + K8sRouteOutput.__init__(self) + K8sSecretOutput.__init__(self) + K8sSecurityContextConstraintOutput.__init__(self) + K8sServiceOutput.__init__(self) + K8sServiceMonitorOutput.__init__(self) + K8sServiceMonitorOutput.__init__(self) + K8sSriovNetworkOutput.__init__(self) + K8sSriovNetworkNodePolicyOutput.__init__(self) + K8sSriovNetworkNodeStateOutput.__init__(self) + K8sStatefulSetOutput.__init__(self) + K8sStorageClassOutput.__init__(self) + K8sSubscriptionOutput.__init__(self) + K8sThanosRulerOutput.__init__(self) + K8sTunedOutput.__init__(self) + K8sVersionOutput.__init__(self) + K8sVirtualMachineOutput.__init__(self) + K8sVirtualMachineCloneOutput.__init__(self) + K8sVirtualMachineClusterInstanceTypeOutput.__init__(self) + K8sVirtualMachineClusterPreferenceOutput.__init__(self) + K8sVirtualMachineExportOutput.__init__(self) + K8sVirtualMachineInstanceOutput.__init__(self) + K8sVirtualMachineInstanceMigrationOutput.__init__(self) + K8sVirtualMachineInstancePresetOutput.__init__(self) + K8sVirtualMachineInstanceReplicaSetOutput.__init__(self) + K8sVirtualMachinePreferenceOutput.__init__(self) + K8sVirtualMachineRestoreOutput.__init__(self) + K8sVirtualMachineSnapshotOutput.__init__(self) + K8sVirtualMachineSnapshotContentOutput.__init__(self) + K8sVolumeAttachmentOutput.__init__(self) + K8sVolumeSnapshotOutput.__init__(self) + K8sVolumeSnapshotClassOutput.__init__(self) + K8sVolumeSnapshotContentOutput.__init__(self) + + def get_namespace_name(self, namespace, name): + namespace_nameT = [] + namespace_nameT.append( + namespace + ) + namespace_nameT.append( + name + ) + return namespace_nameT + + def add_namespace_name(self, values): + for value in values: + value['namespace_nameT'] = self.get_namespace_name( + value['namespace'], + value['name'] + ) + return values + + def print_clusters(self, clusters, title=False): + if title: + self.my_output.default( + 'Cluster [#%s]' % (len(clusters)), + underline=True, + before_newline=True + ) + + if len(clusters) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'defaultTick', + 'type', + 'virtctl.description', + 'helm.description', + 'tools.description', + 'apiTick' + ] + + headers = [ + 'Cluster Name', + 'Default', + 'Type', + 'OCP Virtctl', + 'OCP Helm', + 'OCP Tools', + 'API' + ] + + self.my_output.my_table( + clusters, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + remove_empty_columns=True, + table=True + ) + + def print_clusters_kubeconfig(self, clusters, title=False): + if title: + self.my_output.default( + 'Kubeconfig [#%s]' % (len(clusters)), + underline=True, + before_newline=True + ) + + if len(clusters) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'kubeconfigFilename', + 'isKubeconfigFileTick', + 'apiFqdn', + 'apiVip', + 'kubeApiTick' + ] + + headers = [ + 'Cluster Name', + 'Kubeconfig', + 'IsFile', + 'API FQDN', + 'API VIP', + 'K8s API' + ] + + self.my_output.my_table( + clusters, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + table=True + ) diff --git a/lib/k8s/performance_profile/__init__.py b/lib/k8s/performance_profile/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/performance_profile/api.py b/lib/k8s/performance_profile/api.py new file mode 100644 index 00000000..6d982a71 --- /dev/null +++ b/lib/k8s/performance_profile/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sPerformanceProfileApi(): + def __init__(self): + self.performance_profile_mo = None + + def get_performance_profile_mo(self, cache_enabled=True): + if cache_enabled: + if self.performance_profile_mo is not None: + return self.performance_profile_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='performance.openshift.io/v2', + kind='PerformanceProfile' + ) + self.performance_profile_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'performance_profile', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_performance_profile_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'performance_profile', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'performance_profile', + self.performance_profile_mo + ) + + return self.performance_profile_mo diff --git a/lib/k8s/performance_profile/info.py b/lib/k8s/performance_profile/info.py new file mode 100644 index 00000000..2c662011 --- /dev/null +++ b/lib/k8s/performance_profile/info.py @@ -0,0 +1,222 @@ +from lib import filter_helper + + +class K8sPerformanceProfileInfo(): + def __init__(self): + self.performance_profile = None + + def get_performance_profile_info(self, performance_profile_mo): + if performance_profile_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + performance_profile_mo + ) + info.update(metadata_info) + + conditions_mo = self.get(performance_profile_mo, 'status:conditions', on_error=[], on_none=[]) + + info['available'] = None + info['availableTick'] = '--' + info['__Output']['availableTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Available': + if condition_mo['status'] == 'True': + info['available'] = True + info['availableTick'] = '\u2713' + info['__Output']['availableTick'] = 'Green' + + if condition_mo['status'] == 'False': + info['available'] = False + info['availableTick'] = '\u2717' + info['__Output']['availableTick'] = 'Red' + + info['upgradeable'] = None + info['upgradeableTick'] = '--' + info['__Output']['upgradeableTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Upgradeable': + if condition_mo['status'] == 'True': + info['upgradeable'] = True + info['upgradeableTick'] = '\u2713' + info['__Output']['upgradeableTick'] = 'Green' + + if condition_mo['status'] == 'False': + info['upgradeable'] = False + info['upgradeableTick'] = '\u2717' + info['__Output']['upgradeableTick'] = 'Red' + + info['progressing'] = None + info['progressingTick'] = '--' + info['__Output']['progressingTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Progressing': + if condition_mo['status'] == 'True': + info['progressing'] = True + info['progressingTick'] = '\u2713' + info['__Output']['progressingTick'] = 'Red' + + if condition_mo['status'] == 'False': + info['progressing'] = False + info['progressingTick'] = '\u2717' + info['__Output']['progressingTick'] = 'Green' + + info['degraded'] = None + info['degradedTick'] = '--' + info['__Output']['degradedTick'] = 'Red' + for condition_mo in conditions_mo: + if condition_mo['type'] == 'Degraded': + if condition_mo['status'] == 'True': + info['degraded'] = True + info['degradedTick'] = '\u2713' + info['__Output']['degradedTick'] = 'Red' + + if condition_mo['status'] == 'False': + info['degraded'] = False + info['degradedTick'] = '\u2717' + info['__Output']['degradedTick'] = 'Green' + + info['cpu'] = {} + info['cpu']['isolated'] = self.get(performance_profile_mo, 'spec:cpu:isolated', on_error=None, on_none=None) + info['cpu']['reserved'] = self.get(performance_profile_mo, 'spec:cpu:reserved', on_error=None, on_none=None) + info['cpu']['offlined'] = self.get(performance_profile_mo, 'spec:cpu:offlined', on_error=None, on_none=None) + + info['kernel'] = self.get(performance_profile_mo, 'spec:additionalKernelArgs', on_error=[], on_none=[]) + + info['rt'] = {} + info['rt']['enabled'] = self.get(performance_profile_mo, 'spec:realTimeKernel:enabled', on_error=False, on_none=False) + if info['rt']['enabled']: + info['rt']['enabledTick'] = '\u2713' + else: + info['rt']['enabledTick'] = '\u2717' + + info['hp'] = {} + info['hp']['default_size'] = self.get(performance_profile_mo, 'spec:hugepages:defaultHugepagesSize', on_error=None, on_none=None) + info['hp']['pages'] = self.get(performance_profile_mo, 'spec:hugepages:pages', on_error=[], on_none=[]) + for item in info['hp']['pages']: + item['descr'] = 'Node:%s Size:%s Count:%s' % ( + item['node'], + item['size'], + item['count'] + ) + + info['mcp_selector'] = [] + for key in self.get(performance_profile_mo, 'spec:machineConfigPoolSelector', on_error=[], on_none=[]): + if key.startswith('pools.operator.machineconfiguration.openshift.io'): + info['mcp_selector'].append( + 'mcp:%s' % (key.split('/')[1]) + ) + continue + info['mcp_selector'].append(key) + + info['node_selector'] = [] + for key in self.get(performance_profile_mo, 'spec:nodeSelector', on_error=[], on_none=[]): + if key.startswith('node-role.kubernetes.io/master'): + info['node_selector'].append( + 'role:%s' % (key.split('/')[1]) + ) + continue + info['node_selector'].append(key) + + info['numa'] = {} + info['numa']['topology_policy'] = self.get(performance_profile_mo, 'spec:numa:topologyPolicy', on_error=None, on_none=None) + + info['hints'] = self.get(performance_profile_mo, 'spec:workloadHints', on_error=[], on_none=[]) + + info['runtime_class'] = self.get(performance_profile_mo, 'status:runtimeClass', on_error=None, on_none=None) + info['tuned'] = self.get(performance_profile_mo, 'status:tuned', on_error=None, on_none=None) + + return info + + def get_performance_profiles_info(self, cache_enabled=True): + if cache_enabled: + if self.performance_profile is not None: + return self.performance_profile + + managed_objects = self.get_performance_profile_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.performance_profile = [] + for managed_object in managed_objects: + performance_profile_info = {} + performance_profile_info['info'] = self.get_performance_profile_info( + managed_object + ) + performance_profile_info['mo'] = managed_object + self.performance_profile.append( + performance_profile_info + ) + + return self.performance_profile + + def match_performance_profile(self, performance_profile_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, performance_profile_info['name']): + return False + + if not key_found: + self.log.error( + 'match_performance_profile', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_performance_profiles(self, object_filter=None, return_mo=False, cache_enabled=True): + all_performance_profiles = self.get_performance_profiles_info(cache_enabled=cache_enabled) + if all_performance_profiles is None: + return None + + performance_profiles = [] + + for performance_profile_info in all_performance_profiles: + if not self.match_performance_profile(performance_profile_info['info'], object_filter): + continue + + if return_mo: + performance_profiles.append( + performance_profile_info['mo'] + ) + continue + + performance_profiles.append( + performance_profile_info['info'] + ) + + return performance_profiles + + def is_performance_profile(self, name, cache_enabled=True): + if self.get_performance_profile(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_performance_profile(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + performance_profiles = self.get_performance_profiles( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if performance_profiles is None: + return None + + if len(performance_profiles) == 1: + return performance_profiles[0] + + return None diff --git a/lib/k8s/performance_profile/main.py b/lib/k8s/performance_profile/main.py new file mode 100644 index 00000000..be883ed1 --- /dev/null +++ b/lib/k8s/performance_profile/main.py @@ -0,0 +1,11 @@ +from lib.k8s.performance_profile.api import K8sPerformanceProfileApi +from lib.k8s.performance_profile.info import K8sPerformanceProfileInfo + + +class K8sPerformanceProfile( + K8sPerformanceProfileApi, + K8sPerformanceProfileInfo + ): + def __init__(self): + K8sPerformanceProfileApi.__init__(self) + K8sPerformanceProfileInfo.__init__(self) diff --git a/lib/k8s/performance_profile/output.py b/lib/k8s/performance_profile/output.py new file mode 100644 index 00000000..a093610e --- /dev/null +++ b/lib/k8s/performance_profile/output.py @@ -0,0 +1,96 @@ +class K8sPerformanceProfileOutput(): + def __init__(self): + pass + + def print_performance_profiles(self, info, title=False): + if title: + self.my_output.default( + 'Performance Profile [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['pages'] = item['hp']['pages'] + for key in ['isolated', 'reserved', 'offlined']: + if item['cpu'][key] is None: + item['cpu'][key] = '--' + + if len(item['pages']) == 0: + item['pages'].append( + dict(descr='--') + ) + + if len(item['kernel']) == 0: + item['kernel'].append('--') + + if item['hp']['default_size'] is None: + item['hp']['default_size'] = '--' + + item['hintsT'] = [] + for key in item['hints']: + item['hintsT'].append( + '%s:%s' % ( + key, + item['hints'][key] + ) + ) + + if len(item['hintsT']) == 0: + item['hintsT'].append('--') + + order = [ + 'name', + 'availableTick', + 'upgradeableTick', + 'progressingTick', + 'degradedTick', + 'cpu.isolated', + 'cpu.reserved', + 'cpu.offlined', + 'kernel', + 'rt.enabledTick', + 'hp.default_size', + 'pages.descr', + 'mcp_selector', + 'node_selector', + 'hintsT', + 'age' + ] + + headers = [ + 'Name', + 'Available', + 'Upgradable', + 'Upgrading', + 'Degraded', + 'CPU Isolated', + 'CPU Reserved', + 'CPU Offlined', + 'Kernel Args', + 'RT', + 'HP Def', + 'HP', + 'MCP Selector', + 'Node Selector', + 'HintsT', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['kernel', 'pages', 'mcp_selector', 'node_selector', 'hintsT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/pod/__init__.py b/lib/k8s/pod/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/pod/__pycache__/__init__.cpython-310.pyc b/lib/k8s/pod/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3fa46a76 Binary files /dev/null and b/lib/k8s/pod/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/pod/__pycache__/api.cpython-310.pyc b/lib/k8s/pod/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..5015d99e Binary files /dev/null and b/lib/k8s/pod/__pycache__/api.cpython-310.pyc differ diff --git a/lib/k8s/pod/__pycache__/info.cpython-310.pyc b/lib/k8s/pod/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..f5703fea Binary files /dev/null and b/lib/k8s/pod/__pycache__/info.cpython-310.pyc differ diff --git a/lib/k8s/pod/__pycache__/main.cpython-310.pyc b/lib/k8s/pod/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..27e5ded8 Binary files /dev/null and b/lib/k8s/pod/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/pod/__pycache__/object.cpython-310.pyc b/lib/k8s/pod/__pycache__/object.cpython-310.pyc new file mode 100644 index 00000000..b8436886 Binary files /dev/null and b/lib/k8s/pod/__pycache__/object.cpython-310.pyc differ diff --git a/lib/k8s/pod/__pycache__/task.cpython-310.pyc b/lib/k8s/pod/__pycache__/task.cpython-310.pyc new file mode 100644 index 00000000..e271278f Binary files /dev/null and b/lib/k8s/pod/__pycache__/task.cpython-310.pyc differ diff --git a/lib/k8s/pod/api.py b/lib/k8s/pod/api.py new file mode 100644 index 00000000..c7211def --- /dev/null +++ b/lib/k8s/pod/api.py @@ -0,0 +1,91 @@ +import time +import traceback + + +class K8sPodApi(): + def __init__(self): + self.pod_mo = None + self.pod_log_mo = {} + + def get_pod_mo(self, cache_enabled=True): + if cache_enabled: + if self.pod_mo is not None: + return self.pod_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.list_pod_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'pod', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_pod_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'pod', + False, + int(time.time() * 1000) - start_time + ) + return None + + self.pod_mo = [] + for item in response.items: + pod_mo = self.convert_object(item.to_dict()) + self.pod_mo.append( + pod_mo + ) + + self.log.k8s_mo( + 'pod', + self.pod_mo + ) + + return self.pod_mo + + def get_pod_log_mo(self, namespace, name, cache_enabled=True): + key = '%s.%s' % (namespace, name) + if cache_enabled: + if key in self.pod_log_mo: + return self.pod_log_mo[key] + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#read_namespaced_pod_log + start_time = int(time.time() * 1000) + response = api_handler.read_namespaced_pod_log( + name, + namespace + ) + self.log.k8s( + 'get', + 'pod_log', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_pod_log_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'pod_log', + False, + int(time.time() * 1000) - start_time + ) + return None + + self.pod_log_mo[key] = response + + return self.pod_log_mo[key] diff --git a/lib/k8s/pod/info.py b/lib/k8s/pod/info.py new file mode 100644 index 00000000..490ab228 --- /dev/null +++ b/lib/k8s/pod/info.py @@ -0,0 +1,1428 @@ +import time +import json + +from lib import filter_helper + + +class K8sPodInfo(): + def __init__(self): + self.pod = None + + def get_pod_networks_info(self, pod_mo): + networks = [] + + annotations = self.get(pod_mo, 'metadata:annotations', on_error={}, on_none={}) + if 'k8s.v1.cni.cncf.io/networks-status' in annotations: + networks_mo = json.loads( + annotations['k8s.v1.cni.cncf.io/networks-status'] + ) + for network_mo in networks_mo: + network_info = {} + network_info['name'] = network_mo['name'] + network_info['interface'] = network_mo['interface'] + network_info['mac'] = self.get(network_mo, 'mac') + network_info['ips'] = self.get(network_mo, 'ips', on_error=[], on_none=[]) + network_info['default'] = self.get(network_mo, 'default', on_error=False, on_none=False) + network_info['device-info'] = self.get(network_mo, 'device-info', on_error={}, on_none={}) + network_info['pci'] = self.get(network_mo, 'device-info:pci:pci-address') + network_info['dns'] = self.get(network_mo, 'dns', on_error={}, on_none={}) + networks.append( + network_info + ) + + return networks + + def get_pod_container_res_info(self, res_mo): + info = {} + + keys = ['cpu', 'memory', 'hugepages-2Mi', 'hugepages-1Gi'] + for key in keys: + info[key] = None + if key in res_mo: + info[key] = res_mo[key] + + if info[key] is not None: + info['%sT' % (key)] = info[key] + if info[key] is None: + info['%sT' % (key)] = '--' + + info['hpT'] = '--' + if info['hugepages-2Mi'] is not None: + info['hpT'] = '%s (2Mi)' % ( + info['hugepages-2Mi'] + ) + if info['hugepages-1Gi'] is not None: + info['hpT'] = '%s (1Gi)' % ( + info['hugepages-1Gi'] + ) + + info['custom'] = {} + info['customT'] = [] + for key in res_mo: + if key not in keys: + info['custom'][key] = res_mo[key] + info['customT'].append( + '%s: %s' % (key, res_mo[key]) + ) + + if len(info['customT']) == 0: + info['customT'].append('--') + + return info + + def get_pod_container_port_info(self, ports_mo): + info = [] + + for port_mo in ports_mo: + port_info = {} + for key in ['container_port', 'host_ip', 'host_port', 'name', 'protocol']: + port_info[key] = None + if key in port_mo: + port_info[key] = port_mo[key] + + port_info['portT'] = '%s/%s' % ( + port_info['container_port'], + port_info['protocol'] + ) + if port_info['name'] is not None: + port_info['portT'] = '%s [%s]' % ( + port_info['portT'], + port_info['name'] + ) + + if port_info['host_ip'] is None and port_info['host_port'] is None: + port_info['hostT'] = '--' + + if port_info['host_ip'] is None and port_info['host_port'] is not None: + port_info['hostT'] = port_info['host_port'] + + if port_info['host_ip'] is not None and port_info['host_port'] is not None: + port_info['hostT'] = '%s:%s' % ( + port_info['host_ip'], + port_info['host_port'] + ) + + info.append( + port_info + ) + + return info + + def get_pod_container_info(self, pod_namespace, container_spec_mo, container_status_mo, volumes_info): + info = {} + info['__Output'] = {} + now = int(time.time()) + + info['name'] = self.get(container_spec_mo, 'name') + info['image'] = self.get(container_spec_mo, 'image') + info['image_id'] = self.get(container_status_mo, 'image_id') + info['container_id'] = self.get(container_status_mo, 'container_id') + info['command'] = self.get(container_spec_mo, 'command', on_error=[], on_none=[]) + + info['volume_mount'] = [] + mounts_mo = self.get(container_spec_mo, 'volume_mounts', on_error=[], on_none=[]) + for mount_mo in mounts_mo: + mount_info = {} + mount_info['name'] = self.get(mount_mo, 'name') + mount_info['path'] = self.get(mount_mo, 'mount_path') + mount_info['sub_path'] = self.get(mount_mo, 'sub_path') + mount_info['read_only'] = self.get(mount_mo, 'read_only') + for volume_info in volumes_info: + if volume_info['name'] == mount_info['name']: + mount_info['type'] = volume_info['type'] + mount_info['mo'] = volume_info['mo'] + + info['volume_mount'].append( + mount_info + ) + + info['volume_mount'] = sorted( + info['volume_mount'], + key=lambda i: i['name'] + ) + + envs_mo = self.get(container_spec_mo, 'env', on_error=[], on_none=[]) + info['env'] = [] + for env_mo in envs_mo: + env_info = {} + env_info['name'] = self.get(env_mo, 'name') + env_info['value'] = self.get(env_mo, 'value') + env_info['config_map_key_ref'] = self.get(env_mo, 'value_from:config_map_key_ref') + env_info['field_ref'] = self.get(env_mo, 'value_from:field_ref') + env_info['resource_field_ref'] = self.get(env_mo, 'value_from:resource_field_ref') + env_info['secret_key_ref'] = self.get(env_mo, 'value_from:secret_key_ref') + + env_info['source_type'] = '--' + env_info['source_value'] = '--' + + if env_info['value'] is not None: + env_info['source_type'] = 'value' + env_info['source_value'] = env_info['value'] + + if env_info['config_map_key_ref'] is not None: + env_info['source_type'] = 'cm' + cm_name = self.get(env_mo, 'value_from:config_map_key_ref:name') + cm_key = self.get(env_mo, 'value_from:config_map_key_ref:key') + if cm_name is not None and cm_key is not None: + env_info['source_value'] = '%s:%s' % ( + cm_name, + cm_key + ) + + if env_info['resource_field_ref'] is not None: + env_info['source_type'] = 'res' + + if env_info['field_ref'] is not None: + env_info['source_type'] = 'field' + field_path = self.get(env_mo, 'value_from:field_ref:field_path') + if field_path is not None: + env_info['source_value'] = field_path + + if env_info['secret_key_ref'] is not None: + env_info['source_type'] = 'secret' + secret_name = self.get(env_mo, 'value_from:secret_key_ref:name') + secret_key = self.get(env_mo, 'value_from:secret_key_ref:key') + if secret_name is not None and secret_key is not None: + env_info['source_value'] = '%s:%s' % ( + secret_name, + secret_key + ) + + info['env'].append( + env_info + ) + + info['cm'] = [] + for env_info in info['env']: + if env_info['config_map_key_ref'] is not None: + cm_info = {} + cm_info['namespace'] = pod_namespace + cm_info['name'] = env_info['config_map_key_ref']['name'] + info['cm'].append( + cm_info + ) + + info['requests'] = self.get_pod_container_res_info( + self.get(container_spec_mo, 'resources:requests', on_error={}, on_none={}) + ) + info['limits'] = self.get_pod_container_res_info( + self.get(container_spec_mo, 'resources:limits', on_error={}, on_none={}) + ) + + info['port'] = self.get_pod_container_port_info( + self.get(container_spec_mo, 'ports', on_error=[], on_none=[]) + ) + + info['started_at'] = None + info['finished_at'] = None + info['age'] = '--' + + info['started'] = self.get(container_status_mo, 'started', on_error=False, on_none=False) + info['ready'] = self.get(container_status_mo, 'ready', on_error=False, on_none=False) + info['restart_count'] = self.get(container_status_mo, 'restart_count', on_error=0) + info['restart_countT'] = info['restart_count'] + + container_state_mo = self.get(container_status_mo, 'state', on_error={}) + container_state_running_mo = self.get(container_state_mo, 'running') + container_state_terminated_mo = self.get(container_state_mo, 'terminated') + container_state_waiting_mo = self.get(container_state_mo, 'waiting') + + # ContainerState holds a possible state of container. Only one of its members may be specified. If none of them is specified, the default one is ContainerStateWaiting. + info['stateT'] = 'Waiting' + info['__Output']['stateT'] = 'Yellow' + info['state_waiting'] = True + info['state_running'] = False + info['state_terminated'] = False + + if container_state_running_mo is not None: + info['stateT'] = 'Running' + info['__Output']['stateT'] = 'Green' + info['state_waiting'] = False + info['state_running'] = True + info['state_terminated'] = False + info['started_at'] = self.get(container_state_running_mo, 'started_at') + info['started_at_epoch'] = self.convert_timestamp( + info['started_at'] + ) + info['age'] = self.convert_timestamp_to_age( + info['started_at'], + on_error='--' + ) + + if info['restart_count'] > 0: + info['restart_countT'] = '%s (%s ago)' % ( + info['restart_countT'], + self.convert_age(now - info['started_at_epoch']) + ) + + if container_state_terminated_mo is not None: + info['stateT'] = 'Terminated' + info['state_waiting'] = False + info['state_running'] = False + info['state_terminated'] = True + info['started_at'] = self.get(container_state_terminated_mo, 'started_at') + info['finished_at'] = self.get(container_state_terminated_mo, 'finished_at') + info['terminated_exit_code'] = self.get(container_state_terminated_mo, 'exit_code') + if info['terminated_exit_code'] is None: + info['__Output']['stateT'] = 'Red' + info['stateT'] = 'Terminated (code: --)' + else: + info['stateT'] = 'Terminated (code: %s)' % ( + info['terminated_exit_code'] + ) + if info['terminated_exit_code'] > 0: + info['__Output']['stateT'] = 'Red' + else: + info['__Output']['stateT'] = 'Green' + + info['terminate_message'] = self.get(container_state_terminated_mo, 'message') + info['terminate_reason'] = self.get(container_state_terminated_mo, 'reason') + info['terminate_signal'] = self.get(container_state_terminated_mo, 'signal') + + if container_state_waiting_mo is not None: + info['waiting_message'] = self.get(container_state_waiting_mo, 'message') + info['waiting_reason'] = self.get(container_state_waiting_mo, 'reason') + + return info + + def get_pod_volume_info(self, volume_mo): + info = {} + info['name'] = volume_mo['name'] + info['type'] = None + info['mo'] = None + + unsupported = [ + 'aws_elastic_block_store', + 'azure_disk', + 'azure_file', + 'cephfs', + 'cinder', + 'csi', + 'flex_volume', + 'flocker', + 'gce_persistent_disk', + 'git_repo', + 'glusterfs', + 'iscsi', + 'photon_persistent_disk', + 'quobyte', + 'rbd', + 'scale_io', + 'storageos', + 'vsphere_volume' + ] + for key in unsupported: + if self.get(volume_mo, key) is not None: + info['type'] = 'Unsupported' + self.log.error( + 'get_pod_volume_info', + 'Unsupported volume defined: %s' % (key) + ) + + config_map = self.get(volume_mo, 'config_map') + if config_map is not None: + info['type'] = 'config_map' + info['mo'] = config_map + + downward_api = self.get(volume_mo, 'downward_api') + if downward_api is not None: + info['type'] = 'downward_api' + info['mo'] = downward_api + + empty_dir = self.get(volume_mo, 'empty_dir') + if empty_dir is not None: + info['type'] = 'empty_dir' + info['mo'] = empty_dir + + ephemeral = self.get(volume_mo, 'ephemeral') + if ephemeral is not None: + info['type'] = 'ephemeral' + info['mo'] = ephemeral + + fc_mo = self.get(volume_mo, 'fc') + if fc_mo is not None: + info['type'] = 'fc' + info['mo'] = fc_mo + + host_path = self.get(volume_mo, 'host_path') + if host_path is not None: + info['type'] = 'host_path' + info['mo'] = host_path + + nfs = self.get(volume_mo, 'nfs') + if nfs is not None: + info['type'] = 'nfs' + info['mo'] = nfs + + pvc = self.get(volume_mo, 'persistent_volume_claim') + if pvc is not None: + info['type'] = 'persistent_volume_claim' + info['mo'] = pvc + + portworx_volume = self.get(volume_mo, 'portworx_volume') + if portworx_volume is not None: + info['type'] = 'portworx_volume' + info['mo'] = portworx_volume + + secret = self.get(volume_mo, 'secret') + if secret is not None: + info['type'] = 'secret' + info['mo'] = secret + + projected = self.get(volume_mo, 'projected') + if projected is not None: + info['type'] = 'projected' + info['mo'] = [] + for item_mo in self.get(volume_mo, 'projected:sources', on_error=[], on_none=[]): + config_map = self.get(item_mo, 'config_map') + if config_map is not None: + projected_info = {} + projected_info['name'] = info['name'] + projected_info['type'] = 'config_map' + projected_info['mo'] = config_map + info['mo'].append( + projected_info + ) + + secret = self.get(item_mo, 'secret') + if secret is not None: + projected_info = {} + projected_info['name'] = info['name'] + projected_info['type'] = 'secret' + projected_info['mo'] = secret + info['mo'].append( + projected_info + ) + + downward_api = self.get(item_mo, 'downward_api') + if downward_api is not None: + projected_info = {} + projected_info['name'] = info['name'] + projected_info['type'] = 'downward_api' + projected_info['mo'] = downward_api + info['mo'].append( + projected_info + ) + + service_account_token = self.get(item_mo, 'service_account_token') + if service_account_token is not None: + projected_info = {} + projected_info['name'] = info['name'] + projected_info['type'] = 'service_account_token' + projected_info['mo'] = service_account_token + info['mo'].append( + projected_info + ) + return info + + def get_pod_info(self, pod_mo): + if pod_mo is None: + return None + + now = int(time.time()) + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + pod_mo + ) + info.update(metadata_info) + + info['volume'] = [] + for volume_mo in self.get(pod_mo, 'spec:volumes'): + info['volume'].append( + self.get_pod_volume_info( + volume_mo + ) + ) + + info['volume'] = sorted( + info['volume'], + key=lambda i: i['name'] + ) + + info['container'] = [] + info['container_count'] = 0 + info['container_ready'] = 0 + info['container_restart_count'] = 0 + last_container_started_at_epoch = None + + container_specs = self.get(pod_mo, 'spec:containers', on_error=[], on_none=[]) + container_statuses = self.get(pod_mo, 'status:container_statuses', on_error=[], on_none=[]) + for container_spec in container_specs: + container_spec_name = self.get(container_spec, 'name') + if container_spec_name is None: + self.log.error( + 'k8s.get_pod_info', + 'Unexpected container spec: %s' % (container_spec) + ) + continue + + container_info = None + for container_status in container_statuses: + container_status_name = self.get(container_status, 'name') + if container_status_name is None: + self.log.error( + 'k8s.get_pod_info', + 'Unexpected container status: %s' % (container_status) + ) + continue + + if container_spec_name == container_status_name: + container_info = self.get_pod_container_info( + info['namespace'], + container_spec, + container_status, + info['volume'] + ) + break + + if container_info is None: + self.log.error( + 'k8s.get_pod_info', + 'Unexpected lack of container status: %s' % (container_spec) + ) + container_info = self.get_pod_container_info( + info['namespace'], + container_spec, + None, + info['volume'] + ) + + info['container_count'] = info['container_count'] + 1 + info['container_restart_count'] = info['container_restart_count'] + container_info['restart_count'] + if container_info['ready']: + info['container_ready'] = info['container_ready'] + 1 + + if container_info['state_running']: + if container_info['started_at_epoch'] is not None: + if last_container_started_at_epoch is None: + last_container_started_at_epoch = container_info['started_at_epoch'] + + if last_container_started_at_epoch < container_info['started_at_epoch']: + last_container_started_at_epoch = container_info['started_at_epoch'] + + info['container'].append( + container_info + ) + + info['container'] = sorted( + info['container'], + key=lambda i: i['name'] + ) + + info['container_restart_countT'] = info['container_restart_count'] + if info['container_restart_count'] > 0: + if last_container_started_at_epoch is not None: + info['container_restart_countT'] = '%s (%s ago)' % ( + info['container_restart_count'], + self.convert_age(now - last_container_started_at_epoch) + ) + + info['container_state_summary'] = '%s/%s' % ( + info['container_ready'], + info['container_count'] + ) + + # Condition: Initialized, PodScheduled, ContainersReady, Ready + info['condition'] = [] + for condition_type in ['Initialized', 'PodScheduled', 'ContainersReady', 'Ready']: + condition_info = {} + condition_info['__Output'] = {} + condition_info['type'] = condition_type + condition_info['status'] = 'Unknown' + for condition_mo in self.get(pod_mo, 'status:conditions', on_error=[], on_none=[]): + condition_mo_type = self.get(condition_mo, 'type') + if condition_mo_type is not None and condition_mo_type == condition_type: + condition_info['status'] = self.get(condition_mo, 'status', on_error='Unknown', on_none='Unknown') + + if condition_info['status'] == 'True': + condition_info['typeT'] = '%s: \u2713' % ( + condition_info['type'] + ) + + if condition_info['status'] in ['False', 'Unknown']: + condition_info['typeT'] = '%s: \u2717' % ( + condition_info['type'] + ) + + info['condition'].append( + condition_info + ) + + # Phase: Pending, Running, Succeeded (Completed), Failed, Unknown + info['phase'] = self.get(pod_mo, 'status:phase', on_error='Unknown', on_none='Unknown') + info['phaseT'] = info['phase'] + if info['phaseT'] == 'Succeeded': + info['phaseT'] = 'Completed' + + if info['phaseT'] in ['Running', 'Completed']: + info['__Output']['phaseT'] = 'Green' + + if info['phaseT'] in ['Failed', 'Unknown']: + info['__Output']['phaseT'] = 'Red' + + if info['phaseT'] in ['Pending']: + info['__Output']['phaseT'] = 'Yellow' + + info['running'] = False + if info['phase'] == 'Running': + info['running'] = True + + info['pod_ip'] = self.get(pod_mo, 'status:pod_ip', on_error='--', on_none='--') + info['host_ip'] = self.get(pod_mo, 'status:host_ip', on_error='--', on_none='--') + + info['host_name'] = info['host_ip'] + node_info = self.get_node_with_ip( + info['host_ip'] + ) + if node_info is not None: + info['host_name'] = node_info['name'] + + info['host_network'] = self.get(pod_mo, 'spec:host_network', on_error=False, on_none=False) + info['network'] = self.get_pod_networks_info( + pod_mo + ) + + return info + + def get_pods_info(self, cache_enabled=True): + if cache_enabled: + if self.pod is not None: + return self.pod + + managed_objects = self.get_pod_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.pod = [] + for managed_object in managed_objects: + pod_info = {} + pod_info['info'] = self.get_pod_info( + managed_object + ) + pod_info['mo'] = managed_object + self.pod.append( + pod_info + ) + + return self.pod + + def match_pod(self, pod_info, pod_filter): + if pod_filter is None or len(pod_filter) == 0: + return True + + for ap_rule in pod_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, pod_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (pod_info['namespace'], pod_info['name'])): + return False + + if key == 'owner': + key_found = True + if not filter_helper.match_namespace_name(value, pod_info['owner']): + return False + + if key == 'label': + key_found = True + found = False + for label_name in pod_info['label']: + if filter_helper.match_string(value.split(':', maxsplit=1)[0], label_name): + if filter_helper.match_string(value.split(':')[1], pod_info['label'][label_name]): + found = True + + if not found: + return False + + if key == 'cm': + key_found = True + found = False + + if len(value.split(':')) > 2: + self.log.error( + 'match_pod', + 'Unsupported cm-name value: %s' % (value) + ) + return False + + if len(value.split(':')) == 1: + cm_namespace = None + cm_name = value + + if len(value.split(':')) == 2: + (cm_namespace, cm_name) = value.split(':') + + for container_info in pod_info['container']: + for cm_info in container_info['cm']: + if cm_namespace is None: + if filter_helper.match_string(cm_name, cm_info['name']): + found = True + break + + if cm_namespace is not None: + if filter_helper.match_string(cm_namespace, cm_info['namespace']): + if filter_helper.match_string(cm_name, cm_info['name']): + found = True + break + + if not found: + return False + + if key == 'pvc': + key_found = True + found = False + for volume_info in pod_info['volume']: + if volume_info['type'] == 'persistent_volume_claim': + if filter_helper.match_namespace_name(value, '%s/%s' % (pod_info['namespace'], volume_info['mo']['claim_name'])): + found = True + break + + if not found: + return False + + # if key == 'mac': + # key_found = True + # found = False + # for network in pod_info['networks']: + # if 'mac' in network: + # if filter_helper.match_string(value, network['mac']): + # found = True + + # if not found: + # return False + + # if key == 'network': + # key_found = True + # found = False + # for network in pod_info['networks']: + # if 'mac' in network: + # if filter_helper.match_string(value, network['name']): + # found = True + + # if not found: + # return False + + if not key_found: + self.log.error( + 'match_pod', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_pods(self, object_filter=None, service_info=False, log_info=False, return_mo=False, cache_enabled=True): + all_pods = self.get_pods_info(cache_enabled=cache_enabled) + if all_pods is None: + return None + + pods = [] + + for pod_info in all_pods: + if not self.match_pod(pod_info['info'], object_filter): + continue + + if return_mo: + pods.append( + pod_info['mo'] + ) + continue + + if service_info: + pod_info['info']['service'] = [] + pod_services = [] + for label_key in pod_info['info']['label']: + service_filter = [ + 'selector:%s:%s' % ( + label_key, + pod_info['info']['label'][label_key] + ) + ] + services = self.get_services( + object_filter=service_filter + ) + if services is not None: + for pod_service_info in services: + service_match = True + for key in pod_service_info['selector']: + if key not in pod_info['info']['label']: + service_match = False + break + + if pod_info['info']['label'][key] != pod_service_info['selector'][key]: + service_match = False + break + + if service_match: + if pod_service_info['namespace_name'] not in pod_services: + pod_info['info']['service'].append( + pod_service_info + ) + pod_services.append( + pod_service_info['namespace_name'] + ) + + if log_info: + pod_info['info']['log'] = self.get_pod_log_mo( + pod_info['info']['namespace'], + pod_info['info']['name'] + ) + + pods.append( + pod_info['info'] + ) + + return pods + + # def get_pod_replicaset_info(self, pod_id): + # try: + # data = dict() + + # pod = self.get_pod_summary(self.get_pod(pod_id)) + # if pod is None: + # return None + + # replicaset_name = pod['replicaset_name'] + # data['name'] = replicaset_name + # if data['name'] is not None: + # data['data'] = self.get_replica_set( + # replicaset_name, + # pod['namespace'], + # summary = True + # ) + # data['pods'] = self.get_pods_with_replica_set( + # replicaset_name, + # exclude_pod_id = pod_id + # ) + + # except: + # self.log.error('k8s_pods.get_pod_replicaset_info', traceback.format_exc()) + + # return data + + # def get_pod_replicaset_name(self, pod): + # try: + # for owner_reference in pod['metadata']['owner_references']: + # if owner_reference['kind'] == 'ReplicaSet': + # return owner_reference['name'] + # except: + # self.log.error('k8s_pods.get_pod_replicaset_name', traceback.format_exc()) + # return None + + # def is_pod_ready(self, pod): + # try: + # ready = True + + # if pod['status']['conditions'] is None: + # return False + + # for c in pod['status']['conditions']: + # if c['type'] == 'Ready': + # if c['status'] != 'True': + # ready = False + + # except: + # self.log.error('k8s_pods.is_pod_ready', traceback.format_exc()) + # self.log.error('k8s_pods.is_pod_ready', pod) + # return False + + # return ready + + # def get_pod_job(self, pod): + # try: + # for owner_reference in pod['metadata']['owner_references']: + # if owner_reference['kind'] == 'Job': + # return owner_reference['name'] + + # except: + # self.log.error('k8s_pods.get_pod_job', traceback.format_exc()) + # self.log.error('k8s_pods.get_pod_job', pod) + + # return None + + # def is_pod_scheduled(self, pod): + # try: + # scheduled = True + + # if pod['status']['conditions'] is None: + # return False + + # for c in pod['status']['conditions']: + # if c['type'] == 'PodScheduled': + # if c['status'] != 'True': + # scheduled = False + + # except: + # self.log.error('k8s_pods.is_pod_scheduled', traceback.format_exc()) + # self.log.error('k8s_pods.is_pod_scheduled', pod) + # return False + + # return scheduled + + # def get_pod_scheduling_problem(self, node_labels, node_selector): + # try: + # scheduling_problem = None + # if node_selector is not None: + # for s in node_selector: + # if s['match_expressions'] is not None: + # for m in s['match_expressions']: + # if m['operator'] == 'In': + # k = m['key'] + # for v in m['values']: + # node_exists = False + # for label in node_labels: + # if label['key'] == k and label['value'] == v: + # node_exists = True + + # if not node_exists: + # scheduling_problem = 'No node with label %s:%s' % (k, v) + + # except: + # self.log.error('k8s_pods.get_pod_scheduling_problem', traceback.format_exc()) + # return None + + # return scheduling_problem + + # def are_pods_scheduled(self, pods): + # try: + # scheduled = True + # for p in pods: + # scheduled = scheduled and p['scheduled'] + # if not scheduled: + # break + + # except: + # self.log.error('k8s_pods.are_pods_scheduled', traceback.format_exc()) + # return False + + # return scheduled + + # def get_pods_ready_count(self): + # count = 0 + # try: + # for p in self.pods: + # if p['ready']: + # count = count + 1 + + # except: + # self.log.error('k8s_pods.get_pods_ready_count', traceback.format_exc()) + + # return count + + # def get_pods_status_summary(self, pods): + # try: + # status = dict() + # for p in pods: + # if p['job_name'] is None: + # if p['ready']: + # if 'Ready' in status: + # status['Ready'] = status['Ready'] + 1 + # else: + # status['Ready'] = 1 + + # if not p['ready']: + # if 'Not Ready' in status: + # status['Not Ready'] = status['Not Ready'] + 1 + # else: + # status['Not Ready'] = 1 + + # if p['job_name'] is not None: + # if p['job_succeeded']: + # if 'Succeeded' in status: + # status['Succeeded'] = status['Succeeded'] + 1 + # else: + # status['Succeeded'] = 1 + # else: + # if 'Not Succeeded' in status: + # status['Not Succeeded'] = status['Not Succeeded'] + 1 + # else: + # status['Not Succeeded'] = 1 + + # summary = [] + # for s in status: + # summary.append(dict(status=s, count=status[s])) + + # summary = sorted(summary, key = lambda i: i['status']) + + # except: + # self.log.error('k8s_pods.get_pods_status_summary', traceback.format_exc()) + # return None + + # return summary + + # def get_pod_container_summary(self, pod, job_name): + # ''' + # { + # "ready": 1, + # "completed": 0, + # "count": 1, + # "restarts": 0, + # "reasons": [] + # } + # ''' + # summary = dict() + # summary['ready'] = 0 + # summary['completed'] = 0 + # summary['count'] = 0 + # summary['restarts'] = 0 + # summary['reasons'] = [] + + # if pod['status']['container_statuses'] is not None: + # for c in pod['status']['container_statuses']: + # summary['count'] = summary['count'] + 1 + # summary['restarts'] = summary['restarts'] + c['restart_count'] + # if c['ready']: + # summary['ready'] = summary['ready'] + 1 + # else: + # try: + # reason = c['state']['waiting']['reason'] + # if reason is not None and reason not in summary['reasons']: + # summary['reasons'].append(reason) + # except: + # pass + + # if job_name is not None: + # try: + # if c['state']['terminated']['reason'] == 'Completed': + # summary['completed'] = summary['completed'] + 1 + # except: + # pass + + # return summary + + # def get_pod_summary(self, pod): + # ''' + # { + # "namespace": "iks", + # "labels": { + # "app.kubernetes.io/component": "controller", + # "app.kubernetes.io/instance": "essential-nginx-ingress", + # "app.kubernetes.io/name": "ingress-nginx", + # "controller-revision-hash": "794954b8c6", + # "pod-template-generation": "1" + # }, + # "name": "essential-nginx-ingress-ingress-nginx-controller-2nk8m", + # "uid": "8b2bcc15-da82-4092-9381-71ffca698158", + # "age": 249258, + # "node": "milan-kali-worker-4078840427", + # "replicaset_name": null, + # "scheduled": true, + # "status": "Running", + # "ready": true, + # "pod_ip": "", + # "cni": { + # "ip": "", + # "ports": [ + # { + # "container_port": 80, + # "host_ip": null, + # "host_port": null, + # "name": "http", + # "protocol": "TCP" + # }, + # { + # "container_port": 443, + # "host_ip": null, + # "host_port": null, + # "name": "https", + # "protocol": "TCP" + # } + # ] + # }, + # "job_name": null, + # "job_succeeded": false, + # "healthy": true, + # "containers": { + # "ready": 1, + # "completed": 0, + # "count": 1, + # "restarts": 0, + # "reasons": [] + # }, + # "node_selector": [ + # { + # "match_expressions": null, + # "match_fields": [ + # { + # "key": "metadata.name", + # "operator": "In", + # "values": [ + # "milan-kali-worker-4078840427" + # ] + # } + # ] + # } + # ], + # "scheduling_problem": null + # } + # ''' + # try: + # summary = dict() + + # summary['namespace'] = pod['metadata']['namespace'] + # summary['labels'] = pod['metadata']['labels'] + # summary['name'] = pod['metadata']['name'] + # summary['uid'] = pod['metadata']['uid'] + # summary['age'] = int(time.time()) - pod['metadata']['creation_timestamp'] + # summary['node'] = pod['spec']['node_name'] + # summary['replicaset_name'] = self.get_pod_replicaset_name(pod) + + # summary['scheduled'] = self.is_pod_scheduled(pod) + # summary['status'] = pod['status']['phase'] + # summary['ready'] = self.is_pod_ready(pod) + + # summary['pod_ip'] = pod['status']['pod_ip'] + # summary['cni'] = None + # cni = self.get_pod_calico_ip(pod['metadata']['uid'], pod=pod) + # if cni is not None: + # summary['cni'] = dict() + # summary['cni']['ip'] = cni['ip'] + # summary['cni']['ports'] = cni['ports'] + + # summary['job_name'] = self.get_pod_job(pod) + # summary['job_succeeded'] = False + # summary['healthy'] = False + # if summary['ready']: + # summary['healthy'] = True + # if not summary['ready'] and summary['job_name'] is not None and summary['status'] == 'Succeeded': + # summary['job_succeeded'] = True + # summary['healthy'] = True + + # summary['containers'] = self.get_pod_container_summary(pod, summary['job_name']) + + # try: + # summary['node_selector'] = pod['spec']['affinity']['node_affinity']['required_during_scheduling_ignored_during_execution']['node_selector_terms'] + # except: + # summary['node_selector'] = None + + # summary['scheduling_problem'] = None + # if summary['node_selector'] is not None: + # labels = self.get_nodes_labels() + # summary['scheduling_problem'] = self.get_pod_scheduling_problem(labels, summary['node_selector']) + + # except: + # self.log.error('k8s_pods.get_pod_summary', traceback.format_exc()) + # self.log.error('k8s_pods.get_pod_summary', pod) + # return None + + # return summary + + # def get_pods_namespaces(self): + # namespaces = dict() + # try: + # for p in self.pods: + # namespace = p['namespace'] + # if namespace not in namespaces: + # namespaces[namespace] = dict() + + # except: + # self.log.error('k8s_pods.get_pods_namespaces', traceback.format_exc()) + + # return namespaces + + # def get_pods_in_namespace(self, namespace): + # pods = [] + # try: + # for p in self.pods: + # if p['namespace'] == namespace: + # pods.append(p) + + # except: + # self.log.error('k8s_pods.get_pods_in_namespace', traceback.format_exc()) + + # return pods + + # def get_pod_nodes(self, pods=None): + # nodes = [] + # try: + # for p in self.pods: + # if p['node'] not in nodes: + # nodes.append(p['node']) + + # except: + # self.log.error('k8s_pods.get_pod_nodes', traceback.format_exc()) + + # return nodes + + # def get_pod_id(self, namespace, name, cache=True): + # try: + # for p in self.pods: + # if p['metadata']['name'] == name and p['metadata']['namespace'] == namespace: + # return p['metadata']['uid'] + # except: + # self.log.error('k8s_pods.get_pod_id', traceback.format_exc()) + # return None + + # def get_pod(self, pod_id, cache=True, nice=True, events=False): + # try: + # for p in self.pods: + # if p['metadata']['uid'] == pod_id: + # if not nice: + # return p + + # info = dict() + # info['pod'] = p + # info['summary'] = self.get_pod_summary(p) + # info['timestamp'] = self.get_pods_cache_timestamp() + # info['age'] = int(time.time()*1000) - info['timestamp'] + + # if events: + # field_selector = 'involvedObject.uid=%s' % ( + # info['summary']['uid'] + # ) + # info['events'] = self.get_namespace_events( + # info['summary']['namespace'], + # field_selector = field_selector + # ) + + # return info + + # except: + # self.log.error('k8s_pods.get_pod', traceback.format_exc()) + + # return None + + # def get_pods_state(self, summary_only=False): + # try: + # pods = self.get_pods_summary() + # if pods is None: + # return None + + # state = dict() + # state['summary'] = dict() + # state['summary']['count'] = pods['count'] + # state['summary']['ready'] = pods['ready'] + # state['summary']['job_succeeded'] = pods['job_succeeded'] + # state['summary']['healthy'] = pods['healthy'] + # state['summary']['scheduled'] = pods['scheduled'] + # state['summary']['functional'] = False + # if state['summary']['count'] > 0: + # if state['summary']['count'] == state['summary']['healthy']: + # if state['summary']['count'] == state['summary']['scheduled']: + # state['summary']['functional'] = True + + # state['summary']['status'] = pods['status'] + + # if summary_only: + # return state['summary'] + + # state['pods'] = pods['pods'] + + # state['namespaces'] = self.get_pods_namespaces() + # for n in state['namespaces']: + # npods = self.get_pods_in_namespace(n) + # state['namespaces'][n]['pods'] = npods + # state['namespaces'][n]['summary'] = dict() + # state['namespaces'][n]['summary']['count'] = len(npods) + # state['namespaces'][n]['summary']['status'] = self.get_pods_status_summary(npods) + # state['namespaces'][n]['summary']['scheduled'] = self.are_pods_scheduled(npods) + # state['namespaces'][n]['nodes'] = self.get_pod_nodes(pods=npods) + + # except: + # self.log.error('k8s_pods.get_pods_state', traceback.format_exc()) + # return None + + # return state + + # def get_pods_calico_ip(self, cache=True): + # try: + # pods = self.get_pods(cache=cache) + # if pods is None: + # return None + + # ip = [] + # for p in pods: + # try: + # i = dict() + # i['pod'] = p['metadata']['name'] + # i['pod_id'] = p['metadata']['uid'] + # i['node'] = p['spec']['node_name'] + # i['ip'] = p['metadata']['annotations']['cni.projectcalico.org/podIP'].split('/')[0] + # i['ports'] = [] + # for c in p['spec']['containers']: + # if c['ports'] is not None: + # i['ports'] = i['ports'] + c['ports'] + + # ip.append(i) + + # except: + # pass + + # except: + # self.log.error('k8s_pods.get_pods_calico_ip', traceback.format_exc()) + # return None + + # return ip + + # def get_pod_calico_ip(self, pod_id, pod=None, cache=True): + # try: + # if pod is None: + # pods = self.get_pods(cache=cache) + # if pods is None: + # return None + + # for p in pods: + # if p['metadata']['uid'] == pod_id: + # pod = p + + # if pod is None: + # self.log.error('k8s_pods.get_pod_calico_ip', 'POD not found: %s' % (pod_id)) + # return None + + # cni = dict() + # cni['pod'] = pod['metadata']['name'] + # cni['pod_id'] = pod['metadata']['uid'] + # cni['node'] = pod['spec']['node_name'] + # try: + # cni['ip'] = pod['metadata']['annotations']['cni.projectcalico.org/podIP'].split('/')[0] + # except: + # return None + + # cni['ports'] = [] + # for c in pod['spec']['containers']: + # if c['ports'] is not None: + # cni['ports'] = cni['ports'] + c['ports'] + + # except: + # self.log.error('k8s_pods.get_pod_calico_ip', traceback.format_exc()) + # return None + + # return cni + + # def get_pods_summary(self, namespaces=None): + # try: + # my_pods = [] + # for p in self.pods: + # pod = self.get_pod_summary(p) + # if pod is not None: + # if namespaces is None or pod['namespace'] in namespaces: + # my_pods.append(pod) + + # summary = dict() + # summary['count'] = len(my_pods) + # summary['scheduled'] = 0 + # summary['ready'] = 0 + # summary['job_succeeded'] = 0 + # summary['healthy'] = 0 + # summary['status'] = self.get_pods_status_summary(my_pods) + + # for pod in my_pods: + # if pod['ready']: + # summary['ready'] = summary['ready'] + 1 + # if pod['job_name'] is not None and pod['job_succeeded']: + # summary['job_succeeded'] = summary['job_succeeded'] + 1 + # if pod['scheduled']: + # summary['scheduled'] = summary['scheduled'] + 1 + # if pod['healthy']: + # summary['healthy'] = summary['healthy'] + 1 + + # summary['functional'] = False + # if summary['count'] > 0 and summary['count'] == summary['healthy']: + # summary['functional'] = True + + # except: + # self.log.error('k8s_pods.get_pods_summary', traceback.format_exc()) + # return None + + # return summary + + # def get_pods_health_summary(self, namespaces=None): + # try: + # my_pods = [] + # for p in self.pods: + # pod = self.get_pod_summary(p) + # if pod is not None: + # if namespaces is None or pod['namespace'] in namespaces: + # my_pods.append(pod) + + # return self.get_selected_pods_health_summary(my_pods) + # except: + # self.log.error('k8s_pods.get_pods_summary', traceback.format_exc()) + # return None + + # def get_selected_pods_health_summary(self, my_pods, no_pods_unhealthy = True): + # ''' + # { + # "pods_count": 63, + # "pods_scheduled": 63, + # "pods_ready": 46, + # "pods_job_succeeded": 13, + # "pods_all_good": 59, + # "pods_healthy": false, + # "pods_status": [ + # { + # "status": "Not Ready", + # "count": 4 + # }, + # { + # "status": "Ready", + # "count": 46 + # }, + # { + # "status": "Succeeded", + # "count": 13 + # } + # ] + # } + # ''' + # try: + # summary = dict() + # summary['pods_count'] = len(my_pods) + # summary['pods_scheduled'] = 0 + # summary['pods_ready'] = 0 + # summary['pods_job_succeeded'] = 0 + # summary['pods_all_good'] = 0 + # summary['pods_status'] = self.get_pods_status_summary(my_pods) + + # for pod in my_pods: + # if pod['ready']: + # summary['pods_ready'] = summary['pods_ready'] + 1 + # if pod['job_name'] is not None and pod['job_succeeded']: + # summary['pods_job_succeeded'] = summary['pods_job_succeeded'] + 1 + # if pod['scheduled']: + # summary['pods_scheduled'] = summary['pods_scheduled'] + 1 + # if pod['healthy']: + # summary['pods_all_good'] = summary['pods_all_good'] + 1 + + # summary['pods_healthy'] = True + # if summary['pods_count'] == 0 and no_pods_unhealthy: + # summary['pods_healthy'] = False + # if summary['pods_all_good'] < summary['pods_count']: + # summary['pods_healthy'] = False + + # summary['pods_state_summary'] = '%s/%s' % ( + # summary['pods_count'], + # summary['pods_all_good'] + # ) + + # except: + # self.log.error('k8s_pods.get_pods_summary', traceback.format_exc()) + # return None + + # return summary + + # def get_pod_logs(self, name, namespace): + # # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_secret_for_all_namespaces + # try: + # start_time = int(time.time()*1000) + # response = self.api.read_namespaced_pod_log(name=name, namespace=namespace) + # self.api_statistics( + # 'read_namespaced_pod_log:%s:%s' % (namespace, name), + # int(time.time()*1000) - start_time + # ) + + # except: + # self.log.error('k8s_pods.get_pod_logs', traceback.format_exc()) + # return None + + # return response diff --git a/lib/k8s/pod/main.py b/lib/k8s/pod/main.py new file mode 100644 index 00000000..4b9430ca --- /dev/null +++ b/lib/k8s/pod/main.py @@ -0,0 +1,11 @@ +from lib.k8s.pod.api import K8sPodApi +from lib.k8s.pod.info import K8sPodInfo + + +class K8sPod( + K8sPodApi, + K8sPodInfo + ): + def __init__(self): + K8sPodApi.__init__(self) + K8sPodInfo.__init__(self) diff --git a/lib/k8s/pod/output.py b/lib/k8s/pod/output.py new file mode 100644 index 00000000..e312f67a --- /dev/null +++ b/lib/k8s/pod/output.py @@ -0,0 +1,844 @@ +import copy +import json + + +class K8sPodOutput(): + def __init__(self): + pass + + def print_pods_state(self, info, title=False): + if title: + self.my_output.default( + 'POD [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + item['svc_count'] = len(item['service']) + item['net_count'] = len(item['network']) + for container_info in item['container']: + container_info['volume_count'] = len(container_info['volume_mount']) + container_info['env_count'] = len(container_info['env']) + container_info['cm_count'] = len(container_info['cm']) + + order = [ + 'namespace_nameT', + 'container_state_summary', + 'phaseT', + 'condition.typeT', + 'age', + 'host_name', + 'pod_ip', + 'net_count', + 'svc_count', + 'container_restart_countT' + ] + + headers = [ + 'Pod', + 'Ready', + 'Status', + 'Condition', + 'Age', + 'Node', + 'IP', + 'Net', + 'Svc', + 'Restarts' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'condition'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_metadata(self, info, title=False): + if title: + self.my_output.default( + 'POD - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'Pod', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'annotationT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_container(self, info, title=False): + new_info = [] + for item in info: + for container_info in item['container']: + new_item = {} + new_item['__Output'] = {} + new_item['namespace_nameT'] = [] + new_item['namespace_nameT'].append( + item['namespace'] + ) + new_item['namespace_nameT'].append( + item['name'] + ) + new_item['container_name'] = container_info['name'] + new_item['container_image'] = container_info['image'].split('@') + if len(new_item['container_image']) == 2: + if len(new_item['container_image'][1].split(':')) == 2: + if new_item['container_image'][1].split(':')[0] == 'sha256': + # sha256:7c63fdade857b6dc5e490037a4bab0904279eea097414e67992e5623eff2591d + new_item['container_image'][1] = '%s:...%s' % ( + new_item['container_image'][1].split(':')[0], + new_item['container_image'][1].split(':')[1][-10:] + ) + + new_item['container_command'] = container_info['command'] + new_item['container_state'] = container_info['stateT'] + new_item['__Output']['container_state'] = container_info['__Output']['stateT'] + new_item['container_restart_count'] = container_info['restart_countT'] + new_item['container_volume_count'] = len(container_info['volume_mount']) + new_item['container_env_count'] = len(container_info['env']) + new_item['container_cm_count'] = len(container_info['cm']) + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'POD - Container [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_nameT', + 'container_name', + 'container_image', + 'container_command', + 'container_state', + 'container_restart_count', + 'container_volume_count', + 'container_env_count', + 'container_cm_count' + ] + + headers = [ + 'Pod', + 'Container', + 'Image', + 'Command', + 'State', + 'Restarts', + 'Vol', + 'Env', + 'CM' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['namespace_nameT', 'container_image', 'container_command'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_resource(self, info, title=False): + if title: + self.my_output.default( + 'POD - Resource Requirements [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = [] + for item in info: + for container_info in item['container']: + new_item = {} + new_item['namespace_nameT'] = [] + new_item['namespace_nameT'].append( + item['namespace'] + ) + new_item['namespace_nameT'].append( + item['name'] + ) + new_item['container_name'] = container_info['name'] + new_item['requests_cpu'] = container_info['requests']['cpuT'] + new_item['requests_memory'] = container_info['requests']['memoryT'] + new_item['requests_hp'] = container_info['requests']['hpT'] + new_item['requests_custom'] = container_info['requests']['customT'] + new_item['limits_cpu'] = container_info['limits']['cpuT'] + new_item['limits_memory'] = container_info['limits']['memoryT'] + new_item['limits_hp'] = container_info['limits']['hpT'] + new_item['limits_custom'] = container_info['limits']['customT'] + + new_info.append( + new_item + ) + + order = [ + 'namespace_nameT', + 'container_name', + 'requests_cpu', + 'requests_memory', + 'requests_hp', + 'requests_custom', + 'limits_cpu', + 'limits_memory', + 'limits_hp', + 'limits_custom' + ] + + headers = [ + 'Pod', + 'Container', + 'R:CPU', + 'R:Mem', + 'R:HP', + 'R:Custom', + 'L:CPU', + 'L:Mem', + 'L:HP', + 'L:Custom' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['namespace_nameT', 'requests_custom', 'limits_custom'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_service(self, info, title=False): + if title: + self.my_output.default( + 'POD - Container Ports and Services (running-only) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = [] + for item in info: + if item['running']: + for container_info in item['container']: + new_item = {} + new_item['nameT'] = [] + new_item['nameT'].append( + item['namespace'] + ) + new_item['nameT'].append( + item['name'] + ) + new_item['container'] = container_info['name'] + new_item['port'] = container_info['port'] + if len(new_item['port']) == 0: + new_item['port'].append( + dict( + portT='--', + hostT='--' + ) + ) + + new_item['service'] = item['service'] + if len(new_item['service']) == 0: + new_item['service'].append( + dict( + namespace_name='--', + ports='--' + ) + ) + + new_info.append( + new_item + ) + + order = [ + 'nameT', + 'container', + 'port.portT', + 'port.hostT', + 'service.namespace_name', + 'service.ports' + ] + + headers = [ + 'Pod', + 'Container', + 'Port', + 'Host Port', + 'Service', + 'Service Ports' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['nameT', 'port', 'service'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_env(self, info, title=False): + if title: + self.my_output.default( + 'POD - Container Evironment Variable [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = [] + for item in info: + for container_info in item['container']: + new_item = {} + new_item['namespace'] = item['namespace'] + new_item['name'] = item['name'] + new_item['container'] = container_info['name'] + new_item['nameT'] = [] + new_item['nameT'].append( + new_item['namespace'] + ) + new_item['nameT'].append( + new_item['name'] + ) + new_item['env'] = container_info['env'] + if len(new_item['env']) == 0: + new_item['env'].append( + dict( + namespace='--', + name='--' + ) + ) + new_info.append( + new_item + ) + + order = [ + 'nameT', + 'container', + 'env.name', + 'env.source_type', + 'env.source_value' + ] + + headers = [ + 'Pod', + 'Container', + 'Env', + 'Source', + 'Value' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['nameT', 'env'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_cm(self, info, title=False): + if title: + self.my_output.default( + 'POD - Container Config Map [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = [] + for item in info: + for container_info in item['container']: + new_item = {} + new_item['namespace'] = item['namespace'] + new_item['name'] = item['name'] + new_item['nameT'] = [] + new_item['nameT'].append( + new_item['namespace'] + ) + new_item['nameT'].append( + new_item['name'] + ) + new_item['container'] = container_info['name'] + new_item['cm'] = container_info['cm'] + if len(new_item['cm']) == 0: + new_item['cm'].append( + dict( + namespace='--', + name='--' + ) + ) + new_info.append( + new_item + ) + + order = [ + 'nameT', + 'container', + 'cm.namespace', + 'cm.name' + ] + + headers = [ + 'Pod', + 'Container', + 'CM Namespace', + 'CM Name' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['nameT', 'cm'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_vol(self, info, title=False): + new_info = [] + for item in info: + for container_info in item['container']: + new_item = {} + new_item['nameT'] = [] + new_item['nameT'].append( + item['namespace'] + ) + new_item['nameT'].append( + item['name'] + ) + new_item['container'] = container_info['name'] + new_item['volume_mount'] = [] + + for volume_mount in container_info['volume_mount']: + volume_mount['source'] = '' + + if volume_mount['type'] == 'host_path': + if volume_mount['read_only'] is None or not volume_mount['read_only']: + volume_mount['path'] = '(ro) %s' % (volume_mount['path']) + else: + volume_mount['path'] = '(rw) %s' % (volume_mount['path']) + + volume_mount['source'] = volume_mount['mo']['path'] + if volume_mount['sub_path'] is not None: + volume_mount['source'] = '%s/%s' % ( + volume_mount['source'], + volume_mount['sub_path'] + ) + new_item['volume_mount'].append( + volume_mount + ) + continue + + if volume_mount['type'] == 'config_map': + if volume_mount['mo']['items'] is None: + volume_mount['source'] = volume_mount['mo']['name'] + new_item['volume_mount'].append( + volume_mount + ) + continue + + for item_mo in volume_mount['mo']['items']: + new_volume_mount = copy.deepcopy(volume_mount) + new_volume_mount['source'] = '%s:%s' % ( + volume_mount['mo']['name'], + item_mo['key'] + ) + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + item_mo['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + + continue + + if volume_mount['type'] == 'secret': + if volume_mount['mo']['items'] is None: + volume_mount['source'] = volume_mount['mo']['secret_name'] + new_item['volume_mount'].append( + volume_mount + ) + continue + + for item_mo in volume_mount['mo']['items']: + new_volume_mount = copy.deepcopy(volume_mount) + new_volume_mount['source'] = '%s:%s' % ( + volume_mount['mo']['secret_name'], + item_mo['key'] + ) + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + item_mo['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + + continue + + if volume_mount['type'] == 'downward_api': + if volume_mount['mo']['items'] is not None: + for item_mo in volume_mount['mo']['items']: + new_volume_mount = copy.deepcopy(volume_mount) + if item_mo['field_ref'] is not None: + new_volume_mount['source'] = item_mo['field_ref']['field_path'] + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + item_mo['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + + continue + + if volume_mount['type'] == 'projected': + for projected_mo in volume_mount['mo']: + if projected_mo['type'] == 'config_map': + volume_mount['type'] = 'config_map (p)' + if projected_mo['mo']['items'] is None: + volume_mount['source'] = projected_mo['mo']['name'] + new_item['volume_mount'].append( + projected_mo + ) + continue + + for item_mo in projected_mo['mo']['items']: + new_volume_mount = copy.deepcopy(volume_mount) + new_volume_mount['source'] = '%s:%s' % ( + projected_mo['mo']['name'], + item_mo['key'] + ) + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + item_mo['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + + if projected_mo['type'] == 'secret': + volume_mount['type'] = 'secret (p)' + if projected_mo['mo']['items'] is None: + volume_mount['source'] = projected_mo['mo']['name'] + new_item['volume_mount'].append( + volume_mount + ) + continue + + for item_mo in projected_mo['mo']['items']: + new_volume_mount = copy.deepcopy(volume_mount) + new_volume_mount['source'] = '%s:%s' % ( + projected_mo['mo']['name'], + item_mo['key'] + ) + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + item_mo['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + + if projected_mo['type'] == 'downward_api': + volume_mount['type'] = 'downward_api (p)' + if projected_mo['mo']['items'] is not None: + for item_mo in projected_mo['mo']['items']: + new_volume_mount = copy.deepcopy(volume_mount) + if item_mo['field_ref'] is not None: + new_volume_mount['source'] = item_mo['field_ref']['field_path'] + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + item_mo['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + + continue + + if projected_mo['type'] == 'service_account_token': + volume_mount['type'] = 'service_account_token (p)' + new_volume_mount = copy.deepcopy(volume_mount) + new_volume_mount['path'] = '%s/%s' % ( + volume_mount['path'], + projected_mo['mo']['path'] + ) + new_item['volume_mount'].append( + new_volume_mount + ) + continue + + continue + + new_item['volume_mount'].append( + volume_mount + ) + + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'POD - Container Volume Mount [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(new_info) == 0: + self.my_output.default('None') + return + + order = [ + 'nameT', + 'container', + 'volume_mount.type', + 'volume_mount.source', + 'volume_mount.path' + ] + + headers = [ + 'Pod', + 'Container', + 'Volume Type', + 'Volume Source', + 'Mount Path' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['nameT', 'volume_mount'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_net(self, info, title=False): + if title: + self.my_output.default( + 'POD - Networking [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = [] + for item in info: + new_item = {} + new_item['__Output'] = {} + new_item['nameT'] = [] + new_item['nameT'].append( + item['namespace'] + ) + new_item['nameT'].append( + item['name'] + ) + new_item['container_state_summary'] = item['container_state_summary'] + new_item['phaseT'] = item['phaseT'] + new_item['__Output']['phaseT'] = item['__Output']['phaseT'] + + if item['host_network']: + new_item['host_network_tick'] = '\u2713' + else: + new_item['host_network_tick'] = '\u2717' + + new_item['network'] = item['network'] + for network_info in new_item['network']: + if network_info['mac'] is None: + network_info['mac'] = '--' + + network_info['ip'] = ','.join( + network_info['ips'] + ) + + if len(network_info['dns']) > 0: + network_info['dnsT'] = json.dumps(network_info['dns']) + else: + network_info['dnsT'] = '--' + + if network_info['pci'] is None: + network_info['pciT'] = '--' + else: + network_info['pciT'] = network_info['pci'] + + if network_info['default']: + network_info['default'] = '\u2713' + else: + network_info['default'] = '\u2717' + + new_info.append( + new_item + ) + + order = [ + 'nameT', + 'host_network_tick', + 'network.interface', + 'network.name', + 'network.default', + 'network.mac', + 'network.ip', + 'network.dnsT', + 'network.pciT' + ] + + headers = [ + 'Pod', + 'HostNet', + 'Intf', + 'Network', + 'Def', + 'MAC', + 'IP', + 'DNS', + 'PCI' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['nameT', 'network'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pods_log(self, info, title=False): + for item in info: + if title: + self.my_output.default( + 'POD Log - %s/%s' % (item['namespace'], item['name']), + underline=True, + before_newline=True + ) + + if item['log'] is None or len(item['log']) == 0: + self.my_output.default('None') + return + + self.my_output.default('') + self.my_output.default(item['log']) diff --git a/lib/k8s/pod_monitor/__init__.py b/lib/k8s/pod_monitor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/pod_monitor/api.py b/lib/k8s/pod_monitor/api.py new file mode 100644 index 00000000..11e1dc92 --- /dev/null +++ b/lib/k8s/pod_monitor/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sPodMonitorApi(): + def __init__(self): + self.pod_monitor_mo = None + + def get_pod_monitor_mo(self, cache_enabled=True): + if cache_enabled: + if self.pod_monitor_mo is not None: + return self.pod_monitor_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='PodMonitor' + ) + self.pod_monitor_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'pod_monitor', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_pod_monitor_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'pod_monitor', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'pod_monitor', + self.pod_monitor_mo + ) + + return self.pod_monitor_mo diff --git a/lib/k8s/pod_monitor/info.py b/lib/k8s/pod_monitor/info.py new file mode 100644 index 00000000..08499c61 --- /dev/null +++ b/lib/k8s/pod_monitor/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sPodMonitorInfo(): + def __init__(self): + self.pod_monitor = None + + def get_pod_monitor_info(self, pod_monitor_mo): + if pod_monitor_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_pod_monitors_info(self, cache_enabled=True): + if cache_enabled: + if self.pod_monitor is not None: + return self.pod_monitor + + managed_objects = self.get_pod_monitor_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.pod_monitor = [] + for managed_object in managed_objects: + pod_monitor_info = {} + pod_monitor_info['info'] = self.get_pod_monitor_info( + managed_object + ) + pod_monitor_info['mo'] = managed_object + self.pod_monitor.append( + pod_monitor_info + ) + + return self.pod_monitor + + def match_pod_monitor(self, pod_monitor_info, pod_monitor_filter): + if pod_monitor_filter is None or len(pod_monitor_filter) == 0: + return True + + for ap_rule in pod_monitor_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_pod_monitor', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_pod_monitors(self, object_filter=None, return_mo=False, cache_enabled=True): + all_pod_monitors = self.get_pod_monitors_info(cache_enabled=cache_enabled) + if all_pod_monitors is None: + return None + + pod_monitors = [] + + for pod_monitor_info in all_pod_monitors: + if not self.match_pod_monitor(pod_monitor_info['info'], object_filter): + continue + + if return_mo: + pod_monitors.append( + pod_monitor_info['mo'] + ) + continue + + pod_monitors.append( + pod_monitor_info['info'] + ) + + return pod_monitors diff --git a/lib/k8s/pod_monitor/main.py b/lib/k8s/pod_monitor/main.py new file mode 100644 index 00000000..b67f1a4c --- /dev/null +++ b/lib/k8s/pod_monitor/main.py @@ -0,0 +1,11 @@ +from lib.k8s.pod_monitor.api import K8sPodMonitorApi +from lib.k8s.pod_monitor.info import K8sPodMonitorInfo + + +class K8sPodMonitor( + K8sPodMonitorApi, + K8sPodMonitorInfo + ): + def __init__(self): + K8sPodMonitorApi.__init__(self) + K8sPodMonitorInfo.__init__(self) diff --git a/lib/k8s/pod_monitor/output.py b/lib/k8s/pod_monitor/output.py new file mode 100644 index 00000000..713ecbf7 --- /dev/null +++ b/lib/k8s/pod_monitor/output.py @@ -0,0 +1,33 @@ +class K8sPodMonitorOutput(): + def __init__(self): + pass + + def print_pod_monitors(self, info, title=False): + if title: + self.my_output.default( + 'POD Monitor[#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/priority_class/__init__.py b/lib/k8s/priority_class/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/priority_class/api.py b/lib/k8s/priority_class/api.py new file mode 100644 index 00000000..6af415f6 --- /dev/null +++ b/lib/k8s/priority_class/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sPriorityClassApi(): + def __init__(self): + self.priority_class_mo = None + + def get_priority_class_mo(self, cache_enabled=True): + if cache_enabled: + if self.priority_class_mo is not None: + return self.priority_class_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='scheduling.k8s.io/v1', + kind='PriorityClass' + ) + self.priority_class_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'priority_class', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_priority_class_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'priority_class', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'priority_class', + self.priority_class_mo + ) + + return self.priority_class_mo diff --git a/lib/k8s/priority_class/info.py b/lib/k8s/priority_class/info.py new file mode 100644 index 00000000..ec3d85be --- /dev/null +++ b/lib/k8s/priority_class/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sPriorityClassInfo(): + def __init__(self): + self.priority_class = None + + def get_priority_class_info(self, priority_class_mo): + if priority_class_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_priority_classes_info(self, cache_enabled=True): + if cache_enabled: + if self.priority_class is not None: + return self.priority_class + + managed_objects = self.get_priority_class_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.priority_class = [] + for managed_object in managed_objects: + priority_class_info = {} + priority_class_info['info'] = self.get_priority_class_info( + managed_object + ) + priority_class_info['mo'] = managed_object + self.priority_class.append( + priority_class_info + ) + + return self.priority_class + + def match_priority_class(self, priority_class_info, priority_class_filter): + if priority_class_filter is None or len(priority_class_filter) == 0: + return True + + for ap_rule in priority_class_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_priority_class', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_priority_classes(self, object_filter=None, return_mo=False, cache_enabled=True): + all_priority_classes = self.get_priority_classes_info(cache_enabled=cache_enabled) + if all_priority_classes is None: + return None + + priority_classes = [] + + for priority_class_info in all_priority_classes: + if not self.match_priority_class(priority_class_info['info'], object_filter): + continue + + if return_mo: + priority_classes.append( + priority_class_info['mo'] + ) + continue + + priority_classes.append( + priority_class_info['info'] + ) + + return priority_classes diff --git a/lib/k8s/priority_class/main.py b/lib/k8s/priority_class/main.py new file mode 100644 index 00000000..b442d669 --- /dev/null +++ b/lib/k8s/priority_class/main.py @@ -0,0 +1,11 @@ +from lib.k8s.priority_class.api import K8sPriorityClassApi +from lib.k8s.priority_class.info import K8sPriorityClassInfo + + +class K8sPriorityClass( + K8sPriorityClassApi, + K8sPriorityClassInfo + ): + def __init__(self): + K8sPriorityClassApi.__init__(self) + K8sPriorityClassInfo.__init__(self) diff --git a/lib/k8s/priority_class/output.py b/lib/k8s/priority_class/output.py new file mode 100644 index 00000000..9817bc66 --- /dev/null +++ b/lib/k8s/priority_class/output.py @@ -0,0 +1,33 @@ +class K8sPriorityClassOutput(): + def __init__(self): + pass + + def print_priority_classes(self, info, title=False): + if title: + self.my_output.default( + 'Priority Class [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/probe/__init__.py b/lib/k8s/probe/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/probe/api.py b/lib/k8s/probe/api.py new file mode 100644 index 00000000..76e438ae --- /dev/null +++ b/lib/k8s/probe/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sProbeApi(): + def __init__(self): + self.probe_mo = None + + def get_probe_mo(self, cache_enabled=True): + if cache_enabled: + if self.probe_mo is not None: + return self.probe_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='Probe' + ) + self.probe_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'probe', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_probe_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'probe', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'probe', + self.probe_mo + ) + + return self.probe_mo diff --git a/lib/k8s/probe/info.py b/lib/k8s/probe/info.py new file mode 100644 index 00000000..2109a4f9 --- /dev/null +++ b/lib/k8s/probe/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sProbeInfo(): + def __init__(self): + self.probe = None + + def get_probe_info(self, probe_mo): + if probe_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_probes_info(self, cache_enabled=True): + if cache_enabled: + if self.probe is not None: + return self.probe + + managed_objects = self.get_probe_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.probe = [] + for managed_object in managed_objects: + probe_info = {} + probe_info['info'] = self.get_probe_info( + managed_object + ) + probe_info['mo'] = managed_object + self.probe.append( + probe_info + ) + + return self.probe + + def match_probe(self, probe_info, probe_filter): + if probe_filter is None or len(probe_filter) == 0: + return True + + for ap_rule in probe_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_probe', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_probes(self, object_filter=None, return_mo=False, cache_enabled=True): + all_probes = self.get_probes_info(cache_enabled=cache_enabled) + if all_probes is None: + return None + + probes = [] + + for probe_info in all_probes: + if not self.match_probe(probe_info['info'], object_filter): + continue + + if return_mo: + probes.append( + probe_info['mo'] + ) + continue + + probes.append( + probe_info['info'] + ) + + return probes diff --git a/lib/k8s/probe/main.py b/lib/k8s/probe/main.py new file mode 100644 index 00000000..42473ada --- /dev/null +++ b/lib/k8s/probe/main.py @@ -0,0 +1,11 @@ +from lib.k8s.probe.api import K8sProbeApi +from lib.k8s.probe.info import K8sProbeInfo + + +class K8sProbe( + K8sProbeApi, + K8sProbeInfo + ): + def __init__(self): + K8sProbeApi.__init__(self) + K8sProbeInfo.__init__(self) diff --git a/lib/k8s/probe/output.py b/lib/k8s/probe/output.py new file mode 100644 index 00000000..bbf2933e --- /dev/null +++ b/lib/k8s/probe/output.py @@ -0,0 +1,33 @@ +class K8sProbeOutput(): + def __init__(self): + pass + + def print_probes(self, info, title=False): + if title: + self.my_output.default( + 'Probe [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/profile/__init__.py b/lib/k8s/profile/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/profile/api.py b/lib/k8s/profile/api.py new file mode 100644 index 00000000..f46a47f7 --- /dev/null +++ b/lib/k8s/profile/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sProfileApi(): + def __init__(self): + self.profile_mo = None + + def get_profile_mo(self, cache_enabled=True): + if cache_enabled: + if self.profile_mo is not None: + return self.profile_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='tuned.openshift.io/v1', + kind='Profile' + ) + self.profile_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'profile', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_profile_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'profile', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'profile', + self.profile_mo + ) + + return self.profile_mo diff --git a/lib/k8s/profile/info.py b/lib/k8s/profile/info.py new file mode 100644 index 00000000..ade4b7b9 --- /dev/null +++ b/lib/k8s/profile/info.py @@ -0,0 +1,156 @@ +from lib import filter_helper + + +class K8sProfileInfo(): + def __init__(self): + self.profile = None + + def get_profile_info(self, profile_mo): + if profile_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + profile_mo + ) + info.update(metadata_info) + + info['uid'] = self.get( + profile_mo, + 'metadata:uid' + ) + + info['profile'] = self.get( + profile_mo, + 'spec:config:tunedProfile' + ) + + info['bootcmdline'] = self.get( + profile_mo, + 'status:bootcmdline' + ) + + if info['bootcmdline'] is not None and len(info['bootcmdline']) > 0: + info['bootcmdlineTick'] = '\u2713' + info['__Output']['bootcmdlineTick'] = 'Green' + else: + info['bootcmdlineTick'] = '--' + + info['applied'] = False + info['appliedTick'] = '--' + + info['degraded'] = False + info['degradedTick'] = '--' + + info['error'] = None + + conditions = self.get( + profile_mo, + 'status:conditions', + on_error=[], + on_none=[] + ) + for condition in conditions: + if condition['type'] == 'Applied': + if condition['status'] == 'True': + info['applied'] = True + info['appliedTick'] = '\u2713' + info['__Output']['appliedTick'] = 'Green' + if condition['status'] == 'False': + info['applied'] = False + info['appliedTick'] = '\u2717' + info['__Output']['appliedTick'] = 'Red' + if condition['type'] == 'Degraded': + if condition['status'] == 'True': + info['degraded'] = True + info['degradedTick'] = '\u2713' + info['__Output']['degradedTick'] = 'Red' + if len(condition['message']) > 0: + info['error'] = condition['message'] + if condition['status'] == 'False': + info['degraded'] = False + info['degradedTick'] = '\u2717' + info['__Output']['degradedTick'] = 'Green' + + if info['error'] is not None: + info['errorTick'] = '\u2713' + info['__Output']['errorTick'] = 'Red' + else: + info['errorTick'] = '--' + + return info + + def get_profiles_info(self, cache_enabled=True): + if cache_enabled: + if self.profile is not None: + return self.profile + + managed_objects = self.get_profile_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.profile = [] + for managed_object in managed_objects: + profile_info = {} + profile_info['info'] = self.get_profile_info( + managed_object + ) + profile_info['mo'] = managed_object + self.profile.append( + profile_info + ) + + return self.profile + + def match_profile(self, profile_info, profile_filter): + if profile_filter is None or len(profile_filter) == 0: + return True + + for ap_rule in profile_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, profile_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (profile_info['namespace'], profile_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_profile', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_profiles(self, object_filter=None, return_mo=False, cache_enabled=True): + all_profiles = self.get_profiles_info(cache_enabled=cache_enabled) + if all_profiles is None: + return None + + profiles = [] + + for profile_info in all_profiles: + if not self.match_profile(profile_info['info'], object_filter): + continue + + if return_mo: + profiles.append( + profile_info['mo'] + ) + continue + + profiles.append( + profile_info['info'] + ) + + return profiles diff --git a/lib/k8s/profile/main.py b/lib/k8s/profile/main.py new file mode 100644 index 00000000..6ef44848 --- /dev/null +++ b/lib/k8s/profile/main.py @@ -0,0 +1,11 @@ +from lib.k8s.profile.api import K8sProfileApi +from lib.k8s.profile.info import K8sProfileInfo + + +class K8sProfile( + K8sProfileApi, + K8sProfileInfo + ): + def __init__(self): + K8sProfileApi.__init__(self) + K8sProfileInfo.__init__(self) diff --git a/lib/k8s/profile/output.py b/lib/k8s/profile/output.py new file mode 100644 index 00000000..85c0d83c --- /dev/null +++ b/lib/k8s/profile/output.py @@ -0,0 +1,161 @@ +from lib import filter_helper + + +class K8sProfileOutput(): + def __init__(self): + pass + + def print_profiles(self, info, title=False): + if title: + self.my_output.default( + 'Tuned Profile [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace', + 'name', + 'profile', + 'ownerT', + 'appliedTick', + 'degradedTick', + 'bootcmdlineTick', + 'errorTick', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Tuned', + 'Owner', + 'Applied', + 'Degraded', + 'BootCmd', + 'Error', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ownerT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_profiles_boot(self, info, title=False): + if title: + self.my_output.default( + 'Tuned Profile Boot Command [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['bootcmdlineT'] = [] + if len(item['bootcmdline']) > 0: + item['bootcmdlineT'] = item['bootcmdline'].split(' ') + + if len(item['bootcmdlineT']) == 0: + item['bootcmdlineT'] = ['--'] + + order = [ + 'namespace', + 'name', + 'profile', + 'bootcmdlineT' + ] + + headers = [ + 'Namespace', + 'Name', + 'Profile', + 'Boot Command' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['bootcmdlineT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_profiles_error(self, info, title=False): + if title: + self.my_output.default( + 'Tuned Profile Error [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['errorT'] = [] + if item['error'] is not None and len(item['error']) > 0: + item['errorT'] = filter_helper.get_string_chunks( + item['error'], + 80 + ) + + if len(item['errorT']) == 0: + item['errorT'] = ['--'] + + order = [ + 'namespace', + 'name', + 'profile', + 'errorT' + ] + + headers = [ + 'Namespace', + 'Name', + 'Profile', + 'Error' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['errorT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/prometheus/__init__.py b/lib/k8s/prometheus/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/prometheus/api.py b/lib/k8s/prometheus/api.py new file mode 100644 index 00000000..a3bf7905 --- /dev/null +++ b/lib/k8s/prometheus/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sPrometheusApi(): + def __init__(self): + self.prometheus_mo = None + + def get_prometheus_mo(self, cache_enabled=True): + if cache_enabled: + if self.prometheus_mo is not None: + return self.prometheus_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='Prometheus' + ) + self.prometheus_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'prometheus', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_prometheus_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'prometheus', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'prometheus', + self.prometheus_mo + ) + + return self.prometheus_mo diff --git a/lib/k8s/prometheus/info.py b/lib/k8s/prometheus/info.py new file mode 100644 index 00000000..1bb57718 --- /dev/null +++ b/lib/k8s/prometheus/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sPrometheusInfo(): + def __init__(self): + self.prometheus = None + + def get_prometheus_info(self, prometheus_mo): + if prometheus_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_prometheuss_info(self, cache_enabled=True): + if cache_enabled: + if self.prometheus is not None: + return self.prometheus + + managed_objects = self.get_prometheus_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.prometheus = [] + for managed_object in managed_objects: + prometheus_info = {} + prometheus_info['info'] = self.get_prometheus_info( + managed_object + ) + prometheus_info['mo'] = managed_object + self.prometheus.append( + prometheus_info + ) + + return self.prometheus + + def match_prometheus(self, prometheus_info, prometheus_filter): + if prometheus_filter is None or len(prometheus_filter) == 0: + return True + + for ap_rule in prometheus_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_prometheus', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_prometheuss(self, object_filter=None, return_mo=False, cache_enabled=True): + all_prometheuss = self.get_prometheuss_info(cache_enabled=cache_enabled) + if all_prometheuss is None: + return None + + prometheuss = [] + + for prometheus_info in all_prometheuss: + if not self.match_prometheus(prometheus_info['info'], object_filter): + continue + + if return_mo: + prometheuss.append( + prometheus_info['mo'] + ) + continue + + prometheuss.append( + prometheus_info['info'] + ) + + return prometheuss diff --git a/lib/k8s/prometheus/main.py b/lib/k8s/prometheus/main.py new file mode 100644 index 00000000..5ca112ea --- /dev/null +++ b/lib/k8s/prometheus/main.py @@ -0,0 +1,11 @@ +from lib.k8s.prometheus.api import K8sPrometheusApi +from lib.k8s.prometheus.info import K8sPrometheusInfo + + +class K8sPrometheus( + K8sPrometheusApi, + K8sPrometheusInfo + ): + def __init__(self): + K8sPrometheusApi.__init__(self) + K8sPrometheusInfo.__init__(self) diff --git a/lib/k8s/prometheus/output.py b/lib/k8s/prometheus/output.py new file mode 100644 index 00000000..03ddcf52 --- /dev/null +++ b/lib/k8s/prometheus/output.py @@ -0,0 +1,33 @@ +class K8sPrometheusOutput(): + def __init__(self): + pass + + def print_prometheuss(self, info, title=False): + if title: + self.my_output.default( + 'Prometheus [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/prometheus_rule/__init__.py b/lib/k8s/prometheus_rule/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/prometheus_rule/api.py b/lib/k8s/prometheus_rule/api.py new file mode 100644 index 00000000..c7e7ae7c --- /dev/null +++ b/lib/k8s/prometheus_rule/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sPrometheusRuleApi(): + def __init__(self): + self.prometheus_rule_mo = None + + def get_prometheus_rule_mo(self, cache_enabled=True): + if cache_enabled: + if self.prometheus_rule_mo is not None: + return self.prometheus_rule_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='PrometheusRule' + ) + self.prometheus_rule_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'prometheus_rule', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_prometheus_rule_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'prometheus_rule', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'prometheus_rule', + self.prometheus_rule_mo + ) + + return self.prometheus_rule_mo diff --git a/lib/k8s/prometheus_rule/info.py b/lib/k8s/prometheus_rule/info.py new file mode 100644 index 00000000..a46512d2 --- /dev/null +++ b/lib/k8s/prometheus_rule/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sPrometheusRuleInfo(): + def __init__(self): + self.prometheus_rule = None + + def get_prometheus_rule_info(self, prometheus_rule_mo): + if prometheus_rule_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_prometheus_rules_info(self, cache_enabled=True): + if cache_enabled: + if self.prometheus_rule is not None: + return self.prometheus_rule + + managed_objects = self.get_prometheus_rule_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.prometheus_rule = [] + for managed_object in managed_objects: + prometheus_rule_info = {} + prometheus_rule_info['info'] = self.get_prometheus_rule_info( + managed_object + ) + prometheus_rule_info['mo'] = managed_object + self.prometheus_rule.append( + prometheus_rule_info + ) + + return self.prometheus_rule + + def match_prometheus_rule(self, prometheus_rule_info, prometheus_rule_filter): + if prometheus_rule_filter is None or len(prometheus_rule_filter) == 0: + return True + + for ap_rule in prometheus_rule_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_prometheus_rule', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_prometheus_rules(self, object_filter=None, return_mo=False, cache_enabled=True): + all_prometheus_rules = self.get_prometheus_rules_info(cache_enabled=cache_enabled) + if all_prometheus_rules is None: + return None + + prometheus_rules = [] + + for prometheus_rule_info in all_prometheus_rules: + if not self.match_prometheus_rule(prometheus_rule_info['info'], object_filter): + continue + + if return_mo: + prometheus_rules.append( + prometheus_rule_info['mo'] + ) + continue + + prometheus_rules.append( + prometheus_rule_info['info'] + ) + + return prometheus_rules diff --git a/lib/k8s/prometheus_rule/main.py b/lib/k8s/prometheus_rule/main.py new file mode 100644 index 00000000..d85d15f6 --- /dev/null +++ b/lib/k8s/prometheus_rule/main.py @@ -0,0 +1,11 @@ +from lib.k8s.prometheus_rule.api import K8sPrometheusRuleApi +from lib.k8s.prometheus_rule.info import K8sPrometheusRuleInfo + + +class K8sPrometheusRule( + K8sPrometheusRuleApi, + K8sPrometheusRuleInfo + ): + def __init__(self): + K8sPrometheusRuleApi.__init__(self) + K8sPrometheusRuleInfo.__init__(self) diff --git a/lib/k8s/prometheus_rule/output.py b/lib/k8s/prometheus_rule/output.py new file mode 100644 index 00000000..cc24adba --- /dev/null +++ b/lib/k8s/prometheus_rule/output.py @@ -0,0 +1,33 @@ +class K8sPrometheusRuleOutput(): + def __init__(self): + pass + + def print_prometheus_rules(self, info, title=False): + if title: + self.my_output.default( + 'Prometheus Rule [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/pv/__init__.py b/lib/k8s/pv/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/pv/__pycache__/__init__.cpython-310.pyc b/lib/k8s/pv/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3a06470f Binary files /dev/null and b/lib/k8s/pv/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/pv/__pycache__/api.cpython-310.pyc b/lib/k8s/pv/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..479e86f7 Binary files /dev/null and b/lib/k8s/pv/__pycache__/api.cpython-310.pyc differ diff --git a/lib/k8s/pv/__pycache__/info.cpython-310.pyc b/lib/k8s/pv/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..456bdf26 Binary files /dev/null and b/lib/k8s/pv/__pycache__/info.cpython-310.pyc differ diff --git a/lib/k8s/pv/__pycache__/main.cpython-310.pyc b/lib/k8s/pv/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e688efcb Binary files /dev/null and b/lib/k8s/pv/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/pv/api.py b/lib/k8s/pv/api.py new file mode 100644 index 00000000..a8464894 --- /dev/null +++ b/lib/k8s/pv/api.py @@ -0,0 +1,52 @@ +import time +import traceback + + +class K8sPvApi(): + def __init__(self): + self.pv_mo = None + + def get_pv_mo(self, cache_enabled=True): + if cache_enabled: + if self.pv_mo is not None: + return self.pv_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.list_persistent_volume( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'pv', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_pv', traceback.format_exc()) + self.log.k8s( + 'get', + 'pv', + True, + int(time.time() * 1000) - start_time + ) + return None + + self.pv_mo = [] + for item in response.items: + pv_mo = self.convert_object(item.to_dict()) + self.pv_mo.append( + pv_mo + ) + + self.log.k8s_mo( + 'pv', + self.pv_mo + ) + + return self.pv_mo diff --git a/lib/k8s/pv/info.py b/lib/k8s/pv/info.py new file mode 100644 index 00000000..5bc008f7 --- /dev/null +++ b/lib/k8s/pv/info.py @@ -0,0 +1,147 @@ +from lib import filter_helper + + +class K8sPvInfo(): + def __init__(self): + self.pvol = None + + def get_pv_pod_info(self, annotations): + info = {} + info['name'] = self.get(annotations, 'cdi.kubevirt.io/storage.uploadPodName') + info['phase'] = self.get(annotations, 'cdi.kubevirt.io/storage.pod.phase') + info['ready'] = self.get(annotations, 'cdi.kubevirt.io/storage.pod.ready') + info['restarts'] = self.get(annotations, 'cdi.kubevirt.io/storage.pod.restarts') + return info + + def get_pv_info(self, pv_mo): + if pv_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + pv_mo + ) + info.update(metadata_info) + + info['access_modes'] = self.get(pv_mo, 'spec:access_modes', on_error=[], on_none=[]) + info['access_modes_string'] = ','.join( + info['access_modes'] + ) + + info['volume_mode'] = self.get(pv_mo, 'spec:volume_mode') + info['capacity'] = self.get(pv_mo, 'spec:capacity') + info['csi_driver'] = self.get(pv_mo, 'spec:csi:driver', on_error='--') + info['csi_handle'] = self.get(pv_mo, 'spec:csi:volume_handle', on_error='--') + + info['pvc_namespace'] = self.get(pv_mo, 'spec:claim_ref:namespace') + info['pvc_name'] = self.get(pv_mo, 'spec:claim_ref:name') + + info['phase'] = self.get(pv_mo, 'status:phase') + if info['phase'] is not None and info['phase'] == 'Bound': + info['__Output']['phase'] = 'Green' + else: + info['__Output']['phase'] = 'Red' + + return info + + def match_pv(self, pv_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, pv_info['name']): + return False + + if key == 'pvc-namespace': + key_found = True + if not filter_helper.match_string(value, pv_info['pvc_namespace']): + return False + + if key == 'pvc-name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (pv_info['pvc_namespace'], pv_info['pvc_name'])): + return False + + if not key_found: + self.log.error( + 'match_pv', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_pvs_info(self, cache_enabled=True): + if cache_enabled: + if self.pvol is not None: + return self.pvol + + managed_objects = self.get_pv_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.pvol = [] + for managed_object in managed_objects: + pv_info = {} + pv_info['info'] = self.get_pv_info( + managed_object + ) + pv_info['mo'] = managed_object + self.pvol.append( + pv_info + ) + + return self.pvol + + def get_pvs(self, object_filter=None, return_mo=False, cache_enabled=True): + all_pvs = self.get_pvs_info(cache_enabled=cache_enabled) + if all_pvs is None: + return None + + pvs = [] + + for pv_info in all_pvs: + if not self.match_pv(pv_info['info'], object_filter): + continue + + if return_mo: + pvs.append( + pv_info['mo'] + ) + continue + + pvs.append( + pv_info['info'] + ) + + return pvs + + def is_pv(self, name, cache_enabled=True): + if self.get_pv(name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_pv(self, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + pvs = self.get_pvs( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if pvs is None: + return None + + if len(pvs) == 1: + return pvs[0] + + return None diff --git a/lib/k8s/pv/main.py b/lib/k8s/pv/main.py new file mode 100644 index 00000000..16483839 --- /dev/null +++ b/lib/k8s/pv/main.py @@ -0,0 +1,11 @@ +from lib.k8s.pv.api import K8sPvApi +from lib.k8s.pv.info import K8sPvInfo + + +class K8sPv( + K8sPvApi, + K8sPvInfo + ): + def __init__(self): + K8sPvApi.__init__(self) + K8sPvInfo.__init__(self) diff --git a/lib/k8s/pv/output.py b/lib/k8s/pv/output.py new file mode 100644 index 00000000..811fac02 --- /dev/null +++ b/lib/k8s/pv/output.py @@ -0,0 +1,58 @@ +class K8sPvOutput(): + def __init__(self): + pass + + def print_pvs(self, info, title=False): + if title: + self.my_output.default( + 'PV [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + for item in info: + if len(item['access_modes']) > 1: + row_separator = True + + order = [ + 'name', + 'phase', + 'volume_mode', + 'capacity.storage', + 'access_modes', + 'csi_driver', + 'pvc_namespace', + 'pvc_name', + 'age' + ] + + headers = [ + 'Name', + 'Status', + 'Mode', + 'Size', + 'Access Mode', + 'CSI Driver', + 'PVC Namespace', + 'PVC Name', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['access_modes'] + ), + order=order, + headers=headers, + row_separator=row_separator, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/pvc/__init__.py b/lib/k8s/pvc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/pvc/__pycache__/__init__.cpython-310.pyc b/lib/k8s/pvc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3a06470f Binary files /dev/null and b/lib/k8s/pvc/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/pvc/__pycache__/api.cpython-310.pyc b/lib/k8s/pvc/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..7eccad85 Binary files /dev/null and b/lib/k8s/pvc/__pycache__/api.cpython-310.pyc differ diff --git a/lib/k8s/pvc/__pycache__/info.cpython-310.pyc b/lib/k8s/pvc/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..af76f988 Binary files /dev/null and b/lib/k8s/pvc/__pycache__/info.cpython-310.pyc differ diff --git a/lib/k8s/pvc/__pycache__/main.cpython-310.pyc b/lib/k8s/pvc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..980df572 Binary files /dev/null and b/lib/k8s/pvc/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/pvc/api.py b/lib/k8s/pvc/api.py new file mode 100644 index 00000000..7998a794 --- /dev/null +++ b/lib/k8s/pvc/api.py @@ -0,0 +1,131 @@ +import time +import json +import traceback + + +class K8sPvcApi(): + def __init__(self): + self.pvc_mo = None + + def get_pvc_mo(self, cache_enabled=True): + if cache_enabled: + if self.pvc_mo is not None: + return self.pvc_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.list_persistent_volume_claim_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'pvc', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_pvc', traceback.format_exc()) + self.log.k8s( + 'get', + 'pvc', + True, + int(time.time() * 1000) - start_time + ) + return None + + self.pvc_mo = [] + for item in response.items: + pvc = self.convert_object(item.to_dict()) + self.pvc_mo.append( + pvc + ) + + self.log.k8s_mo( + 'pvc', + self.pvc_mo + ) + + return self.pvc_mo + + def create_namespaced_pvc(self, pvc_definition): + api_handler = self.get_api() + if api_handler is None: + return None + + start_time = int(time.time() * 1000) + namespace = pvc_definition['metadata']['namespace'] + + try: + api_response = api_handler.create_namespaced_persistent_volume_claim( + namespace, + pvc_definition + ) + except BaseException: + api_response = None + self.log.error( + 'k8s.create_namespaced_pvc', + 'PVC create failed: %s' % (json.dumps(pvc_definition, indent=4)) + ) + self.log.error( + 'k8s.create_namespaced_pvc', + traceback.format_exc() + ) + + if api_response is None: + self.log.k8s( + 'create', + 'pvc', + False, + int(time.time() * 1000) - start_time + ) + return False + + self.log.k8s( + 'create', + 'pvc', + True, + int(time.time() * 1000) - start_time + ) + + return True + + def delete_namespaced_pvc(self, namespace, name): + api_handler = self.get_api() + if api_handler is None: + return None + + start_time = int(time.time() * 1000) + try: + api_response = api_handler.delete_namespaced_persistent_volume_claim( + name, + namespace + ) + except BaseException: + api_response = None + self.log.error( + 'k8s.delete_namespaced_pvc', + traceback.format_exc() + ) + + if api_response is None: + self.log.k8s( + 'delete', + 'pvc', + False, + int(time.time() * 1000) - start_time + ) + return False + + self.log.k8s( + 'delete', + 'pvc', + True, + int(time.time() * 1000) - start_time + ) + + return True diff --git a/lib/k8s/pvc/info.py b/lib/k8s/pvc/info.py new file mode 100644 index 00000000..128e3abd --- /dev/null +++ b/lib/k8s/pvc/info.py @@ -0,0 +1,230 @@ +import time + +from lib import filter_helper + + +class K8sPvcInfo(): + def __init__(self): + self.pvc = None + + def get_pvc_pod_info(self, annotations): + info = {} + info['name'] = self.get(annotations, 'cdi.kubevirt.io/storage.uploadPodName') + info['phase'] = self.get(annotations, 'cdi.kubevirt.io/storage.pod.phase') + info['ready'] = self.get(annotations, 'cdi.kubevirt.io/storage.pod.ready') + info['restarts'] = self.get(annotations, 'cdi.kubevirt.io/storage.pod.restarts') + return info + + def get_pvc_info(self, pvc_mo): + if pvc_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + pvc_mo, + exclude_annotations=['cdi.kubevirt.io/storage.clone.token'] + ) + info.update(metadata_info) + + info['access_modes'] = self.get(pvc_mo, 'status:access_modes', on_error=[], on_none=[]) + info['access_modes_string'] = ','.join( + info['access_modes'] + ) + + info['requested_capacity'] = self.get(pvc_mo, 'spec:resources:requests:storage') + info['capacity'] = self.get(pvc_mo, 'status:capacity') + info['phase'] = self.get(pvc_mo, 'status:phase') + if info['phase'] is not None and info['phase'] == 'Bound': + info['__Output']['phase'] = 'Green' + else: + info['__Output']['phase'] = 'Red' + + info['volume_name'] = self.get(pvc_mo, 'spec:volume_name') + info['volume_mode'] = self.get(pvc_mo, 'spec:volume_mode') + info['storage_class_name'] = self.get(pvc_mo, 'spec:storage_class_name') + info['storage_provisioner'] = self.get(pvc_mo, 'metadata:annotations:volume.kubernetes.io/storage-provisioner', on_error='--') + info['selected_node'] = self.get(pvc_mo, 'metadata:annotations:volume.kubernetes.io/selected-node', on_error='--') + + info['pod'] = self.get_pvc_pod_info( + self.get(pvc_mo, 'metadata:annotations') + ) + + return info + + def match_pvc(self, pvc_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, pvc_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (pvc_info['namespace'], pvc_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_pvc', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_pvcs_info(self, cache_enabled=True): + if cache_enabled: + if self.pvc is not None: + return self.pvc + + managed_objects = self.get_pvc_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.pvc = [] + for managed_object in managed_objects: + pvc_info = {} + pvc_info['info'] = self.get_pvc_info( + managed_object + ) + pvc_info['mo'] = managed_object + self.pvc.append( + pvc_info + ) + + self.log.k8s_mo( + 'pvc.info', + self.pvc + ) + + return self.pvc + + def get_pvcs(self, object_filter=None, pv_info=False, usage_info=False, return_mo=False, cache_enabled=True): + all_pvcs = self.get_pvcs_info(cache_enabled=cache_enabled) + if all_pvcs is None: + return None + + pvcs = [] + + for pvc_info in all_pvcs: + if not self.match_pvc(pvc_info['info'], object_filter): + continue + + if return_mo: + pvcs.append( + pvc_info['mo'] + ) + continue + + if pv_info: + pvc_pv_info = self.get_pv( + pvc_info['info']['volume_name'], + cache_enabled=cache_enabled + ) + if pvc_pv_info is None: + pvc_info['info']['__Output']['volume_phase'] = 'Red' + pvc_info['info']['volume_phase'] = '--' + else: + pvc_info['info']['__Output']['volume_phase'] = pvc_pv_info['__Output']['phase'] + pvc_info['info']['volume_phase'] = pvc_pv_info['phase'] + + if usage_info: + pvc_info['info']['usage_pod'] = [] + pvc_info['info']['usage_vmi'] = [] + pvc_info['info']['used'] = False + pvc_info['info']['usedTick'] = '\u2717' + pvc_info['info']['__Output']['usedTick'] = 'Red' + + pods = self.get_pods( + object_filter=['pvc:%s' % (pvc_info['info']['namespace_name'])] + ) + if pods is not None: + for pod in pods: + pvc_info['info']['usage_pod'].append( + pod['namespace_name'] + ) + + vmis = self.get_virtual_machine_instances( + object_filter=['pvc:%s' % (pvc_info['info']['namespace_name'])] + ) + if vmis is not None: + for vmi in vmis: + pvc_info['info']['usage_vmi'].append( + vmi['namespace_name'] + ) + + if len(pvc_info['info']['usage_pod']) > 0 or len(pvc_info['info']['usage_vmi']) > 0: + pvc_info['info']['used'] = True + pvc_info['info']['usedTick'] = '\u2713' + pvc_info['info']['__Output']['usedTick'] = 'Green' + + pvcs.append( + pvc_info['info'] + ) + + return pvcs + + def is_pvc(self, namespace, name, cache_enabled=True): + if self.get_pvc(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def is_pvc_used(self, namespace, name, cache_enabled=True): + pvc_info = self.get_pvc(namespace, name, usage_info=True, cache_enabled=cache_enabled) + if pvc_info is None: + return False + return pvc_info['used'] + + def get_pvc(self, namespace, name, pv_info=False, usage_info=False, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + pvcs = self.get_pvcs( + object_filter=object_filter, + pv_info=pv_info, + usage_info=usage_info, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if pvcs is None: + return None + + if len(pvcs) == 1: + return pvcs[0] + + return None + + def wait_pvc_bound(self, namespace, name, max_time=60, log_error_on_timeout=True): + start_time = int(time.time()) + while True: + pvc_info = self.get_pvc( + namespace, + name, + cache_enabled=False + ) + if pvc_info is not None: + if pvc_info['phase'] == 'Bound': + return True + + duration = int(time.time()) - start_time + if duration > max_time: + if log_error_on_timeout: + self.log.error( + 'k8s.wait_pvc_bound', + 'Max time reached: %s/%s' % (namespace, name) + ) + return False + + time.sleep(5) diff --git a/lib/k8s/pvc/main.py b/lib/k8s/pvc/main.py new file mode 100644 index 00000000..12317fff --- /dev/null +++ b/lib/k8s/pvc/main.py @@ -0,0 +1,14 @@ +from lib.k8s.pvc.api import K8sPvcApi +from lib.k8s.pvc.info import K8sPvcInfo +from lib.k8s.pvc.task.main import K8sPvcTask + + +class K8sPvc( + K8sPvcApi, + K8sPvcInfo, + K8sPvcTask + ): + def __init__(self): + K8sPvcApi.__init__(self) + K8sPvcInfo.__init__(self) + K8sPvcTask.__init__(self) diff --git a/lib/k8s/pvc/output.py b/lib/k8s/pvc/output.py new file mode 100644 index 00000000..1e7f5e15 --- /dev/null +++ b/lib/k8s/pvc/output.py @@ -0,0 +1,264 @@ +class K8sPvcOutput(): + def __init__(self): + pass + + def print_pvcs(self, info, title=False): + if title: + self.my_output.default( + 'PVC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + usage_info = False + for item in info: + if 'usage_pod' in item: + usage_info = True + if len(item['access_modes']) > 1: + row_separator = True + + order = [ + 'namespace', + 'name', + 'phase', + 'volume_name', + 'capacity.storage', + 'access_modes', + 'storage_class_name', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Status', + 'Volume', + 'Size', + 'Access Mode', + 'Storage Class', + 'Age' + ] + + if usage_info: + order.append('usedTick') + headers.append('Used (Pod/VMI)') + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['access_modes'] + ), + order=order, + headers=headers, + row_separator=row_separator, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pvcs_with_usage(self, info, title=False): + if title: + self.my_output.default( + 'PVC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + for item in info: + if len(item['access_modes']) > 1: + row_separator = True + + for item in info: + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace', + 'name', + 'phase', + 'volume_name', + 'capacity.storage', + 'access_modes', + 'storage_class_name', + 'usedTick', + 'ownerT', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Status', + 'Volume', + 'Size', + 'Access Mode', + 'Storage Class', + 'Usage', + 'Owner', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['access_modes', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=row_separator, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pvcs_metadata(self, info, title=False): + if title: + self.my_output.default( + 'PVC - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + info = self.add_namespace_name(info) + for item in info: + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'Name', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'annotationT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pvcs_pv(self, info, title=False): + if title: + self.my_output.default( + 'PVC - Volume [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'volume_name', + 'volume_phase', + 'volume_mode', + 'storage_class_name', + 'storage_provisioner', + 'selected_node' + ] + + headers = [ + 'Namespace', + 'Name', + 'Volume', + 'Status', + 'Mode', + 'Storage Class', + 'Storege Type', + 'Storage Node' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_pvcs_usage(self, info, title=False): + if title: + self.my_output.default( + 'PVC - Usage [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['usage_pod']) == 0: + item['usage_pod'].append('--') + + if len(item['usage_vmi']) == 0: + item['usage_vmi'].append('--') + + order = [ + 'namespace_name', + 'usedTick', + 'usage_pod', + 'usage_vmi' + ] + + headers = [ + 'PVC', + 'Used', + 'Pod', + 'VMI' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['usage_pod', 'usage_vmi'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/pvc/task/__init__.py b/lib/k8s/pvc/task/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/pvc/task/main.py b/lib/k8s/pvc/task/main.py new file mode 100644 index 00000000..9128af51 --- /dev/null +++ b/lib/k8s/pvc/task/main.py @@ -0,0 +1,155 @@ +import os +import uuid + +from lib.linux import main as linux + + +class K8sPvcTask(): + def __init__(self): + pass + + def get_pvc_data_volume_upload_definition(self, namespace, name, access_modes, storage, bind): + dv_definition = {} + dv_definition['apiVersion'] = 'cdi.kubevirt.io/v1beta1' + dv_definition['kind'] = 'DataVolume' + dv_definition['metadata'] = {} + dv_definition['metadata']['namespace'] = namespace + dv_definition['metadata']['name'] = name + if bind: + dv_definition['metadata']['annotations'] = {} + dv_definition['metadata']['annotations']['cdi.kubevirt.io/storage.bind.immediate.requested'] = 'true' + + dv_definition['metadata']['labels'] = {} + dv_definition['metadata']['labels']['createdy-by'] = 'iserver' + + dv_definition['spec'] = {} + + dv_definition['spec']['source'] = {} + dv_definition['spec']['source']['upload'] = {} + + dv_definition['spec']['pvc'] = {} + dv_definition['spec']['pvc']['accessModes'] = access_modes + + dv_definition['spec']['pvc']['resources'] = {} + dv_definition['spec']['pvc']['resources']['requests'] = {} + dv_definition['spec']['pvc']['resources']['requests']['storage'] = storage + + return dv_definition + + def create_pvc_via_data_volume_upload( + self, + namespace, + name, + tools, + virtctl, + source_filename=None, + remote_filename=None, + repository=None, + file_type='file', + access_modes=['ReadWriteOnce'], + size='1Gi', + bind=True, + must_bound=True + ): + if file_type not in ['file', 'day0']: + self.log.error( + 'create_pvc_via_data_volume_upload', + 'Unsupported file type: %s' % (file_type) + ) + return False + + if self.is_data_volume(namespace, name): + self.log.error( + 'create_pvc_via_data_volume_upload', + 'Data volume already exists: %s/%s' % (namespace, name) + ) + return False + + if source_filename is not None: + if not os.path.isfile(source_filename): + self.log.error( + 'create_pvc_via_data_volume_upload', + 'File not found: %s' % (source_filename) + ) + return False + + virtctl_handler = linux.Linux( + virtctl['ip'], + virtctl['username'], + password=virtctl['password'], + key_filename=virtctl['key_filename'], + log_id=self.log_id + ) + + if remote_filename is not None: + if not virtctl_handler.ssh_handler.is_file(remote_filename): + self.log.error( + 'create_pvc_via_data_volume_upload', + 'Remote file not found at virtctl server: %s' % (source_filename) + ) + return False + + data_volume = self.get_pvc_data_volume_upload_definition( + namespace, + name, + access_modes, + size, + bind + ) + + if not self.create_data_volume(data_volume): + return False + + self.log.debug( + 'create_pvc_via_data_volume_upload', + 'Create data volume: %s/%s' % (namespace, name) + ) + self.log.debug( + 'create_pvc_via_data_volume_upload', + data_volume + ) + + if not self.wait_data_volume_upload_ready(namespace, name, log_error_on_timeout=must_bound): + if must_bound: + return False + + self.log.debug( + 'create_pvc_via_data_volume_upload', + 'Data volume ready for upload' + ) + + if source_filename is not None: + if file_type == 'day0': + tools_handler = linux.Linux( + tools['ip'], + tools['username'], + password=tools['password'], + key_filename=tools['key_filename'], + log_id=self.log_id + ) + + local_day0_filename = '/tmp/%s.iso' % (str(uuid.uuid4())) + if not tools_handler.genisoimage(source_filename, local_day0_filename): + return False + + source_filename = local_day0_filename + + remote_filename = '/tmp/%s' % ( + os.path.basename(source_filename) + ) + + success = virtctl_handler.ssh_handler.run_file_upload( + source_filename, + remote_filename + ) + if not success: + self.log.error( + 'create_pvc_via_data_volume_upload', + 'File upload failed: %s => %s' % (source_filename, remote_filename) + ) + return False + + if not virtctl_handler.virtctl_image_upload(namespace, name, remote_filename): + return False + + return True diff --git a/lib/k8s/replica_set/__init__.py b/lib/k8s/replica_set/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/replica_set/api.py b/lib/k8s/replica_set/api.py new file mode 100644 index 00000000..ad668edc --- /dev/null +++ b/lib/k8s/replica_set/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sReplicaSetApi(): + def __init__(self): + self.replica_set_mo = None + + def get_replica_set_mo(self, cache_enabled=True): + if cache_enabled: + if self.replica_set_mo is not None: + return self.replica_set_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='apps/v1', + kind='ReplicaSet' + ) + self.replica_set_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'replica_set', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_replica_set_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'replica_set', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'replica_set', + self.replica_set_mo + ) + + return self.replica_set_mo diff --git a/lib/k8s/replica_set/info.py b/lib/k8s/replica_set/info.py new file mode 100644 index 00000000..2e576399 --- /dev/null +++ b/lib/k8s/replica_set/info.py @@ -0,0 +1,114 @@ +from lib import filter_helper + + +class K8sReplicaSetInfo(): + def __init__(self): + self.replica_set = None + + def get_replica_set_info(self, replica_set_mo): + if replica_set_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + replica_set_mo + ) + info.update(metadata_info) + + keys = [ + 'fullyLabeledReplicas', + 'replicas', + 'readyReplicas', + 'availableReplicas', + 'observedGeneration' + ] + for key in keys: + info[key] = self.get(replica_set_mo, 'status:%s' % (key)) + + if info['replicas'] is not None and info['replicas'] == 0: + if info['availableReplicas'] is None: + info['availableReplicas'] = 0 + if info['readyReplicas'] is None: + info['readyReplicas'] = 0 + + return info + + def get_replica_sets_info(self, cache_enabled=True): + if cache_enabled: + if self.replica_set is not None: + return self.replica_set + + managed_objects = self.get_replica_set_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.replica_set = [] + for managed_object in managed_objects: + replica_set_info = {} + replica_set_info['info'] = self.get_replica_set_info( + managed_object + ) + replica_set_info['mo'] = managed_object + self.replica_set.append( + replica_set_info + ) + + return self.replica_set + + def match_replica_set(self, replica_set_info, replica_set_filter): + if replica_set_filter is None or len(replica_set_filter) == 0: + return True + + for ap_rule in replica_set_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, replica_set_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (replica_set_info['namespace'], replica_set_info['name'])): + return False + + if key == 'owner': + key_found = True + if not filter_helper.match_namespace_name(value, replica_set_info['owner']): + return False + + if not key_found: + self.log.error( + 'match_replica_set', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_replica_sets(self, object_filter=None, return_mo=False, cache_enabled=True): + all_replica_sets = self.get_replica_sets_info(cache_enabled=cache_enabled) + if all_replica_sets is None: + return None + + replica_sets = [] + + for replica_set_info in all_replica_sets: + if not self.match_replica_set(replica_set_info['info'], object_filter): + continue + + if return_mo: + replica_sets.append( + replica_set_info['mo'] + ) + continue + + replica_sets.append( + replica_set_info['info'] + ) + + return replica_sets diff --git a/lib/k8s/replica_set/main.py b/lib/k8s/replica_set/main.py new file mode 100644 index 00000000..0ee17dec --- /dev/null +++ b/lib/k8s/replica_set/main.py @@ -0,0 +1,11 @@ +from lib.k8s.replica_set.api import K8sReplicaSetApi +from lib.k8s.replica_set.info import K8sReplicaSetInfo + + +class K8sReplicaSet( + K8sReplicaSetApi, + K8sReplicaSetInfo + ): + def __init__(self): + K8sReplicaSetApi.__init__(self) + K8sReplicaSetInfo.__init__(self) diff --git a/lib/k8s/replica_set/output.py b/lib/k8s/replica_set/output.py new file mode 100644 index 00000000..b3eafd61 --- /dev/null +++ b/lib/k8s/replica_set/output.py @@ -0,0 +1,97 @@ +class K8sReplicaSetOutput(): + def __init__(self): + pass + + def print_replica_sets(self, info, title=False): + if title: + self.my_output.default( + 'Replica Set [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'replicas', + 'availableReplicas', + 'readyReplicas', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Desired', + 'Current', + 'Ready', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_replica_sets_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Replica Set - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'Replica Set', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'annotationT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/replication_controller/__init__.py b/lib/k8s/replication_controller/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/replication_controller/api.py b/lib/k8s/replication_controller/api.py new file mode 100644 index 00000000..48705ecc --- /dev/null +++ b/lib/k8s/replication_controller/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sReplicationControllerApi(): + def __init__(self): + self.replication_controller_mo = None + + def get_replication_controller_mo(self, cache_enabled=True): + if cache_enabled: + if self.replication_controller_mo is not None: + return self.replication_controller_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='v1', + kind='ReplicationController' + ) + self.replication_controller_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'replication_controller', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_replication_controller_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'replication_controller', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'replication_controller', + self.replication_controller_mo + ) + + return self.replication_controller_mo diff --git a/lib/k8s/replication_controller/info.py b/lib/k8s/replication_controller/info.py new file mode 100644 index 00000000..5d3bb27e --- /dev/null +++ b/lib/k8s/replication_controller/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sReplicationControllerInfo(): + def __init__(self): + self.replication_controller = None + + def get_replication_controller_info(self, replication_controller_mo): + if replication_controller_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + replication_controller_mo + ) + info.update(metadata_info) + + return info + + def get_replication_controllers_info(self, cache_enabled=True): + if cache_enabled: + if self.replication_controller is not None: + return self.replication_controller + + managed_objects = self.get_replication_controller_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.replication_controller = [] + for managed_object in managed_objects: + replication_controller_info = {} + replication_controller_info['info'] = self.get_replication_controller_info( + managed_object + ) + replication_controller_info['mo'] = managed_object + self.replication_controller.append( + replication_controller_info + ) + + return self.replication_controller + + def match_replication_controller(self, replication_controller_info, replication_controller_filter): + if replication_controller_filter is None or len(replication_controller_filter) == 0: + return True + + for ap_rule in replication_controller_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_replication_controller', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_replication_controllers(self, object_filter=None, return_mo=False, cache_enabled=True): + all_replication_controllers = self.get_replication_controllers_info(cache_enabled=cache_enabled) + if all_replication_controllers is None: + return None + + replication_controllers = [] + + for replication_controller_info in all_replication_controllers: + if not self.match_replication_controller(replication_controller_info['info'], object_filter): + continue + + if return_mo: + replication_controllers.append( + replication_controller_info['mo'] + ) + continue + + replication_controllers.append( + replication_controller_info['info'] + ) + + return replication_controllers diff --git a/lib/k8s/replication_controller/main.py b/lib/k8s/replication_controller/main.py new file mode 100644 index 00000000..99b89571 --- /dev/null +++ b/lib/k8s/replication_controller/main.py @@ -0,0 +1,11 @@ +from lib.k8s.replication_controller.api import K8sReplicationControllerApi +from lib.k8s.replication_controller.info import K8sReplicationControllerInfo + + +class K8sReplicationController( + K8sReplicationControllerApi, + K8sReplicationControllerInfo + ): + def __init__(self): + K8sReplicationControllerApi.__init__(self) + K8sReplicationControllerInfo.__init__(self) diff --git a/lib/k8s/replication_controller/output.py b/lib/k8s/replication_controller/output.py new file mode 100644 index 00000000..45771258 --- /dev/null +++ b/lib/k8s/replication_controller/output.py @@ -0,0 +1,33 @@ +class K8sReplicationControllerOutput(): + def __init__(self): + pass + + def print_replication_controllers(self, info, title=False): + if title: + self.my_output.default( + 'Replication Controller [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/resource_quota/__init__.py b/lib/k8s/resource_quota/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/resource_quota/api.py b/lib/k8s/resource_quota/api.py new file mode 100644 index 00000000..367284a9 --- /dev/null +++ b/lib/k8s/resource_quota/api.py @@ -0,0 +1,52 @@ +import time +import traceback + + +class K8sResourceQuotaApi(): + def __init__(self): + self.resource_quota_mo = None + + def get_resource_quota_mo(self, cache_enabled=True): + if cache_enabled: + if self.resource_quota_mo is not None: + return self.resource_quota_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.list_resource_quota_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'resource_quota', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_resource_quota_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'resource_quota', + True, + int(time.time() * 1000) - start_time + ) + return False + + self.resource_quota_mo = [] + for item in response.items: + resource_quota_mo = self.convert_object(item.to_dict()) + self.resource_quota_mo.append( + resource_quota_mo + ) + + self.log.k8s_mo( + 'resource_quota', + self.resource_quota_mo + ) + + return self.resource_quota_mo diff --git a/lib/k8s/resource_quota/info.py b/lib/k8s/resource_quota/info.py new file mode 100644 index 00000000..1ddf1fd6 --- /dev/null +++ b/lib/k8s/resource_quota/info.py @@ -0,0 +1,101 @@ +from lib import filter_helper + + +class K8sResourceQuotaInfo(): + def __init__(self): + self.resource_quota = None + + def get_resource_quota_info(self, resource_quota_mo): + if resource_quota_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + resource_quota_mo + ) + info.update(metadata_info) + + return info + + def get_resource_quotas_info(self, cache_enabled=True): + if cache_enabled: + if self.resource_quota is not None: + return self.resource_quota + + managed_objects = self.get_resource_quota_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.resource_quota = [] + for managed_object in managed_objects: + resource_quota_info = {} + resource_quota_info['info'] = self.get_resource_quota_info( + managed_object + ) + resource_quota_info['mo'] = managed_object + self.resource_quota.append( + resource_quota_info + ) + + return self.resource_quota + + def match_resource_quota(self, resource_quota_info, resource_quota_filter): + if resource_quota_filter is None or len(resource_quota_filter) == 0: + return True + + for ap_rule in resource_quota_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, resource_quota_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (resource_quota_info['namespace'], resource_quota_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_resource_quota', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_resource_quotas(self, object_filter=None, return_mo=False, cache_enabled=True): + all_resource_quotas = self.get_resource_quotas_info(cache_enabled=cache_enabled) + if all_resource_quotas is None: + return None + + resource_quotas = [] + + for resource_quota_info in all_resource_quotas: + if not self.match_resource_quota(resource_quota_info['info'], object_filter): + continue + + if return_mo: + resource_quotas.append( + resource_quota_info['mo'] + ) + continue + + resource_quotas.append( + resource_quota_info['info'] + ) + + resource_quotas = sorted( + resource_quotas, + key=lambda i: ( + i['namespace'], + i['name'] + ) + ) + + return resource_quotas diff --git a/lib/k8s/resource_quota/main.py b/lib/k8s/resource_quota/main.py new file mode 100644 index 00000000..843c23b3 --- /dev/null +++ b/lib/k8s/resource_quota/main.py @@ -0,0 +1,11 @@ +from lib.k8s.resource_quota.api import K8sResourceQuotaApi +from lib.k8s.resource_quota.info import K8sResourceQuotaInfo + + +class K8sResourceQuota( + K8sResourceQuotaApi, + K8sResourceQuotaInfo + ): + def __init__(self): + K8sResourceQuotaApi.__init__(self) + K8sResourceQuotaInfo.__init__(self) diff --git a/lib/k8s/resource_quota/output.py b/lib/k8s/resource_quota/output.py new file mode 100644 index 00000000..95208cfc --- /dev/null +++ b/lib/k8s/resource_quota/output.py @@ -0,0 +1,35 @@ +class K8sResourceQuotaOutput(): + def __init__(self): + pass + + def print_resource_quotas(self, info, title=False): + if title: + self.my_output.default( + 'Resource Quota [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name' + ] + + headers = [ + 'Namespace', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/role_binding/__init__.py b/lib/k8s/role_binding/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/role_binding/api.py b/lib/k8s/role_binding/api.py new file mode 100644 index 00000000..8676c2b9 --- /dev/null +++ b/lib/k8s/role_binding/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sRoleBindingApi(): + def __init__(self): + self.role_binding_mo = None + + def get_role_binding_mo(self, cache_enabled=True): + if cache_enabled: + if self.role_binding_mo is not None: + return self.role_binding_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='rbac.authorization.k8s.io/v1', + kind='RoleBinding' + ) + self.role_binding_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'role_binding', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_role_binding_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'role_binding', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'role_binding', + self.role_binding_mo + ) + + return self.role_binding_mo diff --git a/lib/k8s/role_binding/info.py b/lib/k8s/role_binding/info.py new file mode 100644 index 00000000..5baa266e --- /dev/null +++ b/lib/k8s/role_binding/info.py @@ -0,0 +1,119 @@ +from lib import filter_helper + + +class K8sRoleBindingInfo(): + def __init__(self): + self.role_binding = None + + def get_role_binding_info(self, role_binding_mo): + if role_binding_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + role_binding_mo + ) + info.update(metadata_info) + + info['role'] = self.get(role_binding_mo, 'roleRef') + info['subject'] = self.get(role_binding_mo, 'subjects', on_error=[], on_none=[]) + for subject in info['subject']: + if 'namespace' in subject: + subject['description'] = '%s:%s/%s' % ( + subject['kind'], + subject['namespace'], + subject['name'] + ) + else: + subject['description'] = '%s:%s' % ( + subject['kind'], + subject['name'] + ) + + return info + + def get_role_bindings_info(self, cache_enabled=True): + if cache_enabled: + if self.role_binding is not None: + return self.role_binding + + managed_objects = self.get_role_binding_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.role_binding = [] + for managed_object in managed_objects: + role_binding_info = {} + role_binding_info['info'] = self.get_role_binding_info( + managed_object + ) + role_binding_info['mo'] = managed_object + self.role_binding.append( + role_binding_info + ) + + return self.role_binding + + def match_role_binding(self, role_binding_info, role_binding_filter): + if role_binding_filter is None or len(role_binding_filter) == 0: + return True + + for ap_rule in role_binding_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, role_binding_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (role_binding_info['namespace'], role_binding_info['name'])): + return False + + if key == 'subject': + key_found = True + found = False + for subject in role_binding_info['subject']: + if filter_helper.match_string(value, subject['description']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_role_binding', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_role_bindings(self, object_filter=None, return_mo=False, cache_enabled=True): + all_role_bindings = self.get_role_bindings_info(cache_enabled=cache_enabled) + if all_role_bindings is None: + return None + + role_bindings = [] + + for role_binding_info in all_role_bindings: + if not self.match_role_binding(role_binding_info['info'], object_filter): + continue + + if return_mo: + role_bindings.append( + role_binding_info['mo'] + ) + continue + + role_bindings.append( + role_binding_info['info'] + ) + + return role_bindings diff --git a/lib/k8s/role_binding/main.py b/lib/k8s/role_binding/main.py new file mode 100644 index 00000000..5fe3dcca --- /dev/null +++ b/lib/k8s/role_binding/main.py @@ -0,0 +1,11 @@ +from lib.k8s.role_binding.api import K8sRoleBindingApi +from lib.k8s.role_binding.info import K8sRoleBindingInfo + + +class K8sRoleBinding( + K8sRoleBindingApi, + K8sRoleBindingInfo + ): + def __init__(self): + K8sRoleBindingApi.__init__(self) + K8sRoleBindingInfo.__init__(self) diff --git a/lib/k8s/role_binding/output.py b/lib/k8s/role_binding/output.py new file mode 100644 index 00000000..89cdd8fb --- /dev/null +++ b/lib/k8s/role_binding/output.py @@ -0,0 +1,55 @@ +class K8sRoleBindingOutput(): + def __init__(self): + pass + + def print_role_bindings(self, info, title=False): + if title: + self.my_output.default( + 'Role Binding [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append('Namespace: %s' % (item['namespace'])) + item['namespace_nameT'].append('Name: %s' % (item['name'])) + + item['role_subjectT'] = [] + item['role_subjectT'].append( + 'Role: %s' % (item['role']['name']) + ) + for subject in item['subject']: + item['role_subjectT'].append( + 'Subject: %s' % (subject['description']) + ) + + order = [ + 'namespace_nameT', + 'role_subjectT', + 'age' + ] + + headers = [ + 'Namespace - Name', + 'Role - Subject', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'role_subjectT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/route/__init__.py b/lib/k8s/route/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/route/api.py b/lib/k8s/route/api.py new file mode 100644 index 00000000..43383aaf --- /dev/null +++ b/lib/k8s/route/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sRouteApi(): + def __init__(self): + self.route_mo = None + + def get_route_mo(self, cache_enabled=True): + if cache_enabled: + if self.route_mo is not None: + return self.route_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='route.openshift.io/v1', + kind='Route' + ) + self.route_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'route', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_route_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'route', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'route', + self.route_mo + ) + + return self.route_mo diff --git a/lib/k8s/route/info.py b/lib/k8s/route/info.py new file mode 100644 index 00000000..15458377 --- /dev/null +++ b/lib/k8s/route/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sRouteInfo(): + def __init__(self): + self.route = None + + def get_route_info(self, route_mo): + if route_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + route_mo + ) + info.update(metadata_info) + + return info + + def get_routes_info(self, cache_enabled=True): + if cache_enabled: + if self.route is not None: + return self.route + + managed_objects = self.get_route_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.route = [] + for managed_object in managed_objects: + route_info = {} + route_info['info'] = self.get_route_info( + managed_object + ) + route_info['mo'] = managed_object + self.route.append( + route_info + ) + + return self.route + + def match_route(self, route_info, route_filter): + if route_filter is None or len(route_filter) == 0: + return True + + for ap_rule in route_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_route', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_routes(self, object_filter=None, return_mo=False, cache_enabled=True): + all_routes = self.get_routes_info(cache_enabled=cache_enabled) + if all_routes is None: + return None + + routes = [] + + for route_info in all_routes: + if not self.match_route(route_info['info'], object_filter): + continue + + if return_mo: + routes.append( + route_info['mo'] + ) + continue + + routes.append( + route_info['info'] + ) + + return routes diff --git a/lib/k8s/route/main.py b/lib/k8s/route/main.py new file mode 100644 index 00000000..acc79a56 --- /dev/null +++ b/lib/k8s/route/main.py @@ -0,0 +1,11 @@ +from lib.k8s.route.api import K8sRouteApi +from lib.k8s.route.info import K8sRouteInfo + + +class K8sRoute( + K8sRouteApi, + K8sRouteInfo + ): + def __init__(self): + K8sRouteApi.__init__(self) + K8sRouteInfo.__init__(self) diff --git a/lib/k8s/route/output.py b/lib/k8s/route/output.py new file mode 100644 index 00000000..6d735453 --- /dev/null +++ b/lib/k8s/route/output.py @@ -0,0 +1,33 @@ +class K8sRouteOutput(): + def __init__(self): + pass + + def print_routes(self, info, title=False): + if title: + self.my_output.default( + 'Route [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/secret/__init__.py b/lib/k8s/secret/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/secret/api.py b/lib/k8s/secret/api.py new file mode 100644 index 00000000..04440561 --- /dev/null +++ b/lib/k8s/secret/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sSecretApi(): + def __init__(self): + self.secret_mo = None + + def get_secret_mo(self, cache_enabled=True): + if cache_enabled: + if self.secret_mo is not None: + return self.secret_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='v1', + kind='Secret' + ) + self.secret_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'secret', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_secret_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'secret', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'secret', + self.secret_mo + ) + + return self.secret_mo diff --git a/lib/k8s/secret/info.py b/lib/k8s/secret/info.py new file mode 100644 index 00000000..40072c26 --- /dev/null +++ b/lib/k8s/secret/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sSecretInfo(): + def __init__(self): + self.secret = None + + def get_secret_info(self, secret_mo): + if secret_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + secret_mo + ) + info.update(metadata_info) + + return info + + def get_secrets_info(self, cache_enabled=True): + if cache_enabled: + if self.secret is not None: + return self.secret + + managed_objects = self.get_secret_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.secret = [] + for managed_object in managed_objects: + secret_info = {} + secret_info['info'] = self.get_secret_info( + managed_object + ) + secret_info['mo'] = managed_object + self.secret.append( + secret_info + ) + + return self.secret + + def match_secret(self, secret_info, secret_filter): + if secret_filter is None or len(secret_filter) == 0: + return True + + for ap_rule in secret_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_secret', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_secrets(self, object_filter=None, return_mo=False, cache_enabled=True): + all_secrets = self.get_secrets_info(cache_enabled=cache_enabled) + if all_secrets is None: + return None + + secrets = [] + + for secret_info in all_secrets: + if not self.match_secret(secret_info['info'], object_filter): + continue + + if return_mo: + secrets.append( + secret_info['mo'] + ) + continue + + secrets.append( + secret_info['info'] + ) + + return secrets diff --git a/lib/k8s/secret/main.py b/lib/k8s/secret/main.py new file mode 100644 index 00000000..8feffddd --- /dev/null +++ b/lib/k8s/secret/main.py @@ -0,0 +1,11 @@ +from lib.k8s.secret.api import K8sSecretApi +from lib.k8s.secret.info import K8sSecretInfo + + +class K8sSecret( + K8sSecretApi, + K8sSecretInfo + ): + def __init__(self): + K8sSecretApi.__init__(self) + K8sSecretInfo.__init__(self) diff --git a/lib/k8s/secret/output.py b/lib/k8s/secret/output.py new file mode 100644 index 00000000..a3c9d024 --- /dev/null +++ b/lib/k8s/secret/output.py @@ -0,0 +1,33 @@ +class K8sSecretOutput(): + def __init__(self): + pass + + def print_secrets(self, info, title=False): + if title: + self.my_output.default( + 'Secret [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/secrets.py b/lib/k8s/secrets.py new file mode 100644 index 00000000..52a093bd --- /dev/null +++ b/lib/k8s/secrets.py @@ -0,0 +1,202 @@ +#!usr/bin/env python + +import os +import base64 +import json +import time +import traceback + +class K8sSecrets(): + def __init__(self): + self.k8s_secrets = None + + def convert_secret_output_json(self, output): + try: + if output is None: + return None + + output = str(output) + + if 'last-applied-configuration' in output: + return None + + output = output.replace('\'', '\"') + output = output.replace(': None', ': null') + output = output.replace(': True', ': true') + output = output.replace(': False', ': false') + return json.loads(output) + except: + self.log.error('k8s_secrets.convert_secret_output_json', output) + self.log.error('k8s_secrets.convert_secret_output_json', traceback.format_exc()) + return None + + def convert_secret_metadata_managed_fields(self, mfs): + try: + if mfs is None: + return None + + n = [] + for mf in mfs: + t = dict() + t['api_version'] = mf.api_version + t['fields'] = mf.fields_v1 + t['manager'] = mf.manager + t['operation'] = mf.operation + t['time'] = self.convert_timestamp(mf.time) + n.append(t) + + except: + self.log.error('k8s_secrets.convert_secret_metadata_managed_fields', traceback.format_exc()) + return None + + return n + + def convert_secret_metadata(self, metadata): + try: + n = dict() + n['uid'] = metadata.uid + n['self_link'] = metadata.self_link + n['resource_version'] = metadata.resource_version + if metadata.owner_references is None: + n['owner_references'] = None + else: + n['owner_references'] = str(metadata.owner_references) + n['name'] = metadata.name + n['namespace'] = metadata.namespace + n['annotations'] = self.convert_secret_output_json(metadata.annotations) + n['labels'] = self.convert_secret_output_json(metadata.labels) + n['managed_fields'] = self.convert_secret_metadata_managed_fields(metadata.managed_fields) + n['creation_timestamp'] = self.convert_timestamp(metadata.creation_timestamp) + + except: + self.log.error('k8s_secrets.convert_secret_metadata', traceback.format_exc()) + return None + + return n + + def convert_secret(self, secret, get_data_property_types=None): + try: + n = dict() + if get_data_property_types is None or secret.type in get_data_property_types: + n['data'] = secret.data + n['string_data'] = secret.string_data + + n['kind'] = secret.kind + n['type'] = secret.type + n['metadata'] = self.convert_secret_metadata(secret.metadata) + + try: + n['name'] = n['metadata']['name'] + except: + n['name'] = None + + try: + n['namespace'] = n['metadata']['namespace'] + except: + n['namespace'] = None + + try: + n['age'] = int(time.time()) - n['metadata']['creation_timestamp'] + except: + n['age'] = None + + try: + test = json.dumps(n) + except: + self.log.error('k8s_secrets.convert_secret', 'Secret is not JSON') + self.log.error('k8s_secrets.convert_secret', n) + return None + + except: + self.log.error('k8s_secrets.convert_secret', traceback.format_exc()) + return None + + return n + + def get_secret_data(self, secret_id = None, namespace = None, name = None, name_pattern = None): + self.get_secrets() + if self.k8s_secrets is None: + return None + + try: + for secret in self.k8s_secrets: + match = False + if secret_id is not None and secret['metadata']['uid'] == secret_id: + match = True + + if namespace is not None and name is not None: + if secret['namespace'] == namespace and secret['name'] == name: + match = True + + if namespace is not None and name_pattern is not None: + if secret['namespace'] == namespace and secret['name'].startswith(name_pattern): + match = True + + if match: + secret['decoded'] = dict() + for key in secret['data']: + try: + secret['decoded'][key] = base64.decodestring( + secret['data'][key].encode('utf-8') + ).decode('utf-8') + except: + self.log.error('k8s_secrets.get_secret', traceback.format_exc()) + secret['decoded'][key] = None + + ret = dict() + ret['data'] = secret['data'] + ret['decoded'] = secret['decoded'] + return ret + + except: + self.log.error('k8s_secrets.get_secret', traceback.format_exc()) + + return None + + def get_secret(self, secret_id = None, namespace = None, name = None, name_pattern = None): + self.get_secrets() + if self.k8s_secrets is None: + return None + + try: + for secret in self.k8s_secrets: + match = False + if secret_id is not None and secret['metadata']['uid'] == secret_id: + match = True + + if namespace is not None and name is not None: + if secret['namespace'] == namespace and secret['name'] == name: + match = True + + if namespace is not None and name_pattern is not None: + if secret['namespace'] == namespace and secret['name'].startswith(name_pattern): + match = True + + if match: + return secret + + except: + self.log.error('k8s_secrets.get_secret', traceback.format_exc()) + + return None + + def get_secrets(self, get_data_property_types=None): + if self.k8s_secrets is not None: + return + + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_secret_for_all_namespaces + try: + self.k8s_secrets = [] + + start_time = int(time.time()*1000) + response = self.api.list_secret_for_all_namespaces(timeout_seconds=self.api_timeout_seconds) + self.api_statistics('list_secret_for_all_namespaces', int(time.time()*1000) - start_time) + + if response is not None: + for i in response.items: + secret = self.convert_secret(i, get_data_property_types=get_data_property_types) + if secret is not None: + self.k8s_secrets.append(secret) + + except: + self.log.error('k8s_secrets.get_secrets', traceback.format_exc()) \ No newline at end of file diff --git a/lib/k8s/security_context_constraint/__init__.py b/lib/k8s/security_context_constraint/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/security_context_constraint/api.py b/lib/k8s/security_context_constraint/api.py new file mode 100644 index 00000000..d2df5ee5 --- /dev/null +++ b/lib/k8s/security_context_constraint/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sSecurityContextConstraintApi(): + def __init__(self): + self.security_context_constraint_mo = None + + def get_security_context_constraint_mo(self, cache_enabled=True): + if cache_enabled: + if self.security_context_constraint_mo is not None: + return self.security_context_constraint_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='security.openshift.io/v1', + kind='SecurityContextConstraints' + ) + self.security_context_constraint_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'security_context_constraint', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_security_context_constraint_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'security_context_constraint', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'security_context_constraint', + self.security_context_constraint_mo + ) + + return self.security_context_constraint_mo diff --git a/lib/k8s/security_context_constraint/info.py b/lib/k8s/security_context_constraint/info.py new file mode 100644 index 00000000..de9d0384 --- /dev/null +++ b/lib/k8s/security_context_constraint/info.py @@ -0,0 +1,122 @@ +from lib import filter_helper + + +class K8sSecurityContextConstraintInfo(): + def __init__(self): + self.security_context_constraint = None + + def get_security_context_constraint_info(self, security_context_constraint_mo): + if security_context_constraint_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + security_context_constraint_mo + ) + info.update(metadata_info) + + keys = [ + 'allowHostDirVolumePlugin', + 'allowHostIPC', + 'allowHostNetwork', + 'allowHostPID', + 'allowHostPorts', + 'allowPrivilegeEscalation', + 'allowPrivilegedContainer', + 'defaultAddCapabilities', + 'fsGroup', + 'groups', + 'priority', + 'readOnlyRootFilesystem', + 'requiredDropCapabilities', + 'runAsUser', + 'seLinuxContext', + 'supplementalGroups', + 'users', + 'volumes' + ] + for key in keys: + info[key] = self.get(security_context_constraint_mo, key) + + keys = [ + 'fsGroup', + 'runAsUser', + 'seLinuxContext', + 'supplementalGroups' + ] + for key in keys: + info[key] = self.get(security_context_constraint_mo, '%s:type' % (key)) + + info['allowedCapabilities'] = self.get(security_context_constraint_mo, 'allowedCapabilities', on_error=[], on_none=[]) + + return info + + def get_security_context_constraints_info(self, cache_enabled=True): + if cache_enabled: + if self.security_context_constraint is not None: + return self.security_context_constraint + + managed_objects = self.get_security_context_constraint_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.security_context_constraint = [] + for managed_object in managed_objects: + security_context_constraint_info = {} + security_context_constraint_info['info'] = self.get_security_context_constraint_info( + managed_object + ) + security_context_constraint_info['mo'] = managed_object + self.security_context_constraint.append( + security_context_constraint_info + ) + + return self.security_context_constraint + + def match_security_context_constraint(self, security_context_constraint_info, security_context_constraint_filter): + if security_context_constraint_filter is None or len(security_context_constraint_filter) == 0: + return True + + for ap_rule in security_context_constraint_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, '%s' % (security_context_constraint_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_security_context_constraint', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_security_context_constraints(self, object_filter=None, return_mo=False, cache_enabled=True): + all_security_context_constraints = self.get_security_context_constraints_info(cache_enabled=cache_enabled) + if all_security_context_constraints is None: + return None + + security_context_constraints = [] + + for security_context_constraint_info in all_security_context_constraints: + if not self.match_security_context_constraint(security_context_constraint_info['info'], object_filter): + continue + + if return_mo: + security_context_constraints.append( + security_context_constraint_info['mo'] + ) + continue + + security_context_constraints.append( + security_context_constraint_info['info'] + ) + + return security_context_constraints diff --git a/lib/k8s/security_context_constraint/main.py b/lib/k8s/security_context_constraint/main.py new file mode 100644 index 00000000..338de64a --- /dev/null +++ b/lib/k8s/security_context_constraint/main.py @@ -0,0 +1,11 @@ +from lib.k8s.security_context_constraint.api import K8sSecurityContextConstraintApi +from lib.k8s.security_context_constraint.info import K8sSecurityContextConstraintInfo + + +class K8sSecurityContextConstraint( + K8sSecurityContextConstraintApi, + K8sSecurityContextConstraintInfo + ): + def __init__(self): + K8sSecurityContextConstraintApi.__init__(self) + K8sSecurityContextConstraintInfo.__init__(self) diff --git a/lib/k8s/security_context_constraint/output.py b/lib/k8s/security_context_constraint/output.py new file mode 100644 index 00000000..c89d466f --- /dev/null +++ b/lib/k8s/security_context_constraint/output.py @@ -0,0 +1,64 @@ +class K8sSecurityContextConstraintOutput(): + def __init__(self): + pass + + def print_security_context_constraints(self, info, title=False): + if title: + self.my_output.default( + 'Security Context Constraint [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + info = self.my_output.prepare_list( + info, + empty=['allowedCapabilities', 'priority', 'volumes'] + ) + + order = [ + 'name', + 'allowPrivilegeEscalation', + 'allowPrivilegedContainer', + 'allowedCapabilities', + 'priority', + 'seLinuxContext', + 'runAsUser', + 'fsGroup', + 'supplementalGroups', + 'readOnlyRootFilesystem', + 'volumes', + 'age' + ] + + headers = [ + 'Name', + 'Priv Esc', + 'Priv Cont', + 'Caps', + 'Priority', + 'SELinux', + 'RunAsUser', + 'FsGroup', + 'SupGroup', + 'RO RootFs', + 'Volumes', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['allowedCapabilities', 'volumes'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/service/__init__.py b/lib/k8s/service/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/service/__pycache__/__init__.cpython-310.pyc b/lib/k8s/service/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ab5ded95 Binary files /dev/null and b/lib/k8s/service/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/k8s/service/__pycache__/api.cpython-310.pyc b/lib/k8s/service/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..7181a05f Binary files /dev/null and b/lib/k8s/service/__pycache__/api.cpython-310.pyc differ diff --git a/lib/k8s/service/__pycache__/info.cpython-310.pyc b/lib/k8s/service/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..604b64fe Binary files /dev/null and b/lib/k8s/service/__pycache__/info.cpython-310.pyc differ diff --git a/lib/k8s/service/__pycache__/main.cpython-310.pyc b/lib/k8s/service/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c52764b6 Binary files /dev/null and b/lib/k8s/service/__pycache__/main.cpython-310.pyc differ diff --git a/lib/k8s/service/api.py b/lib/k8s/service/api.py new file mode 100644 index 00000000..15f170fc --- /dev/null +++ b/lib/k8s/service/api.py @@ -0,0 +1,126 @@ +import time +import traceback + + +class K8sServiceApi(): + def __init__(self): + self.service_mo = None + + def get_service_mo(self, cache_enabled=True): + if cache_enabled: + if self.service_mo is not None: + return self.service_mo + + api_handler = self.get_api() + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.list_service_for_all_namespaces( + timeout_seconds=self.api_timeout_seconds + ) + self.log.k8s( + 'get', + 'service', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_service_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'service', + True, + int(time.time() * 1000) - start_time + ) + return None + + self.service_mo = [] + for item in response.items: + service = self.convert_object(item.to_dict()) + self.service_mo.append( + service + ) + + self.log.k8s_mo( + 'service', + self.service_mo + ) + + return self.service_mo + + def create_namespaced_service(self, service_definition): + api_handler = self.get_api() + if api_handler is None: + return None + + start_time = int(time.time() * 1000) + + namespace = service_definition['metadata']['namespace'] + try: + api_response = api_handler.create_namespaced_service( + namespace, + service_definition + ) + except BaseException: + api_response = None + self.log.error( + 'k8s.create_namespaced_service', + traceback.format_exc() + ) + + if api_response is None: + self.log.k8s( + 'create', + 'service', + False, + int(time.time() * 1000) - start_time + ) + return False + + self.log.k8s( + 'create', + 'service', + True, + int(time.time() * 1000) - start_time + ) + + return True + + def delete_namespaced_service(self, namespace, name): + api_handler = self.get_api() + if api_handler is None: + return None + + start_time = int(time.time() * 1000) + try: + api_response = api_handler.delete_namespaced_service( + name, + namespace + ) + except BaseException: + api_response = None + self.log.error( + 'k8s.delete_namespaced_service', + traceback.format_exc() + ) + + if api_response is None: + self.log.k8s( + 'delete', + 'service', + False, + int(time.time() * 1000) - start_time + ) + return False + + self.log.k8s( + 'delete', + 'service', + True, + int(time.time() * 1000) - start_time + ) + + return True diff --git a/lib/k8s/service/info.py b/lib/k8s/service/info.py new file mode 100644 index 00000000..2986948a --- /dev/null +++ b/lib/k8s/service/info.py @@ -0,0 +1,384 @@ +from lib import filter_helper +from lib import ip_helper + + +class K8sServiceInfo(): + def __init__(self): + self.service = None + + def get_service_info(self, service_mo): + if service_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + service_mo + ) + info.update(metadata_info) + + # ExternalName, ClusterIP, NodePort, and LoadBalancer + info['type'] = self.get(service_mo, 'spec:type') + + info['cluster_ip'] = self.get(service_mo, 'spec:cluster_ip', on_error=None) + if info['cluster_ip'] == 'None': + info['cluster_ip'] = None + + info['cluster_ips'] = self.get(service_mo, 'spec:cluster_i_ps', on_error=[], on_none=[]) + if len(info['cluster_ips']) == 1 and 'None' in info['cluster_ips']: + info['cluster_ips'] = [] + + info['external_traffic_policy'] = self.get(service_mo, 'spec:external_traffic_policy') + + info['external_ips'] = self.get(service_mo, 'spec:external_i_ps', on_error=[], on_none=[]) + if len(info['external_ips']) == 1 and 'None' in info['external_ips']: + info['external_ips'] = [] + + info['external_name'] = self.get(service_mo, 'spec:external_name') + info['load_balancer_ip'] = self.get(service_mo, 'spec:load_balancer_ip') + info['load_balancer_ingress'] = self.get(service_mo, 'status:load_balancer:ingress') + + if info['type'] == 'ExternalName': + info['cluster_ipT'] = ['--'] + info['external_ipT'] = [info['external_name']] + + if info['type'] in ['ClusterIP', 'NodePort', 'LoadBalancer']: + info['cluster_ipT'] = info['cluster_ips'] + info['external_ipT'] = info['external_ips'] + + info['port'] = [] + ports = [] + ports_mo = self.get(service_mo, 'spec:ports', on_error=[], on_none=[]) + for port_mo in ports_mo: + service_keys = [ + 'app_protocol', + 'name', + 'node_port', + 'port', + 'protocol', + 'target_port' + ] + port_info = {} + + for service_key in service_keys: + port_info[service_key] = self.get(port_mo, service_key) + + port_info['descr'] = '--' + + if info['type'] in ['NodePort', 'LoadBalancer']: + port_info['descr'] = '%s:%s/%s' % ( + port_info['port'], + port_info['node_port'], + port_info['protocol'] + ) + + if info['type'] == 'ClusterIP': + port_info['descr'] = '%s/%s' % ( + port_info['port'], + port_info['protocol'] + ) + + ports.append( + port_info['descr'] + ) + info['port'].append( + port_info + ) + + ports = sorted(ports) + info['ports'] = ','.join(ports) + + info['special'] = None + info['specialT'] = '--' + + info['selector'] = self.get(service_mo, 'spec:selector', on_error={}, on_none={}) + info['selectorT'] = [] + + for key in info['selector']: + info['selectorT'].append( + '%s:%s' % ( + key, + info['selector'][key] + ) + ) + if key == 'special': + info['special'] = info['selector'][key] + info['specialT'] = info['selector'][key] + + return info + + def get_services_info(self, cache_enabled=True): + if cache_enabled: + if self.service is not None: + return self.service + + managed_objects = self.get_service_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.service = [] + for managed_object in managed_objects: + service_info = {} + service_info['info'] = self.get_service_info( + managed_object + ) + service_info['mo'] = managed_object + self.service.append( + service_info + ) + + return self.service + + def match_service(self, service_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + key = rule.split(':')[0] + value = ':'.join(rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, service_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (service_info['namespace'], service_info['name'])): + return False + + if key == 'owner': + key_found = True + if not filter_helper.match_namespace_name(value, service_info['owner']): + return False + + if key == 'type': + key_found = True + if not filter_helper.match_string(value, service_info['type']): + return False + + if key == 'cluster-ip': + key_found = True + value_match = False + for cluster_ip in service_info['cluster_ips']: + if cluster_ip == value: + value_match = True + + if not value_match: + return False + + if key == 'cluster-subnet': + key_found = True + value_match = False + for cluster_ip in service_info['cluster_ips']: + if ip_helper.is_ipv4_in_cidr(cluster_ip, value): + value_match = True + + if not value_match: + return False + + if key == 'cluster-string': + key_found = True + value_match = False + for cluster_ip in service_info['cluster_ips']: + if filter_helper.match_string(cluster_ip, value): + value_match = True + + if key == 'external-ip': + key_found = True + value_match = False + for external_ip in service_info['external_ips']: + if external_ip == value: + value_match = True + + if not value_match: + return False + + if key == 'external-subnet': + key_found = True + value_match = False + for external_ip in service_info['external_ips']: + if ip_helper.is_ipv4_in_cidr(external_ip, value): + value_match = True + + if not value_match: + return False + + if key == 'external-string': + key_found = True + value_match = False + for external_ip in service_info['external_ips']: + if filter_helper.match_string(external_ip, value): + value_match = True + + if filter_helper.match_string(value, service_info['external_name']): + value_match = True + + if not value_match: + return False + + if key == 'port': + key_found = True + value_match = False + for port in service_info['port']: + if filter_helper.match_integer(value, port['port']): + value_match = True + + if not value_match: + return False + + if key == 'special': + key_found = True + if not filter_helper.match_string(value, service_info['special']): + return False + + if key == 'selector': + key_found = True + (selector_key, selector_value) = value.split(':') + if selector_key not in service_info['selector']: + return False + + if not filter_helper.match_string(selector_value, service_info['selector'][selector_key]): + return False + + if not key_found: + self.log.error( + 'match_service', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_services(self, object_filter=None, pod_info=False, return_mo=False, cache_enabled=True): + all_services = self.get_services_info(cache_enabled=cache_enabled) + if all_services is None: + return None + + services = [] + + for service_info in all_services: + if not self.match_service(service_info['info'], object_filter): + continue + + if return_mo: + services.append( + service_info['mo'] + ) + continue + + if pod_info: + service_info['info']['pod'] = [] + for selector_key in service_info['info']['selector']: + pod_filter = [ + 'label:%s:%s' % ( + selector_key, + service_info['info']['selector'][selector_key] + ) + ] + pods = self.get_pods( + object_filter=pod_filter + ) + if pods is not None: + service_info['info']['pod'] = service_info['info']['pod'] + pods + + services.append( + service_info['info'] + ) + + return services + + def get_service(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + services = self.get_services( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + + if services is None: + return None + + if len(services) == 1: + return services[0] + + return None + + def get_service_node_ip_port(self, namespace, name, cache_enabled=True, port_name=None): + service_info = self.get_service( + namespace, + name, + cache_enabled=cache_enabled + ) + if service_info is None: + return None, None + + if service_info['type'] != 'NodePort': + self.log.error( + 'k8s.get_service_node_ip_port', + 'Unexpected service type: %s/%s' % (namespace, name) + ) + return None, None + + if len(service_info['port']) == 0: + self.log.error( + 'k8s.get_service_node_ip_port', + 'Unexpected no port: %s/%s' % (namespace, name) + ) + return None, None + + if len(service_info['port']) > 1 and port_name is None: + self.log.error( + 'k8s.get_service_node_ip_port', + 'Port name not defined and multiple ports available: %s/%s' % (namespace, name) + ) + return None, None + + node_ip = self.get_any_worker_node_ip() + if node_ip is None: + self.log.error( + 'k8s.get_service_node_ip_port', + 'No ready worker node found' + ) + return None, None + + for port_info in service_info['port']: + if port_name is None or port_info['name'] == port_name: + return node_ip, port_info['node_port'] + + self.log.error( + 'k8s.get_service_node_ip_port', + 'No port found: %s/%s with port name %s' % (namespace, name, port_name) + ) + return None, None + + def get_services_with_special_label(self, label, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'special:%s' % ( + label + ) + ) + services_mo = self.get_services( + object_filter=object_filter, + return_mo=return_mo + ) + return services_mo + + def is_service_with_special_label(self, label, cache_enabled=True): + services_mo = self.get_services_with_special_label( + label, + return_mo=True, + cache_enabled=cache_enabled + ) + if services_mo is not None and len(services_mo) > 0: + return True + return False diff --git a/lib/k8s/service/main.py b/lib/k8s/service/main.py new file mode 100644 index 00000000..2e59dba7 --- /dev/null +++ b/lib/k8s/service/main.py @@ -0,0 +1,8 @@ +from lib.k8s.service.api import K8sServiceApi +from lib.k8s.service.info import K8sServiceInfo + + +class K8sService(K8sServiceApi, K8sServiceInfo): + def __init__(self): + K8sServiceApi.__init__(self) + K8sServiceInfo.__init__(self) diff --git a/lib/k8s/service/output.py b/lib/k8s/service/output.py new file mode 100644 index 00000000..ee26156a --- /dev/null +++ b/lib/k8s/service/output.py @@ -0,0 +1,164 @@ +class K8sServiceOutput(): + def __init__(self): + pass + + def print_services(self, info, title=False): + if title: + self.my_output.default( + 'Service [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['cluster_ipT']) == 0: + item['cluster_ipT'].append('--') + + if len(item['external_ipT']) == 0: + item['external_ipT'].append('--') + + if len(item['port']) == 0: + item['port'].append(dict(descr='--')) + + order = [ + 'namespace', + 'name', + 'type', + 'cluster_ipT', + 'external_ipT', + 'port.descr', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Type', + 'Cluster IP', + 'External IP', + 'Port', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cluster_ipT', 'external_ipT', 'port'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_services_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Service Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + + if len(item['cluster_ipT']) == 0: + item['cluster_ipT'].append('--') + + if len(item['external_ipT']) == 0: + item['external_ipT'].append('--') + + if len(item['port']) == 0: + item['port'].append(dict(descr='--')) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'selectorT', + 'specialT' + ] + + headers = [ + 'Service', + 'Owner', + 'Label', + 'Selector', + 'Special' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'selectorT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_services_pod(self, info, title=False): + if title: + self.my_output.default( + 'Service - Selector and Pods [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_nameT', + 'selectorT', + 'pod.namespace_name', + 'pod.phaseT' + ] + + headers = [ + 'Service', + 'Selector', + 'POD', + 'POD State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'selectorT', 'pod'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/service_account/__init__.py b/lib/k8s/service_account/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/service_account/api.py b/lib/k8s/service_account/api.py new file mode 100644 index 00000000..13940dbc --- /dev/null +++ b/lib/k8s/service_account/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sServiceAccountApi(): + def __init__(self): + self.service_account_mo = None + + def get_service_account_mo(self, cache_enabled=True): + if cache_enabled: + if self.service_account_mo is not None: + return self.service_account_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='v1', + kind='ServiceAccount' + ) + self.service_account_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'service_account', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_service_account_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'service_account', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'service_account', + self.service_account_mo + ) + + return self.service_account_mo diff --git a/lib/k8s/service_account/info.py b/lib/k8s/service_account/info.py new file mode 100644 index 00000000..3fcc9ef3 --- /dev/null +++ b/lib/k8s/service_account/info.py @@ -0,0 +1,96 @@ +from lib import filter_helper + + +class K8sServiceAccountInfo(): + def __init__(self): + self.service_account = None + + def get_service_account_info(self, service_account_mo): + if service_account_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + service_account_mo + ) + info.update(metadata_info) + + info['secret'] = self.get(service_account_mo, 'secrets', on_error=[], on_none=[]) + info['secretCount'] = len(info['secret']) + + return info + + def get_service_accounts_info(self, cache_enabled=True): + if cache_enabled: + if self.service_account is not None: + return self.service_account + + managed_objects = self.get_service_account_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.service_account = [] + for managed_object in managed_objects: + service_account_info = {} + service_account_info['info'] = self.get_service_account_info( + managed_object + ) + service_account_info['mo'] = managed_object + self.service_account.append( + service_account_info + ) + + return self.service_account + + def match_service_account(self, service_account_info, service_account_filter): + if service_account_filter is None or len(service_account_filter) == 0: + return True + + for ap_rule in service_account_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, service_account_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (service_account_info['namespace'], service_account_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_service_account', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_service_accounts(self, object_filter=None, return_mo=False, cache_enabled=True): + all_service_accounts = self.get_service_accounts_info(cache_enabled=cache_enabled) + if all_service_accounts is None: + return None + + service_accounts = [] + + for service_account_info in all_service_accounts: + if not self.match_service_account(service_account_info['info'], object_filter): + continue + + if return_mo: + service_accounts.append( + service_account_info['mo'] + ) + continue + + service_accounts.append( + service_account_info['info'] + ) + + return service_accounts diff --git a/lib/k8s/service_account/main.py b/lib/k8s/service_account/main.py new file mode 100644 index 00000000..7f3fcf82 --- /dev/null +++ b/lib/k8s/service_account/main.py @@ -0,0 +1,11 @@ +from lib.k8s.service_account.api import K8sServiceAccountApi +from lib.k8s.service_account.info import K8sServiceAccountInfo + + +class K8sServiceAccount( + K8sServiceAccountApi, + K8sServiceAccountInfo + ): + def __init__(self): + K8sServiceAccountApi.__init__(self) + K8sServiceAccountInfo.__init__(self) diff --git a/lib/k8s/service_account/output.py b/lib/k8s/service_account/output.py new file mode 100644 index 00000000..d9879faa --- /dev/null +++ b/lib/k8s/service_account/output.py @@ -0,0 +1,48 @@ +class K8sServiceAccountOutput(): + def __init__(self): + pass + + def print_service_accounts(self, info, title=False): + if title: + self.my_output.default( + 'Service Account [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + row_separator = False + for item in info: + if len(item['secret']) > 1: + row_separator = True + + order = [ + 'namespace', + 'name', + 'secret.name', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Secret', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['secret'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=row_separator, + table=True + ) diff --git a/lib/k8s/service_monitor/__init__.py b/lib/k8s/service_monitor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/service_monitor/api.py b/lib/k8s/service_monitor/api.py new file mode 100644 index 00000000..3f4bc727 --- /dev/null +++ b/lib/k8s/service_monitor/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sServiceMonitorApi(): + def __init__(self): + self.service_monitor_mo = None + + def get_service_monitor_mo(self, cache_enabled=True): + if cache_enabled: + if self.service_monitor_mo is not None: + return self.service_monitor_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='ServiceMonitor' + ) + self.service_monitor_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'service_monitor', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_service_monitor_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'service_monitor', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'service_monitor', + self.service_monitor_mo + ) + + return self.service_monitor_mo diff --git a/lib/k8s/service_monitor/info.py b/lib/k8s/service_monitor/info.py new file mode 100644 index 00000000..0115a675 --- /dev/null +++ b/lib/k8s/service_monitor/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sServiceMonitorInfo(): + def __init__(self): + self.service_monitor = None + + def get_service_monitor_info(self, service_monitor_mo): + if service_monitor_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + service_monitor_mo + ) + info.update(metadata_info) + + return info + + def get_service_monitors_info(self, cache_enabled=True): + if cache_enabled: + if self.service_monitor is not None: + return self.service_monitor + + managed_objects = self.get_service_monitor_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.service_monitor = [] + for managed_object in managed_objects: + service_monitor_info = {} + service_monitor_info['info'] = self.get_service_monitor_info( + managed_object + ) + service_monitor_info['mo'] = managed_object + self.service_monitor.append( + service_monitor_info + ) + + return self.service_monitor + + def match_service_monitor(self, service_monitor_info, service_monitor_filter): + if service_monitor_filter is None or len(service_monitor_filter) == 0: + return True + + for ap_rule in service_monitor_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_service_monitor', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_service_monitors(self, object_filter=None, return_mo=False, cache_enabled=True): + all_service_monitors = self.get_service_monitors_info(cache_enabled=cache_enabled) + if all_service_monitors is None: + return None + + service_monitors = [] + + for service_monitor_info in all_service_monitors: + if not self.match_service_monitor(service_monitor_info['info'], object_filter): + continue + + if return_mo: + service_monitors.append( + service_monitor_info['mo'] + ) + continue + + service_monitors.append( + service_monitor_info['info'] + ) + + return service_monitors diff --git a/lib/k8s/service_monitor/main.py b/lib/k8s/service_monitor/main.py new file mode 100644 index 00000000..1c31dc06 --- /dev/null +++ b/lib/k8s/service_monitor/main.py @@ -0,0 +1,11 @@ +from lib.k8s.service_monitor.api import K8sServiceMonitorApi +from lib.k8s.service_monitor.info import K8sServiceMonitorInfo + + +class K8sServiceMonitor( + K8sServiceMonitorApi, + K8sServiceMonitorInfo + ): + def __init__(self): + K8sServiceMonitorApi.__init__(self) + K8sServiceMonitorInfo.__init__(self) diff --git a/lib/k8s/service_monitor/output.py b/lib/k8s/service_monitor/output.py new file mode 100644 index 00000000..a85e8905 --- /dev/null +++ b/lib/k8s/service_monitor/output.py @@ -0,0 +1,33 @@ +class K8sServiceMonitorOutput(): + def __init__(self): + pass + + def print_service_monitors(self, info, title=False): + if title: + self.my_output.default( + 'Service Monitor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/services.py b/lib/k8s/services.py new file mode 100644 index 00000000..9f3c4b1f --- /dev/null +++ b/lib/k8s/services.py @@ -0,0 +1,340 @@ +#!usr/bin/env python + +import os +import base64 +import json +import time +import traceback + +class K8sServices(): + def __init__(self): + self.services = None + + def convert_service_output_json(self, output): + try: + if output is None: + return None + + output = str(output) + + if 'last-applied-configuration' in output: + ''' + Not sure how to change that... + {"kubectl.kubernetes.io/last-applied-configuration": + "{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{}, + "labels":{"k8s-app":"calico-typha"},"name":"calico-typha","namespace":"kube-system"}, + "spec":{"clusterIP":"", + "ports":[{"name":"calico-typha","port":5473,"protocol":"TCP","targetPort":"calico-typha"}], + "selector":{"k8s-app":"calico-typha"}}}\n"} + ''' + return None + + output = output.replace('\'', '\"') + output = output.replace(': None', ': null') + output = output.replace(': True', ': true') + output = output.replace(': False', ': false') + return json.loads(output) + except: + self.log.error('k8s_services.convert_service_output_json', output) + self.log.error('k8s_services.convert_service_output_json', traceback.format_exc()) + return None + + def convert_service_metadata_managed_fields(self, mfs): + try: + if mfs is None: + return None + + n = [] + for mf in mfs: + t = dict() + t['api_version'] = mf.api_version + t['fields'] = mf.fields_v1 + t['manager'] = mf.manager + t['operation'] = mf.operation + t['time'] = self.convert_timestamp(mf.time) + n.append(t) + + except: + self.log.error('k8s_services.convert_service_metadata_managed_fields', traceback.format_exc()) + return None + + return n + + def convert_service_metadata(self, metadata): + try: + n = dict() + n['uid'] = metadata.uid + n['self_link'] = metadata.self_link + n['resource_version'] = metadata.resource_version + if metadata.owner_references is None: + n['owner_references'] = None + else: + n['owner_references'] = str(metadata.owner_references) + n['name'] = metadata.name + n['namespace'] = metadata.namespace + n['annotations'] = self.convert_service_output_json(metadata.annotations) + n['labels'] = self.convert_service_output_json(metadata.labels) + n['managed_fields'] = self.convert_service_metadata_managed_fields(metadata.managed_fields) + n['creation_timestamp'] = self.convert_timestamp(metadata.creation_timestamp) + + except: + self.log.error('k8s_services.convert_service_metadata', traceback.format_exc()) + return None + + return n + + def convert_service(self, service): + try: + n = dict() + n['metadata'] = self.convert_service_metadata(service.metadata) + n['spec'] = self.convert_service_output_json(service.spec) + n['status'] = self.convert_service_output_json(service.status) + except: + self.log.error('k8s_services.convert_service', traceback.format_exc()) + return None + + return n + + def get_service_summary(self, service): + ''' + { + "name": "my-nginx-service-1", + "namespace": "default", + "type": "LoadBalancer", + "ip": "", + "external_ip_list": [ + "" + ], + "external_ips": null, + "lb_ingress_ip": [ + { + "hostname": null, + "ip": "", + "ports": null + } + ], + "external_ip": "", + "ports": "18080/TCP", + "ports_list": [ + { + "app_protocol": null, + "name": "http", + "node_port": 31103, + "port": 80, + "protocol": "TCP", + "target_port": "http" + }, + { + "app_protocol": null, + "name": "https", + "node_port": 30212, + "port": 443, + "protocol": "TCP", + "target_port": "https" + } + ], + "selector": { + "app": "my-nginx-1" + }, + "age": 51731, + "creation_timestamp": 1651519900 + } + ''' + try: + summary = dict() + summary['name'] = service['metadata']['name'] + summary['namespace'] = service['metadata']['namespace'] + summary['type'] = service['spec']['type'] + + summary['ip'] = service['spec']['cluster_ip'] + if summary['ip'] == 'None': + summary['ip'] = None + + summary['external_ip_list'] = [] + + if service['spec']['external_i_ps'] is None: + summary['external_ips'] = None + else: + summary['external_ips'] = service['spec']['external_i_ps'] + summary['external_ip_list'] = service['external_ip_list'] + n['external_ips'] + + if service['status']['load_balancer']['ingress'] is None: + summary['lb_ingress_ip'] = None + else: + summary['lb_ingress_ip'] = service['status']['load_balancer']['ingress'] + for lb_ip in summary['lb_ingress_ip']: + summary['external_ip_list'].append(lb_ip['ip']) + + summary['external_ip'] = ','.join(summary['external_ip_list']) + + ports = [] + for p in service['spec']['ports']: + ports.append('%s/%s' % (p['port'], p['protocol'])) + summary['ports'] = ','.join(ports) + summary['ports_list'] = service['spec']['ports'] + + summary['selector'] = service['spec']['selector'] + + summary['age'] = int(time.time()) - service['metadata']['creation_timestamp'] + summary['creation_timestamp'] = service['metadata']['creation_timestamp'] + + except: + self.log.error('k8s_services.get_service_summary', traceback.format_exc()) + return None + + return summary + + def get_service(self, namespace, name): + self.get_services() + if self.services is not None: + for service in self.services: + info = self.get_service_summary(service) + if info is not None: + if info['name'] == name and info['namespace'] == namespace: + return info + + return None + + def get_lb_services(self, summary = False): + return self.get_services_type('LoadBalancer', summary = summary) + + def get_services_type(self, service_type, summary = False): + self.get_services() + services = [] + if self.services is not None: + for service in self.services: + if service['spec']['type'] == service_type: + if summary: + s = self.get_service_summary(service) + if s is not None: + services.append(s) + else: + services.append(service) + + return services + + def get_services(self): + if self.services is not None: + return self.services + + # https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/CoreV1Api.md#list_service_for_all_namespaces + try: + self.services = [] + start_time = int(time.time()*1000) + response = self.api.list_service_for_all_namespaces(timeout_seconds=self.api_timeout_seconds) + self.api_statistics('list_service_for_all_namespaces', int(time.time()*1000) - start_time) + + if response is not None: + for i in response.items: + service = self.convert_service(i) + if service is not None: + self.services.append(service) + + except: + self.log.error('k8s_services.get_services', traceback.format_exc()) + return None + + return self.services + + def get_service_pods(self, service): + ''' + [ + { + "namespace": "iks", + "labels": { + "app.kubernetes.io/component": "controller", + "app.kubernetes.io/instance": "essential-nginx-ingress", + "app.kubernetes.io/name": "ingress-nginx", + "controller-revision-hash": "794954b8c6", + "pod-template-generation": "1" + }, + "name": "essential-nginx-ingress-ingress-nginx-controller-2nk8m", + "uid": "8b2bcc15-da82-4092-9381-71ffca698158", + "age": 258092, + "node": "milan-kali-worker-4078840427", + "replicaset_name": null, + "scheduled": true, + "status": "Running", + "ready": true, + "pod_ip": "", + "cni": { + "ip": "", + "ports": [ + { + "container_port": 80, + "host_ip": null, + "host_port": null, + "name": "http", + "protocol": "TCP" + }, + { + "container_port": 443, + "host_ip": null, + "host_port": null, + "name": "https", + "protocol": "TCP" + } + ] + }, + "job_name": null, + "job_succeeded": false, + "healthy": true, + "containers": { + "ready": 1, + "completed": 0, + "count": 1, + "restarts": 0, + "reasons": [] + }, + "node_selector": [ + { + "match_expressions": null, + "match_fields": [ + { + "key": "metadata.name", + "operator": "In", + "values": [ + "milan-kali-worker-4078840427" + ] + } + ] + } + ], + "scheduling_problem": null + } + ] + ''' + my_pods = [] + try: + if self.pods is not None: + for p in self.pods: + pod = self.get_pod_summary(p) + if pod is not None: + found = True + if pod['labels'] is None: + continue + + for selector_key in service['selector']: + if selector_key not in pod['labels']: + found = False + break + + if pod['labels'][selector_key] != service['selector'][selector_key]: + found = False + break + + if found: + my_pods.append(pod) + + except: + self.log.error('k8s_services.get_service_pods', traceback.format_exc()) + + return my_pods + + def get_service_pods_health_summary(self, service): + try: + my_pods = self.get_service_pods(service) + return self.get_selected_pods_health_summary(my_pods) + except: + self.log.error('k8s_services.get_service_pods_health_summary', traceback.format_exc()) + return None \ No newline at end of file diff --git a/lib/k8s/settings.py b/lib/k8s/settings.py new file mode 100644 index 00000000..6b68fa00 --- /dev/null +++ b/lib/k8s/settings.py @@ -0,0 +1,427 @@ +import os +import json +import socket +import shutil +import traceback + +from lib import file_helper +from lib import filter_helper +from lib import log_helper +from lib.settings_helper import Settings +from lib.ocp import settings as ocp_settings + + +class K8sSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.k8s_settings_filename = os.path.join( + self.settings_dir, + 'k8s' + ) + + self.k8s_clusters_directory = os.path.join( + self.settings_dir, + 'k8s-clusters' + ) + + if not self.initialize_k8s_settings(): + raise ValueError('K8s settings initialization failed') + + def get_k8s_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Defaults'] = {} + settings['Defaults']['Cluster'] = None + settings['Clusters'] = [] + return settings + + def initialize_k8s_settings(self): + if not os.path.isfile(self.k8s_settings_filename): + settings = self.get_k8s_default_settings() + if not self.set_k8s_settings(settings): + return False + + if not os.path.isdir(self.k8s_clusters_directory): + os.makedirs( + self.k8s_clusters_directory, + exist_ok=True + ) + + if not self.import_ocp_settings(): + return False + + return True + + def delete_ocp_clusters(self): + clusters = self.get_k8s_clusters() + if clusters is not None: + for cluster in clusters: + if cluster['type'] == 'ocp' and cluster['source'] == 'import': + if not self.delete_k8s_cluster(cluster['name']): + self.log.error( + 'delete_ocp_clusters', + 'Cluster delete failed: %s' % (cluster['name']) + ) + return False + + return True + + def import_ocp_settings(self): + default_cluster_name = self.get_default_cluster() + + if not self.delete_ocp_clusters(): + return False + + ocp_settings_handler = ocp_settings.OcpSettings( + log_id=self.log_id + ) + ocp_clusters = ocp_settings_handler.get_ocp_clusters() + for ocp_cluster in ocp_clusters: + if not self.set_k8s_cluster('%s' % (ocp_cluster['name']), ocp_cluster['kubeconfig'], cluster_type='ocp', cluster_source='import'): + self.log.error( + 'import_ocp_settings', + 'Failed to add ocp cluster: %s' % (ocp_cluster['name']) + ) + return False + + if self.get_k8s_cluster(default_cluster_name) is not None: + self.set_default_cluster(default_cluster_name) + + return True + + def get_k8s_settings(self): + if not os.path.isfile(self.k8s_settings_filename): + return None + + try: + with open(self.k8s_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_k8s_settings', traceback.format_exc()) + return None + + return settings + + def set_k8s_settings(self, settings): + try: + with open(self.k8s_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_k8s_settings', traceback.format_exc()) + return False + + return True + + def get_default_cluster(self): + settings = self.get_k8s_settings() + if settings is None: + return None + + try: + default_cluster_name = settings['Defaults']['Cluster'] + except BaseException: + default_cluster_name = None + + return default_cluster_name + + def set_default_cluster(self, name): + settings = self.get_k8s_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Cluster'] = name + return self.set_k8s_settings(settings) + + def get_k8s_cluster_names(self): + clusters = self.get_k8s_clusters() + if clusters is None: + return None + + names = [] + for cluster in clusters: + names.append( + cluster['name'] + ) + + return names + + def match_cluster(self, cluster_settings, cluster_filter): + if cluster_filter is None or len(cluster_filter) == 0: + return True + + for ap_rule in cluster_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cluster_settings['name']): + return False + + if not key_found: + self.log.error( + 'match_cluster', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_k8s_clusters(self, cluster_filter=None): + settings = self.get_k8s_settings() + if settings is None: + return None + + all_clusters = settings['Clusters'] + clusters = [] + for cluster in all_clusters: + if not self.match_cluster(cluster, cluster_filter): + continue + + clusters.append( + cluster + ) + + clusters = sorted( + clusters, + key=lambda i: i['name'] + ) + + return clusters + + def get_k8s_cluster(self, k8s_name, strict_match=True): + clusters = self.get_k8s_clusters() + if clusters is None: + return None + + candidates = [] + for cluster in clusters: + if cluster['name'] == k8s_name: + return cluster + + if not strict_match: + if k8s_name.lower() in cluster['name'].lower(): + candidates.append(cluster) + + if not strict_match and len(candidates) == 1: + return candidates[0] + + return None + + def set_k8s_clusters(self, clusters): + settings = self.get_k8s_settings() + if settings is None: + return False + + settings['Clusters'] = clusters + return self.set_k8s_settings(settings) + + def get_k8s_cluster_directory(self, k8s_name): + cluster_directory = os.path.join( + self.k8s_clusters_directory, + k8s_name + ) + return cluster_directory + + def copy_k8s_cluster_file(self, k8s_name, source_filename, destination_filename): + if not os.path.isfile(source_filename): + self.log.error( + 'copy_k8s_cluster_file', + 'Source file not found: %s' % (source_filename) + ) + return None + + cluster_directory = self.get_k8s_cluster_directory(k8s_name) + if not os.path.isdir(cluster_directory): + self.log.error( + 'copy_k8s_cluster_file', + 'OCP directory not found: %s' % (cluster_directory) + ) + return None + + target_filename = os.path.join( + cluster_directory, + destination_filename + ) + shutil.copy( + source_filename, + target_filename + ) + if not os.path.isfile(target_filename): + self.log.error( + 'copy_k8s_cluster_file', + 'File copy failed: %s => %s' % (source_filename, target_filename) + ) + return None + + return target_filename + + def set_k8s_cluster(self, k8s_name, kubeconfig_filename, cluster_type='standard', cluster_source='user'): + if not os.path.isfile(kubeconfig_filename): + self.log.error( + 'set_k8s_cluster', + 'Kubeconfig file not found: %s' % (kubeconfig_filename) + ) + return False + + clusters = self.get_k8s_clusters() + if clusters is None: + return False + + new_clusters = [] + for cluster in clusters: + if cluster['name'] != k8s_name: + new_clusters.append(cluster) + + cluster_directory = self.get_k8s_cluster_directory(k8s_name) + if not os.path.isdir(cluster_directory): + os.makedirs( + cluster_directory, + exist_ok=True + ) + + target_kubeconfig_filename = os.path.join( + cluster_directory, + 'kubeconfig' + ) + + shutil.copy( + kubeconfig_filename, + target_kubeconfig_filename + ) + if not os.path.isfile(target_kubeconfig_filename): + self.log.error( + 'set_k8s_cluster', + 'Kubeconfig file copy failed: %s => %s' % (kubeconfig_filename, target_kubeconfig_filename) + ) + return False + + new_cluster = {} + new_cluster['name'] = k8s_name + new_cluster['kubeconfig'] = target_kubeconfig_filename + new_cluster['type'] = cluster_type + new_cluster['source'] = cluster_source + new_clusters.append(new_cluster) + + return self.set_k8s_clusters(new_clusters) + + def delete_k8s_cluster(self, k8s_name): + clusters = self.get_k8s_clusters() + if clusters is None: + return False + + default_cluster = self.get_default_cluster() + if default_cluster is not None and default_cluster == k8s_name: + self.set_default_cluster(None) + + new_clusters = [] + for cluster in clusters: + if cluster['name'] != k8s_name: + new_clusters.append(cluster) + + cluster_directory = os.path.join( + self.k8s_clusters_directory, + k8s_name + ) + if os.path.isdir(cluster_directory): + shutil.rmtree(cluster_directory) + + return self.set_k8s_clusters(new_clusters) + + def get_cluster_kubeconfig_filename(self, cluster_name): + cluster_settings = self.get_k8s_cluster(cluster_name) + if cluster_settings is None: + return None + return cluster_settings['kubeconfig'] + + def get_cluster_kubeconfig_server_name(self, content): + try: + api_server = content['clusters'][0]['cluster']['server'] + api_server_name = api_server[8:].split(':')[0] + + except BaseException: + self.log.error( + 'get_cluster_name', + 'Failed getting api server value' + ) + return None + + return api_server_name + + def get_cluster_kubeconfig_info(self, cluster_name): + info = {} + info['__Output'] = {} + + info['name'] = cluster_name + info['kubeconfigFilename'] = self.get_cluster_kubeconfig_filename( + cluster_name + ) + if info['kubeconfigFilename'] is None: + return None + + info['isKubeconfigFile'] = os.path.isfile( + info['kubeconfigFilename'] + ) + if info['isKubeconfigFile']: + info['isKubeconfigFileTick'] = '\u2713' + info['__Output']['isKubeconfigFileTick'] = 'Green' + else: + info['isKubeconfigFile'] = '\u2717' + info['__Output']['isKubeconfigFileTick'] = 'Red' + + info['apiFqdn'] = '' + info['apiVip'] = '' + info['apiDns'] = '' + + if not info['isKubeconfigFile']: + return info + + kubeconfig_content = file_helper.get_file_yaml( + info['kubeconfigFilename'] + ) + if kubeconfig_content is None: + self.log.error( + 'get_ocp_cluster_kubeconfig', + 'File read failed: %s' % ( + info['kubeconfigFilename'] + ) + ) + return info + + info['apiFqdn'] = self.get_cluster_kubeconfig_server_name(kubeconfig_content) + if info['apiFqdn'] is None: + return info + + try: + info['apiVip'] = socket.gethostbyname(info['apiFqdn']) + except BaseException: + info['apiVip'] = 'not-resolved' + return info + + return info + + def get_clusters_kubeconfig_info(self): + cluster_names = self.get_k8s_cluster_names() + if cluster_names is None: + return None + + clusters_info = [] + for cluster_name in cluster_names: + cluster_info = self.get_cluster_kubeconfig_info(cluster_name) + if cluster_info is None: + continue + + clusters_info.append( + cluster_info + ) + + return clusters_info diff --git a/lib/k8s/sriov_network/__init__.py b/lib/k8s/sriov_network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/sriov_network/api.py b/lib/k8s/sriov_network/api.py new file mode 100644 index 00000000..5f387523 --- /dev/null +++ b/lib/k8s/sriov_network/api.py @@ -0,0 +1,100 @@ +import time +import traceback + + +class K8sSriovNetworkApi(): + def __init__(self): + self.sriov_network_mo = None + + def get_sriov_network_mo(self, cache_enabled=True): + if cache_enabled: + if self.sriov_network_mo is not None: + return self.sriov_network_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='sriovnetwork.openshift.io/v1', + kind='SriovNetwork' + ) + self.sriov_network_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'sriov_network', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_sriov_network_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'sriov_network', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'sriov_network', + self.sriov_network_mo + ) + + return self.sriov_network_mo + + def create_sriov_network(self, policy): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='sriovnetwork.openshift.io/v1', kind='SriovNetwork') + success = True + response = obj_list.create( + body=policy, + namespace=policy['metadata']['namespace'], + ) + except BaseException: + success = False + self.log.error('ocp.create_ocp_sriov_network', traceback.format_exc()) + + self.log.ocp( + 'create', + 'sriov_network', + success, + int(time.time() * 1000) - start_time + ) + + return success + + def delete_sriov_network(self, namespace, name): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='sriovnetwork.openshift.io/v1', kind='SriovNetwork') + success = True + response = obj_list.delete( + namespace=namespace, + name=name + ) + except BaseException: + success = False + self.log.error('ocp.delete_ocp_sriov_network', traceback.format_exc()) + + self.log.ocp( + 'delete', + 'delete_ocp_sriov_network', + success, + int(time.time() * 1000) - start_time + ) + + return success diff --git a/lib/k8s/sriov_network/info.py b/lib/k8s/sriov_network/info.py new file mode 100644 index 00000000..b6a21732 --- /dev/null +++ b/lib/k8s/sriov_network/info.py @@ -0,0 +1,165 @@ +import json + +from lib import filter_helper + + +class K8sSriovNetworkInfo(): + def __init__(self): + self.sriov_network = None + + def get_sriov_network_info(self, sriov_network_mo): + if sriov_network_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + sriov_network_mo + ) + info.update(metadata_info) + + info['network_namespace'] = self.get(sriov_network_mo, 'spec:networkNamespace') + info['resource_name'] = self.get(sriov_network_mo, 'spec:resourceName') + info['vlan'] = self.get(sriov_network_mo, 'spec:vlan') + info['vlanT'] = info['vlan'] + if info['vlan'] is None: + info['vlanT'] = '--' + + info['spoof'] = self.get(sriov_network_mo, 'spec:spoofChk', on_none="on (*)", on_error=None) + info['trust'] = self.get(sriov_network_mo, 'spec:trust', on_none="off (*)", on_error=None) + + info['capabilities'] = self.get(sriov_network_mo, 'spec:capabilities', on_none=None, on_error=None) + info['capabilitiesT'] = ['--'] + if info['capabilities'] is not None: + info['capabilitiesT'] = [] + capabilities = json.loads(info['capabilities']) + for key in capabilities: + info['capabilitiesT'].append( + '%s: %s' % ( + key, + capabilities[key] + ) + ) + + info['ipam'] = self.get(sriov_network_mo, 'spec:ipam') + info['ipamT'] = ['--'] + if info['ipam'] is not None: + info['ipamT'] = json.dumps(json.loads(info['ipam']), indent=4).split('\n') + + return info + + def get_sriov_networks_info(self, cache_enabled=True): + if cache_enabled: + if self.sriov_network is not None: + return self.sriov_network + + managed_objects = self.get_sriov_network_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.sriov_network = [] + for managed_object in managed_objects: + sriov_network_info = {} + sriov_network_info['info'] = self.get_sriov_network_info( + managed_object + ) + sriov_network_info['mo'] = managed_object + self.sriov_network.append( + sriov_network_info + ) + + return self.sriov_network + + def match_sriov_network(self, sriov_network_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, sriov_network_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (sriov_network_info['namespace'], sriov_network_info['name'])): + return False + + if key == 'resource': + key_found = True + if not filter_helper.match_string(value, sriov_network_info['resource_name']): + return False + + if not key_found: + self.log.error( + 'match_sriov_network', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_sriov_networks(self, object_filter=None, return_mo=False, cache_enabled=True): + all_sriov_networks = self.get_sriov_networks_info(cache_enabled=cache_enabled) + if all_sriov_networks is None: + return None + + sriov_networks = [] + + for sriov_network_info in all_sriov_networks: + if not self.match_sriov_network(sriov_network_info['info'], object_filter): + continue + + if return_mo: + sriov_networks.append( + sriov_network_info['mo'] + ) + continue + + sriov_networks.append( + sriov_network_info['info'] + ) + + return sriov_networks + + def is_sriov_network(self, name, namespace='openshift-sriov-network-operator', cache_enabled=True): + if self.get_sriov_network(name, namespace=namespace, cache_enabled=cache_enabled) is None: + return False + return True + + def get_sriov_network(self, name, namespace='openshift-sriov-network-operator', return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + sriov_networks = self.get_sriov_networks( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if sriov_networks is None: + return None + + if len(sriov_networks) == 1: + return sriov_networks[0] + + return None + + def get_sriov_networks_with_resource_name(self, resource_name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'resource:%s' % (resource_name) + ) + sriov_networks = self.get_sriov_networks( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + return sriov_networks diff --git a/lib/k8s/sriov_network/main.py b/lib/k8s/sriov_network/main.py new file mode 100644 index 00000000..af39d71a --- /dev/null +++ b/lib/k8s/sriov_network/main.py @@ -0,0 +1,11 @@ +from lib.k8s.sriov_network.api import K8sSriovNetworkApi +from lib.k8s.sriov_network.info import K8sSriovNetworkInfo + + +class K8sSriovNetwork( + K8sSriovNetworkApi, + K8sSriovNetworkInfo + ): + def __init__(self): + K8sSriovNetworkApi.__init__(self) + K8sSriovNetworkInfo.__init__(self) diff --git a/lib/k8s/sriov_network/output.py b/lib/k8s/sriov_network/output.py new file mode 100644 index 00000000..76a26ea1 --- /dev/null +++ b/lib/k8s/sriov_network/output.py @@ -0,0 +1,62 @@ +class K8sSriovNetworkOutput(): + def __init__(self): + pass + + def print_sriov_networks(self, info, title=False): + if title: + self.my_output.default( + 'SR-IOV Network [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + + order = [ + 'namespace_nameT', + 'network_namespace', + 'resource_name', + 'vlanT', + 'spoof', + 'trust', + 'capabilitiesT', + 'ipamT', + 'age' + ] + + headers = [ + 'SR-IOV Network', + 'NetNamespace', + 'Resource', + 'VLAN', + 'Spoof', + 'Trust', + 'Caps', + 'IPAM', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'ipamT', 'capabilitiesT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/sriov_network_node_policy/__init__.py b/lib/k8s/sriov_network_node_policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/sriov_network_node_policy/api.py b/lib/k8s/sriov_network_node_policy/api.py new file mode 100644 index 00000000..d97a3497 --- /dev/null +++ b/lib/k8s/sriov_network_node_policy/api.py @@ -0,0 +1,100 @@ +import time +import traceback + + +class K8sSriovNetworkNodePolicyApi(): + def __init__(self): + self.sriov_network_node_policy_mo = None + + def get_sriov_network_node_policy_mo(self, cache_enabled=True): + if cache_enabled: + if self.sriov_network_node_policy_mo is not None: + return self.sriov_network_node_policy_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='sriovnetwork.openshift.io/v1', + kind='SriovNetworkNodePolicy' + ) + self.sriov_network_node_policy_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'sriov_network_node_policy', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_sriov_network_node_policy_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'sriov_network_node_policy', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'sriov_network_node_policy', + self.sriov_network_node_policy_mo + ) + + return self.sriov_network_node_policy_mo + + def create_sriov_network_node_policy(self, policy): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='sriovnetwork.openshift.io/v1', kind='SriovNetworkNodePolicy') + success = True + response = obj_list.create( + body=policy, + namespace=policy['metadata']['namespace'], + ) + except BaseException: + success = False + self.log.error('k8s.create_sriov_network_node_policy', traceback.format_exc()) + + self.log.k8s( + 'create', + 'sriov_network', + success, + int(time.time() * 1000) - start_time + ) + + return success + + def delete_sriov_network_node_policy(self, namespace, name): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return False + + try: + start_time = int(time.time() * 1000) + obj_list = api_handler.resources.get(api_version='sriovnetwork.openshift.io/v1', kind='SriovNetworkNodePolicy') + success = True + response = obj_list.delete( + namespace=namespace, + name=name + ) + except BaseException: + success = False + self.log.error('k8s.delete_sriov_network_node_policy', traceback.format_exc()) + + self.log.k8s( + 'delete', + 'delete_sriov_network_node_policy', + success, + int(time.time() * 1000) - start_time + ) + + return success diff --git a/lib/k8s/sriov_network_node_policy/info.py b/lib/k8s/sriov_network_node_policy/info.py new file mode 100644 index 00000000..03762d3c --- /dev/null +++ b/lib/k8s/sriov_network_node_policy/info.py @@ -0,0 +1,239 @@ +import json + +from lib import filter_helper + + +class K8sSriovNetworkNodePolicyInfo(): + def __init__(self): + self.sriov_network_node_policy = None + + def get_sriov_network_node_policy_info(self, sriov_network_node_policy_mo): + if sriov_network_node_policy_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + sriov_network_node_policy_mo + ) + info.update(metadata_info) + + info['device_type'] = self.get(sriov_network_node_policy_mo, 'spec:deviceType') + info['device_typeT'] = info['device_type'] + if info['device_type'] is None: + info['device_typeT'] = '--' + + info['is_rdma'] = self.get(sriov_network_node_policy_mo, 'spec:isRdma') + + info['nic_selector'] = self.get(sriov_network_node_policy_mo, 'spec:nicSelector') + if len(info['nic_selector']) == 0: + info['nic_selectorT'] = ['--'] + else: + info['nic_selectorT'] = json.dumps(info['nic_selector'])[1:][:-1].split(',') + + info['interface'] = [] + if 'pfNames' in info['nic_selector']: + for pf_name in info['nic_selector']['pfNames']: + if len(pf_name.split('#')) == 1: + if pf_name not in info['interface']: + info['interface'].append( + pf_name + ) + continue + + if len(pf_name.split('#')) == 2: + if pf_name.split('#')[0] not in info['interface']: + info['interface'].append( + pf_name.split('#')[0] + ) + continue + + info['node_selector'] = self.get(sriov_network_node_policy_mo, 'spec:nodeSelector') + if len(info['node_selector']) == 0: + info['node_selectorT'] = ['--'] + else: + info['node_selectorT'] = json.dumps(info['node_selector'])[1:][:-1].split(',') + + info['vfs'] = self.get(sriov_network_node_policy_mo, 'spec:numVfs') + + info['priority'] = self.get(sriov_network_node_policy_mo, 'spec:priority') + info['priorityT'] = info['priority'] + if info['priority'] is None: + info['priorityT'] = '--' + + info['resource_name'] = self.get(sriov_network_node_policy_mo, 'spec:resourceName') + info['resource_nameT'] = info['resource_name'] + if info['resource_name'] is None or len(info['resource_name']) == 0: + info['resource_nameT'] = '--' + + return info + + def get_sriov_network_node_policies_info(self, cache_enabled=True): + if cache_enabled: + if self.sriov_network_node_policy is not None: + return self.sriov_network_node_policy + + managed_objects = self.get_sriov_network_node_policy_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.sriov_network_node_policy = [] + for managed_object in managed_objects: + sriov_network_node_policy_info = {} + sriov_network_node_policy_info['info'] = self.get_sriov_network_node_policy_info( + managed_object + ) + sriov_network_node_policy_info['mo'] = managed_object + self.sriov_network_node_policy.append( + sriov_network_node_policy_info + ) + + return self.sriov_network_node_policy + + def match_sriov_network_node_policy(self, sriov_network_node_policy_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, sriov_network_node_policy_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (sriov_network_node_policy_info['namespace'], sriov_network_node_policy_info['name'])): + return False + + if key == 'resource': + key_found = True + if not filter_helper.match_string(value, sriov_network_node_policy_info['resource_name']): + return False + + if key == 'device_type': + key_found = True + if not filter_helper.match_string(value, sriov_network_node_policy_info['device_type']): + return False + + if key == 'interface': + key_found = True + found = False + for interface_name in sriov_network_node_policy_info['interface']: + if filter_helper.match_string(value, interface_name): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_sriov_network_node_policy', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_sriov_network_node_policies(self, object_filter=None, return_mo=False, sriov_network_info=False, cache_enabled=True): + all_sriov_network_node_policies = self.get_sriov_network_node_policies_info(cache_enabled=cache_enabled) + if all_sriov_network_node_policies is None: + return None + + sriov_network_node_policies = [] + + for sriov_network_node_policy_info in all_sriov_network_node_policies: + if not self.match_sriov_network_node_policy(sriov_network_node_policy_info['info'], object_filter): + continue + + if return_mo: + sriov_network_node_policies.append( + sriov_network_node_policy_info['mo'] + ) + continue + + if sriov_network_info: + sriov_network_node_policy_info['info']['sriov_network'] = [] + if len(sriov_network_node_policy_info['info']['resource_name']) > 0: + sriov_network_node_policy_info['info']['sriov_network'] = self.get_sriov_networks_with_resource_name( + sriov_network_node_policy_info['info']['resource_name'] + ) + if sriov_network_node_policy_info['info']['sriov_network'] is None: + self.log.error( + 'get_sriov_network_node_policies', + 'Failed to get sriov networks for policy: %s' % (sriov_network_node_policy_info['info']['name']) + ) + sriov_network_node_policy_info['info']['sriov_network_count'] = 0 + else: + sriov_network_node_policy_info['info']['sriov_network_count'] = len( + sriov_network_node_policy_info['info']['sriov_network'] + ) + + sriov_network_node_policies.append( + sriov_network_node_policy_info['info'] + ) + + return sriov_network_node_policies + + def is_sriov_network_node_policy(self, name, namespace='openshift-sriov-network-operator', cache_enabled=True): + if self.get_sriov_network_node_policy(name, namespace=namespace, cache_enabled=cache_enabled) is None: + return False + return True + + def get_sriov_network_node_policy(self, name, namespace='openshift-sriov-network-operator', return_mo=False, sriov_network_info=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + sriov_network_node_policies = self.get_sriov_network_node_policies( + object_filter=object_filter, + return_mo=return_mo, + sriov_network_info=sriov_network_info, + cache_enabled=cache_enabled + ) + if sriov_network_node_policies is None: + return None + + if len(sriov_network_node_policies) == 1: + return sriov_network_node_policies[0] + + return None + + def get_sriov_network_node_policy_with_resource_name(self, resource_name, return_mo=False, sriov_network_info=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'resource:%s' % (resource_name) + ) + sriov_network_node_policies = self.get_sriov_network_node_policies( + object_filter=object_filter, + return_mo=return_mo, + sriov_network_info=sriov_network_info, + cache_enabled=cache_enabled + ) + if sriov_network_node_policies is None: + return None + + if len(sriov_network_node_policies) == 1: + return sriov_network_node_policies[0] + + return None + + def get_sriov_network_node_policies_with_interface(self, interface_name, return_mo=False, sriov_network_info=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'interface:%s' % (interface_name) + ) + sriov_network_node_policies = self.get_sriov_network_node_policies( + object_filter=object_filter, + return_mo=return_mo, + sriov_network_info=sriov_network_info, + cache_enabled=cache_enabled + ) + return sriov_network_node_policies diff --git a/lib/k8s/sriov_network_node_policy/main.py b/lib/k8s/sriov_network_node_policy/main.py new file mode 100644 index 00000000..fd2b632d --- /dev/null +++ b/lib/k8s/sriov_network_node_policy/main.py @@ -0,0 +1,11 @@ +from lib.k8s.sriov_network_node_policy.api import K8sSriovNetworkNodePolicyApi +from lib.k8s.sriov_network_node_policy.info import K8sSriovNetworkNodePolicyInfo + + +class K8sSriovNetworkNodePolicy( + K8sSriovNetworkNodePolicyApi, + K8sSriovNetworkNodePolicyInfo + ): + def __init__(self): + K8sSriovNetworkNodePolicyApi.__init__(self) + K8sSriovNetworkNodePolicyInfo.__init__(self) diff --git a/lib/k8s/sriov_network_node_policy/output.py b/lib/k8s/sriov_network_node_policy/output.py new file mode 100644 index 00000000..7e663d0b --- /dev/null +++ b/lib/k8s/sriov_network_node_policy/output.py @@ -0,0 +1,99 @@ +class K8sSriovNetworkNodePolicyOutput(): + def __init__(self): + pass + + def print_sriov_network_node_policies(self, info, title=False): + if title: + self.my_output.default( + 'SR-IOV Network Node Policy [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'resource_nameT', + 'device_typeT', + 'node_selectorT', + 'nic_selectorT', + 'vfs', + 'priorityT', + 'sriov_network_count', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Resource', + 'Device Type', + 'Node', + 'NIC', + 'VF', + 'Prio', + 'Srn', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['node_selectorT', 'nic_selectorT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_sriov_network_node_policies_srn(self, info, title=False): + if title: + self.my_output.default( + 'SR-IOV Network Node Policy - SR-IOV Network [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'resource_nameT', + 'sriov_network.namespace_name', + 'sriov_network.vlanT', + 'sriov_network.age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Resource', + 'Srn', + 'VLAN', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['sriov_network'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/sriov_network_node_state/__init__.py b/lib/k8s/sriov_network_node_state/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/sriov_network_node_state/api.py b/lib/k8s/sriov_network_node_state/api.py new file mode 100644 index 00000000..36c17f17 --- /dev/null +++ b/lib/k8s/sriov_network_node_state/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sSriovNetworkNodeStateApi(): + def __init__(self): + self.sriov_network_node_state_mo = None + + def get_sriov_network_node_state_mo(self, cache_enabled=True): + if cache_enabled: + if self.sriov_network_node_state_mo is not None: + return self.sriov_network_node_state_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='sriovnetwork.openshift.io/v1', + kind='SriovNetworkNodeState' + ) + self.sriov_network_node_state_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'sriov_network_node_state', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_sriov_network_node_state_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'sriov_network_node_state', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'sriov_network_node_state', + self.sriov_network_node_state_mo + ) + + return self.sriov_network_node_state_mo diff --git a/lib/k8s/sriov_network_node_state/info.py b/lib/k8s/sriov_network_node_state/info.py new file mode 100644 index 00000000..26d46a2f --- /dev/null +++ b/lib/k8s/sriov_network_node_state/info.py @@ -0,0 +1,285 @@ +import json + +from lib import filter_helper + + +class K8sSriovNetworkNodeStateInfo(): + def __init__(self): + self.sriov_network_node_state = None + + def get_sriov_network_node_state_info(self, sriov_network_node_state_mo): + if sriov_network_node_state_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + sriov_network_node_state_mo + ) + info.update(metadata_info) + + info['syncStatus'] = self.get(sriov_network_node_state_mo, 'status:syncStatus') + if info['syncStatus'] == 'Succeeded': + info['syncStatusTick'] = '\u2713' + info['__Output']['syncStatusTick'] = 'Green' + else: + info['syncStatusTick'] = '\u2717' + info['__Output']['syncStatusTick'] = 'Red' + + info['interface'] = [] + + interfaces_state_mo = self.get(sriov_network_node_state_mo, 'status:interfaces', on_error=[], on_none=[]) + for interface_state_mo in interfaces_state_mo: + interface_info = {} + interface_info['name'] = self.get(interface_state_mo, 'name') + interface_info['numVfs'] = self.get(interface_state_mo, 'totalvfs') + interface_info['pciAddress'] = self.get(interface_state_mo, 'pciAddress') + + interface_vfs_mo = self.get(interface_state_mo, 'Vfs', on_error=[], on_none=[]) + interface_info['vfs'] = [] + for interface_vf_mo in interface_vfs_mo: + vf_info = {} + vf_info['deviceId'] = self.get(interface_vf_mo, 'deviceID') + vf_info['driver'] = self.get(interface_vf_mo, 'driver') + vf_info['mac'] = self.get(interface_vf_mo, 'mac') + vf_info['macT'] = vf_info['mac'] + if vf_info['mac'] is None: + vf_info['macT'] = '--' + vf_info['mtu'] = self.get(interface_vf_mo, 'mtu') + vf_info['mtuT'] = vf_info['mtu'] + if vf_info['mtu'] is None: + vf_info['mtuT'] = '--' + vf_info['name'] = self.get(interface_vf_mo, 'name') + vf_info['nameT'] = vf_info['name'] + if vf_info['name'] is None: + vf_info['nameT'] = '--' + vf_info['pciAddress'] = self.get(interface_vf_mo, 'pciAddress') + vf_info['vendor'] = self.get(interface_vf_mo, 'vendor') + vf_info['vfId'] = self.get(interface_vf_mo, 'vfID') + interface_info['vfs'].append( + vf_info + ) + + interface_info['vfs'] = sorted( + interface_info['vfs'], + key=lambda i: i['vfId'] + ) + + interface_info['driver'] = self.get(interface_state_mo, 'driver') + interface_info['linkSpeed'] = self.get(interface_state_mo, 'linkSpeed') + interface_info['linkType'] = self.get(interface_state_mo, 'linkType') + interface_info['mac'] = self.get(interface_state_mo, 'mac') + interface_info['mtu'] = self.get(interface_state_mo, 'mtu') + interface_info['totalVfs'] = self.get(interface_state_mo, 'totalvfs') + interface_info['vendor'] = self.get(interface_state_mo, 'vendor') + interface_info['vendorT'] = interface_info['vendor'] + if interface_info['vendor'] in self.network_vendor: + interface_info['vendorT'] = '%s (%s)' % ( + self.network_vendor[interface_info['vendor']], + interface_info['vendor'] + ) + interface_info['deviceId'] = self.get(interface_state_mo, 'deviceID') + interface_info['deviceIdT'] = interface_info['deviceId'] + if interface_info['vendor'] in self.network_vendor_device: + if interface_info['deviceId'] in self.network_vendor_device[interface_info['vendor']]: + interface_info['deviceIdT'] = '%s (%s)' % ( + self.network_vendor_device[interface_info['vendor']][interface_info['deviceId']], + interface_info['deviceId'] + ) + + interface_info['vfUsed'] = len( + interface_info['vfs'] + ) + interface_info['vfUsage'] = '%s/%s' % ( + interface_info['vfUsed'], + interface_info['numVfs'] + ) + + interface_info['vfGroups'] = [] + + info['interface'].append( + interface_info + ) + + interfaces_mo = self.get(sriov_network_node_state_mo, 'spec:interfaces', on_error=[], on_none=[]) + for interface_mo in interfaces_mo: + for interface_info in info['interface']: + if self.get(interface_mo, 'name') == interface_info['name']: + interface_info['vfGroups'] = self.get(interface_mo, 'vfGroups') + interface_info['vfGroupsT'] = json.dumps(interface_info['vfGroups'], indent=4).split('\n') + + info['interface'] = sorted( + info['interface'], + key=lambda i: i['name'] + ) + + return info + + def get_sriov_network_node_states_info(self, cache_enabled=True): + if cache_enabled: + if self.sriov_network_node_state is not None: + return self.sriov_network_node_state + + managed_objects = self.get_sriov_network_node_state_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.sriov_network_node_state = [] + for managed_object in managed_objects: + sriov_network_node_state_info = {} + sriov_network_node_state_info['info'] = self.get_sriov_network_node_state_info( + managed_object + ) + sriov_network_node_state_info['mo'] = managed_object + self.sriov_network_node_state.append( + sriov_network_node_state_info + ) + + return self.sriov_network_node_state + + def match_sriov_network_node_interface_state(self, sriov_network_node_interface_state_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + + if key == 'name': + key_found = True + + if key == 'interface': + key_found = True + if not filter_helper.match_string(value, sriov_network_node_interface_state_info['name']): + return False + + if not key_found: + self.log.error( + 'match_sriov_network_node_interface_state', + 'Unsupported key: %s' % (key) + ) + + return True + + def match_sriov_network_node_interfaces_state(self, sriov_network_node_state_info, object_filter): + interface = [] + + for interface_info in sriov_network_node_state_info['interface']: + if self.match_sriov_network_node_interface_state(interface_info, object_filter): + interface.append( + interface_info + ) + + return interface + + def match_sriov_network_node_state(self, sriov_network_node_state_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, sriov_network_node_state_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (sriov_network_node_state_info['namespace'], sriov_network_node_state_info['name'])): + return False + + if key == 'interface': + key_found = True + found = False + for interface_info in sriov_network_node_state_info['interface']: + if filter_helper.match_string(value, interface_info['name']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_sriov_network_node_state', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_sriov_network_node_states(self, object_filter=None, return_mo=False, cache_enabled=True): + all_sriov_network_node_states = self.get_sriov_network_node_states_info(cache_enabled=cache_enabled) + if all_sriov_network_node_states is None: + return None + + sriov_network_node_states = [] + + for sriov_network_node_state_info in all_sriov_network_node_states: + if not self.match_sriov_network_node_state(sriov_network_node_state_info['info'], object_filter): + continue + + sriov_network_node_state_info['info']['interface'] = self.match_sriov_network_node_interfaces_state( + sriov_network_node_state_info['info'], + object_filter + ) + if len(sriov_network_node_state_info['info']['interface']) == 0: + continue + + if return_mo: + sriov_network_node_states.append( + sriov_network_node_state_info['mo'] + ) + continue + + sriov_network_node_states.append( + sriov_network_node_state_info['info'] + ) + + return sriov_network_node_states + + def is_sriov_network_node_state(self, name, namespace='openshift-sriov-network-operator', cache_enabled=True): + if self.get_sriov_network_node_state(name, namespace=namespace, cache_enabled=cache_enabled) is None: + return False + return True + + def get_sriov_network_node_state(self, name, namespace='openshift-sriov-network-operator', return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + sriov_network_node_states = self.get_sriov_network_node_states( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if sriov_network_node_states is None: + return None + + if len(sriov_network_node_states) == 1: + return sriov_network_node_states[0] + + return None + + def get_sriov_network_node_state_with_node_interface(self, node_name, interface_name): + object_filter = [] + object_filter.append( + 'name:%s' % (node_name) + ) + object_filter.append( + 'interface:%s' % (interface_name) + ) + state = self.get_sriov_network_node_states( + object_filter=object_filter + ) + return state diff --git a/lib/k8s/sriov_network_node_state/main.py b/lib/k8s/sriov_network_node_state/main.py new file mode 100644 index 00000000..93f6b2be --- /dev/null +++ b/lib/k8s/sriov_network_node_state/main.py @@ -0,0 +1,20 @@ +from lib.k8s.sriov_network_node_state.api import K8sSriovNetworkNodeStateApi +from lib.k8s.sriov_network_node_state.info import K8sSriovNetworkNodeStateInfo + + +class K8sSriovNetworkNodeState( + K8sSriovNetworkNodeStateApi, + K8sSriovNetworkNodeStateInfo + ): + def __init__(self): + K8sSriovNetworkNodeStateApi.__init__(self) + K8sSriovNetworkNodeStateInfo.__init__(self) + + self.network_vendor = {} + self.network_vendor['1137'] = 'Cisco' + self.network_vendor['8086'] = 'Intel' + + self.network_vendor_device = {} + self.network_vendor_device['8086'] = {} + self.network_vendor_device['8086']['158b'] = 'Ethernet Controller XXV710 for 25GbE SFP28' + self.network_vendor_device['1137'] = {} diff --git a/lib/k8s/sriov_network_node_state/output.py b/lib/k8s/sriov_network_node_state/output.py new file mode 100644 index 00000000..60fb962a --- /dev/null +++ b/lib/k8s/sriov_network_node_state/output.py @@ -0,0 +1,209 @@ +from lib import filter_helper + + +class K8sSriovNetworkNodeStateOutput(): + def __init__(self): + pass + + def print_sriov_network_nodes_state(self, info, title=False): + if title: + self.my_output.default( + 'SR-IOV Network Node State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_items = [] + for item in info: + for interface_info in item['interface']: + new_item = {} + new_item['node'] = item['name'] + new_item['syncStatusTick'] = item['syncStatusTick'] + new_item['policyCount'] = len( + interface_info['vfGroups'] + ) + for key in interface_info: + new_item[key] = interface_info[key] + + new_item['deviceIdTT'] = filter_helper.get_string_chunks( + new_item['deviceIdT'], + 30 + ) + + new_items.append( + new_item + ) + + order = [ + 'node', + 'syncStatusTick', + 'name', + 'policyCount', + 'vfUsage', + 'pciAddress', + 'driver', + 'vendorT', + 'deviceIdTT', + 'mac', + 'mtu', + 'linkSpeed' + ] + + headers = [ + 'Node', + 'Sync', + 'Intf', + 'Pol', + 'VF', + 'PCI', + 'Driver', + 'Vendor', + 'Device', + 'MAC', + 'MTU', + 'Speed' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_items, + order, + ['deviceIdTT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_sriov_network_nodes_state_policy(self, info, title=False): + new_info = [] + for item in info: + for interface in item['interface']: + new_item = {} + new_item['namespace'] = item['namespace'] + new_item['name'] = item['name'] + new_item['interfaceName'] = interface['name'] + new_item['vfGroups'] = interface['vfGroups'] + if len(new_item['vfGroups']) == 0: + empty = {} + for key in ['deviceType', 'policyName', 'resourceName', 'vfRange']: + empty[key] = '--' + new_item['vfGroups'].append(empty) + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'SR-IOV Network Node State - VF Groups [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'interfaceName', + 'vfGroups.deviceType', + 'vfGroups.policyName', + 'vfGroups.resourceName', + 'vfGroups.vfRange' + ] + + headers = [ + 'Node', + 'Interface', + 'Device Type', + 'Policy', + 'Resource', + 'VF Range' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['vfGroups'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_sriov_network_nodes_state_vf(self, info, title=False): + new_info = [] + for item in info: + for interface in item['interface']: + new_item = {} + new_item['namespace'] = item['namespace'] + new_item['name'] = item['name'] + new_item['interfaceName'] = interface['name'] + new_item['vfs'] = interface['vfs'] + if len(new_item['vfs']) == 0: + empty = {} + for key in ['vfId', 'nameT', 'macT', 'mtuT', 'pciAddress', 'driver']: + empty[key] = '--' + new_item['vfs'].append(empty) + new_info.append( + new_item + ) + + if title: + self.my_output.default( + 'SR-IOV Network Node State - VF [#%s]' % (len(new_info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'interfaceName', + 'vfs.vfId', + 'vfs.nameT', + 'vfs.macT', + 'vfs.mtuT', + 'vfs.pciAddress', + 'vfs.driver' + ] + + headers = [ + 'Node', + 'Interface', + 'VF ID', + 'VF Name', + 'MAC', + 'MTU', + 'PCI', + 'Driver' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['vfs'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/stateful_set/__init__.py b/lib/k8s/stateful_set/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/stateful_set/api.py b/lib/k8s/stateful_set/api.py new file mode 100644 index 00000000..9bd4bfb8 --- /dev/null +++ b/lib/k8s/stateful_set/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sStatefulSetApi(): + def __init__(self): + self.stateful_set_mo = None + + def get_stateful_set_mo(self, cache_enabled=True): + if cache_enabled: + if self.stateful_set_mo is not None: + return self.stateful_set_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='apps/v1', + kind='StatefulSet' + ) + self.stateful_set_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'stateful_set', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_stateful_set_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'stateful_set', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'stateful_set', + self.stateful_set_mo + ) + + return self.stateful_set_mo diff --git a/lib/k8s/stateful_set/info.py b/lib/k8s/stateful_set/info.py new file mode 100644 index 00000000..918d9b1f --- /dev/null +++ b/lib/k8s/stateful_set/info.py @@ -0,0 +1,98 @@ +from lib import filter_helper + + +class K8sStatefulSetInfo(): + def __init__(self): + self.stateful_set = None + + def get_stateful_set_info(self, stateful_set_mo): + if stateful_set_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + stateful_set_mo + ) + info.update(metadata_info) + + return info + + def get_stateful_sets_info(self, cache_enabled=True): + if cache_enabled: + if self.stateful_set is not None: + return self.stateful_set + + managed_objects = self.get_stateful_set_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.stateful_set = [] + for managed_object in managed_objects: + stateful_set_info = {} + stateful_set_info['info'] = self.get_stateful_set_info( + managed_object + ) + stateful_set_info['mo'] = managed_object + self.stateful_set.append( + stateful_set_info + ) + + return self.stateful_set + + def match_stateful_set(self, stateful_set_info, stateful_set_filter): + if stateful_set_filter is None or len(stateful_set_filter) == 0: + return True + + for ap_rule in stateful_set_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, stateful_set_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (stateful_set_info['namespace'], stateful_set_info['name'])): + return False + + if key == 'owner': + key_found = True + if not filter_helper.match_namespace_name(value, stateful_set_info['owner']): + return False + + if not key_found: + self.log.error( + 'match_stateful_set', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_stateful_sets(self, object_filter=None, return_mo=False, cache_enabled=True): + all_stateful_sets = self.get_stateful_sets_info(cache_enabled=cache_enabled) + if all_stateful_sets is None: + return None + + stateful_sets = [] + + for stateful_set_info in all_stateful_sets: + if not self.match_stateful_set(stateful_set_info['info'], object_filter): + continue + + if return_mo: + stateful_sets.append( + stateful_set_info['mo'] + ) + continue + + stateful_sets.append( + stateful_set_info['info'] + ) + + return stateful_sets diff --git a/lib/k8s/stateful_set/main.py b/lib/k8s/stateful_set/main.py new file mode 100644 index 00000000..8e464350 --- /dev/null +++ b/lib/k8s/stateful_set/main.py @@ -0,0 +1,11 @@ +from lib.k8s.stateful_set.api import K8sStatefulSetApi +from lib.k8s.stateful_set.info import K8sStatefulSetInfo + + +class K8sStatefulSet( + K8sStatefulSetApi, + K8sStatefulSetInfo + ): + def __init__(self): + K8sStatefulSetApi.__init__(self) + K8sStatefulSetInfo.__init__(self) diff --git a/lib/k8s/stateful_set/output.py b/lib/k8s/stateful_set/output.py new file mode 100644 index 00000000..6294810f --- /dev/null +++ b/lib/k8s/stateful_set/output.py @@ -0,0 +1,87 @@ +class K8sStatefulSetOutput(): + def __init__(self): + pass + + def print_stateful_sets(self, info, title=False): + if title: + self.my_output.default( + 'Stateful Set [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_stateful_sets_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Stateful Set - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['namespace_nameT'] = [] + item['namespace_nameT'].append( + item['namespace'] + ) + item['namespace_nameT'].append( + item['name'] + ) + + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_nameT', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'Stateful Set', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['namespace_nameT', 'labelT', 'annotationT', 'ownerT'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/storage_class/__init__.py b/lib/k8s/storage_class/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/storage_class/api.py b/lib/k8s/storage_class/api.py new file mode 100644 index 00000000..dc3413b3 --- /dev/null +++ b/lib/k8s/storage_class/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sStorageClassApi(): + def __init__(self): + self.storage_class_mo = None + + def get_storage_class_mo(self, cache_enabled=True): + if cache_enabled: + if self.storage_class_mo is not None: + return self.storage_class_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='storage.k8s.io/v1', + kind='StorageClass' + ) + self.storage_class_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'storage_class', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_storage_class_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'storage_class', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'storage_class', + self.storage_class_mo + ) + + return self.storage_class_mo diff --git a/lib/k8s/storage_class/info.py b/lib/k8s/storage_class/info.py new file mode 100644 index 00000000..8dfaab5c --- /dev/null +++ b/lib/k8s/storage_class/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sStorageClassInfo(): + def __init__(self): + self.storage_class = None + + def get_storage_class_info(self, storage_class_mo): + if storage_class_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + storage_class_mo + ) + info.update(metadata_info) + + return info + + def get_storage_classes_info(self, cache_enabled=True): + if cache_enabled: + if self.storage_class is not None: + return self.storage_class + + managed_objects = self.get_storage_class_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.storage_class = [] + for managed_object in managed_objects: + storage_class_info = {} + storage_class_info['info'] = self.get_storage_class_info( + managed_object + ) + storage_class_info['mo'] = managed_object + self.storage_class.append( + storage_class_info + ) + + return self.storage_class + + def match_storage_class(self, storage_class_info, storage_class_filter): + if storage_class_filter is None or len(storage_class_filter) == 0: + return True + + for ap_rule in storage_class_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_storage_class', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_storage_classes(self, object_filter=None, return_mo=False, cache_enabled=True): + all_storage_classes = self.get_storage_classes_info(cache_enabled=cache_enabled) + if all_storage_classes is None: + return None + + storage_classes = [] + + for storage_class_info in all_storage_classes: + if not self.match_storage_class(storage_class_info['info'], object_filter): + continue + + if return_mo: + storage_classes.append( + storage_class_info['mo'] + ) + continue + + storage_classes.append( + storage_class_info['info'] + ) + + return storage_classes diff --git a/lib/k8s/storage_class/main.py b/lib/k8s/storage_class/main.py new file mode 100644 index 00000000..7e00c2a0 --- /dev/null +++ b/lib/k8s/storage_class/main.py @@ -0,0 +1,11 @@ +from lib.k8s.storage_class.api import K8sStorageClassApi +from lib.k8s.storage_class.info import K8sStorageClassInfo + + +class K8sStorageClass( + K8sStorageClassApi, + K8sStorageClassInfo + ): + def __init__(self): + K8sStorageClassApi.__init__(self) + K8sStorageClassInfo.__init__(self) diff --git a/lib/k8s/storage_class/output.py b/lib/k8s/storage_class/output.py new file mode 100644 index 00000000..2c708c3a --- /dev/null +++ b/lib/k8s/storage_class/output.py @@ -0,0 +1,33 @@ +class K8sStorageClassOutput(): + def __init__(self): + pass + + def print_storage_classes(self, info, title=False): + if title: + self.my_output.default( + 'Storage Class [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/subscription/__init__.py b/lib/k8s/subscription/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/subscription/api.py b/lib/k8s/subscription/api.py new file mode 100644 index 00000000..8840a65f --- /dev/null +++ b/lib/k8s/subscription/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sSubscriptionApi(): + def __init__(self): + self.subscription_mo = None + + def get_subscription_mo(self, cache_enabled=True): + if cache_enabled: + if self.subscription_mo is not None: + return self.subscription_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='operators.coreos.com/v1alpha1', + kind='Subscription' + ) + self.subscription_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'subscription', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_subscription_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'subscription', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'subscription', + self.subscription_mo + ) + + return self.subscription_mo diff --git a/lib/k8s/subscription/info.py b/lib/k8s/subscription/info.py new file mode 100644 index 00000000..709be6ff --- /dev/null +++ b/lib/k8s/subscription/info.py @@ -0,0 +1,138 @@ +from lib import filter_helper + + +class K8sSubscriptionInfo(): + def __init__(self): + self.subscription = None + + def get_subscription_info(self, subscription_mo): + if subscription_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + subscription_mo + ) + info.update(metadata_info) + + info['channel'] = self.get(subscription_mo, 'spec:channel') + info['channelT'] = info['channel'] + if info['channel'] is None: + info['channelT'] = '--' + + info['package'] = self.get(subscription_mo, 'spec:name') + info['source'] = self.get(subscription_mo, 'spec:source') + + info['install_plan'] = self.get(subscription_mo, 'spec:installPlanApproval') + info['current_csv'] = self.get(subscription_mo, 'status:currentCSV') + info['installed_csv'] = self.get(subscription_mo, 'status:installedCSV') + if info['current_csv'] == info['installed_csv']: + info['is_latest_csv'] = True + info['csvTick'] = '\u2713' + info['__Output']['csvTick'] = 'Green' + else: + info['is_latest_csv'] = False + info['csvTick'] = '\u2717' + info['__Output']['csvTick'] = 'Red' + + return info + + def get_subscriptions_info(self, cache_enabled=True): + if cache_enabled: + if self.subscription is not None: + return self.subscription + + managed_objects = self.get_subscription_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.subscription = [] + for managed_object in managed_objects: + subscription_info = {} + subscription_info['info'] = self.get_subscription_info( + managed_object + ) + subscription_info['mo'] = managed_object + self.subscription.append( + subscription_info + ) + + return self.subscription + + def match_subscription(self, subscription_info, object_filter): + if object_filter is None or len(object_filter) == 0: + return True + + for rule in object_filter: + (key, value) = rule.split(':') + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, subscription_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (subscription_info['namespace'], subscription_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_subscription', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_subscriptions(self, object_filter=None, return_mo=False, cache_enabled=True): + all_subscriptions = self.get_subscriptions_info(cache_enabled=cache_enabled) + if all_subscriptions is None: + return None + + subscriptions = [] + + for subscription_info in all_subscriptions: + if not self.match_subscription(subscription_info['info'], object_filter): + continue + + if return_mo: + subscriptions.append( + subscription_info['mo'] + ) + continue + + subscriptions.append( + subscription_info['info'] + ) + + return subscriptions + + def is_subscription(self, namespace, name, cache_enabled=True): + if self.get_subscription(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def get_subscription(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + object_filter.append( + 'name:%s' % (name) + ) + subscriptions = self.get_subscriptions( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if subscriptions is None: + return None + + if len(subscriptions) == 1: + return subscriptions[0] + + return None diff --git a/lib/k8s/subscription/main.py b/lib/k8s/subscription/main.py new file mode 100644 index 00000000..f45507b9 --- /dev/null +++ b/lib/k8s/subscription/main.py @@ -0,0 +1,11 @@ +from lib.k8s.subscription.api import K8sSubscriptionApi +from lib.k8s.subscription.info import K8sSubscriptionInfo + + +class K8sSubscription( + K8sSubscriptionApi, + K8sSubscriptionInfo + ): + def __init__(self): + K8sSubscriptionApi.__init__(self) + K8sSubscriptionInfo.__init__(self) diff --git a/lib/k8s/subscription/output.py b/lib/k8s/subscription/output.py new file mode 100644 index 00000000..9d7c9ae9 --- /dev/null +++ b/lib/k8s/subscription/output.py @@ -0,0 +1,49 @@ +class K8sSubscriptionOutput(): + def __init__(self): + pass + + def print_subscriptions(self, info, title=False): + if title: + self.my_output.default( + 'Subscription - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace', + 'name', + 'package', + 'source', + 'channelT', + 'install_plan', + 'installed_csv', + 'csvTick', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Package', + 'Source', + 'Channel', + 'Install', + 'CSV', + 'Latest', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=False, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/thanos_ruler/__init__.py b/lib/k8s/thanos_ruler/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/thanos_ruler/api.py b/lib/k8s/thanos_ruler/api.py new file mode 100644 index 00000000..d7717458 --- /dev/null +++ b/lib/k8s/thanos_ruler/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sThanosRulerApi(): + def __init__(self): + self.thanos_ruler_mo = None + + def get_thanos_ruler_mo(self, cache_enabled=True): + if cache_enabled: + if self.thanos_ruler_mo is not None: + return self.thanos_ruler_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='monitoring.coreos.com/v1', + kind='ThanosRuler' + ) + self.thanos_ruler_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'thanos_ruler', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_thanos_ruler_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'thanos_ruler', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'thanos_ruler', + self.thanos_ruler_mo + ) + + return self.thanos_ruler_mo diff --git a/lib/k8s/thanos_ruler/info.py b/lib/k8s/thanos_ruler/info.py new file mode 100644 index 00000000..9cb945d0 --- /dev/null +++ b/lib/k8s/thanos_ruler/info.py @@ -0,0 +1,78 @@ +from lib import filter_helper + + +class K8sThanosRulerInfo(): + def __init__(self): + self.thanos_ruler = None + + def get_thanos_ruler_info(self, thanos_ruler_mo): + if thanos_ruler_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_thanos_rulers_info(self, cache_enabled=True): + if cache_enabled: + if self.thanos_ruler is not None: + return self.thanos_ruler + + managed_objects = self.get_thanos_ruler_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.thanos_ruler = [] + for managed_object in managed_objects: + thanos_ruler_info = {} + thanos_ruler_info['info'] = self.get_thanos_ruler_info( + managed_object + ) + thanos_ruler_info['mo'] = managed_object + self.thanos_ruler.append( + thanos_ruler_info + ) + + return self.thanos_ruler + + def match_thanos_ruler(self, thanos_ruler_info, thanos_ruler_filter): + if thanos_ruler_filter is None or len(thanos_ruler_filter) == 0: + return True + + for ap_rule in thanos_ruler_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_thanos_ruler', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_thanos_rulers(self, object_filter=None, return_mo=False, cache_enabled=True): + all_thanos_rulers = self.get_thanos_rulers_info(cache_enabled=cache_enabled) + if all_thanos_rulers is None: + return None + + thanos_rulers = [] + + for thanos_ruler_info in all_thanos_rulers: + if not self.match_thanos_ruler(thanos_ruler_info['info'], object_filter): + continue + + if return_mo: + thanos_rulers.append( + thanos_ruler_info['mo'] + ) + continue + + thanos_rulers.append( + thanos_ruler_info['info'] + ) + + return thanos_rulers diff --git a/lib/k8s/thanos_ruler/main.py b/lib/k8s/thanos_ruler/main.py new file mode 100644 index 00000000..e5feb2e1 --- /dev/null +++ b/lib/k8s/thanos_ruler/main.py @@ -0,0 +1,11 @@ +from lib.k8s.thanos_ruler.api import K8sThanosRulerApi +from lib.k8s.thanos_ruler.info import K8sThanosRulerInfo + + +class K8sThanosRuler( + K8sThanosRulerApi, + K8sThanosRulerInfo + ): + def __init__(self): + K8sThanosRulerApi.__init__(self) + K8sThanosRulerInfo.__init__(self) diff --git a/lib/k8s/thanos_ruler/output.py b/lib/k8s/thanos_ruler/output.py new file mode 100644 index 00000000..1b276a3c --- /dev/null +++ b/lib/k8s/thanos_ruler/output.py @@ -0,0 +1,33 @@ +class K8sThanosRulerOutput(): + def __init__(self): + pass + + def print_thanos_rulers(self, info, title=False): + if title: + self.my_output.default( + 'Thanos Ruler [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/tuned/__init__.py b/lib/k8s/tuned/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/tuned/api.py b/lib/k8s/tuned/api.py new file mode 100644 index 00000000..27f53c47 --- /dev/null +++ b/lib/k8s/tuned/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sTunedApi(): + def __init__(self): + self.tuned_mo = None + + def get_tuned_mo(self, cache_enabled=True): + if cache_enabled: + if self.tuned_mo is not None: + return self.tuned_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='tuned.openshift.io/v1', + kind='Tuned' + ) + self.tuned_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'tuned', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_tuned_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'tuned', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'tuned', + self.tuned_mo + ) + + return self.tuned_mo diff --git a/lib/k8s/tuned/info.py b/lib/k8s/tuned/info.py new file mode 100644 index 00000000..a8f2c04f --- /dev/null +++ b/lib/k8s/tuned/info.py @@ -0,0 +1,114 @@ +from lib import filter_helper + + +class K8sTunedInfo(): + def __init__(self): + self.tuned = None + + def get_tuned_info(self, tuned_mo): + if tuned_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + tuned_mo + ) + info.update(metadata_info) + + info['profile'] = self.get( + tuned_mo, + 'spec:profile', + on_error=[], + on_none=[] + ) + + info['profile_names'] = [] + for profile_info in info['profile']: + if profile_info['name'] not in info['profile_names']: + info['profile_names'].append( + profile_info['name'] + ) + + info['recommend'] = self.get( + tuned_mo, + 'spec:recommend', + on_error=[], + on_none=[] + ) + + return info + + def get_tuneds_info(self, cache_enabled=True): + if cache_enabled: + if self.tuned is not None: + return self.tuned + + managed_objects = self.get_tuned_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.tuned = [] + for managed_object in managed_objects: + tuned_info = {} + tuned_info['info'] = self.get_tuned_info( + managed_object + ) + tuned_info['mo'] = managed_object + self.tuned.append( + tuned_info + ) + + return self.tuned + + def match_tuned(self, tuned_info, tuned_filter): + if tuned_filter is None or len(tuned_filter) == 0: + return True + + for ap_rule in tuned_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, tuned_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (tuned_info['namespace'], tuned_info['name'])): + return False + + if not key_found: + self.log.error( + 'match_tuned', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_tuneds(self, object_filter=None, return_mo=False, cache_enabled=True): + all_tuneds = self.get_tuneds_info(cache_enabled=cache_enabled) + if all_tuneds is None: + return None + + tuneds = [] + + for tuned_info in all_tuneds: + if not self.match_tuned(tuned_info['info'], object_filter): + continue + + if return_mo: + tuneds.append( + tuned_info['mo'] + ) + continue + + tuneds.append( + tuned_info['info'] + ) + + return tuneds diff --git a/lib/k8s/tuned/main.py b/lib/k8s/tuned/main.py new file mode 100644 index 00000000..6efa1b88 --- /dev/null +++ b/lib/k8s/tuned/main.py @@ -0,0 +1,11 @@ +from lib.k8s.tuned.api import K8sTunedApi +from lib.k8s.tuned.info import K8sTunedInfo + + +class K8sTuned( + K8sTunedApi, + K8sTunedInfo + ): + def __init__(self): + K8sTunedApi.__init__(self) + K8sTunedInfo.__init__(self) diff --git a/lib/k8s/tuned/output.py b/lib/k8s/tuned/output.py new file mode 100644 index 00000000..b08bffbe --- /dev/null +++ b/lib/k8s/tuned/output.py @@ -0,0 +1,51 @@ +class K8sTunedOutput(): + def __init__(self): + pass + + def print_tuneds(self, info, title=False): + if title: + self.my_output.default( + 'Tuned [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace', + 'name', + 'ownerT', + 'profile_names', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Owner', + 'Profile', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['profile_names', 'ownerT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/version/__init__.py b/lib/k8s/version/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/version/api.py b/lib/k8s/version/api.py new file mode 100644 index 00000000..2e38ad75 --- /dev/null +++ b/lib/k8s/version/api.py @@ -0,0 +1,59 @@ +import time +import traceback + + +class K8sVersionApi(): + def __init__(self): + self.version_mo = None + + def get_version_mo(self, cache_enabled=True): + if cache_enabled: + if self.version_mo is not None: + return self.version_mo + + api_handler = self.get_api(api_type='version') + if api_handler is None: + return None + + ocp_handler = self.get_api(cluster_type='ocp') + + try: + start_time = int(time.time() * 1000) + k8s_version = api_handler.get_code().to_dict() + + ocp_version = None + if ocp_handler is not None: + response = ocp_handler.resources.get( + api_version='config.openshift.io/v1', + kind='ClusterVersion' + ) + ocp_version = response.get().to_dict()['items'][0] + + version_mo = {} + version_mo['k8s'] = k8s_version + version_mo['ocp'] = ocp_version + self.version_mo = [version_mo] + + self.log.k8s( + 'get', + 'version', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_version_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'version', + False, + int(time.time() * 1000) - start_time + ) + return None + + self.log.k8s_mo( + 'version', + self.version_mo + ) + + return self.version_mo diff --git a/lib/k8s/version/info.py b/lib/k8s/version/info.py new file mode 100644 index 00000000..561ae75d --- /dev/null +++ b/lib/k8s/version/info.py @@ -0,0 +1,90 @@ +import json +from lib import filter_helper + + +class K8sVersionInfo(): + def __init__(self): + self.version = None + + def get_version_info(self, version_mo): + if version_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['version'] = self.get(version_mo, 'k8s:git_version') + info['build_date'] = self.get(version_mo, 'k8s:build_date') + info['platform'] = self.get(version_mo, 'k8s:platform') + info['ocp'] = self.get(version_mo, 'ocp:status:desired:version', on_error='--', on_none='--') + + return info + + def get_versions_info(self, cache_enabled=True): + if cache_enabled: + if self.version is not None: + return self.version + + managed_objects = self.get_version_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.version = [] + for managed_object in managed_objects: + version_info = {} + version_info['info'] = self.get_version_info( + managed_object + ) + version_info['mo'] = managed_object + self.version.append( + version_info + ) + + return self.version + + def match_version(self, version_info, version_filter): + if version_filter is None or len(version_filter) == 0: + return True + + for ap_rule in version_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_version', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_versions(self, object_filter=None, return_mo=False, cache_enabled=True): + all_versions = self.get_versions_info(cache_enabled=cache_enabled) + if all_versions is None: + return None + + versions = [] + + for version_info in all_versions: + if not self.match_version(version_info['info'], object_filter): + continue + + if return_mo: + versions.append( + version_info['mo'] + ) + continue + + versions.append( + version_info['info'] + ) + + return versions + + def get_version(self): + versions = self.get_versions() + if versions is None or len(versions) != 1: + return None + return versions[0] diff --git a/lib/k8s/version/main.py b/lib/k8s/version/main.py new file mode 100644 index 00000000..4ae5c5f2 --- /dev/null +++ b/lib/k8s/version/main.py @@ -0,0 +1,11 @@ +from lib.k8s.version.api import K8sVersionApi +from lib.k8s.version.info import K8sVersionInfo + + +class K8sVersion( + K8sVersionApi, + K8sVersionInfo + ): + def __init__(self): + K8sVersionApi.__init__(self) + K8sVersionInfo.__init__(self) diff --git a/lib/k8s/version/output.py b/lib/k8s/version/output.py new file mode 100644 index 00000000..0ac3dae6 --- /dev/null +++ b/lib/k8s/version/output.py @@ -0,0 +1,39 @@ +class K8sVersionOutput(): + def __init__(self): + pass + + def print_versions(self, info, title=False): + if title: + self.my_output.default( + 'K8s Cluster Version [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'version', + 'platform', + 'build_date', + 'ocp' + ] + + headers = [ + 'Version', + 'Platform', + 'Build Date', + 'Openshift' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine/__init__.py b/lib/k8s/virtual_machine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine/api.py b/lib/k8s/virtual_machine/api.py new file mode 100644 index 00000000..7383f998 --- /dev/null +++ b/lib/k8s/virtual_machine/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineApi(): + def __init__(self): + self.virtual_machine_mo = None + + def get_virtual_machine_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_mo is not None: + return self.virtual_machine_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='VirtualMachine' + ) + self.virtual_machine_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine', + self.virtual_machine_mo + ) + + return self.virtual_machine_mo diff --git a/lib/k8s/virtual_machine/info.py b/lib/k8s/virtual_machine/info.py new file mode 100644 index 00000000..242d1386 --- /dev/null +++ b/lib/k8s/virtual_machine/info.py @@ -0,0 +1,168 @@ +from lib import filter_helper + + +class K8sVirtualMachineInfo(): + def __init__(self): + self.virtual_machine = None + + def get_virtual_machine_info(self, virtual_machine_mo): + if virtual_machine_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_mo + ) + info.update(metadata_info) + + info['dv'] = [] + dvs_mo = self.get(virtual_machine_mo, 'spec:dataVolumeTemplates', on_error=[], on_none=[]) + for dv_mo in dvs_mo: + dv_info = {} + dv_info['namespace'] = self.get(dv_mo, 'metadata:namespace') + dv_info['name'] = self.get(dv_mo, 'metadata:name') + dv_info['storage'] = self.get(dv_mo, 'spec:pvc:resources:requests:storage') + dv_info['source'] = '--' + pvc_source = self.get(dv_mo, 'spec:source:pvc') + if pvc_source is not None: + dv_info['source'] = 'pvc:%s:%s' % ( + self.get(pvc_source, 'namespace'), + self.get(pvc_source, 'name') + ) + info['dv'].append( + dv_info + ) + + info['cores'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:cpu:cores') + info['sockets'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:cpu:sockets') + info['threads'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:cpu:threads') + info['memory'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:resources:requests:memory') + + info['interface'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:devices:interfaces', on_error=[], on_none=[]) + for interface in info['interface']: + interface['info'] = interface['name'] + if 'masquerade' in interface: + interface['info'] = '%s (masq)' % (interface['name']) + if 'sriov' in interface: + interface['info'] = '%s (sriov)' % (interface['name']) + + info['disk'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:devices:disks', on_error=[], on_none=[]) + for disk in info['disk']: + disk['info'] = disk['name'] + + info['created'] = self.get(virtual_machine_mo, 'status:ready', on_error=False, on_none=False) + if info['created']: + info['createdTick'] = '\u2713' + info['__Output']['createdTick'] = 'Green' + else: + info['createdTick'] = '\u2717' + info['__Output']['createdTick'] = 'Red' + + info['ready'] = self.get(virtual_machine_mo, 'status:ready', on_error=False, on_none=False) + if info['ready']: + info['readyTick'] = '\u2713' + info['__Output']['readyTick'] = 'Green' + else: + info['readyTick'] = '\u2717' + info['__Output']['readyTick'] = 'Red' + + info['status'] = self.get(virtual_machine_mo, 'status:printableStatus') + if info['status'] == 'Running': + info['__Output']['status'] = 'Green' + if info['status'] == 'Provisioning': + info['__Output']['status'] = 'Yellow' + + return info + + def get_virtual_machines_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine is not None: + return self.virtual_machine + + managed_objects = self.get_virtual_machine_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine = [] + for managed_object in managed_objects: + virtual_machine_info = {} + virtual_machine_info['info'] = self.get_virtual_machine_info( + managed_object + ) + virtual_machine_info['mo'] = managed_object + self.virtual_machine.append( + virtual_machine_info + ) + + return self.virtual_machine + + def match_virtual_machine(self, virtual_machine_info, virtual_machine_filter): + if virtual_machine_filter is None or len(virtual_machine_filter) == 0: + return True + + for ap_rule in virtual_machine_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (virtual_machine_info['namespace'], virtual_machine_info['name'])): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['namespace']): + return False + + if not key_found: + self.log.error( + 'match_virtual_machine', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machines(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machines = self.get_virtual_machines_info(cache_enabled=cache_enabled) + if all_virtual_machines is None: + return None + + virtual_machines = [] + + for virtual_machine_info in all_virtual_machines: + if not self.match_virtual_machine(virtual_machine_info['info'], object_filter): + continue + + if return_mo: + virtual_machines.append( + virtual_machine_info['mo'] + ) + continue + + virtual_machines.append( + virtual_machine_info['info'] + ) + + return virtual_machines + + def get_virtual_machine(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append('namespace:%s' % (namespace)) + object_filter.append('name:%s' % (name)) + instances = self.get_virtual_machines( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if instances is None or len(instances) != 1: + return None + return instances[0] + + def is_virtual_machine(self, namespace, name, cache_enabled=True): + if self.get_virtual_machine(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True diff --git a/lib/k8s/virtual_machine/main.py b/lib/k8s/virtual_machine/main.py new file mode 100644 index 00000000..106fd560 --- /dev/null +++ b/lib/k8s/virtual_machine/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine.api import K8sVirtualMachineApi +from lib.k8s.virtual_machine.info import K8sVirtualMachineInfo + + +class K8sVirtualMachine( + K8sVirtualMachineApi, + K8sVirtualMachineInfo + ): + def __init__(self): + K8sVirtualMachineApi.__init__(self) + K8sVirtualMachineInfo.__init__(self) diff --git a/lib/k8s/virtual_machine/output.py b/lib/k8s/virtual_machine/output.py new file mode 100644 index 00000000..4cbe4ad9 --- /dev/null +++ b/lib/k8s/virtual_machine/output.py @@ -0,0 +1,148 @@ +class K8sVirtualMachineOutput(): + def __init__(self): + pass + + def print_virtual_machines(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'cores', + 'memory', + 'disk.info', + 'interface.info', + 'createdTick', + 'readyTick', + 'status', + 'age' + ] + + headers = [ + 'VM', + 'CPU', + 'Memory', + 'Disks', + 'Interfaces', + 'Created', + 'Ready', + 'Status', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disk', 'interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machines_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_name', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'VM', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['annotationT', 'labelT', 'ownerT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machines_dv(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine - Data Volume [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + for dv_item in item['dv']: + dv_item['namespace_name'] = '%s/%s' % ( + dv_item['namespace'], + dv_item['name'] + ) + + order = [ + 'namespace_name', + 'disk.info', + 'dv.namespace_name', + 'dv.storage', + 'dv.source' + ] + + headers = [ + 'VM', + 'Disks', + 'DV Name', + 'DV Storage', + 'DV Source' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disk', 'dv'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/k8s/virtual_machine_clone/__init__.py b/lib/k8s/virtual_machine_clone/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_clone/api.py b/lib/k8s/virtual_machine_clone/api.py new file mode 100644 index 00000000..fd497dea --- /dev/null +++ b/lib/k8s/virtual_machine_clone/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineCloneApi(): + def __init__(self): + self.virtual_machine_clone_mo = None + + def get_virtual_machine_clone_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_clone_mo is not None: + return self.virtual_machine_clone_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='clone.kubevirt.io/v1alpha1', + kind='VirtualMachineClone' + ) + self.virtual_machine_clone_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_clone', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_clone_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_clone', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_clone', + self.virtual_machine_clone_mo + ) + + return self.virtual_machine_clone_mo diff --git a/lib/k8s/virtual_machine_clone/info.py b/lib/k8s/virtual_machine_clone/info.py new file mode 100644 index 00000000..77bbfe98 --- /dev/null +++ b/lib/k8s/virtual_machine_clone/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineCloneInfo(): + def __init__(self): + self.virtual_machine_clone = None + + def get_virtual_machine_clone_info(self, virtual_machine_clone_mo): + if virtual_machine_clone_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_clone_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_clones_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_clone is not None: + return self.virtual_machine_clone + + managed_objects = self.get_virtual_machine_clone_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_clone = [] + for managed_object in managed_objects: + virtual_machine_clone_info = {} + virtual_machine_clone_info['info'] = self.get_virtual_machine_clone_info( + managed_object + ) + virtual_machine_clone_info['mo'] = managed_object + self.virtual_machine_clone.append( + virtual_machine_clone_info + ) + + return self.virtual_machine_clone + + def match_virtual_machine_clone(self, virtual_machine_clone_info, virtual_machine_clone_filter): + if virtual_machine_clone_filter is None or len(virtual_machine_clone_filter) == 0: + return True + + for ap_rule in virtual_machine_clone_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_clone', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_clones(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_clones = self.get_virtual_machine_clones_info(cache_enabled=cache_enabled) + if all_virtual_machine_clones is None: + return None + + virtual_machine_clones = [] + + for virtual_machine_clone_info in all_virtual_machine_clones: + if not self.match_virtual_machine_clone(virtual_machine_clone_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_clones.append( + virtual_machine_clone_info['mo'] + ) + continue + + virtual_machine_clones.append( + virtual_machine_clone_info['info'] + ) + + return virtual_machine_clones diff --git a/lib/k8s/virtual_machine_clone/main.py b/lib/k8s/virtual_machine_clone/main.py new file mode 100644 index 00000000..3fa9c4e8 --- /dev/null +++ b/lib/k8s/virtual_machine_clone/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_clone.api import K8sVirtualMachineCloneApi +from lib.k8s.virtual_machine_clone.info import K8sVirtualMachineCloneInfo + + +class K8sVirtualMachineClone( + K8sVirtualMachineCloneApi, + K8sVirtualMachineCloneInfo + ): + def __init__(self): + K8sVirtualMachineCloneApi.__init__(self) + K8sVirtualMachineCloneInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_clone/output.py b/lib/k8s/virtual_machine_clone/output.py new file mode 100644 index 00000000..b75d55ab --- /dev/null +++ b/lib/k8s/virtual_machine_clone/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineCloneOutput(): + def __init__(self): + pass + + def print_virtual_machine_clones(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Clone [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_cluster_instance_type/__init__.py b/lib/k8s/virtual_machine_cluster_instance_type/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_cluster_instance_type/api.py b/lib/k8s/virtual_machine_cluster_instance_type/api.py new file mode 100644 index 00000000..6fb0c2f6 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_instance_type/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineClusterInstanceTypeApi(): + def __init__(self): + self.virtual_machine_cluster_instance_type_mo = None + + def get_virtual_machine_cluster_instance_type_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_cluster_instance_type_mo is not None: + return self.virtual_machine_cluster_instance_type_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='instancetype.kubevirt.io/v1alpha2', + kind='VirtualMachineClusterInstancetype' + ) + self.virtual_machine_cluster_instance_type_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_cluster_instance_type', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_cluster_instance_type_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_cluster_instance_type', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_cluster_instance_type', + self.virtual_machine_cluster_instance_type_mo + ) + + return self.virtual_machine_cluster_instance_type_mo diff --git a/lib/k8s/virtual_machine_cluster_instance_type/info.py b/lib/k8s/virtual_machine_cluster_instance_type/info.py new file mode 100644 index 00000000..16917490 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_instance_type/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineClusterInstanceTypeInfo(): + def __init__(self): + self.virtual_machine_cluster_instance_type = None + + def get_virtual_machine_cluster_instance_type_info(self, virtual_machine_cluster_instance_type_mo): + if virtual_machine_cluster_instance_type_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_cluster_instance_type_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_cluster_instance_types_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_cluster_instance_type is not None: + return self.virtual_machine_cluster_instance_type + + managed_objects = self.get_virtual_machine_cluster_instance_type_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_cluster_instance_type = [] + for managed_object in managed_objects: + virtual_machine_cluster_instance_type_info = {} + virtual_machine_cluster_instance_type_info['info'] = self.get_virtual_machine_cluster_instance_type_info( + managed_object + ) + virtual_machine_cluster_instance_type_info['mo'] = managed_object + self.virtual_machine_cluster_instance_type.append( + virtual_machine_cluster_instance_type_info + ) + + return self.virtual_machine_cluster_instance_type + + def match_virtual_machine_cluster_instance_type(self, virtual_machine_cluster_instance_type_info, virtual_machine_cluster_instance_type_filter): + if virtual_machine_cluster_instance_type_filter is None or len(virtual_machine_cluster_instance_type_filter) == 0: + return True + + for ap_rule in virtual_machine_cluster_instance_type_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_cluster_instance_type', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_cluster_instance_types(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_cluster_instance_types = self.get_virtual_machine_cluster_instance_types_info(cache_enabled=cache_enabled) + if all_virtual_machine_cluster_instance_types is None: + return None + + virtual_machine_cluster_instance_types = [] + + for virtual_machine_cluster_instance_type_info in all_virtual_machine_cluster_instance_types: + if not self.match_virtual_machine_cluster_instance_type(virtual_machine_cluster_instance_type_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_cluster_instance_types.append( + virtual_machine_cluster_instance_type_info['mo'] + ) + continue + + virtual_machine_cluster_instance_types.append( + virtual_machine_cluster_instance_type_info['info'] + ) + + return virtual_machine_cluster_instance_types diff --git a/lib/k8s/virtual_machine_cluster_instance_type/main.py b/lib/k8s/virtual_machine_cluster_instance_type/main.py new file mode 100644 index 00000000..72c3aa3e --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_instance_type/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_cluster_instance_type.api import K8sVirtualMachineClusterInstanceTypeApi +from lib.k8s.virtual_machine_cluster_instance_type.info import K8sVirtualMachineClusterInstanceTypeInfo + + +class K8sVirtualMachineClusterInstanceType( + K8sVirtualMachineClusterInstanceTypeApi, + K8sVirtualMachineClusterInstanceTypeInfo + ): + def __init__(self): + K8sVirtualMachineClusterInstanceTypeApi.__init__(self) + K8sVirtualMachineClusterInstanceTypeInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_cluster_instance_type/output.py b/lib/k8s/virtual_machine_cluster_instance_type/output.py new file mode 100644 index 00000000..9bc00cb9 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_instance_type/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineClusterInstanceTypeOutput(): + def __init__(self): + pass + + def print_virtual_machine_cluster_instance_types(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Cluster Instance Type [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_cluster_preference/__init__.py b/lib/k8s/virtual_machine_cluster_preference/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_cluster_preference/api.py b/lib/k8s/virtual_machine_cluster_preference/api.py new file mode 100644 index 00000000..9cef3254 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_preference/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineClusterPreferenceApi(): + def __init__(self): + self.virtual_machine_cluster_preference_mo = None + + def get_virtual_machine_cluster_preference_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_cluster_preference_mo is not None: + return self.virtual_machine_cluster_preference_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='instancetype.kubevirt.io/v1alpha2', + kind='VirtualMachineClusterPreference' + ) + self.virtual_machine_cluster_preference_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_cluster_preference', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_cluster_preference_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_cluster_preference', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_cluster_preference', + self.virtual_machine_cluster_preference_mo + ) + + return self.virtual_machine_cluster_preference_mo diff --git a/lib/k8s/virtual_machine_cluster_preference/info.py b/lib/k8s/virtual_machine_cluster_preference/info.py new file mode 100644 index 00000000..9d9bd293 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_preference/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineClusterPreferenceInfo(): + def __init__(self): + self.virtual_machine_cluster_preference = None + + def get_virtual_machine_cluster_preference_info(self, virtual_machine_cluster_preference_mo): + if virtual_machine_cluster_preference_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_cluster_preference_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_cluster_preferences_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_cluster_preference is not None: + return self.virtual_machine_cluster_preference + + managed_objects = self.get_virtual_machine_cluster_preference_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_cluster_preference = [] + for managed_object in managed_objects: + virtual_machine_cluster_preference_info = {} + virtual_machine_cluster_preference_info['info'] = self.get_virtual_machine_cluster_preference_info( + managed_object + ) + virtual_machine_cluster_preference_info['mo'] = managed_object + self.virtual_machine_cluster_preference.append( + virtual_machine_cluster_preference_info + ) + + return self.virtual_machine_cluster_preference + + def match_virtual_machine_cluster_preference(self, virtual_machine_cluster_preference_info, virtual_machine_cluster_preference_filter): + if virtual_machine_cluster_preference_filter is None or len(virtual_machine_cluster_preference_filter) == 0: + return True + + for ap_rule in virtual_machine_cluster_preference_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_cluster_preference', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_cluster_preferences(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_cluster_preferences = self.get_virtual_machine_cluster_preferences_info(cache_enabled=cache_enabled) + if all_virtual_machine_cluster_preferences is None: + return None + + virtual_machine_cluster_preferences = [] + + for virtual_machine_cluster_preference_info in all_virtual_machine_cluster_preferences: + if not self.match_virtual_machine_cluster_preference(virtual_machine_cluster_preference_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_cluster_preferences.append( + virtual_machine_cluster_preference_info['mo'] + ) + continue + + virtual_machine_cluster_preferences.append( + virtual_machine_cluster_preference_info['info'] + ) + + return virtual_machine_cluster_preferences diff --git a/lib/k8s/virtual_machine_cluster_preference/main.py b/lib/k8s/virtual_machine_cluster_preference/main.py new file mode 100644 index 00000000..2c3abec5 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_preference/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_cluster_preference.api import K8sVirtualMachineClusterPreferenceApi +from lib.k8s.virtual_machine_cluster_preference.info import K8sVirtualMachineClusterPreferenceInfo + + +class K8sVirtualMachineClusterPreference( + K8sVirtualMachineClusterPreferenceApi, + K8sVirtualMachineClusterPreferenceInfo + ): + def __init__(self): + K8sVirtualMachineClusterPreferenceApi.__init__(self) + K8sVirtualMachineClusterPreferenceInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_cluster_preference/output.py b/lib/k8s/virtual_machine_cluster_preference/output.py new file mode 100644 index 00000000..ccad75e0 --- /dev/null +++ b/lib/k8s/virtual_machine_cluster_preference/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineClusterPreferenceOutput(): + def __init__(self): + pass + + def print_virtual_machine_cluster_preferences(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Cluster Preference [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_export/__init__.py b/lib/k8s/virtual_machine_export/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_export/api.py b/lib/k8s/virtual_machine_export/api.py new file mode 100644 index 00000000..8960ce78 --- /dev/null +++ b/lib/k8s/virtual_machine_export/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineExportApi(): + def __init__(self): + self.virtual_machine_export_mo = None + + def get_virtual_machine_export_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_export_mo is not None: + return self.virtual_machine_export_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='export.kubevirt.io/v1alpha1', + kind='VirtualMachineExport' + ) + self.virtual_machine_export_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_export', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_export_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_export', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_export', + self.virtual_machine_export_mo + ) + + return self.virtual_machine_export_mo diff --git a/lib/k8s/virtual_machine_export/info.py b/lib/k8s/virtual_machine_export/info.py new file mode 100644 index 00000000..cc098be2 --- /dev/null +++ b/lib/k8s/virtual_machine_export/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineExportInfo(): + def __init__(self): + self.virtual_machine_export = None + + def get_virtual_machine_export_info(self, virtual_machine_export_mo): + if virtual_machine_export_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_export_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_exports_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_export is not None: + return self.virtual_machine_export + + managed_objects = self.get_virtual_machine_export_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_export = [] + for managed_object in managed_objects: + virtual_machine_export_info = {} + virtual_machine_export_info['info'] = self.get_virtual_machine_export_info( + managed_object + ) + virtual_machine_export_info['mo'] = managed_object + self.virtual_machine_export.append( + virtual_machine_export_info + ) + + return self.virtual_machine_export + + def match_virtual_machine_export(self, virtual_machine_export_info, virtual_machine_export_filter): + if virtual_machine_export_filter is None or len(virtual_machine_export_filter) == 0: + return True + + for ap_rule in virtual_machine_export_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_export', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_exports(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_exports = self.get_virtual_machine_exports_info(cache_enabled=cache_enabled) + if all_virtual_machine_exports is None: + return None + + virtual_machine_exports = [] + + for virtual_machine_export_info in all_virtual_machine_exports: + if not self.match_virtual_machine_export(virtual_machine_export_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_exports.append( + virtual_machine_export_info['mo'] + ) + continue + + virtual_machine_exports.append( + virtual_machine_export_info['info'] + ) + + return virtual_machine_exports diff --git a/lib/k8s/virtual_machine_export/main.py b/lib/k8s/virtual_machine_export/main.py new file mode 100644 index 00000000..45d996fc --- /dev/null +++ b/lib/k8s/virtual_machine_export/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_export.api import K8sVirtualMachineExportApi +from lib.k8s.virtual_machine_export.info import K8sVirtualMachineExportInfo + + +class K8sVirtualMachineExport( + K8sVirtualMachineExportApi, + K8sVirtualMachineExportInfo + ): + def __init__(self): + K8sVirtualMachineExportApi.__init__(self) + K8sVirtualMachineExportInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_export/output.py b/lib/k8s/virtual_machine_export/output.py new file mode 100644 index 00000000..e6a57a1b --- /dev/null +++ b/lib/k8s/virtual_machine_export/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineExportOutput(): + def __init__(self): + pass + + def print_virtual_machine_exports(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Export [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_instance/__init__.py b/lib/k8s/virtual_machine_instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_instance/api.py b/lib/k8s/virtual_machine_instance/api.py new file mode 100644 index 00000000..4947a391 --- /dev/null +++ b/lib/k8s/virtual_machine_instance/api.py @@ -0,0 +1,81 @@ +import time +import traceback + + +class K8sVirtualMachineInstanceApi(): + def __init__(self): + self.virtual_machine_instance_mo = None + + def get_virtual_machine_instance_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_mo is not None: + return self.virtual_machine_instance_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='VirtualMachineInstance' + ) + self.virtual_machine_instance_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_instance', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_instance_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_instance', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_instance', + self.virtual_machine_instance_mo + ) + + return self.virtual_machine_instance_mo + + def create_virtual_machine_instance_mo(self, body, cache_enabled=True): + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='VirtualMachineInstance' + ) + response.create(body=body, namespace=body['metadata']['namespace']) + + self.log.k8s( + 'create', + 'virtual_machine_instance', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.create_virtual_machine_instance_mo', traceback.format_exc()) + self.log.k8s( + 'create', + 'virtual_machine_instance', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return False + + return True diff --git a/lib/k8s/virtual_machine_instance/info.py b/lib/k8s/virtual_machine_instance/info.py new file mode 100644 index 00000000..f90b8731 --- /dev/null +++ b/lib/k8s/virtual_machine_instance/info.py @@ -0,0 +1,297 @@ +from lib import filter_helper + + +class K8sVirtualMachineInstanceInfo(): + def __init__(self): + self.virtual_machine_instance = None + + def get_virtual_machine_instance_info(self, virtual_machine_instance_mo): + if virtual_machine_instance_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_instance_mo + ) + info.update(metadata_info) + + info['cores'] = self.get(virtual_machine_instance_mo, 'spec:domain:cpu:cores') + info['sockets'] = self.get(virtual_machine_instance_mo, 'spec:domain:cpu:sockets') + info['threads'] = self.get(virtual_machine_instance_mo, 'spec:domain:cpu:threads') + info['memory'] = self.get(virtual_machine_instance_mo, 'spec:domain:resources:requests:memory') + + info['node_name'] = self.get(virtual_machine_instance_mo, 'status:nodeName') + + info['phase'] = self.get(virtual_machine_instance_mo, 'status:phase', on_error='Unknown', on_none='Unknown') + info['phaseT'] = info['phase'] + if info['phaseT'] == 'Succeeded': + info['phaseT'] = 'Completed' + + if info['phaseT'] in ['Running', 'Completed']: + info['__Output']['phaseT'] = 'Green' + + if info['phaseT'] in ['Failed', 'Unknown']: + info['__Output']['phaseT'] = 'Red' + + if info['phaseT'] in ['Pending']: + info['__Output']['phaseT'] = 'Yellow' + + info['running'] = False + if info['phase'] == 'Running': + info['running'] = True + + info['phase_transitions'] = self.get(virtual_machine_instance_mo, 'status:phaseTransitionTimestamps', on_error=[], on_none=[]) + for item in info['phase_transitions']: + item['timestamp'] = self.convert_timestamp( + item['phaseTransitionTimestamp'] + ) + info['phase_transitions'] = sorted( + info['phase_transitions'], + key=lambda i: i['timestamp'] + ) + + info['runtimeUser'] = self.get(virtual_machine_instance_mo, 'status:runtimeUser') + + info['interface'] = self.get(virtual_machine_instance_mo, 'spec:domain:devices:interfaces', on_error=[], on_none=[]) + interfaces_state = self.get(virtual_machine_instance_mo, 'status:interfaces', on_error=[], on_none=[]) + for interface in info['interface']: + interface['info'] = '--' + + for interface_state in interfaces_state: + if interface['name'] == interface_state['name']: + interface['ip_address'] = self.get(interface_state, 'ipAddress') + interface['ip_addresses'] = self.get(interface_state, 'ipAddresses', on_error=[], on_none=[]) + interface['mac'] = self.get(interface_state, 'mac') + + if interface['name'] == 'default': + if 'ip_address' in interface and interface['ip_address'] is not None: + if 'masquerade' in interface and interface['masquerade'] is not None: + interface['info'] = '%s (masq)' % (interface['ip_address']) + else: + interface['info'] = interface['ip_address'] + continue + + if 'ip_address' in interface and interface['ip_address'] is not None: + if 'sriov' in interface and interface['sriov'] is not None: + interface['info'] = '%s (sriov)' % (interface['ip_address']) + else: + interface['info'] = interface['ip_address'] + continue + + if 'sriov' in interface and interface['sriov'] is not None: + interface['info'] = '%s (sriov)' % (interface['name']) + else: + interface['info'] = interface['name'] + + networks_mo = self.get(virtual_machine_instance_mo, 'spec:networks', on_error=[], on_none=[]) + for network_mo in networks_mo: + for interface_info in info['interface']: + if network_mo['name'] == interface_info['name']: + interface_info['type'] = None + if 'sriov' in interface_info: + interface_info['type'] = 'sriov' + if 'masquerade' in interface_info: + interface_info['type'] = 'pod' + + if interface_info['type'] == 'sriov': + sriov_network_info = self.get_sriov_network(network_mo['multus']['networkName']) + if sriov_network_info is not None: + interface_info['network_name'] = network_mo['multus']['networkName'] + interface_info['resource_name'] = sriov_network_info['resource_name'] + interface_info['vlanT'] = sriov_network_info['vlanT'] + interface_info['ipamT'] = sriov_network_info['ipamT'] + + info['disk'] = self.get(virtual_machine_instance_mo, 'spec:domain:devices:disks', on_error=[], on_none=[]) + + volumes_spec = self.get(virtual_machine_instance_mo, 'spec:volumes', on_error=[], on_none=[]) + volumes_state = self.get(virtual_machine_instance_mo, 'status:volumeStatus', on_error=[], on_none=[]) + for disk in info['disk']: + disk['info'] = '--' + disk['target'] = None + disk['storage'] = None + disk['pvc_namespace'] = None + disk['pvc_name'] = None + disk['pvc_namespace_name'] = None + + for volume_spec in volumes_spec: + if disk['name'] == volume_spec['name']: + if 'dataVolume' in volume_spec: + disk['pvc_namespace'] = info['namespace'] + disk['pvc_name'] = volume_spec['dataVolume']['name'] + disk['pvc_namespace_name'] = '%s/%s' % ( + disk['pvc_namespace'], + disk['pvc_name'] + ) + + if 'persistentVolumeClaim' in volume_spec: + disk['pvc_namespace'] = info['namespace'] + disk['pvc_name'] = volume_spec['persistentVolumeClaim']['claimName'] + disk['pvc_namespace_name'] = '%s/%s' % ( + disk['pvc_namespace'], + disk['pvc_name'] + ) + + for volume_state in volumes_state: + if disk['name'] == volume_state['name']: + disk['target'] = self.get(volume_state, 'target') + if 'persistentVolumeClaimInfo' in volume_state: + + disk['storage'] = self.get(volume_state, 'persistentVolumeClaimInfo:capacity:storage') + disk['info'] = '%s/%s - %s' % ( + disk['name'], + disk['target'], + disk['storage'] + ) + + return info + + def get_virtual_machine_instances_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance is not None: + return self.virtual_machine_instance + + managed_objects = self.get_virtual_machine_instance_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_instance = [] + for managed_object in managed_objects: + virtual_machine_instance_info = {} + virtual_machine_instance_info['info'] = self.get_virtual_machine_instance_info( + managed_object + ) + virtual_machine_instance_info['mo'] = managed_object + self.virtual_machine_instance.append( + virtual_machine_instance_info + ) + + return self.virtual_machine_instance + + def match_virtual_machine_instance(self, virtual_machine_instance_info, virtual_machine_instance_filter): + if virtual_machine_instance_filter is None or len(virtual_machine_instance_filter) == 0: + return True + + for ap_rule in virtual_machine_instance_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name(value, '%s/%s' % (virtual_machine_instance_info['namespace'], virtual_machine_instance_info['name'])): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, virtual_machine_instance_info['namespace']): + return False + + if key == 'pvc': + key_found = True + found = False + for disk_info in virtual_machine_instance_info['disk']: + if disk_info['pvc_namespace_name'] is not None: + if filter_helper.match_namespace_name(value, disk_info['pvc_namespace_name']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_virtual_machine_instance', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_instances(self, object_filter=None, return_mo=False, vm_info=False, service_info=False, cache_enabled=True): + all_virtual_machine_instances = self.get_virtual_machine_instances_info(cache_enabled=cache_enabled) + if all_virtual_machine_instances is None: + return None + + virtual_machine_instances = [] + + for virtual_machine_instance_info in all_virtual_machine_instances: + if not self.match_virtual_machine_instance(virtual_machine_instance_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_instances.append( + virtual_machine_instance_info['mo'] + ) + continue + + if service_info: + virtual_machine_instance_info['info']['service'] = [] + vmi_services = [] + for label_key in virtual_machine_instance_info['info']['label']: + service_filter = [ + 'selector:%s:%s' % ( + label_key, + virtual_machine_instance_info['info']['label'][label_key] + ) + ] + services = self.get_services( + object_filter=service_filter + ) + if services is not None: + for vmi_service_info in services: + service_match = True + for key in vmi_service_info['selector']: + if key not in virtual_machine_instance_info['info']['label']: + service_match = False + break + + if virtual_machine_instance_info['info']['label'][key] != vmi_service_info['selector'][key]: + service_match = False + break + + if service_match: + if vmi_service_info['namespace_name'] not in vmi_services: + virtual_machine_instance_info['info']['service'].append( + vmi_service_info + ) + vmi_services.append( + vmi_service_info['namespace_name'] + ) + + virtual_machine_instance_info['info']['serviceCount'] = len( + virtual_machine_instance_info['info']['service'] + ) + + if vm_info: + if self.is_virtual_machine(virtual_machine_instance_info['info']['namespace'], virtual_machine_instance_info['info']['name'], cache_enabled=cache_enabled): + virtual_machine_instance_info['info']['vmTick'] = '\u2713' + virtual_machine_instance_info['info']['__Output']['vmTick'] = 'Green' + else: + virtual_machine_instance_info['info']['vmTick'] = '\u2717' + virtual_machine_instance_info['info']['__Output']['vmTick'] = 'Red' + + virtual_machine_instances.append( + virtual_machine_instance_info['info'] + ) + + return virtual_machine_instances + + def get_virtual_machine_instance(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append('namespace:%s' % (namespace)) + object_filter.append('name:%s' % (name)) + instances = self.get_virtual_machine_instances( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if instances is None or len(instances) != 1: + return None + return instances[0] + + def is_virtual_machine_instance(self, namespace, name, cache_enabled=True): + if self.get_virtual_machine_instance(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True diff --git a/lib/k8s/virtual_machine_instance/main.py b/lib/k8s/virtual_machine_instance/main.py new file mode 100644 index 00000000..7d982061 --- /dev/null +++ b/lib/k8s/virtual_machine_instance/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_instance.api import K8sVirtualMachineInstanceApi +from lib.k8s.virtual_machine_instance.info import K8sVirtualMachineInstanceInfo + + +class K8sVirtualMachineInstance( + K8sVirtualMachineInstanceApi, + K8sVirtualMachineInstanceInfo + ): + def __init__(self): + K8sVirtualMachineInstanceApi.__init__(self) + K8sVirtualMachineInstanceInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_instance/output.py b/lib/k8s/virtual_machine_instance/output.py new file mode 100644 index 00000000..913519eb --- /dev/null +++ b/lib/k8s/virtual_machine_instance/output.py @@ -0,0 +1,256 @@ +class K8sVirtualMachineInstanceOutput(): + def __init__(self): + pass + + def print_virtual_machine_instances(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['node_name'] is None: + item['node_name'] = '--' + + order = [ + 'namespace_name', + 'vmTick', + 'node_name', + 'cores', + 'memory', + 'disk.info', + 'disk.pvc_namespace_name', + 'interface.info', + 'serviceCount', + 'phaseT', + 'age' + ] + + headers = [ + 'VMI', + 'VM', + 'Node', + 'CPU', + 'Mem', + 'Disk', + 'PVC', + 'Interface', + 'Svc', + 'State', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disk', 'interface', 'labelT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machine_instances_metadata(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance - Metadata [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['owner'] is None: + item['ownerT'] = ['--'] + else: + item['ownerT'] = item['owner'].split('/') + + order = [ + 'namespace_name', + 'ownerT', + 'labelT', + 'annotationT' + ] + + headers = [ + 'VMI', + 'Owner', + 'Label', + 'Annotation' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['annotationT', 'labelT', 'ownerT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machine_instances_phase(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance - Phase Transitions [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'phaseT', + 'phase_transitions.phase', + 'phase_transitions.phaseTransitionTimestamp', + 'age' + ] + + headers = [ + 'VMI', + 'State', + 'Phase', + 'Timestamp', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['phase_transitions'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machine_instances_interface(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance - Interface [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + interfaces = [] + for item in info: + for item_interface in item['interface']: + interface = {} + interface['namespace_name'] = item['namespace_name'] + for key in ['info', 'mac', 'network_name', 'resource_name', 'vlanT']: + interface[key] = '--' + if key in item_interface: + interface[key] = item_interface[key] + if interface[key] is None: + interface[key] = '--' + + for key in ['ipamT']: + interface[key] = ['--'] + if key in item_interface: + interface[key] = item_interface[key] + + interfaces.append(interface) + + order = [ + 'namespace_name', + 'info', + 'mac', + 'network_name', + 'resource_name', + 'vlanT', + 'ipamT' + ] + + headers = [ + 'VMI', + 'Interface', + 'MAC', + 'Multus Network', + 'Resource Name', + 'VLAN', + 'IPAM' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + interfaces, + order, + ['ipamT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machine_instances_service(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance - Service (running-only) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'service.namespace_name', + 'service.type', + 'service.cluster_ip', + 'service.ports' + ] + + headers = [ + 'VMI', + 'Service', + 'Type', + 'Cluster IP', + 'Ports' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['service'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/k8s/virtual_machine_instance_migration/__init__.py b/lib/k8s/virtual_machine_instance_migration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_instance_migration/api.py b/lib/k8s/virtual_machine_instance_migration/api.py new file mode 100644 index 00000000..d1a7c469 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_migration/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineInstanceMigrationApi(): + def __init__(self): + self.virtual_machine_instance_migration_mo = None + + def get_virtual_machine_instance_migration_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_migration_mo is not None: + return self.virtual_machine_instance_migration_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='VirtualMachineInstanceMigration' + ) + self.virtual_machine_instance_migration_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_instance_migration', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_instance_migration_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_instance_migration', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_instance_migration', + self.virtual_machine_instance_migration_mo + ) + + return self.virtual_machine_instance_migration_mo diff --git a/lib/k8s/virtual_machine_instance_migration/info.py b/lib/k8s/virtual_machine_instance_migration/info.py new file mode 100644 index 00000000..59f4922b --- /dev/null +++ b/lib/k8s/virtual_machine_instance_migration/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineInstanceMigrationInfo(): + def __init__(self): + self.virtual_machine_instance_migration = None + + def get_virtual_machine_instance_migration_info(self, virtual_machine_instance_migration_mo): + if virtual_machine_instance_migration_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_instance_migration_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_instance_migrations_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_migration is not None: + return self.virtual_machine_instance_migration + + managed_objects = self.get_virtual_machine_instance_migration_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_instance_migration = [] + for managed_object in managed_objects: + virtual_machine_instance_migration_info = {} + virtual_machine_instance_migration_info['info'] = self.get_virtual_machine_instance_migration_info( + managed_object + ) + virtual_machine_instance_migration_info['mo'] = managed_object + self.virtual_machine_instance_migration.append( + virtual_machine_instance_migration_info + ) + + return self.virtual_machine_instance_migration + + def match_virtual_machine_instance_migration(self, virtual_machine_instance_migration_info, virtual_machine_instance_migration_filter): + if virtual_machine_instance_migration_filter is None or len(virtual_machine_instance_migration_filter) == 0: + return True + + for ap_rule in virtual_machine_instance_migration_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_instance_migration', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_instance_migrations(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_instance_migrations = self.get_virtual_machine_instance_migrations_info(cache_enabled=cache_enabled) + if all_virtual_machine_instance_migrations is None: + return None + + virtual_machine_instance_migrations = [] + + for virtual_machine_instance_migration_info in all_virtual_machine_instance_migrations: + if not self.match_virtual_machine_instance_migration(virtual_machine_instance_migration_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_instance_migrations.append( + virtual_machine_instance_migration_info['mo'] + ) + continue + + virtual_machine_instance_migrations.append( + virtual_machine_instance_migration_info['info'] + ) + + return virtual_machine_instance_migrations diff --git a/lib/k8s/virtual_machine_instance_migration/main.py b/lib/k8s/virtual_machine_instance_migration/main.py new file mode 100644 index 00000000..468bd709 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_migration/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_instance_migration.api import K8sVirtualMachineInstanceMigrationApi +from lib.k8s.virtual_machine_instance_migration.info import K8sVirtualMachineInstanceMigrationInfo + + +class K8sVirtualMachineInstanceMigration( + K8sVirtualMachineInstanceMigrationApi, + K8sVirtualMachineInstanceMigrationInfo + ): + def __init__(self): + K8sVirtualMachineInstanceMigrationApi.__init__(self) + K8sVirtualMachineInstanceMigrationInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_instance_migration/output.py b/lib/k8s/virtual_machine_instance_migration/output.py new file mode 100644 index 00000000..4e463437 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_migration/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineInstanceMigrationOutput(): + def __init__(self): + pass + + def print_virtual_machine_instance_migrations(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance Migration [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_instance_preset/__init__.py b/lib/k8s/virtual_machine_instance_preset/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_instance_preset/api.py b/lib/k8s/virtual_machine_instance_preset/api.py new file mode 100644 index 00000000..66680ee2 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_preset/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineInstancePresetApi(): + def __init__(self): + self.virtual_machine_instance_preset_mo = None + + def get_virtual_machine_instance_preset_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_preset_mo is not None: + return self.virtual_machine_instance_preset_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='VirtualMachineInstancePreset' + ) + self.virtual_machine_instance_preset_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_instance_preset', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_instance_preset_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_instance_preset', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_instance_preset', + self.virtual_machine_instance_preset_mo + ) + + return self.virtual_machine_instance_preset_mo diff --git a/lib/k8s/virtual_machine_instance_preset/info.py b/lib/k8s/virtual_machine_instance_preset/info.py new file mode 100644 index 00000000..8d259982 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_preset/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineInstancePresetInfo(): + def __init__(self): + self.virtual_machine_instance_preset = None + + def get_virtual_machine_instance_preset_info(self, virtual_machine_instance_preset_mo): + if virtual_machine_instance_preset_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_instance_preset_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_instance_presets_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_preset is not None: + return self.virtual_machine_instance_preset + + managed_objects = self.get_virtual_machine_instance_preset_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_instance_preset = [] + for managed_object in managed_objects: + virtual_machine_instance_preset_info = {} + virtual_machine_instance_preset_info['info'] = self.get_virtual_machine_instance_preset_info( + managed_object + ) + virtual_machine_instance_preset_info['mo'] = managed_object + self.virtual_machine_instance_preset.append( + virtual_machine_instance_preset_info + ) + + return self.virtual_machine_instance_preset + + def match_virtual_machine_instance_preset(self, virtual_machine_instance_preset_info, virtual_machine_instance_preset_filter): + if virtual_machine_instance_preset_filter is None or len(virtual_machine_instance_preset_filter) == 0: + return True + + for ap_rule in virtual_machine_instance_preset_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_instance_preset', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_instance_presets(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_instance_presets = self.get_virtual_machine_instance_presets_info(cache_enabled=cache_enabled) + if all_virtual_machine_instance_presets is None: + return None + + virtual_machine_instance_presets = [] + + for virtual_machine_instance_preset_info in all_virtual_machine_instance_presets: + if not self.match_virtual_machine_instance_preset(virtual_machine_instance_preset_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_instance_presets.append( + virtual_machine_instance_preset_info['mo'] + ) + continue + + virtual_machine_instance_presets.append( + virtual_machine_instance_preset_info['info'] + ) + + return virtual_machine_instance_presets diff --git a/lib/k8s/virtual_machine_instance_preset/main.py b/lib/k8s/virtual_machine_instance_preset/main.py new file mode 100644 index 00000000..680070a1 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_preset/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_instance_preset.api import K8sVirtualMachineInstancePresetApi +from lib.k8s.virtual_machine_instance_preset.info import K8sVirtualMachineInstancePresetInfo + + +class K8sVirtualMachineInstancePreset( + K8sVirtualMachineInstancePresetApi, + K8sVirtualMachineInstancePresetInfo + ): + def __init__(self): + K8sVirtualMachineInstancePresetApi.__init__(self) + K8sVirtualMachineInstancePresetInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_instance_preset/output.py b/lib/k8s/virtual_machine_instance_preset/output.py new file mode 100644 index 00000000..440c75b6 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_preset/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineInstancePresetOutput(): + def __init__(self): + pass + + def print_virtual_machine_instance_presets(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance Preset [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_instance_replica_set/__init__.py b/lib/k8s/virtual_machine_instance_replica_set/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_instance_replica_set/api.py b/lib/k8s/virtual_machine_instance_replica_set/api.py new file mode 100644 index 00000000..34119a05 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_replica_set/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineInstanceReplicaSetApi(): + def __init__(self): + self.virtual_machine_instance_replica_set_mo = None + + def get_virtual_machine_instance_replica_set_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_replica_set_mo is not None: + return self.virtual_machine_instance_replica_set_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='kubevirt.io/v1', + kind='VirtualMachineInstanceReplicaSet' + ) + self.virtual_machine_instance_replica_set_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_instance_replica_set', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_instance_replica_set_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_instance_replica_set', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_instance_replica_set', + self.virtual_machine_instance_replica_set_mo + ) + + return self.virtual_machine_instance_replica_set_mo diff --git a/lib/k8s/virtual_machine_instance_replica_set/info.py b/lib/k8s/virtual_machine_instance_replica_set/info.py new file mode 100644 index 00000000..095a258b --- /dev/null +++ b/lib/k8s/virtual_machine_instance_replica_set/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineInstanceReplicaSetInfo(): + def __init__(self): + self.virtual_machine_instance_replica_set = None + + def get_virtual_machine_instance_replica_set_info(self, virtual_machine_instance_replica_set_mo): + if virtual_machine_instance_replica_set_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_instance_replica_set_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_instance_replica_sets_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_replica_set is not None: + return self.virtual_machine_instance_replica_set + + managed_objects = self.get_virtual_machine_instance_replica_set_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_instance_replica_set = [] + for managed_object in managed_objects: + virtual_machine_instance_replica_set_info = {} + virtual_machine_instance_replica_set_info['info'] = self.get_virtual_machine_instance_replica_set_info( + managed_object + ) + virtual_machine_instance_replica_set_info['mo'] = managed_object + self.virtual_machine_instance_replica_set.append( + virtual_machine_instance_replica_set_info + ) + + return self.virtual_machine_instance_replica_set + + def match_virtual_machine_instance_replica_set(self, virtual_machine_instance_replica_set_info, virtual_machine_instance_replica_set_filter): + if virtual_machine_instance_replica_set_filter is None or len(virtual_machine_instance_replica_set_filter) == 0: + return True + + for ap_rule in virtual_machine_instance_replica_set_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_instance_replica_set', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_instance_replica_sets(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_instance_replica_sets = self.get_virtual_machine_instance_replica_sets_info(cache_enabled=cache_enabled) + if all_virtual_machine_instance_replica_sets is None: + return None + + virtual_machine_instance_replica_sets = [] + + for virtual_machine_instance_replica_set_info in all_virtual_machine_instance_replica_sets: + if not self.match_virtual_machine_instance_replica_set(virtual_machine_instance_replica_set_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_instance_replica_sets.append( + virtual_machine_instance_replica_set_info['mo'] + ) + continue + + virtual_machine_instance_replica_sets.append( + virtual_machine_instance_replica_set_info['info'] + ) + + return virtual_machine_instance_replica_sets diff --git a/lib/k8s/virtual_machine_instance_replica_set/main.py b/lib/k8s/virtual_machine_instance_replica_set/main.py new file mode 100644 index 00000000..3e67766e --- /dev/null +++ b/lib/k8s/virtual_machine_instance_replica_set/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_instance_replica_set.api import K8sVirtualMachineInstanceReplicaSetApi +from lib.k8s.virtual_machine_instance_replica_set.info import K8sVirtualMachineInstanceReplicaSetInfo + + +class K8sVirtualMachineInstanceReplicaSet( + K8sVirtualMachineInstanceReplicaSetApi, + K8sVirtualMachineInstanceReplicaSetInfo + ): + def __init__(self): + K8sVirtualMachineInstanceReplicaSetApi.__init__(self) + K8sVirtualMachineInstanceReplicaSetInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_instance_replica_set/output.py b/lib/k8s/virtual_machine_instance_replica_set/output.py new file mode 100644 index 00000000..c762cc4b --- /dev/null +++ b/lib/k8s/virtual_machine_instance_replica_set/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineInstanceReplicaSetOutput(): + def __init__(self): + pass + + def print_virtual_machine_instance_replica_sets(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance Replica Set [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_instance_type/__init__.py b/lib/k8s/virtual_machine_instance_type/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_instance_type/api.py b/lib/k8s/virtual_machine_instance_type/api.py new file mode 100644 index 00000000..acf8afdb --- /dev/null +++ b/lib/k8s/virtual_machine_instance_type/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineInstanceTypeApi(): + def __init__(self): + self.virtual_machine_instance_type_mo = None + + def get_virtual_machine_instance_type_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_type_mo is not None: + return self.virtual_machine_instance_type_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='instancetype.kubevirt.io/v1alpha2', + kind='VirtualMachineInstancetype' + ) + self.virtual_machine_instance_type_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_instance_type', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_instance_type_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_instance_type', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_instance_type', + self.virtual_machine_instance_type_mo + ) + + return self.virtual_machine_instance_type_mo diff --git a/lib/k8s/virtual_machine_instance_type/info.py b/lib/k8s/virtual_machine_instance_type/info.py new file mode 100644 index 00000000..34c30cae --- /dev/null +++ b/lib/k8s/virtual_machine_instance_type/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineInstanceTypeInfo(): + def __init__(self): + self.virtual_machine_instance_type = None + + def get_virtual_machine_instance_type_info(self, virtual_machine_instance_type_mo): + if virtual_machine_instance_type_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_instance_type_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_instance_types_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_type is not None: + return self.virtual_machine_instance_type + + managed_objects = self.get_virtual_machine_instance_type_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_instance_type = [] + for managed_object in managed_objects: + virtual_machine_instance_type_info = {} + virtual_machine_instance_type_info['info'] = self.get_virtual_machine_instance_type_info( + managed_object + ) + virtual_machine_instance_type_info['mo'] = managed_object + self.virtual_machine_instance_type.append( + virtual_machine_instance_type_info + ) + + return self.virtual_machine_instance_type + + def match_virtual_machine_instance_type(self, virtual_machine_instance_type_info, virtual_machine_instance_type_filter): + if virtual_machine_instance_type_filter is None or len(virtual_machine_instance_type_filter) == 0: + return True + + for ap_rule in virtual_machine_instance_type_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_instance_type', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_instance_types(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_instance_types = self.get_virtual_machine_instance_types_info(cache_enabled=cache_enabled) + if all_virtual_machine_instance_types is None: + return None + + virtual_machine_instance_types = [] + + for virtual_machine_instance_type_info in all_virtual_machine_instance_types: + if not self.match_virtual_machine_instance_type(virtual_machine_instance_type_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_instance_types.append( + virtual_machine_instance_type_info['mo'] + ) + continue + + virtual_machine_instance_types.append( + virtual_machine_instance_type_info['info'] + ) + + return virtual_machine_instance_types diff --git a/lib/k8s/virtual_machine_instance_type/main.py b/lib/k8s/virtual_machine_instance_type/main.py new file mode 100644 index 00000000..b8cb6e38 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_type/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_instance_type.api import K8sVirtualMachineInstanceTypeApi +from lib.k8s.virtual_machine_instance_type.info import K8sVirtualMachineInstanceTypeInfo + + +class K8sVirtualMachineInstanceType( + K8sVirtualMachineInstanceTypeApi, + K8sVirtualMachineInstanceTypeInfo + ): + def __init__(self): + K8sVirtualMachineInstanceTypeApi.__init__(self) + K8sVirtualMachineInstanceTypeInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_instance_type/output.py b/lib/k8s/virtual_machine_instance_type/output.py new file mode 100644 index 00000000..174db448 --- /dev/null +++ b/lib/k8s/virtual_machine_instance_type/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineInstanceTypeOutput(): + def __init__(self): + pass + + def print_virtual_machine_instance_types(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Instance Type [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_preference/__init__.py b/lib/k8s/virtual_machine_preference/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_preference/api.py b/lib/k8s/virtual_machine_preference/api.py new file mode 100644 index 00000000..b09af0d4 --- /dev/null +++ b/lib/k8s/virtual_machine_preference/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachinePreferenceApi(): + def __init__(self): + self.virtual_machine_preference_mo = None + + def get_virtual_machine_preference_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_preference_mo is not None: + return self.virtual_machine_preference_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='instancetype.kubevirt.io/v1alpha2', + kind='VirtualMachinePreference' + ) + self.virtual_machine_preference_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_preference', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_preference_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_preference', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_preference', + self.virtual_machine_preference_mo + ) + + return self.virtual_machine_preference_mo diff --git a/lib/k8s/virtual_machine_preference/info.py b/lib/k8s/virtual_machine_preference/info.py new file mode 100644 index 00000000..d8eb6162 --- /dev/null +++ b/lib/k8s/virtual_machine_preference/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachinePreferenceInfo(): + def __init__(self): + self.virtual_machine_preference = None + + def get_virtual_machine_preference_info(self, virtual_machine_preference_mo): + if virtual_machine_preference_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_preference_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_preferences_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_preference is not None: + return self.virtual_machine_preference + + managed_objects = self.get_virtual_machine_preference_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_preference = [] + for managed_object in managed_objects: + virtual_machine_preference_info = {} + virtual_machine_preference_info['info'] = self.get_virtual_machine_preference_info( + managed_object + ) + virtual_machine_preference_info['mo'] = managed_object + self.virtual_machine_preference.append( + virtual_machine_preference_info + ) + + return self.virtual_machine_preference + + def match_virtual_machine_preference(self, virtual_machine_preference_info, virtual_machine_preference_filter): + if virtual_machine_preference_filter is None or len(virtual_machine_preference_filter) == 0: + return True + + for ap_rule in virtual_machine_preference_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_preference', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_preferences(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_preferences = self.get_virtual_machine_preferences_info(cache_enabled=cache_enabled) + if all_virtual_machine_preferences is None: + return None + + virtual_machine_preferences = [] + + for virtual_machine_preference_info in all_virtual_machine_preferences: + if not self.match_virtual_machine_preference(virtual_machine_preference_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_preferences.append( + virtual_machine_preference_info['mo'] + ) + continue + + virtual_machine_preferences.append( + virtual_machine_preference_info['info'] + ) + + return virtual_machine_preferences diff --git a/lib/k8s/virtual_machine_preference/main.py b/lib/k8s/virtual_machine_preference/main.py new file mode 100644 index 00000000..cbc8bb1b --- /dev/null +++ b/lib/k8s/virtual_machine_preference/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_preference.api import K8sVirtualMachinePreferenceApi +from lib.k8s.virtual_machine_preference.info import K8sVirtualMachinePreferenceInfo + + +class K8sVirtualMachinePreference( + K8sVirtualMachinePreferenceApi, + K8sVirtualMachinePreferenceInfo + ): + def __init__(self): + K8sVirtualMachinePreferenceApi.__init__(self) + K8sVirtualMachinePreferenceInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_preference/output.py b/lib/k8s/virtual_machine_preference/output.py new file mode 100644 index 00000000..6d8cdf14 --- /dev/null +++ b/lib/k8s/virtual_machine_preference/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachinePreferenceOutput(): + def __init__(self): + pass + + def print_virtual_machine_preferences(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Preference [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_restore/__init__.py b/lib/k8s/virtual_machine_restore/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_restore/api.py b/lib/k8s/virtual_machine_restore/api.py new file mode 100644 index 00000000..07016f4a --- /dev/null +++ b/lib/k8s/virtual_machine_restore/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineRestoreApi(): + def __init__(self): + self.virtual_machine_restore_mo = None + + def get_virtual_machine_restore_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_restore_mo is not None: + return self.virtual_machine_restore_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='snapshot.kubevirt.io/v1alpha1', + kind='VirtualMachineRestore' + ) + self.virtual_machine_restore_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_restore', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_restore_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_restore', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_restore', + self.virtual_machine_restore_mo + ) + + return self.virtual_machine_restore_mo diff --git a/lib/k8s/virtual_machine_restore/info.py b/lib/k8s/virtual_machine_restore/info.py new file mode 100644 index 00000000..cf8ae67a --- /dev/null +++ b/lib/k8s/virtual_machine_restore/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineRestoreInfo(): + def __init__(self): + self.virtual_machine_restore = None + + def get_virtual_machine_restore_info(self, virtual_machine_restore_mo): + if virtual_machine_restore_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_restore_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_restores_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_restore is not None: + return self.virtual_machine_restore + + managed_objects = self.get_virtual_machine_restore_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_restore = [] + for managed_object in managed_objects: + virtual_machine_restore_info = {} + virtual_machine_restore_info['info'] = self.get_virtual_machine_restore_info( + managed_object + ) + virtual_machine_restore_info['mo'] = managed_object + self.virtual_machine_restore.append( + virtual_machine_restore_info + ) + + return self.virtual_machine_restore + + def match_virtual_machine_restore(self, virtual_machine_restore_info, virtual_machine_restore_filter): + if virtual_machine_restore_filter is None or len(virtual_machine_restore_filter) == 0: + return True + + for ap_rule in virtual_machine_restore_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_restore', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_restores(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_restores = self.get_virtual_machine_restores_info(cache_enabled=cache_enabled) + if all_virtual_machine_restores is None: + return None + + virtual_machine_restores = [] + + for virtual_machine_restore_info in all_virtual_machine_restores: + if not self.match_virtual_machine_restore(virtual_machine_restore_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_restores.append( + virtual_machine_restore_info['mo'] + ) + continue + + virtual_machine_restores.append( + virtual_machine_restore_info['info'] + ) + + return virtual_machine_restores diff --git a/lib/k8s/virtual_machine_restore/main.py b/lib/k8s/virtual_machine_restore/main.py new file mode 100644 index 00000000..80826972 --- /dev/null +++ b/lib/k8s/virtual_machine_restore/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_restore.api import K8sVirtualMachineRestoreApi +from lib.k8s.virtual_machine_restore.info import K8sVirtualMachineRestoreInfo + + +class K8sVirtualMachineRestore( + K8sVirtualMachineRestoreApi, + K8sVirtualMachineRestoreInfo + ): + def __init__(self): + K8sVirtualMachineRestoreApi.__init__(self) + K8sVirtualMachineRestoreInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_restore/output.py b/lib/k8s/virtual_machine_restore/output.py new file mode 100644 index 00000000..0eaeacde --- /dev/null +++ b/lib/k8s/virtual_machine_restore/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineRestoreOutput(): + def __init__(self): + pass + + def print_virtual_machine_restores(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Restore [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_snapshot/__init__.py b/lib/k8s/virtual_machine_snapshot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_snapshot/api.py b/lib/k8s/virtual_machine_snapshot/api.py new file mode 100644 index 00000000..fdbe7670 --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineSnapshotApi(): + def __init__(self): + self.virtual_machine_snapshot_mo = None + + def get_virtual_machine_snapshot_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_snapshot_mo is not None: + return self.virtual_machine_snapshot_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='snapshot.kubevirt.io/v1alpha1', + kind='VirtualMachineSnapshot' + ) + self.virtual_machine_snapshot_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_snapshot', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_snapshot_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_snapshot', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_snapshot', + self.virtual_machine_snapshot_mo + ) + + return self.virtual_machine_snapshot_mo diff --git a/lib/k8s/virtual_machine_snapshot/info.py b/lib/k8s/virtual_machine_snapshot/info.py new file mode 100644 index 00000000..a7ed512a --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineSnapshotInfo(): + def __init__(self): + self.virtual_machine_snapshot = None + + def get_virtual_machine_snapshot_info(self, virtual_machine_snapshot_mo): + if virtual_machine_snapshot_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_snapshot_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_snapshots_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_snapshot is not None: + return self.virtual_machine_snapshot + + managed_objects = self.get_virtual_machine_snapshot_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_snapshot = [] + for managed_object in managed_objects: + virtual_machine_snapshot_info = {} + virtual_machine_snapshot_info['info'] = self.get_virtual_machine_snapshot_info( + managed_object + ) + virtual_machine_snapshot_info['mo'] = managed_object + self.virtual_machine_snapshot.append( + virtual_machine_snapshot_info + ) + + return self.virtual_machine_snapshot + + def match_virtual_machine_snapshot(self, virtual_machine_snapshot_info, virtual_machine_snapshot_filter): + if virtual_machine_snapshot_filter is None or len(virtual_machine_snapshot_filter) == 0: + return True + + for ap_rule in virtual_machine_snapshot_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_snapshot', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_snapshots(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_snapshots = self.get_virtual_machine_snapshots_info(cache_enabled=cache_enabled) + if all_virtual_machine_snapshots is None: + return None + + virtual_machine_snapshots = [] + + for virtual_machine_snapshot_info in all_virtual_machine_snapshots: + if not self.match_virtual_machine_snapshot(virtual_machine_snapshot_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_snapshots.append( + virtual_machine_snapshot_info['mo'] + ) + continue + + virtual_machine_snapshots.append( + virtual_machine_snapshot_info['info'] + ) + + return virtual_machine_snapshots diff --git a/lib/k8s/virtual_machine_snapshot/main.py b/lib/k8s/virtual_machine_snapshot/main.py new file mode 100644 index 00000000..956a7283 --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_snapshot.api import K8sVirtualMachineSnapshotApi +from lib.k8s.virtual_machine_snapshot.info import K8sVirtualMachineSnapshotInfo + + +class K8sVirtualMachineSnapshot( + K8sVirtualMachineSnapshotApi, + K8sVirtualMachineSnapshotInfo + ): + def __init__(self): + K8sVirtualMachineSnapshotApi.__init__(self) + K8sVirtualMachineSnapshotInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_snapshot/output.py b/lib/k8s/virtual_machine_snapshot/output.py new file mode 100644 index 00000000..4d3ee067 --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineSnapshotOutput(): + def __init__(self): + pass + + def print_virtual_machine_snapshots(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Snapshot [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/virtual_machine_snapshot_content/__init__.py b/lib/k8s/virtual_machine_snapshot_content/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/virtual_machine_snapshot_content/api.py b/lib/k8s/virtual_machine_snapshot_content/api.py new file mode 100644 index 00000000..94c06a1b --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot_content/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVirtualMachineSnapshotContentApi(): + def __init__(self): + self.virtual_machine_snapshot_content_mo = None + + def get_virtual_machine_snapshot_content_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_snapshot_content_mo is not None: + return self.virtual_machine_snapshot_content_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='snapshot.kubevirt.io/v1alpha1', + kind='VirtualMachineSnapshotContent' + ) + self.virtual_machine_snapshot_content_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'virtual_machine_snapshot_content', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_virtual_machine_snapshot_content_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'virtual_machine_snapshot_content', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'virtual_machine_snapshot_content', + self.virtual_machine_snapshot_content_mo + ) + + return self.virtual_machine_snapshot_content_mo diff --git a/lib/k8s/virtual_machine_snapshot_content/info.py b/lib/k8s/virtual_machine_snapshot_content/info.py new file mode 100644 index 00000000..5392d4c3 --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot_content/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVirtualMachineSnapshotContentInfo(): + def __init__(self): + self.virtual_machine_snapshot_content = None + + def get_virtual_machine_snapshot_content_info(self, virtual_machine_snapshot_content_mo): + if virtual_machine_snapshot_content_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + virtual_machine_snapshot_content_mo + ) + info.update(metadata_info) + + return info + + def get_virtual_machine_snapshot_contents_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_snapshot_content is not None: + return self.virtual_machine_snapshot_content + + managed_objects = self.get_virtual_machine_snapshot_content_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_snapshot_content = [] + for managed_object in managed_objects: + virtual_machine_snapshot_content_info = {} + virtual_machine_snapshot_content_info['info'] = self.get_virtual_machine_snapshot_content_info( + managed_object + ) + virtual_machine_snapshot_content_info['mo'] = managed_object + self.virtual_machine_snapshot_content.append( + virtual_machine_snapshot_content_info + ) + + return self.virtual_machine_snapshot_content + + def match_virtual_machine_snapshot_content(self, virtual_machine_snapshot_content_info, virtual_machine_snapshot_content_filter): + if virtual_machine_snapshot_content_filter is None or len(virtual_machine_snapshot_content_filter) == 0: + return True + + for ap_rule in virtual_machine_snapshot_content_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_virtual_machine_snapshot_content', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_snapshot_contents(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_snapshot_contents = self.get_virtual_machine_snapshot_contents_info(cache_enabled=cache_enabled) + if all_virtual_machine_snapshot_contents is None: + return None + + virtual_machine_snapshot_contents = [] + + for virtual_machine_snapshot_content_info in all_virtual_machine_snapshot_contents: + if not self.match_virtual_machine_snapshot_content(virtual_machine_snapshot_content_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_snapshot_contents.append( + virtual_machine_snapshot_content_info['mo'] + ) + continue + + virtual_machine_snapshot_contents.append( + virtual_machine_snapshot_content_info['info'] + ) + + return virtual_machine_snapshot_contents diff --git a/lib/k8s/virtual_machine_snapshot_content/main.py b/lib/k8s/virtual_machine_snapshot_content/main.py new file mode 100644 index 00000000..67681307 --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot_content/main.py @@ -0,0 +1,11 @@ +from lib.k8s.virtual_machine_snapshot_content.api import K8sVirtualMachineSnapshotContentApi +from lib.k8s.virtual_machine_snapshot_content.info import K8sVirtualMachineSnapshotContentInfo + + +class K8sVirtualMachineSnapshotContent( + K8sVirtualMachineSnapshotContentApi, + K8sVirtualMachineSnapshotContentInfo + ): + def __init__(self): + K8sVirtualMachineSnapshotContentApi.__init__(self) + K8sVirtualMachineSnapshotContentInfo.__init__(self) diff --git a/lib/k8s/virtual_machine_snapshot_content/output.py b/lib/k8s/virtual_machine_snapshot_content/output.py new file mode 100644 index 00000000..0776ca93 --- /dev/null +++ b/lib/k8s/virtual_machine_snapshot_content/output.py @@ -0,0 +1,33 @@ +class K8sVirtualMachineSnapshotContentOutput(): + def __init__(self): + pass + + def print_virtual_machine_snapshot_contents(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Snapshot Content [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/volume_attachment/__init__.py b/lib/k8s/volume_attachment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/volume_attachment/api.py b/lib/k8s/volume_attachment/api.py new file mode 100644 index 00000000..0e533d5e --- /dev/null +++ b/lib/k8s/volume_attachment/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVolumeAttachmentApi(): + def __init__(self): + self.volume_attachment_mo = None + + def get_volume_attachment_mo(self, cache_enabled=True): + if cache_enabled: + if self.volume_attachment_mo is not None: + return self.volume_attachment_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='storage.k8s.io/v1', + kind='VolumeAttachment' + ) + self.volume_attachment_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'volume_attachment', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_volume_attachment_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'volume_attachment', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'volume_attachment', + self.volume_attachment_mo + ) + + return self.volume_attachment_mo diff --git a/lib/k8s/volume_attachment/info.py b/lib/k8s/volume_attachment/info.py new file mode 100644 index 00000000..a72d3720 --- /dev/null +++ b/lib/k8s/volume_attachment/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVolumeAttachmentInfo(): + def __init__(self): + self.volume_attachment = None + + def get_volume_attachment_info(self, volume_attachment_mo): + if volume_attachment_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + volume_attachment_mo + ) + info.update(metadata_info) + + return info + + def get_volume_attachments_info(self, cache_enabled=True): + if cache_enabled: + if self.volume_attachment is not None: + return self.volume_attachment + + managed_objects = self.get_volume_attachment_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.volume_attachment = [] + for managed_object in managed_objects: + volume_attachment_info = {} + volume_attachment_info['info'] = self.get_volume_attachment_info( + managed_object + ) + volume_attachment_info['mo'] = managed_object + self.volume_attachment.append( + volume_attachment_info + ) + + return self.volume_attachment + + def match_volume_attachment(self, volume_attachment_info, volume_attachment_filter): + if volume_attachment_filter is None or len(volume_attachment_filter) == 0: + return True + + for ap_rule in volume_attachment_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_volume_attachment', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_volume_attachments(self, object_filter=None, return_mo=False, cache_enabled=True): + all_volume_attachments = self.get_volume_attachments_info(cache_enabled=cache_enabled) + if all_volume_attachments is None: + return None + + volume_attachments = [] + + for volume_attachment_info in all_volume_attachments: + if not self.match_volume_attachment(volume_attachment_info['info'], object_filter): + continue + + if return_mo: + volume_attachments.append( + volume_attachment_info['mo'] + ) + continue + + volume_attachments.append( + volume_attachment_info['info'] + ) + + return volume_attachments diff --git a/lib/k8s/volume_attachment/main.py b/lib/k8s/volume_attachment/main.py new file mode 100644 index 00000000..150878d5 --- /dev/null +++ b/lib/k8s/volume_attachment/main.py @@ -0,0 +1,11 @@ +from lib.k8s.volume_attachment.api import K8sVolumeAttachmentApi +from lib.k8s.volume_attachment.info import K8sVolumeAttachmentInfo + + +class K8sVolumeAttachment( + K8sVolumeAttachmentApi, + K8sVolumeAttachmentInfo + ): + def __init__(self): + K8sVolumeAttachmentApi.__init__(self) + K8sVolumeAttachmentInfo.__init__(self) diff --git a/lib/k8s/volume_attachment/output.py b/lib/k8s/volume_attachment/output.py new file mode 100644 index 00000000..adb8275d --- /dev/null +++ b/lib/k8s/volume_attachment/output.py @@ -0,0 +1,33 @@ +class K8sVolumeAttachmentOutput(): + def __init__(self): + pass + + def print_volume_attachments(self, info, title=False): + if title: + self.my_output.default( + 'Volume Attachment [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/volume_snapshot copy/info.py b/lib/k8s/volume_snapshot copy/info.py new file mode 100644 index 00000000..fb8cc828 --- /dev/null +++ b/lib/k8s/volume_snapshot copy/info.py @@ -0,0 +1,75 @@ +class K8sVolumeSnapshotInfo(): + def __init__(self): + self.volume_snapshot = None + + def get_volume_snapshot_info(self, volume_snapshot_mo): + if volume_snapshot_mo is None: + return None + + info = {} + info['__Output'] = {} + + return info + + def get_volume_snapshots_info(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot is not None: + return self.volume_snapshot + + managed_objects = self.get_volume_snapshot_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.volume_snapshot = [] + for managed_object in managed_objects: + volume_snapshot_info = {} + volume_snapshot_info['info'] = self.get_volume_snapshot_info( + managed_object + ) + volume_snapshot_info['mo'] = managed_object + self.volume_snapshot.append( + volume_snapshot_info + ) + + return self.volume_snapshot + + def match_volume_snapshot(self, volume_snapshot_info, volume_snapshot_filter): + if volume_snapshot_filter is None or len(volume_snapshot_filter) == 0: + return True + + for ap_rule in volume_snapshot_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_volume_snapshot', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_volume_snapshots(self, object_filter=None, return_mo=False, cache_enabled=True): + all_volume_snapshots = self.get_volume_snapshots_info(cache_enabled=cache_enabled) + if all_volume_snapshots is None: + return None + + volume_snapshots = [] + + for volume_snapshot_info in all_volume_snapshots: + if not self.match_volume_snapshot(volume_snapshot_info['info'], object_filter): + continue + + if return_mo: + volume_snapshots.append( + volume_snapshot_info['mo'] + ) + continue + + volume_snapshots.append( + volume_snapshot_info['info'] + ) + + return volume_snapshots diff --git a/lib/k8s/volume_snapshot/__init__.py b/lib/k8s/volume_snapshot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/volume_snapshot/api.py b/lib/k8s/volume_snapshot/api.py new file mode 100644 index 00000000..480b6c79 --- /dev/null +++ b/lib/k8s/volume_snapshot/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVolumeSnapshotApi(): + def __init__(self): + self.volume_snapshot_mo = None + + def get_volume_snapshot_mo(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot_mo is not None: + return self.volume_snapshot_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='snapshot.storage.k8s.io/v1', + kind='VolumeSnapshot' + ) + self.volume_snapshot_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'volume_snapshot', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_volume_snapshot_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'volume_snapshot', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'volume_snapshot', + self.volume_snapshot_mo + ) + + return self.volume_snapshot_mo diff --git a/lib/k8s/volume_snapshot/info.py b/lib/k8s/volume_snapshot/info.py new file mode 100644 index 00000000..3cfa40af --- /dev/null +++ b/lib/k8s/volume_snapshot/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVolumeSnapshotInfo(): + def __init__(self): + self.volume_snapshot = None + + def get_volume_snapshot_info(self, volume_snapshot_mo): + if volume_snapshot_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + volume_snapshot_mo + ) + info.update(metadata_info) + + return info + + def get_volume_snapshots_info(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot is not None: + return self.volume_snapshot + + managed_objects = self.get_volume_snapshot_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.volume_snapshot = [] + for managed_object in managed_objects: + volume_snapshot_info = {} + volume_snapshot_info['info'] = self.get_volume_snapshot_info( + managed_object + ) + volume_snapshot_info['mo'] = managed_object + self.volume_snapshot.append( + volume_snapshot_info + ) + + return self.volume_snapshot + + def match_volume_snapshot(self, volume_snapshot_info, volume_snapshot_filter): + if volume_snapshot_filter is None or len(volume_snapshot_filter) == 0: + return True + + for ap_rule in volume_snapshot_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_volume_snapshot', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_volume_snapshots(self, object_filter=None, return_mo=False, cache_enabled=True): + all_volume_snapshots = self.get_volume_snapshots_info(cache_enabled=cache_enabled) + if all_volume_snapshots is None: + return None + + volume_snapshots = [] + + for volume_snapshot_info in all_volume_snapshots: + if not self.match_volume_snapshot(volume_snapshot_info['info'], object_filter): + continue + + if return_mo: + volume_snapshots.append( + volume_snapshot_info['mo'] + ) + continue + + volume_snapshots.append( + volume_snapshot_info['info'] + ) + + return volume_snapshots diff --git a/lib/k8s/volume_snapshot/main.py b/lib/k8s/volume_snapshot/main.py new file mode 100644 index 00000000..9d72ca92 --- /dev/null +++ b/lib/k8s/volume_snapshot/main.py @@ -0,0 +1,11 @@ +from lib.k8s.volume_snapshot.api import K8sVolumeSnapshotApi +from lib.k8s.volume_snapshot.info import K8sVolumeSnapshotInfo + + +class K8sVolumeSnapshot( + K8sVolumeSnapshotApi, + K8sVolumeSnapshotInfo + ): + def __init__(self): + K8sVolumeSnapshotApi.__init__(self) + K8sVolumeSnapshotInfo.__init__(self) diff --git a/lib/k8s/volume_snapshot/output.py b/lib/k8s/volume_snapshot/output.py new file mode 100644 index 00000000..d857f6c0 --- /dev/null +++ b/lib/k8s/volume_snapshot/output.py @@ -0,0 +1,33 @@ +class K8sVolumeSnapshotOutput(): + def __init__(self): + pass + + def print_volume_snapshots(self, info, title=False): + if title: + self.my_output.default( + 'Volume Snapshot [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/volume_snapshot_class/__init__.py b/lib/k8s/volume_snapshot_class/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/volume_snapshot_class/api.py b/lib/k8s/volume_snapshot_class/api.py new file mode 100644 index 00000000..d767f722 --- /dev/null +++ b/lib/k8s/volume_snapshot_class/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVolumeSnapshotClassApi(): + def __init__(self): + self.volume_snapshot_class_mo = None + + def get_volume_snapshot_class_mo(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot_class_mo is not None: + return self.volume_snapshot_class_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='snapshot.storage.k8s.io/v1', + kind='VolumeSnapshotClass' + ) + self.volume_snapshot_class_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'volume_snapshot_class', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_volume_snapshot_class_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'volume_snapshot_class', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'volume_snapshot_class', + self.volume_snapshot_class_mo + ) + + return self.volume_snapshot_class_mo diff --git a/lib/k8s/volume_snapshot_class/info.py b/lib/k8s/volume_snapshot_class/info.py new file mode 100644 index 00000000..be65bbf9 --- /dev/null +++ b/lib/k8s/volume_snapshot_class/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVolumeSnapshotClassInfo(): + def __init__(self): + self.volume_snapshot_class = None + + def get_volume_snapshot_class_info(self, volume_snapshot_class_mo): + if volume_snapshot_class_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + volume_snapshot_class_mo + ) + info.update(metadata_info) + + return info + + def get_volume_snapshot_classs_info(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot_class is not None: + return self.volume_snapshot_class + + managed_objects = self.get_volume_snapshot_class_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.volume_snapshot_class = [] + for managed_object in managed_objects: + volume_snapshot_class_info = {} + volume_snapshot_class_info['info'] = self.get_volume_snapshot_class_info( + managed_object + ) + volume_snapshot_class_info['mo'] = managed_object + self.volume_snapshot_class.append( + volume_snapshot_class_info + ) + + return self.volume_snapshot_class + + def match_volume_snapshot_class(self, volume_snapshot_class_info, volume_snapshot_class_filter): + if volume_snapshot_class_filter is None or len(volume_snapshot_class_filter) == 0: + return True + + for ap_rule in volume_snapshot_class_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_volume_snapshot_class', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_volume_snapshot_classs(self, object_filter=None, return_mo=False, cache_enabled=True): + all_volume_snapshot_classs = self.get_volume_snapshot_classs_info(cache_enabled=cache_enabled) + if all_volume_snapshot_classs is None: + return None + + volume_snapshot_classs = [] + + for volume_snapshot_class_info in all_volume_snapshot_classs: + if not self.match_volume_snapshot_class(volume_snapshot_class_info['info'], object_filter): + continue + + if return_mo: + volume_snapshot_classs.append( + volume_snapshot_class_info['mo'] + ) + continue + + volume_snapshot_classs.append( + volume_snapshot_class_info['info'] + ) + + return volume_snapshot_classs diff --git a/lib/k8s/volume_snapshot_class/main.py b/lib/k8s/volume_snapshot_class/main.py new file mode 100644 index 00000000..ed8cacfa --- /dev/null +++ b/lib/k8s/volume_snapshot_class/main.py @@ -0,0 +1,11 @@ +from lib.k8s.volume_snapshot_class.api import K8sVolumeSnapshotClassApi +from lib.k8s.volume_snapshot_class.info import K8sVolumeSnapshotClassInfo + + +class K8sVolumeSnapshotClass( + K8sVolumeSnapshotClassApi, + K8sVolumeSnapshotClassInfo + ): + def __init__(self): + K8sVolumeSnapshotClassApi.__init__(self) + K8sVolumeSnapshotClassInfo.__init__(self) diff --git a/lib/k8s/volume_snapshot_class/output.py b/lib/k8s/volume_snapshot_class/output.py new file mode 100644 index 00000000..1ab5417a --- /dev/null +++ b/lib/k8s/volume_snapshot_class/output.py @@ -0,0 +1,33 @@ +class K8sVolumeSnapshotClassOutput(): + def __init__(self): + pass + + def print_alert_managers(self, info, title=False): + if title: + self.my_output.default( + 'Volume Snapshot Class [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/k8s/volume_snapshot_content/__init__.py b/lib/k8s/volume_snapshot_content/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/k8s/volume_snapshot_content/api.py b/lib/k8s/volume_snapshot_content/api.py new file mode 100644 index 00000000..0a7ec802 --- /dev/null +++ b/lib/k8s/volume_snapshot_content/api.py @@ -0,0 +1,48 @@ +import time +import traceback + + +class K8sVolumeSnapshotContentApi(): + def __init__(self): + self.volume_snapshot_content_mo = None + + def get_volume_snapshot_content_mo(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot_content_mo is not None: + return self.volume_snapshot_content_mo + + api_handler = self.get_api(cluster_type='ocp') + if api_handler is None: + return None + + try: + start_time = int(time.time() * 1000) + response = api_handler.resources.get( + api_version='snapshot.storage.k8s.io/v1', + kind='VolumeSnapshotContent' + ) + self.volume_snapshot_content_mo = response.get().to_dict()['items'] + self.log.k8s( + 'get', + 'volume_snapshot_content', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('k8s.get_volume_snapshot_content_mo', traceback.format_exc()) + self.log.k8s( + 'get', + 'volume_snapshot_content', + True, + int(time.time() * 1000) - start_time + ) + print(traceback.format_exc()) + return None + + self.log.k8s_mo( + 'volume_snapshot_content', + self.volume_snapshot_content_mo + ) + + return self.volume_snapshot_content_mo diff --git a/lib/k8s/volume_snapshot_content/info.py b/lib/k8s/volume_snapshot_content/info.py new file mode 100644 index 00000000..b726e30e --- /dev/null +++ b/lib/k8s/volume_snapshot_content/info.py @@ -0,0 +1,83 @@ +from lib import filter_helper + + +class K8sVolumeSnapshotContentInfo(): + def __init__(self): + self.volume_snapshot_content = None + + def get_volume_snapshot_content_info(self, volume_snapshot_content_mo): + if volume_snapshot_content_mo is None: + return None + + info = {} + info['__Output'] = {} + + metadata_info = self.get_metadata_info( + volume_snapshot_content_mo + ) + info.update(metadata_info) + + return info + + def get_volume_snapshot_contents_info(self, cache_enabled=True): + if cache_enabled: + if self.volume_snapshot_content is not None: + return self.volume_snapshot_content + + managed_objects = self.get_volume_snapshot_content_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.volume_snapshot_content = [] + for managed_object in managed_objects: + volume_snapshot_content_info = {} + volume_snapshot_content_info['info'] = self.get_volume_snapshot_content_info( + managed_object + ) + volume_snapshot_content_info['mo'] = managed_object + self.volume_snapshot_content.append( + volume_snapshot_content_info + ) + + return self.volume_snapshot_content + + def match_volume_snapshot_content(self, volume_snapshot_content_info, volume_snapshot_content_filter): + if volume_snapshot_content_filter is None or len(volume_snapshot_content_filter) == 0: + return True + + for ap_rule in volume_snapshot_content_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_volume_snapshot_content', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_volume_snapshot_contents(self, object_filter=None, return_mo=False, cache_enabled=True): + all_volume_snapshot_contents = self.get_volume_snapshot_contents_info(cache_enabled=cache_enabled) + if all_volume_snapshot_contents is None: + return None + + volume_snapshot_contents = [] + + for volume_snapshot_content_info in all_volume_snapshot_contents: + if not self.match_volume_snapshot_content(volume_snapshot_content_info['info'], object_filter): + continue + + if return_mo: + volume_snapshot_contents.append( + volume_snapshot_content_info['mo'] + ) + continue + + volume_snapshot_contents.append( + volume_snapshot_content_info['info'] + ) + + return volume_snapshot_contents diff --git a/lib/k8s/volume_snapshot_content/main.py b/lib/k8s/volume_snapshot_content/main.py new file mode 100644 index 00000000..866f9e3a --- /dev/null +++ b/lib/k8s/volume_snapshot_content/main.py @@ -0,0 +1,11 @@ +from lib.k8s.volume_snapshot_content.api import K8sVolumeSnapshotContentApi +from lib.k8s.volume_snapshot_content.info import K8sVolumeSnapshotContentInfo + + +class K8sVolumeSnapshotContent( + K8sVolumeSnapshotContentApi, + K8sVolumeSnapshotContentInfo + ): + def __init__(self): + K8sVolumeSnapshotContentApi.__init__(self) + K8sVolumeSnapshotContentInfo.__init__(self) diff --git a/lib/k8s/volume_snapshot_content/output.py b/lib/k8s/volume_snapshot_content/output.py new file mode 100644 index 00000000..0f61c12f --- /dev/null +++ b/lib/k8s/volume_snapshot_content/output.py @@ -0,0 +1,33 @@ +class K8sVolumeSnapshotContentOutput(): + def __init__(self): + pass + + def print_volume_snapshot_contents(self, info, title=False): + if title: + self.my_output.default( + 'Volume Snapshot Content [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tbd' + ] + + headers = [ + 'tbd' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/kubevirt/README.md b/lib/kubevirt/README.md new file mode 100644 index 00000000..71128df1 --- /dev/null +++ b/lib/kubevirt/README.md @@ -0,0 +1,34 @@ +important fix in windows + +C:\Users\\AppData\Local\Programs\Python\Python39\Lib\site-packages\kubevirt\api_client.py + + def __call_api(self, resource_path, method, + path_params=None, query_params=None, header_params=None, + body=None, post_params=None, files=None, + response_type=None, auth_settings=None, callback=None, + _return_http_data_only=None, collection_formats=None, _preload_content=True, + _request_timeout=None): + + config = Configuration() + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params['Cookie'] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict(self.parameters_to_tuples(header_params, + collection_formats)) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples(path_params, + collection_formats) + for k, v in path_params: + # THIS NEEDS TO BE CHANGED + resource_path = resource_path.replace( + '{%s}' % k, quote(str(v), safe=config.safe_chars_for_path_param)) + resource_path = resource_path.replace( + '{%s:[a-z0-9][a-z0-9\-]*}' % k, quote(str(v), safe=config.safe_chars_for_path_param)) diff --git a/lib/kubevirt/__init__.py b/lib/kubevirt/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/kubevirt/__pycache__/__init__.cpython-310.pyc b/lib/kubevirt/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4fcd532b Binary files /dev/null and b/lib/kubevirt/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/kubevirt/__pycache__/main.cpython-310.pyc b/lib/kubevirt/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8e0e0aed Binary files /dev/null and b/lib/kubevirt/__pycache__/main.cpython-310.pyc differ diff --git a/lib/kubevirt/__pycache__/vm.cpython-310.pyc b/lib/kubevirt/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..36366ff7 Binary files /dev/null and b/lib/kubevirt/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/kubevirt/__pycache__/vmi.cpython-310.pyc b/lib/kubevirt/__pycache__/vmi.cpython-310.pyc new file mode 100644 index 00000000..3229b0f9 Binary files /dev/null and b/lib/kubevirt/__pycache__/vmi.cpython-310.pyc differ diff --git a/lib/kubevirt/api.py b/lib/kubevirt/api.py new file mode 100644 index 00000000..7de5f702 --- /dev/null +++ b/lib/kubevirt/api.py @@ -0,0 +1,57 @@ +import os +import time +import traceback + +from kubernetes import config +import kubevirt + + +class KubevirtApi(): + def __init__(self, kubeconfig_filename): + self.kubeconfig_filename = kubeconfig_filename + self.api = None + + def connect(self): + # https://github.com/kubevirt/client-python + if self.api is not None: + return True + + if not os.path.isfile(self.kubeconfig_filename): + self.log.error( + 'k8s.connect', + 'Kubeconfig file not found: %s' % (self.kubeconfig_filename) + ) + return False + + try: + start_time = int(time.time() * 1000) + + config_loader = config.kube_config._get_kube_config_loader_for_yaml_file( + self.kubeconfig_filename + ) + + kubevirt_configuration = kubevirt.configuration + kubevirt_configuration.verify_ssl = False + config_loader.load_and_set( + kubevirt_configuration + ) + + api_client = kubevirt.ApiClient() + self.api = kubevirt.DefaultApi(api_client=api_client) + + self.log.kubevirt( + 'connect', + '-', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error( + 'kubevirt.connect', + 'Kubeconfig file failed: %s' % (self.kubeconfig_filename) + ) + self.log.error('k8s.connect', traceback.format_exc()) + return False + + return True diff --git a/lib/kubevirt/common.py b/lib/kubevirt/common.py new file mode 100644 index 00000000..1699294f --- /dev/null +++ b/lib/kubevirt/common.py @@ -0,0 +1,136 @@ +import time +import datetime + + +class KubevirtCommon(): + def __init__(self): + pass + + def _get(self, value, key): + if value is None: + return '__ERROR' + + if ':' in key: + subkey = key.split(':')[0] + if subkey not in value: + return '__ERROR' + + new_key = ':'.join(key.split(':')[1:]) + return self._get(value[subkey], new_key) + + if key in value: + return value[key] + + return '__ERROR' + + def get(self, managed_object, key, on_error=None, on_none=None): + if managed_object is None: + return on_error + + if not isinstance(managed_object, dict): + return on_error + + value = self._get(managed_object, key) + if value == '__ERROR': + return on_error + + if value is None: + return on_none + + return value + + def convert_object(self, item): + if item is None: + return None + + if isinstance(item, str): + return item + + if isinstance(item, int): + return item + + if isinstance(item, dict): + converted = {} + for key in item: + converted[key] = self.convert_object( + item[key] + ) + return converted + + if isinstance(item, list): + converted = [] + for key in item: + converted.append( + self.convert_object( + key + ) + ) + return converted + + converted = str( + item + ) + + return converted + + def convert_age(self, seconds): + if seconds > 60 * 60 * 24: + return '%sd' % (int(seconds / (60 * 60 * 24))) + + if seconds > 60 * 60: + hours = 0 + while True: + if seconds < 60 * 60: + break + + hours = hours + 1 + seconds = seconds - 60 * 60 + + return '%sh%sm' % ( + hours, + int(seconds / 60) + ) + + if seconds > 60: + return '%sm' % (int(seconds / 60)) + + return '%ss' % (seconds) + + def convert_timestamp(self, timestamp): + if timestamp is None: + return None + + new_timestamp = None + if isinstance(timestamp, str): + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S%z').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp.rstrip('Z'), '%Y-%m-%dT%H:%M:%S').timetuple())) + except BaseException: + pass + + return new_timestamp + + try: + new_timestamp = int(timestamp.timestamp()) + except BaseException: + pass + + return new_timestamp + + def convert_timestamp_to_age(self, timestamp, on_error=None): + timestamp = self.convert_timestamp(timestamp) + if timestamp is None: + return on_error + + return self.convert_age(int(time.time()) - timestamp) diff --git a/lib/kubevirt/main.py b/lib/kubevirt/main.py new file mode 100644 index 00000000..4e3f12bd --- /dev/null +++ b/lib/kubevirt/main.py @@ -0,0 +1,24 @@ +from lib import log_helper + +from lib.kubevirt.api import KubevirtApi +from lib.kubevirt.common import KubevirtCommon +from lib.kubevirt.virtual_machine.main import KubevirtVirtualMachine +from lib.kubevirt.virtual_machine_instance.main import KubevirtVirtualMachineInstance + + +class Kubevirt( + KubevirtApi, + KubevirtCommon, + KubevirtVirtualMachine, + KubevirtVirtualMachineInstance + ): + def __init__(self, kubeconfig_filename, verbose=False, debug=False, log_id=None): + self.verbose = verbose + self.debug = debug + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + KubevirtApi.__init__(self, kubeconfig_filename) + KubevirtCommon.__init__(self) + KubevirtVirtualMachine.__init__(self) + KubevirtVirtualMachineInstance.__init__(self) diff --git a/lib/kubevirt/output.py b/lib/kubevirt/output.py new file mode 100644 index 00000000..0e5f08ea --- /dev/null +++ b/lib/kubevirt/output.py @@ -0,0 +1,19 @@ +from lib import output_helper + +from lib.kubevirt.virtual_machine.output import KubevirtVirtualMachineOutput +from lib.kubevirt.virtual_machine_instance.output import KubevirtVirtualMachineInstanceOutput + + +class KubevirtOutput( + KubevirtVirtualMachineOutput, + KubevirtVirtualMachineInstanceOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + KubevirtVirtualMachineOutput.__init__(self) + KubevirtVirtualMachineInstanceOutput.__init__(self) diff --git a/lib/kubevirt/virtual_machine/__init__.py b/lib/kubevirt/virtual_machine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/kubevirt/virtual_machine/api.py b/lib/kubevirt/virtual_machine/api.py new file mode 100644 index 00000000..66ddea1d --- /dev/null +++ b/lib/kubevirt/virtual_machine/api.py @@ -0,0 +1,184 @@ +import time +import traceback +import kubevirt + + +class KubevirtVirtualMachineApi(): + def __init__(self): + self.virtual_machine_mo = None + + def patch_namespaced_virtual_machine(self, namespace, name, body): + if not self.connect(): + return False + + if self.api is None: + return False + + start_time = int(time.time() * 1000) + + try: + api_response = self.api.patch_namespaced_virtual_machine( + name, + namespace, + body + ) + except BaseException: + api_response = None + self.log.error( + 'kubevirt.patch_namespaced_virtual_machine', + traceback.format_exc() + ) + + self.log.kubevirt( + 'patch', + 'vm', + True, + int(time.time() * 1000) - start_time + ) + + if api_response is None: + return False + + return True + + def create_namespaced_virtual_machine(self, vm_definition): + if not self.connect(): + return False + + if self.api is None: + return False + + start_time = int(time.time() * 1000) + + namespace = vm_definition['metadata']['namespace'] + body = kubevirt.V1VirtualMachine( + api_version=vm_definition['apiVersion'], + kind='VirtualMachine', + metadata=vm_definition['metadata'], + spec=vm_definition['spec'] + ) + + try: + api_response = self.api.create_namespaced_virtual_machine( + body, + namespace + ) + except BaseException: + api_response = None + self.log.error( + 'kubevirt.create_namespaced_virtual_machine', + traceback.format_exc() + ) + + if api_response is None: + self.log.kubevirt( + 'create', + 'vm', + False, + int(time.time() * 1000) - start_time + ) + return False + + self.log.kubevirt( + 'create', + 'vm', + True, + int(time.time() * 1000) - start_time + ) + + return True + + def delete_namespaced_virtual_machine(self, namespace, name): + if not self.connect(): + return False + + if self.api is None: + return False + + start_time = int(time.time() * 1000) + + body = kubevirt.K8sIoApimachineryPkgApisMetaV1DeleteOptions() + + try: + api_response = self.api.delete_namespaced_virtual_machine( + name, + namespace, + body + ) + except BaseException: + api_response = None + self.log.error( + 'kubevirt.delete_namespaced_virtual_machine', + traceback.format_exc() + ) + + self.log.kubevirt( + 'delete', + 'vm', + True, + int(time.time() * 1000) - start_time + ) + + if api_response is None: + return False + + return True + + def start_virtual_machine(self, namespace, name): + body = {} + body['spec'] = {} + body['spec']['running'] = True + return self.patch_namespaced_virtual_machine(namespace, name, body) + + def stop_virtual_machine(self, namespace, name): + body = {} + body['spec'] = {} + body['spec']['running'] = False + return self.patch_namespaced_virtual_machine(namespace, name, body) + + def get_virtual_machine_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_mo is not None: + return self.virtual_machine_mo + + if not self.connect(): + return None + + if self.api is None: + return None + + try: + start_time = int(time.time() * 1000) + api_response = self.api.list_virtual_machine_for_all_namespaces() + if api_response is not None: + self.virtual_machine_mo = [] + for obj in api_response.items: + self.virtual_machine_mo.append( + obj.to_dict() + ) + + self.log.kubevirt( + 'get', + 'virtual_machine', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error( + 'kubevirt.get_virtual_machine_mo', + traceback.format_exc() + ) + self.log.kubevirt( + 'get', + 'virtual_machine', + True, + int(time.time() * 1000) - start_time + ) + + self.log.kubevirt_mo( + 'vm', + self.virtual_machine_mo + ) + + return self.virtual_machine_mo diff --git a/lib/kubevirt/virtual_machine/info.py b/lib/kubevirt/virtual_machine/info.py new file mode 100644 index 00000000..5168766b --- /dev/null +++ b/lib/kubevirt/virtual_machine/info.py @@ -0,0 +1,481 @@ +import time + +from lib import filter_helper + + +class KubevirtVirtualMachineInfo(): + def __init__(self): + self.virtual_machine = None + + def get_virtual_machine_disk_type(self, disk_mo): + if disk_mo is None: + return 'n/a' + + if 'cdrom' in disk_mo and disk_mo['cdrom'] is not None: + return 'cdrom' + + if 'disk' in disk_mo and disk_mo['disk'] is not None: + return 'disk' + + if 'lun' in disk_mo and disk_mo['lun'] is not None: + return 'lun' + + return 'unknown' + + def get_virtual_machine_disk_volume_spec_info(self, volume_spec_mo): + info = {} + info['name'] = volume_spec_mo['name'] + info['type'] = 'unknown' + info['attributes'] = {} + info['info'] = info['name'] + + if 'cloud_init_config_drive' in volume_spec_mo and volume_spec_mo['cloud_init_config_drive'] is not None: + info['type'] = 'cloudInitConfigDrive' + for key in volume_spec_mo['cloud_init_config_drive']: + info['attributes'][key] = volume_spec_mo['cloud_init_config_drive'][key] + + info['info'] = '%s (cloud-init-config-drive)' % ( + info['name'] + ) + + if 'cloud_init_no_cloud' in volume_spec_mo and volume_spec_mo['cloud_init_no_cloud'] is not None: + info['type'] = 'cloudInitNoCloud' + for key in volume_spec_mo['cloud_init_no_cloud']: + info['attributes'][key] = volume_spec_mo['cloud_init_no_cloud'][key] + + info['info'] = '%s (cloud-init-no-cloud)' % ( + info['name'] + ) + + if 'config_map' in volume_spec_mo and volume_spec_mo['config_map'] is not None: + info['type'] = 'configMap' + for key in volume_spec_mo['config_map']: + info['attributes'][key] = volume_spec_mo['config_map'][key] + + info['info'] = '%s (config-map)' % ( + info['name'] + ) + + if 'container_disk' in volume_spec_mo and volume_spec_mo['container_disk'] is not None: + info['type'] = 'containerDisk' + for key in volume_spec_mo['container_disk']: + info['attributes'][key] = volume_spec_mo['container_disk'][key] + + info['info'] = '%s (cont-disk)' % ( + info['name'] + ) + + if 'data_volume' in volume_spec_mo and volume_spec_mo['data_volume'] is not None: + info['type'] = 'dataVolume' + for key in volume_spec_mo['data_volume']: + info['attributes'][key] = volume_spec_mo['data_volume'][key] + + info['info'] = '%s - %s (dv)' % ( + info['name'], + info['attributes']['name'] + ) + + if 'empty_disk' in volume_spec_mo and volume_spec_mo['empty_disk'] is not None: + info['type'] = 'emptyDisk' + for key in volume_spec_mo['empty_disk']: + info['attributes'][key] = volume_spec_mo['empty_disk'][key] + + info['info'] = '%s (empty-disk)' % ( + info['name'] + ) + + if 'host_disk' in volume_spec_mo and volume_spec_mo['host_disk'] is not None: + info['type'] = 'hostDisk' + for key in volume_spec_mo['host_disk']: + info['attributes'][key] = volume_spec_mo['host_disk'][key] + + info['info'] = '%s (host-disk)' % ( + info['name'] + ) + + if 'ephemeral' in volume_spec_mo and volume_spec_mo['ephemeral'] is not None: + info['type'] = 'ephemeral' + for key in volume_spec_mo['ephemeral']: + info['attributes'][key] = volume_spec_mo['ephemeral'][key] + + info['info'] = '%s (ephemeral)' % ( + info['name'] + ) + + if 'persistent_volume_claim' in volume_spec_mo and volume_spec_mo['persistent_volume_claim'] is not None: + info['type'] = 'persistentVolumeClaim' + for key in volume_spec_mo['persistent_volume_claim']: + info['attributes'][key] = volume_spec_mo['persistent_volume_claim'][key] + + info['info'] = '%s - %s (pvc)' % ( + info['name'], + info['attributes']['claim_name'] + ) + + if 'secret' in volume_spec_mo and volume_spec_mo['secret'] is not None: + info['type'] = 'secret' + for key in volume_spec_mo['secret']: + info['attributes'][key] = volume_spec_mo['secret'][key] + + info['info'] = '%s (secret)' % ( + info['name'] + ) + + return info + + def get_virtual_machine_info(self, virtual_machine_mo): + if virtual_machine_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['namespace'] = self.get(virtual_machine_mo, 'metadata:namespace') + info['name'] = self.get(virtual_machine_mo, 'metadata:name') + info['namespace_name'] = '%s/%s' % ( + info['namespace'], + info['name'] + ) + + info['vm_id'] = self.get(virtual_machine_mo, 'metadata:uid') + info['special'] = self.get(virtual_machine_mo, 'spec:template:metadata:labels:special') + info['cpu'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:cpu') + info['memory'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:resources:requests:memory') + info['state'] = self.get(virtual_machine_mo, 'status:printable_status') + + info['running'] = False + info['provisioning'] = False + info['stopped'] = False + if info['state'] is not None and info['state'] == 'Running': + info['running'] = True + if info['state'] is not None and info['state'] == 'Stopped': + info['stopped'] = True + if info['state'] is not None and info['state'] == 'Provisioning': + info['provisioning'] = True + + info['disks'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:devices:disks') + info['volumes'] = self.get(virtual_machine_mo, 'spec:template:spec:volumes') + + if info['disks'] is not None: + for disk_mo in info['disks']: + disk_mo['info'] = disk_mo['name'] + disk_mo['type'] = self.get_virtual_machine_disk_type(disk_mo) + disk_mo['bus'] = '' + if disk_mo['type'] == 'cdrom': + disk_mo['bus'] = self.get(disk_mo, 'cdrom:bus') + if disk_mo['type'] == 'disk': + disk_mo['bus'] = self.get(disk_mo, 'disk:bus') + if info['volumes'] is not None: + for volume_mo in info['volumes']: + if volume_mo['name'] == disk_mo['name']: + disk_mo['volume'] = self.get_virtual_machine_disk_volume_spec_info(volume_mo) + + info['networks'] = self.get(virtual_machine_mo, 'spec:template:spec:networks') + info['interfaces'] = self.get(virtual_machine_mo, 'spec:template:spec:domain:devices:interfaces') + if info['interfaces'] is not None: + for interface_info in info['interfaces']: + interface_info['__Output'] = {} + interface_info['podTick'] = '' + interface_info['multusTick'] = '' + interface_info['multusNetworkName'] = '' + interface_info['sriovEnabled'] = False + interface_info['sriovTick'] = '' + interface_info['masqueradeTick'] = '' + + if info['networks'] is not None: + for network_info in info['networks']: + if interface_info['name'] == network_info['name']: + if 'multus' in network_info and network_info['multus'] is not None: + interface_info['multusTick'] = '\u2713' + interface_info['__Output']['multusTick'] = 'Green' + if network_info['multus']['network_name'] is not None: + interface_info['multusNetworkName'] = network_info['multus']['network_name'] + + if 'multus' not in network_info or network_info['multus'] is None: + if network_info['pod'] is not None: + interface_info['podTick'] = '\u2713' + interface_info['__Output']['podTick'] = 'Green' + + if interface_info['sriov'] is not None: + interface_info['sriovTick'] = '\u2713' + interface_info['__Output']['sriovTick'] = 'Green' + interface_info['sriovEnabled'] = True + + if interface_info['masquerade'] is not None: + interface_info['masqueradeTick'] = '\u2713' + interface_info['__Output']['masqueradeTick'] = 'Green' + + info['ready'] = False + info['readyTick'] = '\u2717' + info['__Output']['readyTick'] = 'Red' + + info['liveMigration'] = False + info['liveMigrationTick'] = '\u2717' + info['__Output']['liveMigrationTick'] = 'Red' + + info['failures'] = [] + info['failure'] = False + info['failureTick'] = '' + + conditions = self.get(virtual_machine_mo, 'status:conditions') + if conditions is not None: + for condition in conditions: + if condition['type'] == 'Ready': + if condition['status'] == 'True': + info['ready'] = True + info['readyTick'] = '\u2713' + info['__Output']['readyTick'] = 'Green' + + continue + + if condition['type'] == 'LiveMigratable': + if condition['status'] == 'True': + info['ready'] = True + info['liveMigrationTick'] = '\u2713' + info['__Output']['liveMigrationTick'] = 'Green' + + continue + + if condition['type'] == 'Initialized': + continue + + if condition['type'] == 'Paused': + continue + + if condition['type'] == 'AgentConnected': + continue + + if condition['type'] == 'Provisioning': + continue + + if condition['type'] == 'Synchronized': + continue + + if condition['type'] == 'PodScheduled': + if condition['status'] == 'False': + info['failures'].append( + condition['reason'] + ) + if 'message' in condition and condition['message'] is not None: + info['failures'] = info['failures'] + filter_helper.get_string_chunks( + filter_helper.sanitize_string( + condition['message'] + ), + 30 + ) + + info['failure'] = True + info['failureTick'] = '\u2713' + info['__Output']['failureTick'] = 'Red' + continue + + if condition['type'] == 'Failure': + info['failures'].append(condition) + info['failure'] = True + info['failureTick'] = '\u2713' + info['__Output']['failureTick'] = 'Red' + continue + + self.log.error( + 'get_virtual_machine_info', + 'Unsupported condition type: %s' % (condition) + ) + + return info + + def get_virtual_machines_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine is not None: + return self.virtual_machine + + managed_objects = self.get_virtual_machine_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine = [] + virtual_machines_info = [] + for managed_object in managed_objects: + virtual_machine_info = {} + virtual_machine_info['info'] = self.get_virtual_machine_info( + managed_object + ) + virtual_machines_info.append( + virtual_machine_info['info'] + ) + virtual_machine_info['mo'] = managed_object + self.virtual_machine.append( + virtual_machine_info + ) + + self.log.kubevirt_mo( + 'vm.info', + virtual_machines_info + ) + + return self.virtual_machine + + def match_virtual_machine(self, virtual_machine_info, virtual_machine_filter): + if virtual_machine_filter is None or len(virtual_machine_filter) == 0: + return True + + for ap_rule in virtual_machine_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, virtual_machine_info['namespace_name']): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['namespace']): + return False + + if not key_found: + self.log.error( + 'match_virtual_machine', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machines(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machines = self.get_virtual_machines_info(cache_enabled=cache_enabled) + if all_virtual_machines is None: + return None + + virtual_machines = [] + + for virtual_machine_info in all_virtual_machines: + if not self.match_virtual_machine(virtual_machine_info['info'], object_filter): + continue + + if return_mo: + virtual_machines.append( + virtual_machine_info['mo'] + ) + continue + + virtual_machines.append( + virtual_machine_info['info'] + ) + + return virtual_machines + + def get_virtual_machine(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append('namespace:%s' % (namespace)) + object_filter.append('name:%s' % (name)) + instances = self.get_virtual_machines( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if instances is None or len(instances) != 1: + return None + return instances[0] + + def get_virtual_machine_state(self, namespace, name, cache_enabled=True): + virtual_machine_info = self.get_virtual_machine( + namespace, + name, + cache_enabled=cache_enabled + ) + if virtual_machine_info is not None: + return virtual_machine_info['state'] + return None + + def is_virtual_machine(self, namespace, name, cache_enabled=True): + if self.get_virtual_machine(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True + + def is_virtual_machine_running(self, namespace, name, cache_enabled=True): + vm_info = self.get_virtual_machine( + namespace, + name, + cache_enabled=cache_enabled + ) + if vm_info is None: + return False + + return vm_info['running'] + + def wait_virtual_machine_running(self, namespace, vm_name, timeout=600, output_handler=None): + start_time = int(time.time()) + initial_state = self.get_virtual_machine_state( + namespace, + vm_name, + cache_enabled=False + ) + if output_handler is not None: + output_handler.default( + 'Initial virtual machine state: %s' % ( + initial_state + ) + ) + + while True: + if self.is_virtual_machine_running(namespace, vm_name, cache_enabled=False): + return True + + if int(time.time()) - start_time > timeout: + return False + + time.sleep(5) + + if output_handler is not None: + current_state = self.get_virtual_machine_state( + namespace, + vm_name, + cache_enabled=False + ) + if initial_state != current_state: + initial_state = current_state + output_handler.default( + 'New virtual machine state: %s' % ( + initial_state + ) + ) + + if initial_state == 'ErrorUnschedulable': + return False + + def is_virtual_machine_stopped(self, namespace, name, cache_enabled=True): + vm_info = self.get_virtual_machine( + namespace, + name, + cache_enabled=cache_enabled + ) + if vm_info is None: + return False + + return vm_info['stopped'] + + def is_virtual_machine_provisioning(self, namespace, name, cache_enabled=True): + vm_info = self.get_virtual_machine( + namespace, + name, + cache_enabled=cache_enabled + ) + if vm_info is None: + return False + + return vm_info['provisioning'] + + def wait_virtual_machine_stopped(self, namespace, vm_name, timeout=300): + start_time = int(time.time()) + while True: + if self.is_virtual_machine_provisioning(namespace, vm_name, cache_enabled=False): + return True + + if self.is_virtual_machine_stopped(namespace, vm_name, cache_enabled=False): + return True + + if int(time.time()) - start_time > timeout: + return False + + time.sleep(5) diff --git a/lib/kubevirt/virtual_machine/main.py b/lib/kubevirt/virtual_machine/main.py new file mode 100644 index 00000000..d0eb8d64 --- /dev/null +++ b/lib/kubevirt/virtual_machine/main.py @@ -0,0 +1,11 @@ +from lib.kubevirt.virtual_machine.api import KubevirtVirtualMachineApi +from lib.kubevirt.virtual_machine.info import KubevirtVirtualMachineInfo + + +class KubevirtVirtualMachine( + KubevirtVirtualMachineApi, + KubevirtVirtualMachineInfo + ): + def __init__(self): + KubevirtVirtualMachineApi.__init__(self) + KubevirtVirtualMachineInfo.__init__(self) diff --git a/lib/kubevirt/virtual_machine/output.py b/lib/kubevirt/virtual_machine/output.py new file mode 100644 index 00000000..4a641d0f --- /dev/null +++ b/lib/kubevirt/virtual_machine/output.py @@ -0,0 +1,70 @@ +class KubevirtVirtualMachineOutput(): + def __init__(self): + pass + + def print_virtual_machines(self, info, title=False): + if title: + self.my_output.default( + 'Kubevirt Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'special', + 'cpu.cores', + 'memory', + 'disks.volume.info', + 'interfaces.name', + 'interfaces.mac_address', + 'interfaces.masqueradeTick', + 'interfaces.sriovTick', + 'interfaces.multusTick', + 'interfaces.multusNetworkName', + 'state', + 'readyTick', + 'failures', + 'liveMigrationTick' + ] + + headers = [ + 'VM', + 'Special', + 'CPU', + 'Memory', + 'Disks', + 'Interfaces', + 'MAC', + 'Masq', + 'SRIOV', + 'Multus', + 'Network', + 'State', + 'Ready', + 'Failure', + 'LM' + ] + + for item in info: + if len(item['failures']) == 0: + item['failures'].append('--') + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disks', 'interfaces', 'failures'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + table=True + ) diff --git a/lib/kubevirt/virtual_machine_instance/__init__.py b/lib/kubevirt/virtual_machine_instance/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/kubevirt/virtual_machine_instance/api.py b/lib/kubevirt/virtual_machine_instance/api.py new file mode 100644 index 00000000..843e09b4 --- /dev/null +++ b/lib/kubevirt/virtual_machine_instance/api.py @@ -0,0 +1,139 @@ +import time +import traceback + +import kubevirt + + +class KubevirtVirtualMachineInstanceApi(): + def __init__(self): + self.virtual_machine_instance_mo = None + + def delete_namespaced_virtual_machine_instance(self, namespace, name): + if not self.connect(): + return None + + if self.api is None: + return None + + start_time = int(time.time() * 1000) + + body = kubevirt.K8sIoApimachineryPkgApisMetaV1DeleteOptions() + + try: + api_response = self.api.delete_namespaced_virtual_machine_instance( + name, + namespace, + body + ) + except BaseException: + api_response = None + self.log.error( + 'kubevirt.delete_namespaced_virtual_machine_instance', + traceback.format_exc() + ) + + self.log.kubevirt( + 'delete', + 'vmi', + True, + int(time.time() * 1000) - start_time + ) + + if api_response is None: + return False + + return True + + def create_namespaced_virtual_machine_instance(self, vmi_definition): + if not self.connect(): + return False + + if self.api is None: + return False + + start_time = int(time.time() * 1000) + + namespace = vmi_definition['metadata']['namespace'] + body = kubevirt.V1VirtualMachineInstance( + api_version=vmi_definition['apiVersion'], + kind='VirtualMachineInstance', + metadata=vmi_definition['metadata'], + spec=vmi_definition['spec'] + ) + + try: + api_response = self.api.create_namespaced_virtual_machine_instance( + body, + namespace + ) + except BaseException: + api_response = None + self.log.error( + 'kubevirt.create_namespaced_virtual_machine_instance', + traceback.format_exc() + ) + + if api_response is None: + self.log.kubevirt( + 'create', + 'vmi', + False, + int(time.time() * 1000) - start_time + ) + return False + + self.log.kubevirt( + 'create', + 'vmi', + True, + int(time.time() * 1000) - start_time + ) + + return True + + def get_virtual_machine_instance_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance_mo is not None: + return self.virtual_machine_instance_mo + + if not self.connect(): + return None + + if self.api is None: + return None + + try: + start_time = int(time.time() * 1000) + api_response = self.api.list_virtual_machine_instance_for_all_namespaces() + if api_response is not None: + self.virtual_machine_instance_mo = [] + for obj in api_response.items: + self.virtual_machine_instance_mo.append( + obj.to_dict() + ) + + self.log.kubevirt( + 'get', + 'virtual_machine_instance', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error( + 'kubevirt.virtual_machine_instance_mo', + traceback.format_exc() + ) + self.log.kubevirt( + 'get', + 'virtual_machine_instance', + True, + int(time.time() * 1000) - start_time + ) + + self.log.kubevirt_mo( + 'vmi', + self.virtual_machine_instance_mo + ) + + return self.virtual_machine_instance_mo diff --git a/lib/kubevirt/virtual_machine_instance/info.py b/lib/kubevirt/virtual_machine_instance/info.py new file mode 100644 index 00000000..19d06d20 --- /dev/null +++ b/lib/kubevirt/virtual_machine_instance/info.py @@ -0,0 +1,193 @@ +from lib import filter_helper + + +class KubevirtVirtualMachineInstanceInfo(): + def __init__(self): + self.virtual_machine_instance = None + + def get_virtual_machine_instance_info(self, virtual_machine_instance_mo): + if virtual_machine_instance_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['namespace'] = self.get(virtual_machine_instance_mo, 'metadata:namespace') + info['name'] = self.get(virtual_machine_instance_mo, 'metadata:name') + info['namespace_name'] = '%s/%s' % ( + info['namespace'], + info['name'] + ) + + info['vmi_id'] = self.get(virtual_machine_instance_mo, 'metadata:uid') + info['cpu'] = self.get(virtual_machine_instance_mo, 'spec:domain:cpu') + info['node_name'] = self.get(virtual_machine_instance_mo, 'status:node_name') + info['guest_os_info'] = self.get(virtual_machine_instance_mo, 'status:guest_os_info') + info['state_transitions'] = self.get(virtual_machine_instance_mo, 'status:phase_transition_timestamps') + + info['volume_spec'] = [] + volume_specs = self.get(virtual_machine_instance_mo, 'spec:volumes') + if volume_specs is not None: + for volume_spec in volume_specs: + info['volume_spec'].append( + self.get_virtual_machine_disk_volume_spec_info( + volume_spec + ) + ) + + info['volume_status'] = self.get(virtual_machine_instance_mo, 'status:volume_status') + if info['volume_status'] is not None: + for volume_status_mo in info['volume_status']: + volume_status_mo['storage'] = self.get(volume_status_mo, 'persistent_volume_claim_info:capacity:storage') + + volume_status_mo['info'] = volume_status_mo['name'] + for volume_spec in info['volume_spec']: + if volume_spec['name'] == volume_status_mo['name']: + volume_status_mo['info'] = volume_spec['info'] + + info['networks'] = self.get(virtual_machine_instance_mo, 'spec:networks') + info['interface_spec'] = self.get(virtual_machine_instance_mo, 'spec:domain:devices:interfaces') + info['interfaces'] = self.get(virtual_machine_instance_mo, 'status:interfaces') + if info['interfaces'] is not None: + for interface_info in info['interfaces']: + interface_info['__Output'] = {} + interface_info['podTick'] = '' + interface_info['multusTick'] = '' + interface_info['multusNetworkName'] = '' + interface_info['sriovEnabled'] = False + interface_info['sriovTick'] = '' + interface_info['masqueradeTick'] = '' + + if info['networks'] is not None: + for network_info in info['networks']: + if interface_info['name'] == network_info['name']: + if 'multus' in network_info and network_info['multus'] is not None: + interface_info['multusTick'] = '\u2713' + interface_info['__Output']['multusTick'] = 'Green' + if network_info['multus']['network_name'] is not None: + interface_info['multusNetworkName'] = network_info['multus']['network_name'] + + if 'multus' not in network_info or network_info['multus'] is None: + if network_info['pod'] is not None: + interface_info['podTick'] = '\u2713' + interface_info['__Output']['podTick'] = 'Green' + + for interface_spec in info['interface_spec']: + if interface_spec['name'] == interface_info['name']: + if interface_spec['sriov'] is not None: + interface_info['sriovTick'] = '\u2713' + interface_info['__Output']['sriovTick'] = 'Green' + interface_info['sriovEnabled'] = True + + if interface_spec['masquerade'] is not None: + interface_info['masqueradeTick'] = '\u2713' + interface_info['__Output']['masqueradeTick'] = 'Green' + + info['age'] = '--' + for step in info['state_transitions']: + if step['phase'] == 'Running': + info['age'] = self.convert_timestamp_to_age( + step['phase_transition_timestamp'] + ) + + return info + + def get_virtual_machine_instances_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_instance is not None: + return self.virtual_machine_instance + + managed_objects = self.get_virtual_machine_instance_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.virtual_machine_instance = [] + virtual_machine_instances = [] + for managed_object in managed_objects: + virtual_machine_instance_info = {} + virtual_machine_instance_info['info'] = self.get_virtual_machine_instance_info( + managed_object + ) + virtual_machine_instances.append( + virtual_machine_instance_info['info'] + ) + virtual_machine_instance_info['mo'] = managed_object + self.virtual_machine_instance.append( + virtual_machine_instance_info + ) + + self.log.kubevirt_mo( + 'vmi.info', + virtual_machine_instances + ) + + return self.virtual_machine_instance + + def match_virtual_machine_instance(self, virtual_machine_instance_info, virtual_machine_instance_filter): + if virtual_machine_instance_filter is None or len(virtual_machine_instance_filter) == 0: + return True + + for ap_rule in virtual_machine_instance_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_tenant_name(value, virtual_machine_instance_info['namespace_name']): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, virtual_machine_instance_info['namespace']): + return False + + if not key_found: + self.log.error( + 'match_virtual_machine_instance', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machine_instances(self, object_filter=None, return_mo=False, cache_enabled=True): + all_virtual_machine_instances = self.get_virtual_machine_instances_info(cache_enabled=cache_enabled) + if all_virtual_machine_instances is None: + return None + + virtual_machine_instances = [] + + for virtual_machine_instance_info in all_virtual_machine_instances: + if not self.match_virtual_machine_instance(virtual_machine_instance_info['info'], object_filter): + continue + + if return_mo: + virtual_machine_instances.append( + virtual_machine_instance_info['mo'] + ) + continue + + virtual_machine_instances.append( + virtual_machine_instance_info['info'] + ) + + return virtual_machine_instances + + def get_virtual_machine_instance(self, namespace, name, return_mo=False, cache_enabled=True): + object_filter = [] + object_filter.append('namespace:%s' % (namespace)) + object_filter.append('name:%s' % (name)) + instances = self.get_virtual_machine_instances( + object_filter=object_filter, + return_mo=return_mo, + cache_enabled=cache_enabled + ) + if instances is None or len(instances) != 1: + return None + return instances[0] + + def is_virtual_machine_instance(self, namespace, name, cache_enabled=True): + if self.get_virtual_machine_instance(namespace, name, cache_enabled=cache_enabled) is None: + return False + return True diff --git a/lib/kubevirt/virtual_machine_instance/main.py b/lib/kubevirt/virtual_machine_instance/main.py new file mode 100644 index 00000000..481b7399 --- /dev/null +++ b/lib/kubevirt/virtual_machine_instance/main.py @@ -0,0 +1,11 @@ +from lib.kubevirt.virtual_machine_instance.api import KubevirtVirtualMachineInstanceApi +from lib.kubevirt.virtual_machine_instance.info import KubevirtVirtualMachineInstanceInfo + + +class KubevirtVirtualMachineInstance( + KubevirtVirtualMachineInstanceApi, + KubevirtVirtualMachineInstanceInfo + ): + def __init__(self): + KubevirtVirtualMachineInstanceApi.__init__(self) + KubevirtVirtualMachineInstanceInfo.__init__(self) diff --git a/lib/kubevirt/virtual_machine_instance/output.py b/lib/kubevirt/virtual_machine_instance/output.py new file mode 100644 index 00000000..02e2f677 --- /dev/null +++ b/lib/kubevirt/virtual_machine_instance/output.py @@ -0,0 +1,71 @@ +class KubevirtVirtualMachineInstanceOutput(): + def __init__(self): + pass + + def print_virtual_machine_instances(self, info, title=False): + if title: + self.my_output.default( + 'Kubevirt Virtual Machine Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'node_name', + 'state_transitions.phase', + 'state_transitions.phase_transition_timestamp', + 'interfaces.name', + 'interfaces.mac', + 'interfaces.ip_address', + 'interfaces.masqueradeTick', + 'interfaces.sriovTick', + 'interfaces.multusTick', + 'interfaces.multusNetworkName', + 'volume_status.info', + 'volume_status.target', + 'volume_status.storage', + 'age' + ] + + headers = [ + 'VM', + 'Node', + 'Phase', + 'Timestamp', + 'Interface', + 'MAC', + 'IP', + 'Masq', + 'SRIOV', + 'Multus', + 'Network', + 'Volume', + 'Target', + 'Size', + 'Age' + ] + + for item in info: + for interface in item['interfaces']: + if interface['ip_address'] is None: + interface['ip_address'] = '--' + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['volume_status', 'interfaces', 'state_transitions'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + table=True + ) diff --git a/lib/linux/__init__.py b/lib/linux/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/__pycache__/__init__.cpython-310.pyc b/lib/linux/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..aa8662bf Binary files /dev/null and b/lib/linux/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/commands.cpython-310.pyc b/lib/linux/__pycache__/commands.cpython-310.pyc new file mode 100644 index 00000000..57cdb0a9 Binary files /dev/null and b/lib/linux/__pycache__/commands.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/interface.cpython-310.pyc b/lib/linux/__pycache__/interface.cpython-310.pyc new file mode 100644 index 00000000..6cabf4a3 Binary files /dev/null and b/lib/linux/__pycache__/interface.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/linux_helper.cpython-310.pyc b/lib/linux/__pycache__/linux_helper.cpython-310.pyc new file mode 100644 index 00000000..e3726e7e Binary files /dev/null and b/lib/linux/__pycache__/linux_helper.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/linux_iptables.cpython-310.pyc b/lib/linux/__pycache__/linux_iptables.cpython-310.pyc new file mode 100644 index 00000000..791d248d Binary files /dev/null and b/lib/linux/__pycache__/linux_iptables.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/linux_state.cpython-310.pyc b/lib/linux/__pycache__/linux_state.cpython-310.pyc new file mode 100644 index 00000000..e5ebb1da Binary files /dev/null and b/lib/linux/__pycache__/linux_state.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/lvm.cpython-310.pyc b/lib/linux/__pycache__/lvm.cpython-310.pyc new file mode 100644 index 00000000..c979c7e2 Binary files /dev/null and b/lib/linux/__pycache__/lvm.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/main.cpython-310.pyc b/lib/linux/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..77329d10 Binary files /dev/null and b/lib/linux/__pycache__/main.cpython-310.pyc differ diff --git a/lib/linux/__pycache__/state.cpython-310.pyc b/lib/linux/__pycache__/state.cpython-310.pyc new file mode 100644 index 00000000..976499e8 Binary files /dev/null and b/lib/linux/__pycache__/state.cpython-310.pyc differ diff --git a/lib/linux/bond/__init__.py b/lib/linux/bond/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/bond/cmd.py b/lib/linux/bond/cmd.py new file mode 100644 index 00000000..3f2c3976 --- /dev/null +++ b/lib/linux/bond/cmd.py @@ -0,0 +1,50 @@ +class LinuxBondCmd(): + def __init__(self): + self.bond_cmd = None + + def get_bond_cmd(self): + if self.bond_cmd is not None: + return self.bond_cmd + + cache = self.get_cmd_cache( + 'bond' + ) + if cache is not None: + self.bond_cmd = cache + return self.bond_cmd + + directory_name = '/proc/net/bonding' + bond_filenames = self.ssh_handler.get_filenames( + directory_name + ) + if bond_filenames is None: + self.log.debug( + 'get_bond_cmd', + 'No bonding files: %s' % (directory_name) + ) + return None + + self.bond_cmd = {} + success = True + for bond_filename in bond_filenames: + bond_name = bond_filename.split('/')[-1] + content = self.ssh_handler.get_file( + bond_filename + ) + if content is None: + success = False + self.log.error( + 'get_bond_cmd', + 'Failed to get file: %s' % (bond_filename) + ) + continue + + self.bond_cmd[bond_name] = content + + if success: + self.set_cmd_cache( + 'bond', + self.bond_cmd + ) + + return self.bond_cmd diff --git a/lib/linux/bond/info.py b/lib/linux/bond/info.py new file mode 100644 index 00000000..fdd1be8a --- /dev/null +++ b/lib/linux/bond/info.py @@ -0,0 +1,72 @@ +class LinuxBondInfo(): + def __init__(self): + self.bond = None + + def get_bond_info(self): + if self.bond is not None: + return self.bond + + bonds_mo = self.get_bond_cmd() + + self.bond = [] + for bond_name in bonds_mo: + bond_info = {} + bond_info['__Output'] = {} + bond_info['server'] = self.server_display_name + bond_info['name'] = bond_name + bond_info['driver'] = self.get_line(bonds_mo[bond_name], 'Ethernet Channel Bonding Driver: ', strip=True) + bond_info['mode'] = self.get_line(bonds_mo[bond_name], 'Bonding Mode: ', strip=True) + bond_info['transmit_hash_policy'] = self.get_line(bonds_mo[bond_name], 'Transmit Hash Policy: ', strip=True) + bond_info['mii_status'] = self.get_line(bonds_mo[bond_name], 'MII Status: ', strip=True) + if bond_info['mii_status'] == 'up': + bond_info['__Output']['mii_status'] = 'Green' + else: + bond_info['__Output']['mii_status'] = 'Red' + bond_info['mii_polling_ms'] = self.get_line(bonds_mo[bond_name], 'MII Polling Interval (ms): ', strip=True) + bond_info['up_delay_ms'] = self.get_line(bonds_mo[bond_name], 'Up Delay (ms): ', strip=True) + bond_info['down_delay_ms'] = self.get_line(bonds_mo[bond_name], 'Down Delay (ms): ', strip=True) + bond_info['lacp_active'] = self.get_line(bonds_mo[bond_name], 'LACP active: ', strip=True) + bond_info['lacp_rate'] = self.get_line(bonds_mo[bond_name], 'LACP rate: ', strip=True) + bond_info['min_links'] = self.get_line(bonds_mo[bond_name], 'Min links: ', strip=True) + + member_interfaces = self.get_lines(bonds_mo[bond_name], begin_pattern='Slave Interface: ', strip=True) + bond_info['member'] = [] + if member_interfaces is not None: + for member_interface in member_interfaces: + section = self.get_section( + bonds_mo[bond_name], + 'Slave Interface: %s' % (member_interface), + 'Slave Interface: ' + ) + if section is None or len(section) == 0: + self.log.error( + 'get_bond_info', + 'Section not found: %s' % (member_interface) + ) + continue + + member_info = {} + member_info['__Output'] = {} + member_info['name'] = member_interface + member_info['mii_status'] = self.get_line(section, 'MII Status: ', strip=True) + if member_info['mii_status'] == 'up': + member_info['__Output']['mii_status'] = 'Green' + else: + member_info['__Output']['mii_status'] = 'Red' + member_info['speed'] = self.get_line(section, 'Speed: ', strip=True) + member_info['duplex'] = self.get_line(section, 'Duplex: ', strip=True) + member_info['link_failure_count'] = self.get_line(section, 'Link Failure Count: ', strip=True) + member_info['mac'] = self.get_line(section, 'Permanent HW addr: ', strip=True) + + bond_info['member'].append( + member_info + ) + + self.bond.append( + bond_info + ) + + return self.bond + + def get_bond(self): + return self.get_bond_info() diff --git a/lib/linux/bond/main.py b/lib/linux/bond/main.py new file mode 100644 index 00000000..b3e062ce --- /dev/null +++ b/lib/linux/bond/main.py @@ -0,0 +1,11 @@ +from lib.linux.bond.cmd import LinuxBondCmd +from lib.linux.bond.info import LinuxBondInfo + + +class LinuxBond( + LinuxBondCmd, + LinuxBondInfo + ): + def __init__(self): + LinuxBondCmd.__init__(self) + LinuxBondInfo.__init__(self) diff --git a/lib/linux/bond/output.py b/lib/linux/bond/output.py new file mode 100644 index 00000000..58253a67 --- /dev/null +++ b/lib/linux/bond/output.py @@ -0,0 +1,193 @@ +class LinuxBondOutput(): + def __init__(self): + pass + + def print_linux_bond(self, info, title=False): + if title: + self.my_output.default( + 'Bond', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'server', + 'name', + 'mii_status', + 'mii_polling_ms', + 'transmit_hash_policy', + 'up_delay_ms', + 'down_delay_ms', + 'lacp_active', + 'lacp_rate', + 'member.name' + ] + + headers = [ + 'Linux', + 'Bond', + 'Status', + 'Polling [ms]', + 'Hash', + 'Up delay [ms]', + 'Down delay [ms]', + 'LACP Active', + 'LACP Rate', + 'Member' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['member'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_linux_bond_member(self, info, title=False): + if title: + self.my_output.default( + 'Bond - Member', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'server', + 'name', + 'mii_status', + 'member.name', + 'member.mii_status', + 'member.speed', + 'member.duplex', + 'member.mac' + ] + + headers = [ + 'Linux', + 'Bond', + 'Status', + 'Member', + 'Status', + 'Speed', + 'Duplex', + 'MAC' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['member'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_linux_bond_aci(self, info, title=False): + if title: + self.my_output.default( + 'Bond - ACI', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'server', + 'interface', + 'pod_node_name', + 'id', + 'key', + 'adjacency.sysId', + 'adjacency.sysPrio', + 'adjacency.key', + 'adjacency.port', + 'adjacency.portPrio' + ] + + headers = [ + 'Linux', + 'Interface', + 'ACI Node', + 'Member', + 'Oper Key', + 'Nbr System MAC', + 'Nbr System Prio', + 'Nbr Oper Key', + 'Nbr Port', + 'Nbr Port Prio' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) + + def print_linux_bond_nexus(self, info, title=False): + if title: + self.my_output.default( + 'Bond - Nexus', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'server', + 'interface', + 'nexus_name', + 'interface', + 'port.port', + 'port.partner_mac' + ] + + headers = [ + 'Linux', + 'Interface', + 'Nexus', + 'Interface', + 'Port', + 'Partner' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['port'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + merge=True + ) diff --git a/lib/linux/boot/__init__.py b/lib/linux/boot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/boot/cmd.py b/lib/linux/boot/cmd.py new file mode 100644 index 00000000..6c7614f5 --- /dev/null +++ b/lib/linux/boot/cmd.py @@ -0,0 +1,25 @@ +class LinuxBootCmd(): + def __init__(self): + self.boot_cmd = None + + def get_boot_cmd(self): + if self.boot_cmd is not None: + return self.boot_cmd + + cache = self.get_cmd_cache( + 'boot' + ) + if cache is not None: + self.boot_cmd = cache + return self.boot_cmd + + self.boot_cmd = self.ssh_handler.get_file( + '/proc/cmdline' + ) + + self.set_cmd_cache( + 'boot', + self.boot_cmd + ) + + return self.boot_cmd diff --git a/lib/linux/boot/info.py b/lib/linux/boot/info.py new file mode 100644 index 00000000..1b70d328 --- /dev/null +++ b/lib/linux/boot/info.py @@ -0,0 +1,14 @@ +class LinuxBootInfo(): + def __init__(self): + self.boot = None + + def get_boot_info(self): + if self.boot is not None: + return self.boot + + boot = self.get_boot_cmd() + self.boot = boot.split(' ') + return self.boot + + def get_boot(self): + return self.get_boot_info() diff --git a/lib/linux/boot/main.py b/lib/linux/boot/main.py new file mode 100644 index 00000000..164211c1 --- /dev/null +++ b/lib/linux/boot/main.py @@ -0,0 +1,11 @@ +from lib.linux.boot.cmd import LinuxBootCmd +from lib.linux.boot.info import LinuxBootInfo + + +class LinuxBoot( + LinuxBootCmd, + LinuxBootInfo + ): + def __init__(self): + LinuxBootCmd.__init__(self) + LinuxBootInfo.__init__(self) diff --git a/lib/linux/boot/output.py b/lib/linux/boot/output.py new file mode 100644 index 00000000..3cde18a3 --- /dev/null +++ b/lib/linux/boot/output.py @@ -0,0 +1,14 @@ +class LinuxBootOutput(): + def __init__(self): + pass + + def print_linux_boot(self, info): + + self.my_output.default( + 'Boot parameters', + underline=True, + before_newline=True + ) + + for item in info: + self.my_output.default(item) diff --git a/lib/linux/cache.py b/lib/linux/cache.py new file mode 100644 index 00000000..b87b77fb --- /dev/null +++ b/lib/linux/cache.py @@ -0,0 +1,95 @@ +import time +import os +import json + +from lib.linux import settings + + +class Cache(): + def __init__(self, server_name, no_cache=False): + if server_name is None: + self.cache_enabled = False + return + + settings_handler = settings.LinuxSettings() + server_settings = settings_handler.get_linux_server(server_name) + if server_settings is None: + self.cache_enabled = False + return + + self.cache_server_name = server_name + self.cache_enabled = server_settings['cache']['enabled'] + self.cache_directory = server_settings['cache']['directory'] + self.cache_ttl = server_settings['cache']['ttl'] + + if no_cache: + self.cache_enabled = False + + def is_cache_enabled(self): + return self.cache_enabled + + def get_cmd_cache_filename(self, cmd_name): + filename = os.path.join( + self.cache_directory, + cmd_name + ) + return filename + + def get_cmd_cache(self, cmd_name, cmd_selector=None): + if not self.is_cache_enabled(): + return None + + filename = self.get_cmd_cache_filename(cmd_name) + if filename is None: + return None + + if cmd_selector is not None: + filename = '%s.%s' % (filename, cmd_selector) + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + return None + + age = int(time.time()) - content['timestamp'] + if age > self.cache_ttl: + return None + + return content['cache'] + + def set_cmd_cache(self, cmd_name, cache, cmd_selector=None): + filename = self.get_cmd_cache_filename(cmd_name) + if filename is None: + return False + + if not os.path.isdir(self.cache_directory): + os.makedirs(self.cache_directory, exist_ok=True) + + content = {} + content['cmd'] = cmd_name + content['selector'] = cmd_selector + content['timestamp'] = int(time.time()) + content['cache'] = cache + + if cmd_selector is not None: + filename = '%s.%s' % (filename, cmd_selector) + + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(content, indent=4)) + + except BaseException: + self.log.error( + 'set_cmd_cache.set_object_cache', + 'Set cache failed: %s %s %s %s' % ( + self.cache_server_name, + cmd_name, + cmd_selector, + filename + ) + ) + return False + + return True diff --git a/lib/linux/chrony/__init__.py b/lib/linux/chrony/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/chrony/cmd.py b/lib/linux/chrony/cmd.py new file mode 100644 index 00000000..8b3b677e --- /dev/null +++ b/lib/linux/chrony/cmd.py @@ -0,0 +1,52 @@ +class LinuxChronyCmd(): + def __init__(self): + self.chrony_config_cmd = None + self.chrony_tracking_cmd = None + + def get_chrony_config_cmd(self): + if self.chrony_config_cmd is not None: + return self.chrony_config_cmd + + cache = self.get_cmd_cache( + 'chrony.conf' + ) + if cache is not None: + self.chrony_config_cmd = cache + return self.chrony_config_cmd + + filename = '/etc/chrony.conf' + chrony_config = self.ssh_handler.get_file( + filename + ) + if chrony_config is None: + self.log.debug( + 'get_chrony_config_cmd', + 'No chrony configuration file: %s' % (filename) + ) + return None + + self.chrony_config_cmd = chrony_config + return self.chrony_config_cmd + + def get_chrony_tracking_cmd(self): + if self.chrony_tracking_cmd is not None: + return self.chrony_tracking_cmd + + cache = self.get_cmd_cache( + 'chrony.tracking' + ) + if cache is not None: + self.chrony_tracking_cmd = cache + return self.chrony_tracking_cmd + + command = 'chronyc tracking -n' + success, output, error = self.ssh_handler.run_cmd(command) + if not success: + self.log.debug( + 'get_chrony_tracking_cmd', + 'Failed to get chrony state' + ) + return None + + self.chrony_tracking_cmd = output + return self.chrony_tracking_cmd diff --git a/lib/linux/chrony/info.py b/lib/linux/chrony/info.py new file mode 100644 index 00000000..80e9d415 --- /dev/null +++ b/lib/linux/chrony/info.py @@ -0,0 +1,82 @@ +class LinuxChronyInfo(): + def __init__(self): + self.chrony_config = None + self.chrony_tracking = None + + def get_chrony_config_info(self): + if self.chrony_config is not None: + return self.chrony_config + + chrony_config_mo = self.get_chrony_config_cmd() + + # pool 0.rhel.pool.ntp.org iburst + # driftfile /var/lib/chrony/drift + # makestep 1.0 3 + # rtcsync + # logdir /var/log/chrony + # server iburst prefer + + self.chrony_config = {} + self.chrony_config['configuration'] = self.get_lines(chrony_config_mo) + self.chrony_config['server'] = [] + self.chrony_config['pool'] = [] + + servers = self.get_lines(chrony_config_mo, begin_pattern='server ', strip=True) + if servers is not None: + for server in servers: + self.chrony_config['server'].append( + server.split(' ')[0] + ) + + pools = self.get_lines(chrony_config_mo, begin_pattern='pool ', strip=True) + if pools is not None: + for pool in pools: + self.chrony_config['pool'].append( + pool.split(' ')[0] + ) + + return self.chrony_config + + def get_chrony_tracking_info(self): + if self.chrony_tracking is not None: + return self.chrony_tracking + + chrony_tracking_mo = self.get_chrony_tracking_cmd() + + # Reference ID : AD26C943 (fqdn) + # Stratum : 2 + # Ref time (UTC) : Fri Apr 19 11:48:32 2024 + # System time : 0.000012511 seconds fast of NTP time + # Last offset : -0.000027058 seconds + # RMS offset : 0.000115619 seconds + # Frequency : 13.625 ppm slow + # Residual freq : -0.000 ppm + # Skew : 0.031 ppm + # Root delay : 0.020759970 seconds + # Root dispersion : 0.001136309 seconds + # Update interval : 1028.0 seconds + # Leap status : Normal + + self.chrony_tracking = {} + self.chrony_tracking['__Output'] = {} + self.chrony_tracking['reference'] = self.get_line(chrony_tracking_mo, 'Reference ID').split(':')[1].strip() + self.chrony_tracking['stratum'] = self.get_line(chrony_tracking_mo, 'Stratum').split(':')[1].strip() + self.chrony_tracking['time'] = self.get_line(chrony_tracking_mo, 'Ref time').split(':')[1].strip() + self.chrony_tracking['system_time'] = self.get_line(chrony_tracking_mo, 'System time').split(':')[1].strip() + self.chrony_tracking['last_offset'] = self.get_line(chrony_tracking_mo, 'Last offset').split(':')[1].strip() + self.chrony_tracking['rms_offset'] = self.get_line(chrony_tracking_mo, 'RMS offset').split(':')[1].strip() + self.chrony_tracking['frequency'] = self.get_line(chrony_tracking_mo, 'Frequency').split(':')[1].strip() + self.chrony_tracking['residual_frequency'] = self.get_line(chrony_tracking_mo, 'Residual freq').split(':')[1].strip() + self.chrony_tracking['skew'] = self.get_line(chrony_tracking_mo, 'Skew').split(':')[1].strip() + self.chrony_tracking['root_delay'] = self.get_line(chrony_tracking_mo, 'Root delay').split(':')[1].strip() + self.chrony_tracking['root_dispertion'] = self.get_line(chrony_tracking_mo, 'Root dispersion').split(':')[1].strip() + self.chrony_tracking['update_interval'] = self.get_line(chrony_tracking_mo, 'Update interval').split(':')[1].strip() + self.chrony_tracking['status'] = self.get_line(chrony_tracking_mo, 'Leap status').split(':')[1].strip() + if self.chrony_tracking['status'] == 'Normal': + self.chrony_tracking['__Output']['status'] = 'Green' + self.chrony_tracking['ok'] = True + else: + self.chrony_tracking['__Output']['status'] = 'Red' + self.chrony_tracking['ok'] = False + + return self.chrony_tracking diff --git a/lib/linux/chrony/main.py b/lib/linux/chrony/main.py new file mode 100644 index 00000000..e6e2eb53 --- /dev/null +++ b/lib/linux/chrony/main.py @@ -0,0 +1,11 @@ +from lib.linux.chrony.cmd import LinuxChronyCmd +from lib.linux.chrony.info import LinuxChronyInfo + + +class LinuxChrony( + LinuxChronyCmd, + LinuxChronyInfo + ): + def __init__(self): + LinuxChronyCmd.__init__(self) + LinuxChronyInfo.__init__(self) diff --git a/lib/linux/chrony/output.py b/lib/linux/chrony/output.py new file mode 100644 index 00000000..8e732b89 --- /dev/null +++ b/lib/linux/chrony/output.py @@ -0,0 +1,18 @@ +class LinuxChronyOutput(): + def __init__(self): + pass + + def print_linux_chrony_config(self, info, title=False): + if title: + self.my_output.default( + 'Chrony Configuration', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for line in info['config']: + self.my_output.default(line) diff --git a/lib/linux/commands.py b/lib/linux/commands.py new file mode 100644 index 00000000..f3997353 --- /dev/null +++ b/lib/linux/commands.py @@ -0,0 +1,30 @@ +from progress.bar import IncrementalBar + + +class LinuxCommands(): + def __init__(self): + pass + + def run_commands(self, commands, progress_bar=False): + outputs = {} + if progress_bar: + bar_handler = IncrementalBar('Command', max=len(commands)) + bar_handler.goto(0) + + for command in commands: + success, output, error = self.ssh_handler.run_cmd( + command + ) + if not success: + self.my_output.error('Command failed: %s' % (command)) + self.my_output.default(error) + return None + + outputs[command] = output + if progress_bar: + bar_handler.next() + + if progress_bar: + bar_handler.finish() + + return outputs diff --git a/lib/linux/common.py b/lib/linux/common.py new file mode 100644 index 00000000..54a49236 --- /dev/null +++ b/lib/linux/common.py @@ -0,0 +1,83 @@ +class Common(): + def __init__(self): + pass + + def get_section(self, content, starting_line, ending_pattern): + lines = [] + section = False + + input_lines = None + + if isinstance(content, str): + input_lines = content.split('\n') + + if isinstance(content, list): + input_lines = content + + if input_lines is None: + self.log.error( + 'get_section', + 'Unexpected content: %s' % (content) + ) + return None + + for line in input_lines: + if line.startswith(ending_pattern): + if section: + section = False + break + + if line == starting_line: + section = True + continue + + if section: + lines.append( + line + ) + + return lines + + def get_lines(self, content, begin_pattern=None, strip=False, limit=-1): + lines = [] + + input_lines = None + + if isinstance(content, str): + input_lines = content.split('\n') + + if isinstance(content, list): + input_lines = content + + if input_lines is None: + self.log.error( + 'get_section', + 'Unexpected content: %s' % (content) + ) + return None + + for line in input_lines: + if begin_pattern is None: + lines.append(line) + else: + if line.startswith(begin_pattern): + if strip: + lines.append(line[len(begin_pattern):]) + else: + lines.append(line) + + if limit > 0 and len(lines) >= limit: + break + + return lines + + def get_line(self, content, begin_pattern, strip=False): + lines = self.get_lines( + content, + begin_pattern=begin_pattern, + strip=strip, + limit=1 + ) + if len(lines) == 1: + return lines[0] + return None diff --git a/lib/linux/container_policy/__init__.py b/lib/linux/container_policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/container_policy/cmd.py b/lib/linux/container_policy/cmd.py new file mode 100644 index 00000000..91956de2 --- /dev/null +++ b/lib/linux/container_policy/cmd.py @@ -0,0 +1,28 @@ +class LinuxContainerPolicyCmd(): + def __init__(self): + self.container_policy_config_cmd = None + + def get_container_policy_config_cmd(self): + if self.container_policy_config_cmd is not None: + return self.container_policy_config_cmd + + cache = self.get_cmd_cache( + 'container_policy.conf' + ) + if cache is not None: + self.container_policy_config_cmd = cache + return self.container_policy_config_cmd + + filename = '/etc/containers/policy.json' + container_policy_config = self.ssh_handler.get_file( + filename + ) + if container_policy_config is None: + self.log.debug( + 'get_container_policy_config_cmd', + 'No container_policy configuration file: %s' % (filename) + ) + return None + + self.container_policy_config_cmd = container_policy_config + return self.container_policy_config_cmd diff --git a/lib/linux/container_policy/info.py b/lib/linux/container_policy/info.py new file mode 100644 index 00000000..390d2fd4 --- /dev/null +++ b/lib/linux/container_policy/info.py @@ -0,0 +1,60 @@ +import json + + +class LinuxContainerPolicyInfo(): + def __init__(self): + self.container_policy_config = None + + def get_container_policy_config_info(self): + if self.container_policy_config is not None: + return self.container_policy_config + + container_policy_config_mo = self.get_container_policy_config_cmd() + + # { + # "default": [ + # { + # "type": "reject" + # } + # ], + # "transports": { + # "atomic": { + # "quay.io": [ + # { + # "type": "insecureAcceptAnything" + # } + # ], + # "registry.redhat.io": [ + # { + # "type": "insecureAcceptAnything" + # } + # ] + # }, + # "docker": { + # "quay.io": [ + # { + # "type": "insecureAcceptAnything" + # } + # ], + # "registry.redhat.io": [ + # { + # "type": "insecureAcceptAnything" + # } + # ] + # }, + # "docker-daemon": { + # "": [ + # { + # "type": "insecureAcceptAnything" + # } + # ] + # } + # } + # } + + + self.container_policy_config = json.loads( + container_policy_config_mo + ) + + return self.container_policy_config diff --git a/lib/linux/container_policy/main.py b/lib/linux/container_policy/main.py new file mode 100644 index 00000000..681ad1ce --- /dev/null +++ b/lib/linux/container_policy/main.py @@ -0,0 +1,11 @@ +from lib.linux.container_policy.cmd import LinuxContainerPolicyCmd +from lib.linux.container_policy.info import LinuxContainerPolicyInfo + + +class LinuxContainerPolicy( + LinuxContainerPolicyCmd, + LinuxContainerPolicyInfo + ): + def __init__(self): + LinuxContainerPolicyCmd.__init__(self) + LinuxContainerPolicyInfo.__init__(self) diff --git a/lib/linux/container_policy/output.py b/lib/linux/container_policy/output.py new file mode 100644 index 00000000..12402ce9 --- /dev/null +++ b/lib/linux/container_policy/output.py @@ -0,0 +1,25 @@ +import json + + +class LinuxContainerPolicyOutput(): + def __init__(self): + pass + + def print_linux_container_policy_config(self, info, title=False): + if title: + self.my_output.default( + 'Container Policy Configuration', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + self.my_output.default( + json.dumps( + info, + indent=4 + ) + ) \ No newline at end of file diff --git a/lib/linux/genisoimage/__init__.py b/lib/linux/genisoimage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/genisoimage/main.py b/lib/linux/genisoimage/main.py new file mode 100644 index 00000000..403c22e1 --- /dev/null +++ b/lib/linux/genisoimage/main.py @@ -0,0 +1,83 @@ +import os +import uuid + + +class LinuxGenIsoImage(): + def __init__(self): + pass + + def genisoimage(self, source_filepath, iso_filepath): + remote_directory = '/tmp/%s' % (str(uuid.uuid4())) + if not self.ssh_handler.create_directory(remote_directory): + self.log.error( + 'genisoimage', + 'Upload directory create failed: %s' % (remote_directory) + ) + return False + + remote_filepath = '%s/%s' % ( + remote_directory, + os.path.basename(source_filepath) + ) + + success = self.ssh_handler.scp_file( + source_filepath, + remote_filepath, + put=True + ) + if not success: + self.log.error( + 'genisoimage', + 'Iso source upload failed: %s => %s' % (source_filepath, remote_filepath) + ) + return False + + remote_iso_filepath = '%s/%s' % ( + remote_directory, + os.path.basename(iso_filepath) + ) + command = 'genisoimage -r -o %s %s' % ( + remote_iso_filepath, + remote_filepath + ) + success, output, error = self.ssh_handler.run_cmd( + command, + live_output=False + ) + if not success: + self.log.error( + 'genisoimage', + 'Iso generation failed: %s' % (remote_iso_filepath) + ) + self.log.error( + 'genisoimage', + output + ) + self.log.error( + 'genisoimage', + error + ) + return False + + self.log.debug( + 'genisoimage', + 'Iso generated: %s' % (remote_iso_filepath) + ) + self.log.debug( + 'genisoimage', + output + ) + + success = self.ssh_handler.scp_file( + remote_iso_filepath, + iso_filepath, + put=False + ) + if not success: + self.log.error( + 'genisoimage', + 'Iso download failed: %s => %s' % (remote_iso_filepath, iso_filepath) + ) + return False + + return True diff --git a/lib/linux/huge_pages/__init__.py b/lib/linux/huge_pages/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/huge_pages/cmd.py b/lib/linux/huge_pages/cmd.py new file mode 100644 index 00000000..0a089376 --- /dev/null +++ b/lib/linux/huge_pages/cmd.py @@ -0,0 +1,54 @@ +class LinuxHugePagesCmd(): + def __init__(self): + self.huge_pages_cmd = None + + def get_huge_pages_cmd(self): + if self.huge_pages_cmd is not None: + return self.huge_pages_cmd + + cache = self.get_cmd_cache( + 'huge_pages' + ) + if cache is not None: + self.huge_pages_cmd = cache + return self.huge_pages_cmd + + self.huge_pages_cmd = {} + self.huge_pages_cmd['node0'] = {} + self.huge_pages_cmd['node0']['2M'] = {} + self.huge_pages_cmd['node0']['2M']['total'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages' + ).rstrip('\n') + self.huge_pages_cmd['node0']['2M']['free'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages' + ).rstrip('\n') + self.huge_pages_cmd['node0']['1G'] = {} + self.huge_pages_cmd['node0']['1G']['total'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages' + ).rstrip('\n') + self.huge_pages_cmd['node0']['1G']['free'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node0/hugepages/hugepages-1048576kB/free_hugepages' + ).rstrip('\n') + + self.huge_pages_cmd['node1'] = {} + self.huge_pages_cmd['node1']['2M'] = {} + self.huge_pages_cmd['node1']['2M']['total'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages' + ).rstrip('\n') + self.huge_pages_cmd['node1']['2M']['free'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node1/hugepages/hugepages-2048kB/free_hugepages' + ).rstrip('\n') + self.huge_pages_cmd['node1']['1G'] = {} + self.huge_pages_cmd['node1']['1G']['total'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages' + ).rstrip('\n') + self.huge_pages_cmd['node1']['1G']['free'] = self.ssh_handler.get_file( + '/sys/devices/system/node/node1/hugepages/hugepages-1048576kB/free_hugepages' + ).rstrip('\n') + + self.set_cmd_cache( + 'huge_pages', + self.huge_pages_cmd + ) + + return self.huge_pages_cmd diff --git a/lib/linux/huge_pages/info.py b/lib/linux/huge_pages/info.py new file mode 100644 index 00000000..60735727 --- /dev/null +++ b/lib/linux/huge_pages/info.py @@ -0,0 +1,12 @@ +class LinuxHugePagesInfo(): + def __init__(self): + self.huge_pages = None + + def get_huge_pages_info(self): + if self.huge_pages is not None: + return self.huge_pages + self.huge_pages = self.get_huge_pages_cmd() + return self.huge_pages + + def get_huge_pages(self): + return self.get_huge_pages_info() diff --git a/lib/linux/huge_pages/main.py b/lib/linux/huge_pages/main.py new file mode 100644 index 00000000..992183c7 --- /dev/null +++ b/lib/linux/huge_pages/main.py @@ -0,0 +1,11 @@ +from lib.linux.huge_pages.cmd import LinuxHugePagesCmd +from lib.linux.huge_pages.info import LinuxHugePagesInfo + + +class LinuxHugePages( + LinuxHugePagesCmd, + LinuxHugePagesInfo + ): + def __init__(self): + LinuxHugePagesCmd.__init__(self) + LinuxHugePagesInfo.__init__(self) diff --git a/lib/linux/huge_pages/output.py b/lib/linux/huge_pages/output.py new file mode 100644 index 00000000..0613a5bf --- /dev/null +++ b/lib/linux/huge_pages/output.py @@ -0,0 +1,60 @@ +class LinuxHugePagesOutput(): + def __init__(self): + pass + + def print_linux_huge_pages(self, info, title=False): + if title: + self.my_output.default( + 'Huge Pages', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + items = [] + for server_info in info: + item = {} + item['server'] = server_info['name'] + item['name'] = 'Node 0' + item['2mf'] = server_info['hp']['node0']['2M']['free'] + item['2mt'] = server_info['hp']['node0']['2M']['total'] + item['1gf'] = server_info['hp']['node0']['1G']['free'] + item['1gt'] = server_info['hp']['node0']['1G']['total'] + items.append(item) + + item = {} + item['server'] = server_info['name'] + item['name'] = 'Node 1' + item['2mf'] = server_info['hp']['node1']['2M']['free'] + item['2mt'] = server_info['hp']['node1']['2M']['total'] + item['1gf'] = server_info['hp']['node1']['1G']['free'] + item['1gt'] = server_info['hp']['node1']['1G']['total'] + items.append(item) + + order = [ + 'server', + 'name', + '2mf', + '2mt', + '1gf', + '1gt' + ] + + headers = [ + 'Server', + 'Node', + '2M Free', + '2M Total', + '1G Free', + '1G Total' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + table=True + ) diff --git a/lib/linux/interface.py b/lib/linux/interface.py new file mode 100644 index 00000000..e44a40a2 --- /dev/null +++ b/lib/linux/interface.py @@ -0,0 +1,167 @@ +import traceback + +from lib import ip_helper + + +class LinuxInterface(): + def __init__(self): + self.interfaces = None + + def get_interfaces_commands(self): + commands = [] + commands.append('ip link show') + return commands + + def analyze_ip_link_show_output(self, output): + interfaces = [] + + info = None + for line in output.split('\n'): + if ' mtu ' in line: + if info is not None: + interfaces.append( + info + ) + + # 4: br-8bc193248176: mtu 1500 qdisc noqueue state UP mode DEFAULT group default + info = {} + info['index'] = line.split(':')[0] + info['name'] = line.split(':')[1].strip() + info['flags'] = line.split('<')[1].split('>')[0] + info['mtu'] = line.split(' mtu ')[1].split(' ')[0] + info['state'] = line.split(' state ')[1].split(' ')[0] + info['mac'] = '' + info['vf'] = [] + + if ' vf ' in line: + vf_info = {} + vf_info['index'] = line.split(' vf ')[1].split(' ')[0] + vf_info['mac'] = line.split(' link/ether ')[1].split(' ')[0] + vf_info['vlan'] = None + if ' vlan ' in line: + vf_info['vlan'] = line.split(' vlan ')[1].split(' ')[0].rstrip(',') + vf_info['spoof'] = line.split(' spoof checking ')[1].split(' ')[0].rstrip(',') + vf_info['link'] = line.split(' link-state ')[1].split(' ')[0].rstrip(',') + vf_info['trust'] = line.split(' trust ')[1].split(' ')[0].rstrip(',') + info['vf'].append( + vf_info + ) + + if ' vf ' not in line and ' link/ether ' in line: + info['mac'] = line.split(' link/ether ')[1].split(' ')[0] + + if info is not None: + interfaces.append( + info + ) + + return interfaces + + def get_interface(self, mac_address, cache=False): + if not cache or self.interfaces is None: + self.interfaces = self.get_interfaces() + if self.interfaces is None: + return None + + for interface in self.interfaces: + if ip_helper.is_mac_equal(interface['mac'], mac_address): + interface['vf_info'] = None + return interface + + for virtual_function in interface['vf']: + if ip_helper.is_mac_equal(virtual_function['mac'], mac_address): + interface['vf_info'] = virtual_function + return interface + + return None + + def get_interfaces(self, progress_bar=False): + try: + commands = self.get_interfaces_commands() + outputs = self.run_commands(commands, progress_bar=progress_bar) + if outputs is None: + self.my_output.error('Commands output collection failed') + return None + + interfaces = self.analyze_ip_link_show_output( + outputs['ip link show'] + ) + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return interfaces + + def get_sriov_interfaces(self, numa_info=False, pci_info=False): + all_interfaces = self.get_interfaces() + + sriov_interfaces = [] + for interface in all_interfaces: + if len(interface['vf']) > 0: + interface['vfCount'] = len(interface['vf']) + if numa_info: + interface['numa'] = self.get_interface_numa( + interface['name'] + ) + + if pci_info: + interface['pci'] = self.get_interface_pci( + interface['name'] + ) + + sriov_interfaces.append( + interface + ) + + return sriov_interfaces + + def get_interface_numa(self, interface_name): + command = 'cat /sys/class/net/%s/device/numa_node' % (interface_name) + outputs = self.run_commands([command]) + if outputs is None: + self.my_output.error('Interface numa check failed failed:%s' % (interface_name)) + return None + + numa = outputs[command].strip().replace('\n', '') + return numa + + def get_interface_pci(self, interface_name): + command = 'cat /sys/class/net/%s/device/uevent' % (interface_name) + outputs = self.run_commands([command]) + if outputs is None: + self.my_output.error('Interface pci check failed failed:%s' % (interface_name)) + return None + + # DRIVER=vmxnet3 + # PCI_CLASS=20000 + # PCI_ID=15AD:07B0 + # PCI_SUBSYS_ID=15AD:07B0 + # PCI_SLOT_NAME=0000:03:00.0 + # MODALIAS=pci:v000015ADd000007B0sv000015ADsd000007B0bc02sc00i00 + pci_info = {} + + for line in outputs[command].split('\n'): + if len(line.split('=')) == 2: + (key, value) = line.split('=') + if key == 'DRIVER': + pci_info['driver'] = value + continue + + if key == 'PCI_CLASS': + pci_info['class'] = value + continue + + if key == 'PCI_ID': + pci_info['id'] = value + continue + + if key == 'PCI_SUBSYS_ID': + pci_info['subid'] = value + continue + + if key == 'PCI_SLOT_NAME': + pci_info['slot'] = value + continue + + return pci_info diff --git a/lib/linux/lvm.py b/lib/linux/lvm.py new file mode 100644 index 00000000..2edd8348 --- /dev/null +++ b/lib/linux/lvm.py @@ -0,0 +1,100 @@ +import re + + +class LinuxLvm(): + def __init__(self): + self.lvm = None + + def get_lvms_info(self, output): + # --- Logical volume --- + # LV Path /dev/vg1/18af6b30-a3a2-4420-abd5-d42e2d5633eb + # LV Name 18af6b30-a3a2-4420-abd5-d42e2d5633eb + # VG Name vg1 + # LV UUID Gc7Wes-8Eh3-6cdf-9TD2-tPey-rdEA-j26ntX + # LV Write Access read/write + # LV Creation host, time ocp-bm2, 2023-06-01 12:41:24 +0000 + # LV Pool name thin-pool-1 + # LV Status available + # # open 2 + # LV Size 10.00 GiB + # Mapped size 93.44% + # Current LE 2560 + # Segments 1 + # Allocation inherit + # Read ahead sectors auto + # - currently set to 8192 + # Block device 253:37 + lvms = [] + + lvm_section = False + for line in output.split('\n'): + if '--- Logical volume ---' in line: + lvm_info = {} + lvm_info['name'] = None + lvm_section = True + continue + + if lvm_section: + line = re.sub(' +', ' ', line) + if 'LV Path' in line: + lvm_info['path'] = line.split('LV Path')[1].strip() + continue + + if 'LV Name' in line: + lvm_info['name'] = line.split('LV Name')[1].strip() + continue + + if 'VG Name' in line: + lvm_info['vg'] = line.split('VG Name')[1].strip() + continue + + if 'LV UUID' in line: + lvm_info['uuid'] = line.split('LV UUID')[1].strip() + continue + + if 'LV Write Access' in line: + lvm_info['access'] = line.split('LV Write Access')[1].strip() + continue + + if 'LV Pool name' in line: + lvm_info['pool'] = line.split('LV Pool name')[1].strip() + continue + + if 'LV Status' in line: + lvm_info['status'] = line.split('LV Status')[1].strip() + continue + + if 'LV Size' in line: + lvm_info['size'] = line.split('LV Size')[1].strip() + continue + + if 'Mapped size' in line: + lvm_info['mapped'] = line.split('Mapped size')[1].strip() + continue + + if 'Block device' in line: + lvm_info['block_device'] = line.split('Block device')[1].strip() + lvms.append(lvm_info) + lvm_section = False + continue + + return lvms + + def get_lvms(self, progress_bar=False, cache=False): + if cache and self.lvm is not None: + return self.lvm + + commands = ['sudo lvm lvdisplay'] + outputs = self.run_commands(commands, progress_bar=progress_bar) + if outputs is None: + self.log.error( + 'get_lvms', + 'Commands output collection failed' + ) + return None + + self.lvm = self.get_lvms_info( + outputs['sudo lvm lvdisplay'] + ) + + return self.lvm diff --git a/lib/linux/main.py b/lib/linux/main.py new file mode 100644 index 00000000..8d6b972d --- /dev/null +++ b/lib/linux/main.py @@ -0,0 +1,80 @@ +from lib.linux.bond.main import LinuxBond +from lib.linux.boot.main import LinuxBoot +from lib.linux.chrony.main import LinuxChrony +from lib.linux.container_policy.main import LinuxContainerPolicy +from lib.linux.commands import LinuxCommands +from lib.linux.genisoimage.main import LinuxGenIsoImage +from lib.linux.huge_pages.main import LinuxHugePages +from lib.linux.interface import LinuxInterface +from lib.linux.lvm import LinuxLvm +from lib.linux.state import LinuxState +from lib.linux.sysctl.main import LinuxSysctl +from lib.linux.virtctl.main import LinuxVirtctl +from lib.linux.cache import Cache +from lib.linux.common import Common + +from lib import output_helper +from lib import log_helper +from lib import ssh + + +class Linux( + Cache, + Common, + LinuxBond, + LinuxBoot, + LinuxChrony, + LinuxContainerPolicy, + LinuxCommands, + LinuxGenIsoImage, + LinuxHugePages, + LinuxInterface, + LinuxLvm, + LinuxState, + LinuxSysctl, + LinuxVirtctl + ): + def __init__(self, ip_address, username, password=None, key_filename=None, server_name=None, no_cache=False, verbose=False, debug=False, log_id=None): + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper( + verbose=verbose, + debug=debug + ) + + self.ssh_handler = ssh.Ssh( + ip_address, + username, + password=password, + key_filename=key_filename, + verbose=verbose, + debug=debug, + log_id=log_id + ) + + self.server_name = server_name + self.management_ip = ip_address + if server_name is None: + self.server_display_name = ip_address + else: + self.server_display_name = server_name + + self.username = username + self.password = password + self.key_filename = key_filename + self.verbose = verbose + self.debug = debug + + Cache.__init__(self, server_name, no_cache=no_cache) + Common.__init__(self) + LinuxBond.__init__(self) + LinuxBoot.__init__(self) + LinuxChrony.__init__(self) + LinuxContainerPolicy.__init__(self) + LinuxCommands.__init__(self) + LinuxGenIsoImage.__init__(self) + LinuxHugePages.__init__(self) + LinuxInterface.__init__(self) + LinuxLvm.__init__(self) + LinuxState.__init__(self) + LinuxSysctl.__init__(self) + LinuxVirtctl.__init__(self) diff --git a/lib/linux/output.py b/lib/linux/output.py new file mode 100644 index 00000000..292e23ea --- /dev/null +++ b/lib/linux/output.py @@ -0,0 +1,90 @@ +from lib import output_helper + +from lib.linux.bond.output import LinuxBondOutput +from lib.linux.boot.output import LinuxBootOutput +from lib.linux.chrony.output import LinuxChronyOutput +from lib.linux.container_policy.output import LinuxContainerPolicyOutput +from lib.linux.huge_pages.output import LinuxHugePagesOutput +from lib.linux.sysctl.output import LinuxSysctlOutput + + +class LinuxOutput( + LinuxBondOutput, + LinuxBootOutput, + LinuxChronyOutput, + LinuxContainerPolicyOutput, + LinuxHugePagesOutput, + LinuxSysctlOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + LinuxBondOutput.__init__(self) + LinuxBootOutput.__init__(self) + LinuxChronyOutput.__init__(self) + LinuxContainerPolicyOutput.__init__(self) + LinuxHugePagesOutput.__init__(self) + LinuxSysctlOutput.__init__(self) + + def print_linux_servers(self, servers, show_password=True): + if self.my_output is None: + self.my_output = output_helper.OutputHelper( + log_id=self.log_id, + verbose=False, + debug=False + ) + + servers = sorted(servers, key=lambda i: i['name']) + if not show_password: + for server in servers: + if server['password'] is not None: + server['password'] = '******' + + for server in servers: + server['__Output'] = {} + if server['cache']['enabled']: + server['cache']['enabledTick'] = '\u2713' + server['__Output']['cache.enabledTick'] = 'Green' + else: + server['cache']['enabledTick'] = '\u2717' + server['__Output']['cache.enabledTick'] = 'Red' + + if server['password'] is None: + server['password'] = '--' + + if server['key'] is None: + server['key'] = '--' + + order = [ + 'name', + 'address', + 'username', + 'password', + 'key', + 'cache.enabledTick', + 'cache.ttlT', + 'cache.directory' + ] + + headers = [ + 'Name', + 'IP', + 'Username', + 'Password', + 'Key', + 'Cache', + 'TTL', + 'Directory' + ] + + self.my_output.my_table( + servers, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) diff --git a/lib/linux/settings.py b/lib/linux/settings.py new file mode 100644 index 00000000..2ec4922e --- /dev/null +++ b/lib/linux/settings.py @@ -0,0 +1,207 @@ +import os +import json +from datetime import timedelta +import shutil +import uuid +import traceback + +from lib import log_helper +from lib.settings_helper import Settings + + +class LinuxSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.linux_settings_dir = os.path.join( + self.settings_dir, + 'linux' + ) + self.linux_settings_filename = os.path.join( + self.linux_settings_dir, + 'settings' + ) + + if not self.initialize_linux_settings(): + raise ValueError('K8s settings initialization failed') + + def get_linux_default_settings(self): + settings = {} + settings['defaults'] = None + settings['servers'] = [] + return settings + + def get_linux_default_cache_settings(self): + settings = {} + settings['enabled'] = True + settings['ttl'] = 600 + settings['ttlT'] = '{}'.format(str(timedelta(seconds=settings['ttl']))) + settings['object'] = [] + return settings + + def initialize_linux_settings(self): + if not os.path.isdir(self.linux_settings_dir): + os.makedirs(self.linux_settings_dir, exist_ok=True) + + if not os.path.isfile(self.linux_settings_filename): + settings = self.get_linux_default_settings() + if not self.set_linux_settings(settings): + return False + + return True + + def get_linux_settings(self): + if not os.path.isfile(self.linux_settings_filename): + return None + + try: + with open(self.linux_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_linux_settings', traceback.format_exc()) + return None + + return settings + + def set_linux_settings(self, settings): + try: + with open(self.linux_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_linux_settings', traceback.format_exc()) + return False + + return True + + def get_default_server(self): + settings = self.get_linux_settings() + if settings is None: + return None + + try: + default_server_name = settings['defaults'] + except BaseException: + default_server_name = None + + return default_server_name + + def set_default_server(self, name): + settings = self.get_linux_settings() + if settings is None: + return False + + if 'defaults' not in settings: + settings['defaults'] = None + + settings['defaults'] = name + return self.set_linux_settings(settings) + + def get_linux_servers(self): + settings = self.get_linux_settings() + if settings is None: + return None + + servers = settings['servers'] + servers = sorted( + servers, + key=lambda i: i['name'] + ) + + return servers + + def get_linux_server(self, linux_name, strict_match=True): + servers = self.get_linux_servers() + if servers is None: + return None + + candidates = [] + for server in servers: + if server['name'] == linux_name: + return server + + if not strict_match: + if linux_name.lower() in server['name'].lower(): + candidates.append(server) + + if not strict_match and len(candidates) == 1: + return candidates[0] + + return None + + def set_linux_servers(self, servers): + settings = self.get_linux_settings() + if settings is None: + return False + + settings['servers'] = servers + return self.set_linux_settings(settings) + + def set_linux_server(self, linux_name, linux_ip, username, password=None, key_filename=None): + servers = self.get_linux_servers() + if servers is None: + return False + + new_servers = [] + previous = None + for server in servers: + if server['name'] == linux_name: + previous = server + if server['name'] != linux_name: + new_servers.append(server) + + new_server = {} + new_server['name'] = linux_name + new_server['address'] = linux_ip + new_server['username'] = username + new_server['password'] = password + new_server['key'] = key_filename + if previous is None: + new_server['id'] = str(uuid.uuid4()) + new_server['cache'] = self.get_linux_default_cache_settings() + server_directory = os.path.join( + self.linux_settings_dir, + new_server['id'] + ) + if not os.path.isdir(server_directory): + os.makedirs(server_directory, exist_ok=True) + new_server['cache']['directory'] = server_directory + + if previous is not None: + new_server['id'] = previous['id'] + new_server['cache'] = previous['cache'] + + new_servers.append(new_server) + + return self.set_linux_servers(new_servers) + + def delete_linux_server(self, linux_name): + servers = self.get_linux_servers() + if servers is None: + return False + + default_server = self.get_default_server() + if default_server is not None and default_server == linux_name: + self.set_default_server(None) + + new_servers = [] + server_id = None + for server in servers: + if server['name'] == linux_name: + server_id = server['id'] + if server['name'] != linux_name: + new_servers.append(server) + + if server_id is not None: + server_directory = os.path.join( + self.linux_settings_dir, + server_id + ) + if os.path.isdir(server_directory): + shutil.rmtree(server_directory) + + return self.set_linux_servers(new_servers) diff --git a/lib/linux/state.py b/lib/linux/state.py new file mode 100644 index 00000000..776fa552 --- /dev/null +++ b/lib/linux/state.py @@ -0,0 +1,393 @@ +import time +import json +import re +import traceback + +from progress.bar import IncrementalBar + + +class LinuxState(): + def __init__(self): + pass + + def convert_pct(self, pct): + try: + value = '%s%%' % (round(pct, 2)) + except BaseException: + self.log.error('iwe_cluster_info.convert_cpu_capacity', pct) + return None + return value + + def convert_memory(self, value): + try: + unit = ['KiB', 'MiB', 'GiB', 'TiB'] + for index in range(0, 4): + value = value / 1024 + if value < 1000: + break + + value = '%s [%s]' % ( + round(value, 2), + unit[index] + ) + + except BaseException: + self.my_output.traceback(traceback.format_exc()) + return None + + return value + + def convert_storage(self, value): + try: + unit = ['KB', 'MB', 'GB', 'TB'] + for index in range(0, 4): + value = value / 1000 + if value < 1000: + break + + value = '%s [%s]' % ( + round(value, 2), + unit[index] + ) + + except BaseException: + self.log.error('iwe_cluster_info.convert_storage', value) + return None + + return value + + def get_cpu_load(self, output): + try: + load = {} + for line in output.split('\n'): + if 'load average:' in line: + value = line.split('load average:')[1] + if ',' in value: + load_list = value.split(',') + else: + load_list = value.split(' ') + + load['cpu_load_1min'] = float(load_list[0].strip()) + load['cpu_load_5min'] = float(load_list[1].strip()) + load['cpu_load_15min'] = float(load_list[2].strip()) + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return load + + def get_memory_utilization(self, output): + try: + memory_utilization = {} + for line in output.split('\n'): + line = line.rstrip('\n') + if line.startswith('Mem:'): + values = line.split('Mem:')[1].strip() + mem_string = re.sub(' +', ' ', values).split(' ') + memory_utilization['memory_total'] = int(mem_string[0]) + memory_utilization['memory_total_unit'] = self.convert_memory( + memory_utilization['memory_total'] + ) + memory_utilization['memory_used'] = int(mem_string[1]) + memory_utilization['memory_used_unit'] = self.convert_memory( + memory_utilization['memory_used'] + ) + memory_utilization['memory_free'] = int(mem_string[2]) + memory_utilization['memory_free_unit'] = self.convert_memory( + memory_utilization['memory_free'] + ) + memory_utilization['memory_shared'] = int(mem_string[3]) + memory_utilization['memory_shared_unit'] = self.convert_memory( + memory_utilization['memory_shared'] + ) + memory_utilization['memory_cache'] = int(mem_string[4]) + memory_utilization['memory_cache_unit'] = self.convert_memory( + memory_utilization['memory_cache'] + ) + memory_utilization['memory_available'] = int(mem_string[5]) + memory_utilization['memory_available_unit'] = self.convert_memory( + memory_utilization['memory_available'] + ) + memory_utilization['memory_used_pct'] = int(memory_utilization['memory_used'] * 100 / memory_utilization['memory_total']) + memory_utilization['memory_used_pct_unit'] = self.convert_pct( + memory_utilization['memory_used_pct'] + ) + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return memory_utilization + + def get_disk_utilization(self, output): + try: + disk_info = {} + disk_info['disk_count'] = 0 + disk_info['disk_total_capacity'] = 0 + disk_info['disk_total_used'] = 0 + disk_info['disk_max_used_pct'] = 0 + for line in output.split('\n'): + if line.startswith('/dev/'): + disk_info['disk_count'] = disk_info['disk_count'] + 1 + values = re.sub(' +', ' ', line).split(' ') + disk_info['disk_total_capacity'] = disk_info['disk_total_capacity'] + int(values[1]) * 1024 + disk_info['disk_total_used'] = disk_info['disk_total_used'] + int(values[2]) * 1024 + disk_info['disk_max_used_pct'] = max( + disk_info['disk_max_used_pct'], + int(int(values[2]) * 100 / int(values[1])) + ) + + disk_info['disk_total_used_pct'] = int(disk_info['disk_total_used'] * 100 / disk_info['disk_total_capacity']) + disk_info['disk_total_used_pct_unit'] = self.convert_pct(disk_info['disk_total_used_pct']) + disk_info['disk_total_capacity_unit'] = self.convert_storage(disk_info['disk_total_capacity']) + disk_info['disk_total_used_unit'] = self.convert_storage(disk_info['disk_total_used']) + disk_info['disk_max_used_pct_unit'] = self.convert_pct(disk_info['disk_max_used_pct']) + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return disk_info + + def get_cpu_info(self, output): + try: + # Architecture: x86_64 + # CPU op-mode(s): 32-bit, 64-bit + # Byte Order: Little Endian + # CPU(s): 28 + # On-line CPU(s) list: 0-27 + # Thread(s) per core: 1 + # Core(s) per socket: 14 + # Socket(s): 2 + # NUMA node(s): 2 + # Vendor ID: GenuineIntel + # CPU family: 6 + # Model: 79 + # Model name: Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz + # Stepping: 1 + # CPU MHz: 2600.158 + # CPU max MHz: 2600.0000 + # CPU min MHz: 1200.0000 + # BogoMIPS: 5187.67 + # Virtualization: VT-x + # L1d cache: 32K + # L1i cache: 32K + # L2 cache: 256K + # L3 cache: 35840K + # NUMA node0 CPU(s): 0-13 + # NUMA node1 CPU(s): 14-27 + info = {} + info['numa_count'] = None + info['numa_nodes'] = [] + for line in output.split('\n'): + if line.startswith('Model name:'): + line = re.sub(' +', ' ', line) + info['cpu_model'] = line.split('Model name:')[1].strip() + if line.startswith('CPU(s):'): + line = re.sub(' +', ' ', line) + info['cpu_count'] = int(line.split('CPU(s):')[1]) + if line.startswith('Core(s) per socket:'): + line = re.sub(' +', ' ', line) + info['cpu_per_socket'] = int(line.split('Core(s) per socket:')[1]) + if line.startswith('Socket(s):'): + line = re.sub(' +', ' ', line) + info['socket_count'] = int(line.split('Socket(s):')[1]) + if line.startswith('NUMA node(s):'): + line = re.sub(' +', ' ', line) + info['numa_count'] = int(line.split('NUMA node(s):')[1]) + if line.startswith('Thread(s) per core:'): + line = re.sub(' +', ' ', line) + info['threads_count'] = int(line.split('Thread(s) per core:')[1]) + + info['hyperthreading'] = False + if info['cpu_per_socket'] * info['socket_count'] < info['cpu_count']: + info['hyperthreading'] = True + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return info + + def is_hypervisor(self, output): + try: + hypervisor = False + for line in output.split('\n'): + if line.startswith('Hypervisor vendor:'): + hypervisor = True + + if line.startswith('Flags:'): + if 'hypervisor' in line: + hypervisor = True + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return hypervisor + + def get_release_info(self, output): + try: + # NAME="Ubuntu" + # VERSION="18.04.4 LTS (Bionic Beaver)" + # ID=ubuntu + # ID_LIKE=debian + # PRETTY_NAME="Ubuntu 18.04.4 LTS" + # VERSION_ID="18.04" + # HOME_URL="https://www.ubuntu.com/" + # SUPPORT_URL="https://help.ubuntu.com/" + # BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" + # PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" + # VERSION_CODENAME=bionic + # UBUNTU_CODENAME=bionic + info = {} + for line in output.split('\n'): + if line.startswith('NAME='): + line = re.sub(' +', ' ', line) + info['release_name'] = line.split('=')[1].strip('"') + if line.startswith('VERSION='): + line = re.sub(' +', ' ', line) + info['release_version'] = line.split('=')[1].strip('"') + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return info + + def get_uptime(self, output): + try: + # cat /proc/uptime + # 3864040.37 102139784.03 + epoch = round(float(output.split(' ')[0])) + days = 0 + while True: + if epoch < 24 * 60 * 60: + break + + epoch = epoch - 24 * 60 * 60 + days = days + 1 + + if days == 0: + uptime = time.strftime('%H:%M:%S', time.gmtime(epoch)) + else: + uptime = '%s (%s days)' % (time.strftime('%H:%M:%S', time.gmtime(epoch)), days) + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return uptime + + def get_state_commands(self, settings): + commands = [] + commands.append('cat /etc/hostname') + commands.append('cat /proc/uptime') + commands.append('cat /etc/os-release') + + if settings['cpu']: + commands.append('uptime') + commands.append('lscpu') + + if settings['memory']: + commands.append('free -b') + + if settings['disk']: + commands.append('df -k') + + return commands + + def get_state(self, settings, progress_bar=False): + try: + commands = self.get_state_commands(settings) + outputs = self.run_commands(commands, progress_bar=progress_bar) + if outputs is None: + self.my_output.error('Commands output collection failed') + return None + + state = {} + state['management_ip'] = self.management_ip + state['ssh_username'] = self.username + state['ssh_password'] = self.password + + state['hostname'] = outputs['cat /etc/hostname'].rstrip('\n') + state['uptime'] = self.get_uptime(outputs['cat /proc/uptime']) + release_info = self.get_release_info(outputs['cat /etc/os-release']) + if release_info is not None: + for key in release_info: + state[key] = release_info[key] + + if settings['cpu']: + cpu_load = self.get_cpu_load(outputs['uptime']) + if cpu_load is not None: + for key in cpu_load: + state[key] = cpu_load[key] + + cpu_info = self.get_cpu_info(outputs['lscpu']) + if cpu_info is not None: + for key in cpu_info: + state[key] = cpu_info[key] + + state['hypervisor'] = self.is_hypervisor(outputs['lscpu']) + + if settings['memory']: + memory_info = self.get_memory_utilization(outputs['free -b']) + if memory_info is not None: + for key in memory_info: + state[key] = memory_info[key] + + if settings['disk']: + disk_info = self.get_disk_utilization(outputs['df -k']) + if disk_info is not None: + for key in disk_info: + state[key] = disk_info[key] + + except BaseException: + self.my_output.default(traceback.format_exc()) + return None + + return state + + def print_state(self, state): + self.my_output.dictionary( + state, + title='Linux State Summary', + underline=True, + prefix="- ", + justify=True, + keys=[ + 'management_ip', + 'ssh_username', + 'ssh_password', + 'hostname', + 'uptime', + 'release_name', + 'release_version', + 'cpu_count', + 'hyperthreading', + 'cpu_load_1min', + 'memory_total_unit', + 'memory_used_pct_unit', + 'disk_total_capacity_unit', + 'disk_total_used_pct_unit', + 'disk_max_used_pct_unit' + ], + title_keys=[ + 'IP Address', + 'Username', + 'Password', + 'Hostname', + 'Uptime', + 'Release name', + 'Release version', + 'CPU count', + 'Hyperthreading', + 'CPU load (1 minute)', + 'Memory', + 'Memory usage', + 'Disk total capacity', + 'Disk total usage', + 'Max disk usage' + ] + ) diff --git a/lib/linux/sysctl/__init__.py b/lib/linux/sysctl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/sysctl/cmd.py b/lib/linux/sysctl/cmd.py new file mode 100644 index 00000000..ab67a3db --- /dev/null +++ b/lib/linux/sysctl/cmd.py @@ -0,0 +1,35 @@ +import re + + +class LinuxSysctlCmd(): + def __init__(self): + self.sysctl_cmd = None + + def get_sysctl_cmd(self): + command = 'sudo sysctl -a' + if self.sysctl_cmd is not None: + return self.sysctl_cmd + + cache = self.get_cmd_cache( + 'sysctl' + ) + if cache is not None: + self.sysctl_cmd = cache + return self.sysctl_cmd + + outputs = self.run_commands([command]) + if outputs is None: + self.log.error( + 'get_sysctl_cmd', + 'Commands output collection failed' + ) + return None + + self.sysctl_cmd = outputs[command] + + self.set_cmd_cache( + 'sysctl', + self.sysctl_cmd + ) + + return self.sysctl_cmd diff --git a/lib/linux/sysctl/info.py b/lib/linux/sysctl/info.py new file mode 100644 index 00000000..6a085850 --- /dev/null +++ b/lib/linux/sysctl/info.py @@ -0,0 +1,69 @@ +import re + +from lib import filter_helper + + +class LinuxSysctlInfo(): + def __init__(self): + self.sysctl = None + + def get_sysctl_info(self): + if self.sysctl is not None: + return self.sysctl + + output = self.get_sysctl_cmd() + if output is None: + return None + + self.sysctl = [] + for line in output.split('\n'): + if len(line.split(' = ')) == 2: + (key, value) = line.split(' = ') + + item = {} + item['key'] = key + item['value'] = re.sub(' +', ' ', value).replace('\t', ' ') + self.sysctl.append( + item + ) + + return self.sysctl + + def match_sysctl(self, sysctl_info, sysctl_filter): + if sysctl_filter is None or len(sysctl_filter) == 0: + return True + + for ap_rule in sysctl_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'key': + key_found = True + if not filter_helper.match_string(value, sysctl_info['key']): + return False + + if not key_found: + self.log.error( + 'match_sysctl', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_sysctl(self, sysctl_filter=None): + all_sysctl = self.get_sysctl_info() + if all_sysctl is None: + return None + + sysctl = [] + + for sysctl_info in all_sysctl: + if not self.match_sysctl(sysctl_info, sysctl_filter): + continue + + sysctl.append( + sysctl_info + ) + + return sysctl diff --git a/lib/linux/sysctl/main.py b/lib/linux/sysctl/main.py new file mode 100644 index 00000000..0bf3461a --- /dev/null +++ b/lib/linux/sysctl/main.py @@ -0,0 +1,11 @@ +from lib.linux.sysctl.cmd import LinuxSysctlCmd +from lib.linux.sysctl.info import LinuxSysctlInfo + + +class LinuxSysctl( + LinuxSysctlCmd, + LinuxSysctlInfo + ): + def __init__(self): + LinuxSysctlCmd.__init__(self) + LinuxSysctlInfo.__init__(self) diff --git a/lib/linux/sysctl/output.py b/lib/linux/sysctl/output.py new file mode 100644 index 00000000..023bea71 --- /dev/null +++ b/lib/linux/sysctl/output.py @@ -0,0 +1,52 @@ +class LinuxSysctlOutput(): + def __init__(self): + pass + + def print_linux_sysctl(self, info, diff_servers, diff_sysctl, title=False): + if title: + self.my_output.default( + 'Sysctl [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'key', + 'value' + ] + + headers = [ + 'Key', + 'Value' + ] + + if len(diff_servers) > 0: + for diff_server in diff_servers: + order.append(diff_server) + headers.append('Server: %s' % (diff_server)) + + for item in info: + for diff_item in diff_sysctl[diff_server]: + if item['key'] == diff_item['key']: + item[diff_server] = diff_item['value'] + + for item in info: + item['__Output'] = {} + for diff_server in diff_servers: + if item['value'] != item[diff_server]: + item['__Output']['key'] = 'Red' + item['__Output']['value'] = 'Red' + item['__Output'][diff_server] = 'Red' + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=False, + underline=True, + table=True + ) diff --git a/lib/linux/virtctl/__init__.py b/lib/linux/virtctl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/linux/virtctl/main.py b/lib/linux/virtctl/main.py new file mode 100644 index 00000000..c3787b78 --- /dev/null +++ b/lib/linux/virtctl/main.py @@ -0,0 +1,54 @@ +import os +import time +import uuid + + +class LinuxVirtctl(): + def __init__(self): + pass + + def virtctl_image_upload(self, data_volume_namespace, data_volume_name, source_filename, max_attempts=1): + attempt = 1 + while True: + time.sleep(5) + + command = 'virtctl image-upload dv -n %s %s --no-create --insecure --image-path %s' % ( + data_volume_namespace, + data_volume_name, + source_filename + ) + + success, output, error = self.ssh_handler.run_cmd( + command, + live_output=False + ) + if not success: + self.log.error( + 'virtctl_image_upload', + 'Data volume upload failed: %s => %s' % (source_filename, data_volume_name) + ) + self.log.error( + 'virtctl_image_upload', + output + ) + self.log.error( + 'virtctl_image_upload', + error + ) + attempt = attempt + 1 + if attempt > max_attempts: + return False + + if success: + self.log.debug( + 'virtctl_image_upload', + 'Data volume uploaded: %s => %s' % (source_filename, data_volume_name) + ) + self.log.debug( + 'virtctl_image_upload', + output + ) + + break + + return True diff --git a/lib/log_helper.py b/lib/log_helper.py new file mode 100644 index 00000000..0bd431a8 --- /dev/null +++ b/lib/log_helper.py @@ -0,0 +1,1806 @@ +import datetime +import os +import glob +import time +import json +import shutil +import csv +from xlsxwriter.workbook import Workbook + +from lib import output_helper +from lib import ssh + + +class Log(): + def __init__(self, log_id=None): + self.logs_directory = '/tmp/iserver' + self.bot_logs_directory = '/tmp/iserver.bot' + if log_id is not None: + if log_id.startswith('bot.'): + self.logs_directory = os.path.join(self.bot_logs_directory, log_id[4:]) + else: + self.logs_directory = os.path.join(self.logs_directory, log_id) + + self.log_id = log_id + + self.command_filename = os.path.join(self.logs_directory, 'command') + self.error_filename = os.path.join(self.logs_directory, 'iserver.error') + self.info_filename = os.path.join(self.logs_directory, 'iserver.info') + self.debug_filename = os.path.join(self.logs_directory, 'iserver.debug') + self.isctl_filename = os.path.join(self.logs_directory, 'isctl.debug') + self.api_filename = os.path.join(self.logs_directory, 'api.debug') + self.redfish_filename = os.path.join(self.logs_directory, 'redfish.debug') + self.odata_filename = os.path.join(self.logs_directory, 'odata.debug') + self.ucsm_filename = os.path.join(self.logs_directory, 'ucsm.debug') + self.k8s_filename = os.path.join(self.logs_directory, 'k8s.debug') + self.osp_filename = os.path.join(self.logs_directory, 'osp.debug') + self.psirt_filename = os.path.join(self.logs_directory, 'psirt.debug') + self.nso_filename = os.path.join(self.logs_directory, 'nso.debug') + self.ocapi_filename = os.path.join(self.logs_directory, 'ocapi.debug') + self.ocp_filename = os.path.join(self.logs_directory, 'ocp.debug') + self.kubevirt_filename = os.path.join(self.logs_directory, 'kubevirt.debug') + self.vcenter_filename = os.path.join(self.logs_directory, 'vcenter.debug') + self.nexus_filename = os.path.join(self.logs_directory, 'nexus.debug') + self.apic_filename = os.path.join(self.logs_directory, 'apic.debug') + self.openshift_filename = os.path.join(self.logs_directory, 'openshift.debug') + self.iwo_filename = os.path.join(self.logs_directory, 'iwo.debug') + self.ssh_filename = os.path.join(self.logs_directory, 'ssh.debug') + self.devel_filename = os.path.join(self.logs_directory, 'devel.debug') + self.lcm_report_filename = os.path.join(self.logs_directory, 'lcm.report') + self.cache_filename = os.path.join(self.logs_directory, 'cache') + self.trace_filename = os.path.join(self.logs_directory, 'trace') + + self.mapping = {} + self.mapping['command'] = self.command_filename + self.mapping['error'] = self.error_filename + self.mapping['info'] = self.info_filename + self.mapping['debug'] = self.debug_filename + self.mapping['isctl'] = self.isctl_filename + self.mapping['api'] = self.api_filename + self.mapping['odata'] = self.odata_filename + self.mapping['redfish'] = self.redfish_filename + self.mapping['ucsm'] = self.ucsm_filename + self.mapping['k8s'] = self.k8s_filename + self.mapping['osp'] = self.osp_filename + self.mapping['psirt'] = self.psirt_filename + self.mapping['nso'] = self.nso_filename + self.mapping['ocapi'] = self.ocapi_filename + self.mapping['ocp'] = self.ocp_filename + self.mapping['kubevirt'] = self.kubevirt_filename + self.mapping['vcenter'] = self.vcenter_filename + self.mapping['nexus'] = self.nexus_filename + self.mapping['apic'] = self.apic_filename + self.mapping['openshift'] = self.openshift_filename + self.mapping['iwo'] = self.iwo_filename + self.mapping['ssh'] = self.ssh_filename + + def initialize(self, max_dirs=100): + try: + if self.log_id is not None: + if not os.path.isdir(self.logs_directory): + os.makedirs(self.logs_directory, exist_ok=True) + + logs_base_directory = os.path.dirname(self.logs_directory) + my_dirs = [] + for name in os.listdir(logs_base_directory): + directory = os.path.join(logs_base_directory, name) + if os.path.isdir(directory): + my_dirs.append( + dict( + directory=directory, + create_time=int(os.path.getmtime(directory)) + ) + ) + + if len(my_dirs) > max_dirs: + my_dirs = sorted(my_dirs, key=lambda i: i['create_time']) + my_max = len(my_dirs) - max_dirs + for index in range(0, my_max): + directory = my_dirs[index]['directory'] + if directory.startswith(logs_base_directory): + if directory != self.logs_directory: + shutil.rmtree(directory) + + except BaseException: + pass + + def clean(self): + if self.log_id is not None: + shutil.rmtree(self.logs_directory) + + def output_html(self, content, filename='output.html'): + self.safe_write( + os.path.join(self.logs_directory, filename), + content + ) + + def bot_output(self, content, log_id=None): + if log_id is None: + filename = os.path.join(self.logs_directory, 'bot.txt') + else: + filename = os.path.join(self.logs_directory, '%s.txt' % (log_id)) + + if not self.safe_write(filename, content): + return None + + return filename + + def bot_csv(self, name, fields, rows): + filename = os.path.join(self.logs_directory, '%s.csv' % (name)) + with open(filename, 'w', encoding='utf8') as file_handler: + write = csv.writer(file_handler) + write.writerow(fields) + for row in rows: + write.writerow(row) + + def bot_xls(self, items, log_id=None): + if log_id is None: + filename = os.path.join(self.logs_directory, 'bot.xlsx') + else: + filename = os.path.join(self.logs_directory, '%s.xlsx' % (log_id)) + + workbook = Workbook(filename) + for item in items: + csv_filename = os.path.join(self.logs_directory, '%s.csv' % (item)) + if os.path.isfile(csv_filename): + worksheet = workbook.add_worksheet(item) + with open(csv_filename, "rt", encoding="utf8") as f: + reader = csv.reader(f) + for r, row in enumerate(reader): + for c, col in enumerate(row): + worksheet.write(r, c, col) + + workbook.close() + return filename + + def trace(self, name, start_time): + log_filename = os.path.join(self.logs_directory, self.trace_filename) + try: + self.safe_append( + log_filename, + '%s\t%s\n' % ( + int(time.time() * 1000) - start_time, + name + ) + ) + except BaseException: + pass + + def analyze_isctl(self): + result = {} + result['read'] = False + result['calls'] = 0 + result['success'] = 0 + result['failed'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.isctl_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + result['calls'] = result['calls'] + 1 + (when, success, duration, count, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + return result + + def analyze_ucsm(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['disconnect'] = 0 + result['mo'] = 0 + result['connect_time'] = 0 + result['disconnect_time'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.ucsm_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + if 'disconnect ' in command: + result['disconnect'] = result['disconnect'] + 1 + result['disconnect_time'] = result['disconnect_time'] + int(duration) + continue + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_apic(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['disconnect'] = 0 + result['mo'] = 0 + result['connect_time'] = 0 + result['disconnect_time'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.apic_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + if len(line.split('\t')) != 4: + print(line) + + (success, duration, count, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + if 'disconnect ' in command: + result['disconnect'] = result['disconnect'] + 1 + result['disconnect_time'] = result['disconnect_time'] + int(duration) + continue + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_openshift(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['disconnect'] = 0 + result['mo'] = 0 + result['connect_time'] = 0 + result['disconnect_time'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.openshift_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + if len(line.split('\t')) != 4: + print(line) + + (success, duration, count, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + if 'disconnect ' in command: + result['disconnect'] = result['disconnect'] + 1 + result['disconnect_time'] = result['disconnect_time'] + int(duration) + continue + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_iwo(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['disconnect'] = 0 + result['mo'] = 0 + result['connect_time'] = 0 + result['disconnect_time'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.iwo_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, count, command, url, body) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + if 'disconnect ' in command: + result['disconnect'] = result['disconnect'] + 1 + result['disconnect_time'] = result['disconnect_time'] + int(duration) + continue + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_k8s(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.k8s_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, scope, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_osp(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.osp_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, scope, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_psirt(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.psirt_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, scope, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_nso(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.nso_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, command, scope) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_ocp(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.ocp_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + try: + (when, success, duration, scope, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + except BaseException: + pass + + return result + + def analyze_kubevirt(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.kubevirt_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, scope, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_vcenter(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['connect_time'] = 0 + result['mo'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.vcenter_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, scope, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_nexus(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['disconnect'] = 0 + result['mo'] = 0 + result['connect_time'] = 0 + result['disconnect_time'] = 0 + result['mo_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.nexus_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + (when, success, duration, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + if 'disconnect ' in command: + result['disconnect'] = result['disconnect'] + 1 + result['disconnect_time'] = result['disconnect_time'] + int(duration) + continue + + result['mo'] = result['mo'] + 1 + result['mo_time'] = result['mo_time'] + int(duration) + + return result + + def analyze_redfish(self): + result = {} + result['read'] = False + result['success'] = 0 + result['failed'] = 0 + result['connect'] = 0 + result['disconnect'] = 0 + result['path'] = 0 + result['connect_time'] = 0 + result['disconnect_time'] = 0 + result['path_time'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.redfish_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + if len(line.split('\t')) != 4: + continue + + (when, success, duration, command) = line.split('\t') + if success == 'True': + result['success'] = result['success'] + 1 + else: + result['failed'] = result['failed'] + 1 + + result['total_time'] = result['total_time'] + int(duration) + + if 'connect ' in command: + result['connect'] = result['connect'] + 1 + result['connect_time'] = result['connect_time'] + int(duration) + continue + + if 'disconnect ' in command: + result['disconnect'] = result['disconnect'] + 1 + result['disconnect_time'] = result['disconnect_time'] + int(duration) + continue + + result['path'] = result['path'] + 1 + result['path_time'] = result['path_time'] + int(duration) + + return result + + def analyze_ssh(self): + result = {} + result['read'] = False + result['calls'] = 0 + result['total_time'] = 0 + + content = self.get_file(self.ssh_filename) + if content is None: + return result + + result['read'] = True + for line in content.split('\n'): + if len(line) > 0: + result['calls'] = result['calls'] + 1 + (when, success, duration, ip_address, command) = line.split('\t') + result['total_time'] = result['total_time'] + int(duration) + + return result + + def analyze_log(self, filename): + result = {} + result['read'] = False + result['lines'] = 0 + + content = self.get_file(filename) + if content is None: + return result + + result['read'] = True + result['lines'] = len(content.split('\n')) + return result + + def analyze(self, duration): + result = {} + result['duration'] = duration + info = self.analyze_isctl() + if info['read']: + result['isctl'] = info + + info = self.analyze_redfish() + if info['read']: + result['redfish'] = info + + info = self.analyze_ucsm() + if info['read']: + result['ucsm'] = info + + info = self.analyze_nexus() + if info['read']: + result['nexus'] = info + + info = self.analyze_k8s() + if info['read']: + result['k8s'] = info + + info = self.analyze_osp() + if info['read']: + result['osp'] = info + + info = self.analyze_psirt() + if info['read']: + result['psirt'] = info + + info = self.analyze_nso() + if info['read']: + result['nso'] = info + + info = self.analyze_ocp() + if info['read']: + result['ocp'] = info + + info = self.analyze_kubevirt() + if info['read']: + result['kubevirt'] = info + + info = self.analyze_vcenter() + if info['read']: + result['vcenter'] = info + + info = self.analyze_apic() + if info['read']: + result['apic'] = info + + info = self.analyze_openshift() + if info['read']: + result['openshift'] = info + + info = self.analyze_iwo() + if info['read']: + result['iwo'] = info + + info = self.analyze_ssh() + if info['read']: + result['ssh'] = info + + result['error'] = self.analyze_log(self.error_filename) + result['info'] = self.analyze_log(self.info_filename) + result['debug'] = self.analyze_log(self.debug_filename) + result['cache_hits'] = self.analyze_cache_hit() + + return result + + def get_file(self, filename): + if os.path.isfile(filename): + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + return file_handler.read() + except BaseException: + pass + return None + + def get_log(self, log_name, json_conversion=False): + filename = os.path.join( + self.logs_directory, + log_name + ) + + content = None + if os.path.isfile(filename): + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + if json_conversion: + content = json.loads(content) + + except BaseException: + return None + + return content + + def set_log(self, log_name, content, json_conversion=False): + filename = os.path.join( + self.logs_directory, + log_name + ) + + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + if json_conversion: + file_handler.write(json.dumps(content, indent=4)) + else: + file_handler.write(content) + + except BaseException: + return False + + return True + + def get_log_filename(self, log_name): + if log_name in self.mapping: + return self.mapping[log_name] + return None + + def is_log(self, log_name): + if log_name in self.mapping: + return os.path.isfile(self.mapping[log_name]) + return False + + def get_logs(self, files=None): + if files is None: + files = ['debug', 'info', 'error', 'isctl', 'ssh', 'redfish', 'ucsm', 'nexus', 'k8s', 'osp', 'psirt', 'nso', 'ocapi', 'ocp', 'kubevirt', 'vcenter', 'apic', 'openshift', 'iwo'] + + content = {} + for filename in files: + if filename in self.mapping: + content[filename] = self.get_file(self.mapping[filename]) + + return content + + def analyze_cache_hit(self): + content = self.get_file(self.cache_filename) + if content is None: + return 0 + return len(content.split('\n')) + + def cache_hit(self, object_type, object_scope, object_name, filename, ttl, age): + msg = "%s\t%s\t%s\t%s\t%s\t%s\n" % ( + ttl, + age, + object_type, + object_scope, + object_name, + filename + ) + + success = self.safe_append( + self.cache_filename, + msg + ) + if not success: + print('SSH log failed...') + + def is_cache(self, key): + filename = '%s.%s' % ( + self.cache_filename, + key + ) + return os.path.isfile(filename) + + def get_cache(self, key): + try: + filename = '%s.%s' % ( + self.cache_filename, + key + ) + if not os.path.isfile(filename): + return None + + content = json.loads( + self.get_file( + filename + ) + ) + + except BaseException: + return None + + return content + + def wait_for_no_file(self, filename, max_wait_ms=1000, gap=0.1): + try: + start = int(time.time() * 1000) + while True: + if not os.path.isfile(filename): + return True + time.sleep(0.1) + if int(time.time() * 1000) - start > max_wait_ms: + return False + except BaseException: + return False + + def safe_write(self, filename, content, force=True): + success = True + try: + lock = '%s.lock' % (filename) + if not self.wait_for_no_file(lock): + if not force: + return False + + loop = 0 + while True: + try: + with open(lock, 'w', encoding='utf-8') as file_handler: + file_handler.write('lock') + file_handler.close() + + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + if os.path.isfile(lock): + os.remove(lock) + + break + + except BaseException: + if os.path.isfile(lock): + os.remove(lock) + + time.sleep(0.01) + loop = loop + 1 + if loop > 3: + success = False + break + + if os.path.isfile(lock): + os.remove(lock) + + except BaseException: + return False + + return success + + def safe_append(self, filename, content, force=True): + success = True + try: + lock = '%s.lock' % (filename) + if not self.wait_for_no_file(lock): + if not force: + return False + + loop = 0 + while True: + try: + with open(lock, 'w', encoding='utf-8') as file_handler: + file_handler.write('lock') + file_handler.close() + + with open(filename, 'a', encoding='utf-8') as file_handler: + file_handler.write(content) + + if os.path.isfile(lock): + os.remove(lock) + + break + + except BaseException: + if os.path.isfile(lock): + os.remove(lock) + + time.sleep(0.01) + loop = loop + 1 + if loop > 3: + success = False + break + + if os.path.isfile(lock): + os.remove(lock) + + except BaseException: + return False + + return success + + def ssh(self, ip_address, cmd, success, duration): + try: + current_time = datetime.datetime.now() + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, success, duration, ip_address, cmd) + + success = self.safe_append( + self.ssh_filename, + msg + ) + if not success: + print('SSH log failed...') + + except BaseException: + pass + + def ucsm(self, command, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command + ) + + success = self.safe_append( + self.ucsm_filename, + msg + ) + if not success: + print('Ucsm log failed...') + + except BaseException: + pass + + def apic(self, command, success, duration, item_count=None): + try: + count = '-' + if item_count is not None: + count = int(item_count) + + msg = "%s\t%s\t%s\t%s\n" % ( + success, + duration, + count, + command + ) + + success = self.safe_append( + self.apic_filename, + msg + ) + if not success: + print('Apic log failed...') + + except BaseException: + pass + + def get_apic_mo(self, name): + filename = os.path.join( + self.logs_directory, + 'apic.mo.%s' % (name) + ) + + content = self.get_file(filename) + if content is not None: + content = json.loads(content) + + return content + + def apic_mo(self, name, managed_object, overwrite=False): + try: + name = name.replace('/', '_') + filename = os.path.join( + self.logs_directory, + 'apic.mo.%s' % (name) + ) + + if overwrite or not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def openshift(self, command, success, duration, item_count=None): + try: + count = '-' + if item_count is not None: + count = int(item_count) + + msg = "%s\t%s\t%s\t%s\n" % ( + success, + duration, + count, + command + ) + + success = self.safe_append( + self.openshift_filename, + msg + ) + if not success: + print('OpenShift log failed...') + + except BaseException: + pass + + def openshift_mo(self, name, managed_object, overwrite=False): + try: + name = name.replace('/', '_') + filename = os.path.join( + self.logs_directory, + 'openshift.mo.%s' % (name) + ) + + if overwrite or not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def intersight_mo(self, name, managed_object, overwrite=False): + try: + name = name.replace('/', '_') + filename = os.path.join( + self.logs_directory, + 'intersight.mo.%s' % (name) + ) + + if overwrite or not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def iwo(self, command, url, body, success, duration, item_count=None): + try: + current_time = datetime.datetime.now() + + count = '-' + if item_count is not None: + count = int(item_count) + + msg = "%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + count, + command, + url, + body + ) + + success = self.safe_append( + self.iwo_filename, + msg + ) + if not success: + print('Iwo log failed...') + + except BaseException: + pass + + def get_iwo_mo(self, name): + filename = os.path.join( + self.logs_directory, + 'iwo.mo.%s' % (name) + ) + + content = self.get_file(filename) + if content is not None: + content = json.loads(content) + + return content + + def iwo_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'iwo.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def k8s_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'k8s.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def k8s(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.k8s_filename, + msg + ) + if not success: + print('K8s log failed...') + + except BaseException: + pass + + def osp_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'osp.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def osp(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.osp_filename, + msg + ) + if not success: + print('Osp log failed...') + + except BaseException: + pass + + def psirt_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'psirt.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def psirt(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.psirt_filename, + msg + ) + if not success: + print('Psirt log failed...') + + except BaseException: + pass + + def nso_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'nso.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def nso(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.nso_filename, + msg + ) + if not success: + print('NSO log failed...') + + except BaseException: + pass + + def ocp_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'ocp.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def ocp(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.ocp_filename, + msg + ) + if not success: + print('ocp log failed...') + + except BaseException: + pass + + def ocapi_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'ocapi.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def ocapi(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.ocapi_filename, + msg + ) + if not success: + print('ocapi log failed...') + + except BaseException: + pass + + def kubevirt_mo(self, name, managed_object): + try: + filename = os.path.join( + self.logs_directory, + 'kubevirt.mo.%s' % (name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + managed_object, + indent=4 + ) + ) + + except BaseException: + pass + + def kubevirt(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.kubevirt_filename, + msg + ) + if not success: + print('K8s log failed...') + + except BaseException: + pass + + def vcenter(self, command, scope, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command, + scope + ) + + success = self.safe_append( + self.vcenter_filename, + msg + ) + if not success: + print('vcenter log failed...') + + except BaseException: + pass + + def nexus_cli(self, nexus_ip, name, output): + try: + filename = os.path.join( + self.logs_directory, + 'nexus.%s.%s' % (nexus_ip, name) + ) + + if not os.path.isfile(filename): + self.safe_write( + filename, + json.dumps( + output, + indent=4 + ) + ) + + except BaseException: + pass + + def nexus(self, command, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command + ) + + success = self.safe_append( + self.nexus_filename, + msg + ) + if not success: + print('Nexus log failed...') + + except BaseException: + pass + + def redfish(self, command, success, duration): + try: + current_time = datetime.datetime.now() + + msg = "%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + command + ) + + success = self.safe_append( + self.redfish_filename, + msg + ) + if not success: + print('Redfish log failed...') + + except BaseException: + pass + + def get_api(self): + content = self.get_file(self.api_filename) + if content is None: + return {} + return json.loads(content) + + def api(self, command, content): + try: + apis = self.get_api() + apis[command] = content + + success = self.safe_write( + self.api_filename, + json.dumps(apis, indent=4) + ) + if not success: + print('Api log failed...') + + except BaseException: + pass + + def get_odata(self): + content = self.get_file(self.odata_filename) + if content is None: + return {} + return json.loads(content) + + def odata(self, path, content): + try: + odatas = self.get_odata() + odatas[path] = content + + success = self.safe_write( + self.odata_filename, + json.dumps(odatas, indent=4) + ) + if not success: + print('Odata log failed...') + + except BaseException: + pass + + def cli(self, command, success, duration, item_count=None): + try: + current_time = datetime.datetime.now() + + count = '-' + if item_count is not None: + count = int(item_count) + + msg = "%s\t%s\t%s\t%s\t%s\n" % ( + current_time, + success, + duration, + count, + command + ) + + success = self.safe_append( + self.isctl_filename, + msg + ) + if not success: + print('Isctl log failed...') + + except BaseException: + pass + + def adhoc(self, filename, info): + log_filename = os.path.join(self.logs_directory, filename) + try: + success = self.safe_append( + log_filename, + info + ) + except BaseException: + pass + return log_filename + + def error(self, location, message): + try: + current_time = datetime.datetime.now() + msg = "[%s]\t[%s]\t%s\n" % ( + current_time, location, message) + + success = self.safe_append( + self.error_filename, + msg + ) + if not success: + print('Error log failed (%s): %s' % (self.error_filename, msg)) + + self.info(location, message) + + except BaseException: + pass + + def info(self, location, message): + try: + current_time = datetime.datetime.now() + msg = "[%s]\t[%s]\t%s\n" % ( + current_time, location, message) + + success = self.safe_append( + self.info_filename, + msg + ) + if not success: + print('Info log failed...') + + self.debug(location, message) + + except BaseException: + pass + + def debug(self, location, message): + try: + current_time = datetime.datetime.now() + msg = "[%s]\t[%s]\t%s\n" % ( + current_time, location, message) + + success = self.safe_append( + self.debug_filename, + msg + ) + if not success: + print('Debug log failed...') + + except BaseException: + pass + + def get_lcm_report(self): + if os.path.isfile(self.lcm_report_filename): + try: + with open(self.lcm_report_filename, 'r', encoding='utf-8') as file_handler: + return json.loads(file_handler.read()) + + except BaseException: + pass + + return None + + def set_lcm_report(self, report): + try: + with open(self.lcm_report_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(report, indent=4)) + + except BaseException: + return False + + return True + + def set_command(self, command): + try: + with open(self.command_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(command) + except BaseException: + pass + + def get_command(self): + try: + if os.path.isfile(self.command_filename): + with open(self.command_filename, 'r', encoding='utf-8') as file_handler: + return file_handler.read() + + except BaseException: + pass + + return None + + def show_last_logs(self): + my_dirs = [] + logs_directory = os.path.dirname(self.logs_directory) + for name in os.listdir(logs_directory): + directory = os.path.join(logs_directory, name) + if os.path.isdir(directory): + directory_info = {} + directory_info['name'] = name + directory_info['directory'] = directory + directory_info['create_time'] = int(os.path.getmtime(directory)) + directory_info['time'] = datetime.datetime.fromtimestamp(directory_info['create_time']).strftime('%Y-%m-%d %H:%M:%S') + + command_filename = os.path.join(directory, 'command') + command = self.get_file(command_filename) + if command is not None: + directory_info['command'] = command + my_dirs.append(directory_info) + + my_dirs = sorted(my_dirs, key=lambda i: i['create_time'], reverse=True) + + my_output = output_helper.OutputHelper(log_id=self.log_id) + my_output.my_table( + my_dirs, + order=['name', 'command', 'directory', 'time'], + headers=['Name', 'Command', 'Directory', 'Time'] + ) + + def get_command_directory(self, search_command, debug=False): + my_dirs = [] + logs_directory = self.logs_directory + if self.log_id is not None: + logs_directory = os.path.dirname(self.logs_directory) + + for name in os.listdir(logs_directory): + directory = os.path.join(logs_directory, name) + if os.path.isdir(directory): + directory_info = {} + directory_info['name'] = name + directory_info['directory'] = directory + directory_info['create_time'] = int(os.path.getmtime(directory)) + directory_info['time'] = datetime.datetime.fromtimestamp(directory_info['create_time']).strftime('%Y-%m-%d %H:%M:%S') + + command_filename = os.path.join(directory, 'command') + command = self.get_file(command_filename) + if command is not None: + directory_info['command'] = command + my_dirs.append(directory_info) + + if debug: + print(json.dumps(directory_info, indent=4)) + + my_dirs = sorted(my_dirs, key=lambda i: i['create_time'], reverse=True) + + for my_dir in my_dirs: + if my_dir['command'] == search_command: + return my_dir['directory'] + + if '"' in search_command: + search_command = search_command.replace('"', '') + for my_dir in my_dirs: + if my_dir['command'] == search_command: + return my_dir['directory'] + + return None diff --git a/lib/my_server_helper.py b/lib/my_server_helper.py new file mode 100644 index 00000000..24f03693 --- /dev/null +++ b/lib/my_server_helper.py @@ -0,0 +1,137 @@ +import json +import os +import traceback + +from lib.settings_helper import Settings + +SSH_TIMEOUT = 3 + + +class MyServer(Settings): + def __init__(self): + Settings.__init__(self) + self.my_server_filename = os.path.join( + self.settings_dir, + 'my_server' + ) + + def clear_my_server(self): + return self.set_my_server([]) + + def is_my_server(self): + ''' + Returns True if $HOME/.itool/my_server file exists + Returns False otherwise + ''' + return os.path.isfile(self.my_server_filename) + + def initialize(self): + ''' + If $HOME/.iwectl/my_server does not exist, then save it with [] content + Return True/False + ''' + if not self.is_my_server(): + return self.set_my_server([]) + return True + + def get_my_server_names(self, iaccount): + ''' + [ + "milan-kali", + "milan-kali-bgp" + ] + ''' + try: + clusters = self.get_my_server() + if clusters is not None: + names = [] + for cluster in clusters: + if cluster['iaccount'] == iaccount: + names.append(cluster['cluster_name']) + return names + + except BaseException: + self.log.error('my_server_helper.get_my_server_names', traceback.format_exc()) + + return None + + def get_my_server(self): + ''' + [ + { + "iaccount": "isctl", + "cluster_name": "milan-kali" + }, + { + "iaccount": "isctl", + "cluster_name": "milan-kali-bgp" + } + ] + ''' + if self.is_my_server(): + try: + with open(self.my_server_filename, 'r', encoding='utf-8') as file_handler: + values = json.loads(file_handler.read()) + + if len(values) > 0: + values = sorted(values, key=lambda i: (i['iaccount'], i['cluster_name'])) + + return values + + except BaseException: + self.log.error('my_server_helper.get_my_server', traceback.format_exc()) + + return None + + def set_my_server(self, my_server): + ''' + Returns True/False + ''' + try: + with open(self.my_server_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(my_server, indent=4)) + except BaseException: + self.log.error('my_server_helper.set_my_server', traceback.format_exc()) + return False + return True + + def is_my_cluster(self, iaccount, cluster_name): + ''' + True/False + Checks (iaccount, cluster_name) entry in my_server json + ''' + my_server = self.get_my_server() + for my_cluster in my_server: + if my_cluster['iaccount'] == iaccount and my_cluster['cluster_name'] == cluster_name: + return True + return False + + def add(self, iaccount, cluster_name): + if self.is_my_cluster(iaccount, cluster_name): + return True, None + + my_server = self.get_my_server() + my_server.append( + dict( + iaccount=iaccount, + cluster_name=cluster_name + ) + ) + success = self.set_my_server(my_server) + response = None + if not success: + response = 'Failed to write my_server file' + return success, response + + def delete(self, iaccount, cluster_name): + my_server = self.get_my_server() + new_my_server = [] + for my_cluster in my_server: + if my_cluster['iaccount'] == iaccount and my_cluster['cluster_name'] == cluster_name: + continue + new_my_server.append(my_cluster) + success = self.set_my_server(new_my_server) + response = None + if not success: + response = 'Failed to write my_server file' + return success, response diff --git a/lib/my_servers_helper.py b/lib/my_servers_helper.py new file mode 100644 index 00000000..33615533 --- /dev/null +++ b/lib/my_servers_helper.py @@ -0,0 +1,325 @@ +import copy +import json +import os +import traceback + +from lib.settings_helper import Settings +from lib import output_helper + +SSH_TIMEOUT = 3 + + +class MyServers(Settings): + def __init__(self): + Settings.__init__(self) + self.my_servers_filename = os.path.join( + self.settings_dir, + 'my_servers' + ) + self.my_output = None + + def clear_my_servers(self): + return self.set_my_servers({}) + + def is_my_servers(self): + ''' + Returns True if $HOME/.itool/my_servers file exists + Returns False otherwise + ''' + return os.path.isfile(self.my_servers_filename) + + def initialize(self): + ''' + If $HOME/.itool/my_servers does not exist, then save it with [] content + Return True/False + ''' + if not self.is_my_servers(): + return self.set_my_servers({}) + return True + + def get_serials(self): + serials = {} + my_servers = self.get_my_servers() + if my_servers is None: + return serials + + for group_name in my_servers: + for server in my_servers[group_name]: + if server['Serial'] not in serials: + serials[server['Serial']] = [] + serials[server['Serial']].append(group_name) + + return serials + + def get_my_servers(self): + if self.is_my_servers(): + try: + with open(self.my_servers_filename, 'r', encoding='utf-8') as file_handler: + values = json.loads(file_handler.read()) + + except BaseException: + self.log.error('my_servers_helper.get_my_servers', traceback.format_exc()) + return None + + return values + + def set_my_servers(self, my_servers): + ''' + Returns True/False + ''' + try: + with open(self.my_servers_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(my_servers, indent=4)) + except BaseException: + self.log.error('my_servers_helper.set_my_servers', traceback.format_exc()) + return False + return True + + def is_group(self, group_name): + ''' + True/False + Checks group_name dict entry in my_servers + ''' + my_servers = self.get_my_servers() + if group_name in my_servers: + return True + return False + + def get_group(self, group_name): + """Get group members + + Args: + group_name (string): group name + + Returns: + list: list of servers or None if group not found + """ + my_servers = self.get_my_servers() + if group_name in my_servers: + return my_servers[group_name] + return None + + def get_group_serials(self, group_name): + """Get group members' serial list + + Args: + group_name (string): group name + + Returns: + list: list of serials + """ + servers = self.get_group(group_name) + if servers is None: + return None + + serials = [] + for server in servers: + serials.append(server['Serial']) + + return serials + + def add_group(self, group_name): + """Add empty group + + Args: + group_name (string): group name + + Return True if group already exists + + Returns: + bool: success or failure + """ + if self.is_group(group_name): + return True + + my_servers = self.get_my_servers() + if my_servers is None: + return False + + my_servers[group_name] = [] + return self.set_my_servers(my_servers) + + def del_group(self, group_name): + """Delete group with all servers + + Args: + group_name (string): group name + + Return True if group does not exist + + Returns: + bool: success or failure + """ + if not self.is_group(group_name): + return True + + my_servers = self.get_my_servers() + if my_servers is None: + return False + + del my_servers[group_name] + return self.set_my_servers(my_servers) + + def is_group_server(self, group_name, server_serial): + """Check if server serial is member of group + + Args: + group_name (string): group name + server_serial (string): serial number + """ + my_servers = self.get_my_servers() + if my_servers is None: + return False + + if group_name not in my_servers: + return False + + for server in my_servers[group_name]: + if server['Serial'] == server_serial: + return True + + return False + + def get_server_definition(self, server): + """Get subset of the server properties to be stored in my_servers structure + + Args: + server (dict): Full server description + """ + + attributes = {} + for key in ['Name', 'Serial', 'Model', 'ManagementIp']: + if key in server: + attributes[key] = server[key] + else: + attributes[key] = None + + return attributes + + def add_group_servers(self, group_name, servers): + """Add server to group + + Args: + group_name (string): group name + servers (list): list of server definitions + + If group does not exist, create it + + Returns: + bool: success or failure + """ + my_servers = self.get_my_servers() + if my_servers is None: + return False + + if group_name not in my_servers: + my_servers[group_name] = [] + + for server in servers: + if not self.is_group_server(group_name, server['Serial']): + my_servers[group_name].append( + self.get_server_definition(server) + ) + + return self.set_my_servers(my_servers) + + def add_group_server(self, group_name, server): + return self.add_group_servers(group_name, [server]) + + def set_group_servers(self, group_name, servers): + """Set group with servers + + Args: + group_name (string): group name + servers (list): list of server definitions + + If group does not exist, create it + + Returns: + bool: success or failure + """ + my_servers = self.get_my_servers() + if my_servers is None: + return False + + my_servers[group_name] = [] + + for server in servers: + my_servers[group_name].append( + self.get_server_definition(server) + ) + + return self.set_my_servers(my_servers) + + def set_group_server(self, group_name, server): + return self.set_group_servers(group_name, [server]) + + def del_group_servers(self, group_name, servers): + """Delete servers from group + + Args: + group_name (string): group name + servers (list): list of server definitions + + If group does not exist, return True + + Returns: + bool: success or failure + """ + my_servers = self.get_my_servers() + if my_servers is None: + return False + + if group_name not in my_servers: + return True + + current_members = copy.deepcopy(my_servers[group_name]) + my_servers[group_name] = [] + + for server in servers: + for current_member in current_members: + add_server = True + for server in servers: + if server['Serial'] == current_member['Serial']: + add_server = False + break + + if add_server: + my_servers[group_name].append(current_member) + + return self.set_my_servers(my_servers) + + def del_group_server(self, group_name, server): + return self.del_group_servers(group_name, [server]) + + def print_group(self, group_name): + if self.my_output is None: + self.my_output = output_helper.OutputHelper() + + servers = self.get_group(group_name) + if servers is None: + self.my_output.error('Group not found: %s' % (group_name)) + return + + sorted_servers = sorted(servers, key=lambda i: i['Name']) + + order = [ + 'Name', + 'Serial', + 'Model', + 'ManagementIP' + ] + + headers = [ + 'Name', + 'Serial', + 'Model', + 'IP' + ] + + self.my_output.my_table( + sorted_servers, + order=order, + headers=headers, + table=True + ) diff --git a/lib/netconf/__init__.py b/lib/netconf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/netconf/notification.py b/lib/netconf/notification.py new file mode 100644 index 00000000..10afc1d1 --- /dev/null +++ b/lib/netconf/notification.py @@ -0,0 +1,104 @@ +import time +import traceback + +from lib.netconf import ssh +from lib import log_helper + + +class NetconfNotification(): + def __init__(self, netconf_ip, netconf_port, netconf_username, netconf_password, log_id=None): + self.log = log_helper.Log(log_id=log_id) + + self.netconf_ip = netconf_ip + self.netconf_port = netconf_port + self.netconf_username = netconf_username + self.netconf_password = netconf_password + + self.netconf_handler = ssh.NetconfSsh( + self.netconf_ip, + self.netconf_port, + self.netconf_username, + self.netconf_password + ) + + def is_working(self): + if self.netconf_handler.connect(): + self.netconf_handler.disconnect() + return True + return False + + def is_stream(self, stream): + msg = ''' + + + %s + + ''' % stream + + try: + if self.netconf_handler.connect(): + success, xmlint = self.netconf_handler.hello() + if not success: + self.netconf_handler.disconnect() + return False + + self.netconf_handler.send_msg(msg) + ret = self.netconf_handler.recv_msg(timeout=3) + self.netconf_handler.disconnect() + + if ret is None: + self.log.error('is_stream', 'No message received') + return False + + self.log.debug('is_stream', ret) + if 'no such stream' in ret: + return False + + except BaseException: + self.log.error('is_stream', traceback.format_exc()) + return False + + return True + + def get_notifications(self, stream, timeout=60): + msg = ''' + + + %s + + ''' % stream + + try: + if self.netconf_handler.connect(): + success, xmlint = self.netconf_handler.hello() + if not success: + self.netconf_handler.disconnect() + return False + + start_time = int(time.time()) + while True: + if msg is not None: + self.netconf_handler.send_msg(msg) + msg = None + + while True: + try: + (code, chunk) = self.netconf_handler.recv_chunk(timeout=5) + print(code) + print(chunk) + except BaseException: + print('timeout') + + if int(time.time()) - start_time > timeout: + break + + if int(time.time()) - start_time > timeout: + break + + except BaseException: + self.log.error('get_notifications', traceback.format_exc()) + return + + self.netconf_handler.disconnect() diff --git a/lib/netconf/ssh.py b/lib/netconf/ssh.py new file mode 100644 index 00000000..15d83771 --- /dev/null +++ b/lib/netconf/ssh.py @@ -0,0 +1,201 @@ +import sys +import base64 +import socket +import xml.dom.minidom +import paramiko +import traceback + +from lib.netconf.transport import NetconfSSHLikeTransport + + +class NetconfSsh(NetconfSSHLikeTransport): + def __init__( + self, + hostname, + port, + username, + password, + private_key=None, + public_key_type=None, + private_key_file='', + private_key_type='' + ): + NetconfSSHLikeTransport.__init__(self) + self.hostname = str(hostname) + self.port = int(port) + + self.private_key_file = private_key_file + self.private_key_type = private_key_type + self.public_key = private_key + self.public_key_type = public_key_type + self.password = password + self.username = username + self.saved = "" + self.ssh = None + self.chan = None + + def _send(self, buf): + try: + # self.chan.sendall(buf) + # return + if self.saved: + buf = self.saved + buf + # sending too little data in each SSH packet makes the + # transfer slow. + # paramiko still has bug (?) where it doesn't send a full + # SSH message, but keeps 64 bytes. so we will send MAX-64, 64, + # MAX-64, 64, ... instead of MAX all the time. + if len(buf) < 16384: + self.saved = buf + else: + self.chan.sendall(buf[:16384]) + self.saved = buf[16384:] + except socket.error as x: + print('socket error:', str(x)) + + def _send_eom(self): + try: + self.chan.sendall(self.saved + self._get_eom()) + self.saved = "" + except socket.error as x: + self.saved = "" + print('socket error:', str(x)) + + def _flush(self): + try: + self.chan.sendall(self.saved) + self.saved = "" + except socket.error as x: + self.saved = "" + print('socket error:', str(x)) + + def _recv(self, bufsiz): + s = self.chan.recv(bufsiz) + if self.trace: + sys.stdout.write(s) + sys.stdout.flush() + return s + + def _set_timeout(self, timeout=None): + self.chan.settimeout(timeout) + + def create_connection(self, host, port): + sock_err = None + sock = None + for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + try: + sock = socket.socket(af, socktype, proto) + except socket.error as err: + sock_err = err + sock = None + continue + try: + sock.connect(sa) + except socket.error as err: + sock_err = err + sock.close() + sock = None + continue + break + + if sock is None: + print("Failed to connect to %s: %s" % (host, str(sock_err))) + return None + + return sock + + def connect(self): + sock = self.create_connection(self.hostname, self.port) + if sock is None: + return False + + self.ssh = paramiko.Transport(sock) + + if self.public_key_type is None: + agent_public_key = None + else: + if self.public_key_type == 'rsa': + # TODO: The decodestring method is deprecated in python3 + agent_public_key = paramiko.RSAKey( + data=base64.decodestring(self.private_key)) + elif self.public_key_type == 'dss': + # TODO: The decodestring method is deprecated in python3 + agent_public_key = paramiko.DSSKey( + data=base64.decodestring(self.private_key)) + + if not self.private_key_file == '': + if self.private_key_type == "rsa": + user_private_key = paramiko.RSAKey.from_private_key_file( + self.private_key_file) + else: + user_private_key = paramiko.DSSKey.from_private_key_file( + self.private_key_file) + + try: + self.ssh.connect(hostkey=agent_public_key, + username=self.username, + pkey=user_private_key) + except paramiko.AuthenticationException: + print("Authentication failed.") + return False + + else: + try: + self.ssh.connect(hostkey=agent_public_key, + username=self.username, + password=self.password) + except paramiko.AuthenticationException: + print("Authentication failed.") + return False + + self.chan = self.ssh.open_session() + self.chan.invoke_subsystem("netconf") + + return True + + def hello(self): + try: + # figure out which versions to advertise + versions = [] + versions.append('1.0') + + # hello exchange + self.send_msg(self.hello_msg(versions)) + hello_reply = self.recv_msg() + + # parse the hello message to figure out which framing + # protocol to use + item = xml.dom.minidom.parseString(hello_reply) + if item is not None: + item = item.firstChild + + if item is not None: + self.strip(item) + if (item.namespaceURI == 'urn:ietf:params:xml:ns:netconf:base:1.0' and item.localName == 'hello' and item.firstChild is not None): + item = item.firstChild + self.strip(item) + if (item.namespaceURI == 'urn:ietf:params:xml:ns:netconf:base:1.0' and item.localName == 'capabilities'): + item = item.firstChild + self.strip(item) + while (item is not None): + if (item.namespaceURI == 'urn:ietf:params:xml:ns:netconf:base:1.0' and item.localName == 'capability'): + if ('1.1' in versions and item.firstChild.nodeValue.strip() == 'urn:ietf:params:netconf:base:1.1'): + item.framing = 1 + item = item.nextSibling + + xmllint = "xmllint --format - " + success = True + + except BaseException: + print(traceback.format_exc()) + success = False + xmllint = None + + return success, xmllint + + def disconnect(self): + self.ssh.close() + self.ssh = None + self.chan = None + return True diff --git a/lib/netconf/transport.py b/lib/netconf/transport.py new file mode 100644 index 00000000..38c5ee0d --- /dev/null +++ b/lib/netconf/transport.py @@ -0,0 +1,183 @@ +from xml.dom import Node + +# pylint: disable=assignment-from-no-return + +class NetconfSSHLikeTransport(): + def __init__(self): + self.buf = "" + self.framing = 0 + self.eom_found = False + self.trace = False + + def connect(self): + # should be overridden by subclass + pass + + def _send(self, buf): + # should be overridden by subclass + pass + + def _send_eom(self): + # should be overridden by subclass + pass + + def _flush(self): + # should be overridden by subclass, if needed + pass + + def _set_timeout(self, timeout=None): + # should be overridden by subclass + pass + + def _recv(self, bufsiz): + # should be overridden by subclass + pass + + def send(self, request): + if self.framing == 1: + self._send('\n#%d\n' % len(request) + request) + else: + self._send(request) + + def send_msg(self, request): + self.send(request) + self._send_eom() + + def send_eom(self): + self._send_eom() + + def _get_eom(self): + if self.framing == 0: + return ']]>]]>' + elif self.framing == 1: + return '\n##\n' + else: + return '' + + def hello_msg(self, versions): + body = '''''' + + if '1.0' in versions: + body += 'urn:ietf:params:netconf:base:1.0' + if '1.1' in versions: + body += 'urn:ietf:params:netconf:base:1.1\n' + body += '''''' + return body + + def strip(self, node): + """Remove empty text nodes, and non-element nodes. + The result after strip () is a child list with non-empty text-nodes, + and element nodes only.""" + child = node.firstChild + while child is not None: + remove = False + if child.nodeType == Node.TEXT_NODE: + if child.nodeValue.strip() == "": + remove = True + else: + if child.nodeType != Node.ELEMENT_NODE: + remove = True + if remove: + tmp = child.nextSibling + node.removeChild(child) + child.unlink() + child = tmp + else: + child = child.nextSibling + + # ret: (-2, bytes) on framing error + # (-1, bytes) on socket EOF + # (0, "") on EOM + # (1, chunk-data) on data + def recv_chunk(self, timeout=None): + self._set_timeout(timeout) + if self.framing == 0: + if self.eom_found: + self.eom_found = False + return (0, "") + bytes_value = self.buf + self.buf = "" + while len(bytes_value) < 6: + x = self._recv(16384) + if x == "": + return (-1, bytes_value) + bytes_value += x.decode() + idx = bytes_value.find("]]>]]>") + if idx > -1: + # eom marker found; store rest in buf + self.eom_found = True + self.buf = bytes_value[idx + 6:] + return (1, bytes_value[:idx]) + else: + # no eom marker found, keep the last 5 bytes_value + # (might contain parts of the eom marker) + self.buf = bytes_value[-5:] + return (1, bytes_value[:-5]) + else: + # new framing + bytes_value = self.buf + self.buf = "" + # make sure we have at least 4 bytes_value; LF HASH INT/HASH LF + while len(bytes_value) < 4: + x = self._recv(16384) + if x == "": + # error, return what we have + return (-1, bytes_value) + bytes_value += x + # check the first two bytes_value + if bytes_value[0:2] != "\n#": + # framing error + return (-2, bytes_value) + # read the chunk size + sz = -1 + while sz == -1: + # find the terminating LF + idx = bytes_value.find("\n", 2) + if idx > 12: + # framing error - too large integer or not correct + # chunk size specification + return (-2, bytes_value) + if idx > -1: + # newline found, scan for number of bytes_value to read + try: + sz = int(bytes_value[2:idx]) + if sz < 1 or sz > 4294967295: + # framing error - range error + return (-2, bytes_value) + except BaseException: + if bytes_value[2:idx] == "#": + # EOM + self.buf = bytes_value[idx + 1:] + return (0, "") + # framing error - not an integer, and not EOM + return (-2, bytes_value) + # skip the chunk size. the while loop is now done + bytes_value = bytes_value[idx + 1:] + else: + # terminating LF not found, read more + x = self._recv(16384) + if x == "": + # error, return what we have + return (-1, bytes_value) + bytes_value += x + # read the chunk data + while len(bytes_value) < sz: + x = self._recv(16384) + if x == "": + return (-1, bytes_value) + bytes_value += x + # save rest of data + self.buf = bytes_value[sz:] + return (1, bytes_value[:sz]) + + def recv_msg(self, timeout=None): + msg = "" + while True: + (code, bytes_value) = self.recv_chunk(timeout) + if code == 1: + msg += bytes_value + elif code == 0: + return msg + else: + # error + return msg + bytes_value diff --git a/lib/nexus/__init__.py b/lib/nexus/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/__pycache__/__init__.cpython-310.pyc b/lib/nexus/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b9c8cf89 Binary files /dev/null and b/lib/nexus/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/nexus/__pycache__/cache.cpython-310.pyc b/lib/nexus/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..e8225a36 Binary files /dev/null and b/lib/nexus/__pycache__/cache.cpython-310.pyc differ diff --git a/lib/nexus/__pycache__/lldp.cpython-310.pyc b/lib/nexus/__pycache__/lldp.cpython-310.pyc new file mode 100644 index 00000000..c5f627ef Binary files /dev/null and b/lib/nexus/__pycache__/lldp.cpython-310.pyc differ diff --git a/lib/nexus/__pycache__/nxapi.cpython-310.pyc b/lib/nexus/__pycache__/nxapi.cpython-310.pyc new file mode 100644 index 00000000..6d265332 Binary files /dev/null and b/lib/nexus/__pycache__/nxapi.cpython-310.pyc differ diff --git a/lib/nexus/__pycache__/settings.cpython-310.pyc b/lib/nexus/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..7a1bce6e Binary files /dev/null and b/lib/nexus/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/nexus/bot_output.py b/lib/nexus/bot_output.py new file mode 100644 index 00000000..6f99a4db --- /dev/null +++ b/lib/nexus/bot_output.py @@ -0,0 +1,145 @@ +from lib import output_helper + +from lib.nexus.lacp.bot_output import LacpBotOutput +from lib.nexus.lldp.bot_output import LldpBotOutput +from lib.nexus.mac.bot_output import MacBotOutput +from lib.nexus.version.bot_output import VersionBotOutput + + +class NexusBotOutput( + LacpBotOutput, + LldpBotOutput, + MacBotOutput, + VersionBotOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + LacpBotOutput.__init__(self) + LldpBotOutput.__init__(self) + MacBotOutput.__init__(self) + VersionBotOutput.__init__(self) + + def print_devices(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Nexus Device [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'name', + 'ip', + 'username', + 'domain', + 'cache_enabled', + 'cache_ttl', + 'cache_valid' + ] + + headers = [ + 'Name', + 'IP', + 'Username', + 'Domain', + 'Cache', + 'TTL', + 'Valid' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Nexus Device' + ) + + html_output = self.my_output.get_output() + + return output, html_output + + def print_devices_cache(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Nexus Cache [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'name', + 'cache_enabled', + 'cache_ttl', + 'cache_valid', + 'cache_command.command', + 'cache_command.time', + 'cache_command.valid' + ] + + headers = [ + 'Name', + 'Cache', + 'TTL', + 'Valid', + 'Command', + 'Time', + 'Valid' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cache_command'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='Nexus Cache' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/nexus/cache.py b/lib/nexus/cache.py new file mode 100644 index 00000000..9ad4d628 --- /dev/null +++ b/lib/nexus/cache.py @@ -0,0 +1,152 @@ +import time +import os +import json +from datetime import datetime + +from lib.nexus import settings + + +class Cache(): + def __init__(self, cache_enabled): + settings_handler = settings.NexusSettings() + self.cache_directory = os.path.join( + settings_handler.get_nexus_cache_base_directory(), + self.nexus_ip + ) + + self.cache_enabled = cache_enabled + if not self.cache_enabled: + self.cache_settings = {} + self.cache_settings['Enabled'] = False + self.cache_settings['Ttl'] = 180 + self.cache_settings['Command'] = {} + + if self.cache_enabled: + self.cache_settings = settings_handler.get_nexus_cache_settings() + + self.cache_commands = [ + 'show lacp neighbor', + 'show lldp neighbors', + 'show mac address-table', + 'show version' + ] + + def is_cache_enabled(self): + if not self.cache_enabled: + return False + + if self.cache_settings is None: + return False + + return self.cache_settings['Enabled'] + + def get_command_cache_settings(self, command): + command_cache_settings = {} + command_cache_settings['enabled'] = self.cache_settings['Enabled'] + command_cache_settings['ttl'] = self.cache_settings['Ttl'] + if not command_cache_settings['enabled']: + return command_cache_settings + + if command in self.cache_settings['Command']: + command_cache_settings['enabled'] = self.cache_settings['Command'][command]['enabled'] + command_cache_settings['ttl'] = self.cache_settings['Command'][command]['ttl'] + + return command_cache_settings + + def get_command_cache_filename(self, command): + filename = os.path.join( + self.cache_directory, + command.replace(' ', '_').replace('-', '_') + ) + return filename + + def get_command_cache_timestamp(self, command): + filename = self.get_command_cache_filename(command) + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + return None + + return content['timestamp'] + + def get_cache_commands_timestamp(self): + now = int(time.time()) + all_valid = True + entries = [] + for command in self.cache_commands: + command_cache_settings = self.get_command_cache_settings(command) + ttl = command_cache_settings['ttl'] + + entry = {} + entry['command'] = command + entry['timestamp'] = self.get_command_cache_timestamp(command) + + if entry['timestamp'] is None: + entry['time'] = None + entry['valid'] = False + all_valid = False + + if entry['timestamp'] is not None: + entry['time'] = datetime.fromtimestamp(entry['timestamp']) + if now - entry['timestamp'] > ttl: + entry['valid'] = False + all_valid = False + else: + entry['valid'] = True + + entries.append(entry) + + response = {} + response['valid'] = all_valid + response['command'] = entries + + return response + + def get_command_cache(self, command): + command_cache_settings = self.get_command_cache_settings(command) + if not command_cache_settings['enabled']: + return None + + filename = self.get_command_cache_filename(command) + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + return None + + if content['timestamp'] - int(time.time()) > command_cache_settings['ttl']: + return None + + return content['cache'] + + def set_command_cache(self, command, cache): + filename = self.get_command_cache_filename(command) + if filename is None: + return False + + if not os.path.isdir(self.cache_directory): + os.makedirs(self.cache_directory, exist_ok=True) + + content = {} + content['command'] = command + content['timestamp'] = int(time.time()) + content['cache'] = cache + + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(content, indent=4)) + + except BaseException: + self.log.error( + 'nexus.set_command_cache', + 'Set cache failed: %s %s' % ( + self.nexus_ip, + command + ) + ) + return False + + return True diff --git a/lib/nexus/config/__init__.py b/lib/nexus/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/config/api.py b/lib/nexus/config/api.py new file mode 100644 index 00000000..e7dc2abc --- /dev/null +++ b/lib/nexus/config/api.py @@ -0,0 +1,37 @@ +class ConfigApi(): + def __init__(self): + self.config_mo = None + + def get_config_mo(self, cache_enabled=True): + command = 'show running-config' + + if cache_enabled: + if self.config_mo is not None: + return self.config_mo + + cached_mo = self.get_command_cache(command) + if cached_mo is not None: + return cached_mo + + if not self.connect(): + self.log.error( + 'get_config_mo', + 'API connection failed: %s' % (self.nexus_name) + ) + return None + + response = self.run_show_command(command) + if response is None: + self.log.error( + 'get_config_mo', + 'Command failed on %s: %s' % ( + self.nexus_name, + command + ) + ) + return None + + self.set_command_cache(command, response) + self.config_mo = [response] + + return self.config_mo diff --git a/lib/nexus/config/bot_output.py b/lib/nexus/config/bot_output.py new file mode 100644 index 00000000..036ac118 --- /dev/null +++ b/lib/nexus/config/bot_output.py @@ -0,0 +1,25 @@ +class ConfigBotOutput(): + def __init__(self): + pass + + def print_configs(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'Configuration [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + output = self.my_output.get_output() + + self.my_output.clear_output() + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/nexus/config/info.py b/lib/nexus/config/info.py new file mode 100644 index 00000000..7e85d68f --- /dev/null +++ b/lib/nexus/config/info.py @@ -0,0 +1,58 @@ +from lib import filter_helper +from lib import ip_helper + + +class ConfigInfo(): + def __init__(self): + self.config = None + + def get_config_info(self, config_mo): + if config_mo is None: + return None + + info = {} + info['__Output'] = {} + info['nexus_name'] = self.nexus_name + + return info + + def get_configs_info(self, cache_enabled=True): + if cache_enabled: + if self.config is not None: + return self.config + + managed_objects = self.get_config_mo(cache_enabled=cache_enabled) + if managed_objects is None: + self.log.error( + 'get_configs_info', + 'No config managed objects: %s' % (self.nexus_name) + ) + return None + + self.config = [] + for managed_object in managed_objects: + self.config.append( + self.get_config_info( + managed_object + ) + ) + + return self.config + + def get_configs(self, cache_enabled=True): + all_configs = self.get_configs_info(cache_enabled=cache_enabled) + if all_configs is None: + self.log.error( + 'get_configs', + 'Failed to get config: %s' % (self.nexus_name) + ) + return None + + configs = [] + + for config_info in all_configs: + configs.append( + config_info + ) + + return configs diff --git a/lib/nexus/config/main.py b/lib/nexus/config/main.py new file mode 100644 index 00000000..07d46119 --- /dev/null +++ b/lib/nexus/config/main.py @@ -0,0 +1,11 @@ +from lib.nexus.config.api import ConfigApi +from lib.nexus.config.info import ConfigInfo + + +class Config( + ConfigApi, + ConfigInfo + ): + def __init__(self): + ConfigApi.__init__(self) + ConfigInfo.__init__(self) diff --git a/lib/nexus/config/output.py b/lib/nexus/config/output.py new file mode 100644 index 00000000..0db72d3e --- /dev/null +++ b/lib/nexus/config/output.py @@ -0,0 +1,15 @@ +class ConfigOutput(): + def __init__(self): + pass + + def print_versions(self, info, title=False): + if title: + self.my_output.default( + 'Configuration [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return diff --git a/lib/nexus/lacp/__init__.py b/lib/nexus/lacp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/lacp/api.py b/lib/nexus/lacp/api.py new file mode 100644 index 00000000..34ab2a77 --- /dev/null +++ b/lib/nexus/lacp/api.py @@ -0,0 +1,67 @@ +class LacpApi(): + def __init__(self): + self.lacp_mo = None + + def get_lacp_mo(self, local_cache_enabled=True, cache_enabled=True): + command = 'show lacp neighbor' + + if local_cache_enabled: + if self.lacp_mo is not None: + return self.lacp_mo + + if cache_enabled: + cached_mo = self.get_command_cache(command) + if cached_mo is not None: + return cached_mo + + if not self.connect(): + self.log.error( + 'get_lacp_mo', + 'API connection failed: %s' % (self.nexus_name) + ) + return None + + response = self.run_show_command(command) + if response is None: + self.log.error( + 'get_lacp_mo', + 'Command failed on %s: %s' % ( + self.nexus_name, + command + ) + ) + return None + + if 'TABLE_interface' not in response: + self.log.error( + 'get_lacp_mo', + 'Unexpected rest response %s: %s' % ( + self.nexus_name, + response + ) + ) + return None + + if 'ROW_interface' not in response['TABLE_interface']: + self.log.error( + 'get_lacp_mo', + 'Unexpected rest response %s: %s' % ( + self.nexus_name, + response + ) + ) + return None + + if isinstance(response['TABLE_interface']['ROW_interface'], dict): + new_response = {} + new_response['TABLE_interface'] = {} + new_response['TABLE_interface']['ROW_interface'] = [] + new_response['TABLE_interface']['ROW_interface'].append( + response['TABLE_interface']['ROW_interface'] + ) + response = new_response + + self.set_command_cache(command, response) + self.lacp_mo = response + + return self.lacp_mo diff --git a/lib/nexus/lacp/bot_output.py b/lib/nexus/lacp/bot_output.py new file mode 100644 index 00000000..b4e72026 --- /dev/null +++ b/lib/nexus/lacp/bot_output.py @@ -0,0 +1,64 @@ +class LacpBotOutput(): + def __init__(self): + pass + + def print_lacps(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'LACP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'nexus_name', + 'interface', + 'port.port', + 'port.partner_mac', + 'port.partner_port_num', + 'port.partner_port_state' + ] + + headers = [ + 'Device', + 'Interface', + 'Port', + 'Partner MAC', + 'Partner Port', + 'Partner State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['port'] + ), + order=order, + headers=headers, + underline=True, + table=True, + allow_order_subkeys=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='LACP' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/nexus/lacp/info.py b/lib/nexus/lacp/info.py new file mode 100644 index 00000000..03097b5e --- /dev/null +++ b/lib/nexus/lacp/info.py @@ -0,0 +1,149 @@ +from lib import filter_helper +from lib import ip_helper + + +class LacpInfo(): + def __init__(self): + self.lacp = None + + def get_lacp_info(self, lacp_mo): + if lacp_mo is None: + return None + + info = {} + info['__Output'] = {} + info['nexus_name'] = self.nexus_name + info['interface'] = lacp_mo['interface'] + info['port'] = [] + + if isinstance(lacp_mo['TABLE_member']['ROW_member'], dict): + port_info = {} + for key in lacp_mo['TABLE_member']['ROW_member']: + port_info[key.replace('-', '_')] = lacp_mo['TABLE_member']['ROW_member'][key] + info['port'].append( + port_info + ) + + if isinstance(lacp_mo['TABLE_member']['ROW_member'], list): + for port_mo in lacp_mo['TABLE_member']['ROW_member']: + port_info = {} + for key in port_mo: + port_info[key.replace('-', '_')] = port_mo[key] + info['port'].append( + port_info + ) + + for port_info in info['port']: + port_info['partner_mac'] = None + if len(port_info['partner_system_id'].split(',')) == 2: + if len(port_info['partner_system_id'].split(',')[1].split('-')) == 6: + mac_address = [] + for item in port_info['partner_system_id'].split(',')[1].split('-'): + if len(item) == 2: + mac_address.append( + item + ) + else: + mac_address.append( + '0%s' % (item) + ) + + port_info['partner_mac'] = ':'.join(mac_address) + + return info + + def get_lacps_info(self, local_cache_enabled=True, cache_enabled=True): + if local_cache_enabled: + if self.lacp is not None: + return self.lacp + + managed_objects = self.get_lacp_mo( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if managed_objects is None: + self.log.error( + 'get_lacps_info', + 'No lacp neighbor managed objects: %s' % (self.nexus_name) + ) + return None + + self.lacp = [] + for managed_object in managed_objects['TABLE_interface']['ROW_interface']: + lacp_info = self.get_lacp_info( + managed_object + ) + self.lacp.append( + lacp_info + ) + + return self.lacp + + def match_lacp(self, lacp_info, lacp_filter): + if lacp_filter is None or len(lacp_filter) == 0: + return True + + for ap_rule in lacp_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'mac': + key_found = True + found = False + for mac_address in value.split(','): + for port_info in lacp_info['port']: + if port_info['partner_mac'] is not None: + if ip_helper.is_mac_match(mac_address, port_info['partner_mac']): + found = True + + if not found: + return False + + if not key_found: + self.log.error( + 'match_lacp', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_lacps(self, object_filter=None, local_cache_enabled=True, cache_enabled=True): + all_lacps = self.get_lacps_info( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if all_lacps is None: + self.log.error( + 'get_lacps', + 'Failed to get lacp neighbors: %s' % (self.nexus_name) + ) + return None + + lacps = [] + + for lacp_info in all_lacps: + if not self.match_lacp(lacp_info, object_filter): + continue + + lacps.append( + lacp_info + ) + + return lacps + + def get_macs_lacp(self, mac_address): + object_filter = [] + object_filter.append( + 'mac:%s' % (','.join(mac_address)) + ) + + lacps = [] + device_interfaces = self.get_lacps( + object_filter=object_filter + ) + if device_interfaces is not None: + lacps = lacps + device_interfaces + + return lacps diff --git a/lib/nexus/lacp/main.py b/lib/nexus/lacp/main.py new file mode 100644 index 00000000..0e1dcb5c --- /dev/null +++ b/lib/nexus/lacp/main.py @@ -0,0 +1,11 @@ +from lib.nexus.lacp.api import LacpApi +from lib.nexus.lacp.info import LacpInfo + + +class Lacp( + LacpApi, + LacpInfo + ): + def __init__(self): + LacpApi.__init__(self) + LacpInfo.__init__(self) diff --git a/lib/nexus/lacp/output.py b/lib/nexus/lacp/output.py new file mode 100644 index 00000000..802a768b --- /dev/null +++ b/lib/nexus/lacp/output.py @@ -0,0 +1,46 @@ +class LacpOutput(): + def __init__(self): + pass + + def print_lacps(self, info, title=False): + if title: + self.my_output.default( + 'LACP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nexus_name', + 'interface', + 'port.port', + 'port.partner_mac', + 'port.partner_port_num', + 'port.partner_port_state' + ] + + headers = [ + 'Device', + 'Interface', + 'Port', + 'Partner MAC', + 'Partner Port', + 'Partner State' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['port'] + ), + order=order, + headers=headers, + underline=True, + table=True, + allow_order_subkeys=True + ) diff --git a/lib/nexus/lldp/__init__.py b/lib/nexus/lldp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/lldp/api.py b/lib/nexus/lldp/api.py new file mode 100644 index 00000000..9f290788 --- /dev/null +++ b/lib/nexus/lldp/api.py @@ -0,0 +1,71 @@ +class LldpApi(): + def __init__(self): + self.lldp_mo = None + + def get_lldp_mo(self, local_cache_enabled=True, cache_enabled=True): + command = 'show lldp neighbors' + + if local_cache_enabled: + if self.lldp_mo is not None: + return self.lldp_mo + + if cache_enabled: + cached_mo = self.get_command_cache(command) + if cached_mo is not None: + self.log.debug( + 'get_lldp_mo', + 'Cache hit: %s' % (command) + ) + return cached_mo + + if not self.connect(): + self.log.error( + 'get_lldp_mo', + 'API connection failed: %s' % (self.nexus_name) + ) + return None + + response = self.run_show_command(command) + if response is None: + self.log.error( + 'get_lldp_mo', + 'Command failed on %s: %s' % ( + self.nexus_name, + command + ) + ) + return None + + if 'TABLE_nbor' not in response: + self.log.error( + 'get_lldp_mo', + 'Unexpected rest response %s: %s' % ( + self.nexus_name, + response + ) + ) + return None + + if 'ROW_nbor' not in response['TABLE_nbor']: + self.log.error( + 'get_lldp_mo', + 'Unexpected rest response %s: %s' % ( + self.nexus_name, + response + ) + ) + return None + + if isinstance(response['TABLE_nbor']['ROW_nbor'], dict): + new_response = {} + new_response['TABLE_nbor'] = {} + new_response['TABLE_nbor']['ROW_nbor'] = [] + new_response['TABLE_nbor']['ROW_nbor'].append( + response['TABLE_nbor']['ROW_nbor'] + ) + response = new_response + + self.set_command_cache(command, response) + self.lldp_mo = response + + return self.lldp_mo diff --git a/lib/nexus/lldp/bot_output.py b/lib/nexus/lldp/bot_output.py new file mode 100644 index 00000000..beadb194 --- /dev/null +++ b/lib/nexus/lldp/bot_output.py @@ -0,0 +1,63 @@ +class LldpBotOutput(): + def __init__(self): + pass + + def print_lldps(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'LLDP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + for item in info: + if item['system_capability'] is None: + item['system_capability'] = '--' + + order = [ + 'nexus_name', + 'l_port_id', + 'chassis_id', + 'port_id', + 'hold_time', + 'system_capability' + ] + + headers = [ + 'Device', + 'Local Interface', + 'Device ID', + 'Port ID', + 'Hold Time', + 'Capability' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='LLDP' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/nexus/lldp/info.py b/lib/nexus/lldp/info.py new file mode 100644 index 00000000..a08baf88 --- /dev/null +++ b/lib/nexus/lldp/info.py @@ -0,0 +1,112 @@ +from lib import filter_helper +from lib import ip_helper + + +class LldpInfo(): + def __init__(self): + self.lldp = None + + def get_lldp_info(self, lldp_mo): + if lldp_mo is None: + return None + + info = {} + info['__Output'] = {} + info['nexus_name'] = self.nexus_name + + for key in lldp_mo: + info[key] = lldp_mo[key] + + if isinstance(info['system_capability'], dict): + info['system_capability'] = None + + return info + + def get_lldps_info(self, local_cache_enabled=True, cache_enabled=True): + if local_cache_enabled: + if self.lldp is not None: + return self.lldp + + managed_objects = self.get_lldp_mo( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if managed_objects is None: + self.log.error( + 'get_lldps_info', + 'No lldp neighbor managed objects: %s' % (self.nexus_name) + ) + return None + + self.lldp = [] + for managed_object in managed_objects['TABLE_nbor']['ROW_nbor']: + lldp_info = self.get_lldp_info( + managed_object + ) + self.lldp.append( + lldp_info + ) + + return self.lldp + + def match_lldp(self, lldp_info, lldp_filter): + if lldp_filter is None or len(lldp_filter) == 0: + return True + + for ap_rule in lldp_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, lldp_info['chassis_id']): + return False + + if key == 'mac': + key_found = True + + if lldp_info['port_type'] != 'Mac Address': + return False + + found = False + for mac_address in value.split(','): + if ip_helper.is_mac_match(mac_address, lldp_info['port_id']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_lldp', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_lldps(self, object_filter=None, local_cache_enabled=True, cache_enabled=True): + all_lldps = self.get_lldps_info( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if all_lldps is None: + self.log.error( + 'get_lldps', + 'Failed to get lldp neighbors: %s' % (self.nexus_name) + ) + return None + + lldps = [] + + for lldp_info in all_lldps: + if not self.match_lldp(lldp_info, object_filter): + continue + + lldps.append( + lldp_info + ) + + return lldps diff --git a/lib/nexus/lldp/main.py b/lib/nexus/lldp/main.py new file mode 100644 index 00000000..1c3ec409 --- /dev/null +++ b/lib/nexus/lldp/main.py @@ -0,0 +1,11 @@ +from lib.nexus.lldp.api import LldpApi +from lib.nexus.lldp.info import LldpInfo + + +class Lldp( + LldpApi, + LldpInfo + ): + def __init__(self): + LldpApi.__init__(self) + LldpInfo.__init__(self) diff --git a/lib/nexus/lldp/output.py b/lib/nexus/lldp/output.py new file mode 100644 index 00000000..6fe4da6f --- /dev/null +++ b/lib/nexus/lldp/output.py @@ -0,0 +1,45 @@ +class LldpOutput(): + def __init__(self): + pass + + def print_lldps(self, info, title=False): + if title: + self.my_output.default( + 'LLDP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['system_capability'] is None: + item['system_capability'] = '--' + + order = [ + 'nexus_name', + 'l_port_id', + 'chassis_id', + 'port_id', + 'hold_time', + 'system_capability' + ] + + headers = [ + 'Device', + 'Local Interface', + 'Device ID', + 'Port ID', + 'Hold Time', + 'Capability' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/nexus/mac/__init__.py b/lib/nexus/mac/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/mac/api.py b/lib/nexus/mac/api.py new file mode 100644 index 00000000..fe845efa --- /dev/null +++ b/lib/nexus/mac/api.py @@ -0,0 +1,67 @@ +class MacApi(): + def __init__(self): + self.mac_mo = None + + def get_mac_mo(self, local_cache_enabled=True, cache_enabled=True): + command = 'show mac address-table' + + if local_cache_enabled: + if self.mac_mo is not None: + return self.mac_mo + + if cache_enabled: + cached_mo = self.get_command_cache(command) + if cached_mo is not None: + return cached_mo + + if not self.connect(): + self.log.error( + 'get_mac_mo', + 'API connection failed: %s' % (self.nexus_name) + ) + return None + + response = self.run_show_command(command) + if response is None: + self.log.error( + 'get_mac_mo', + 'Command failed on %s: %s' % ( + self.nexus_name, + command + ) + ) + return None + + if 'TABLE_mac_address' not in response: + self.log.error( + 'get_mac_mo', + 'Unexpected rest response %s: %s' % ( + self.nexus_name, + response + ) + ) + return None + + if 'ROW_mac_address' not in response['TABLE_mac_address']: + self.log.error( + 'get_mac_mo', + 'Unexpected rest response %s: %s' % ( + self.nexus_name, + response + ) + ) + return None + + if isinstance(response['TABLE_mac_address']['ROW_mac_address'], dict): + new_response = {} + new_response['TABLE_mac_address'] = {} + new_response['TABLE_mac_address']['ROW_mac_address'] = [] + new_response['TABLE_mac_address']['ROW_mac_address'].append( + response['TABLE_mac_address']['ROW_mac_address'] + ) + response = new_response + + self.set_command_cache(command, response) + self.mac_mo = response + + return self.mac_mo diff --git a/lib/nexus/mac/bot_output.py b/lib/nexus/mac/bot_output.py new file mode 100644 index 00000000..19dc3add --- /dev/null +++ b/lib/nexus/mac/bot_output.py @@ -0,0 +1,63 @@ +class MacBotOutput(): + def __init__(self): + pass + + def print_macs(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'MAC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'nexus_name', + 'vlan', + 'mac_addr', + 'type', + 'age', + 'is_secure', + 'is_ntfy', + 'port' + ] + + headers = [ + 'Device', + 'VLAN', + 'MAC', + 'Type', + 'Age', + 'Sec', + 'Ntfy', + 'Port' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='MAC Address Table' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/nexus/mac/info.py b/lib/nexus/mac/info.py new file mode 100644 index 00000000..951b34c2 --- /dev/null +++ b/lib/nexus/mac/info.py @@ -0,0 +1,115 @@ +from lib import filter_helper +from lib import ip_helper + + +class MacInfo(): + def __init__(self): + self.mac = None + + def get_mac_info(self, mac_mo): + if mac_mo is None: + return None + + info = {} + info['__Output'] = {} + info['nexus_name'] = self.nexus_name + + # "disp_mac_addr": "0008.312b.d2a8", + # "disp_type": "dynamic", + # "disp_vlan": "3", + # "disp_age": "0", + # "disp_is_secure": "F", + # "disp_is_ntfy": "F", + # "disp_port": "Po3" + for key in mac_mo: + if key.startswith('disp_'): + info[key[5:]] = mac_mo[key] + else: + info[key] = mac_mo[key] + + return info + + def get_macs_info(self, local_cache_enabled=True, cache_enabled=True): + if local_cache_enabled: + if self.mac is not None: + return self.mac + + managed_objects = self.get_mac_mo( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if managed_objects is None: + self.log.error( + 'get_macs_info', + 'No mac neighbor managed objects: %s' % (self.nexus_name) + ) + return None + + self.mac = [] + for managed_object in managed_objects['TABLE_mac_address']['ROW_mac_address']: + mac_info = self.get_mac_info( + managed_object + ) + self.mac.append( + mac_info + ) + + return self.mac + + def match_mac(self, mac_info, mac_filter): + if mac_filter is None or len(mac_filter) == 0: + return True + + for ap_rule in mac_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'vlan': + key_found = True + if not filter_helper.match_string(value, mac_info['vlan']): + return False + + if key == 'mac': + key_found = True + found = False + for mac_address in value.split(','): + if ip_helper.is_mac_match(mac_address, mac_info['mac_addr']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_mac', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_macs(self, object_filter=None, local_cache_enabled=True, cache_enabled=True): + all_macs = self.get_macs_info( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if all_macs is None: + self.log.error( + 'get_macs', + 'Failed to get mac neighbors: %s' % (self.nexus_name) + ) + return None + + macs = [] + + for mac_info in all_macs: + if not self.match_mac(mac_info, object_filter): + continue + + macs.append( + mac_info + ) + + return macs diff --git a/lib/nexus/mac/main.py b/lib/nexus/mac/main.py new file mode 100644 index 00000000..7ca1f36c --- /dev/null +++ b/lib/nexus/mac/main.py @@ -0,0 +1,11 @@ +from lib.nexus.mac.api import MacApi +from lib.nexus.mac.info import MacInfo + + +class Mac( + MacApi, + MacInfo + ): + def __init__(self): + MacApi.__init__(self) + MacInfo.__init__(self) diff --git a/lib/nexus/mac/output.py b/lib/nexus/mac/output.py new file mode 100644 index 00000000..70429c16 --- /dev/null +++ b/lib/nexus/mac/output.py @@ -0,0 +1,45 @@ +class MacOutput(): + def __init__(self): + pass + + def print_macs(self, info, title=False): + if title: + self.my_output.default( + 'MAC [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nexus_name', + 'vlan', + 'mac_addr', + 'type', + 'age', + 'is_secure', + 'is_ntfy', + 'port' + ] + + headers = [ + 'Device', + 'VLAN', + 'MAC', + 'Type', + 'Age', + 'Sec', + 'Ntfy', + 'Port' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/nexus/nxapi.py b/lib/nexus/nxapi.py new file mode 100644 index 00000000..12fe56ff --- /dev/null +++ b/lib/nexus/nxapi.py @@ -0,0 +1,203 @@ +import json +import time +import traceback +import requests + +from lib import output_helper +from lib import log_helper +from lib import info_helper + +from lib.nexus.cache import Cache +from lib.nexus.ws import WebSocket + +from lib.nexus.config.main import Config +from lib.nexus.lacp.main import Lacp +from lib.nexus.lldp.main import Lldp +from lib.nexus.mac.main import Mac +from lib.nexus.server.main import Server +from lib.nexus.version.main import Version + + +class NxApi( + Cache, + Config, + Lacp, + Lldp, + Mac, + Server, + Version, + WebSocket + ): + def __init__(self, ip_address, username, password, name=None, verbose=False, debug=False, log_id=None, cache_enabled=False): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + self.info_handler = info_helper.InfoHelper(log_id=log_id) + + self.nexus_name = name + if self.nexus_name is None: + self.nexus_name = ip_address + self.nexus_ip = ip_address + self.username = username + self.password = password + + self.session_handler = None + self.session_connected = False + self.token = None + + Cache.__init__(self, cache_enabled) + WebSocket.__init__(self, ip_address, debug=debug) + + Config.__init__(self) + Lacp.__init__(self) + Lldp.__init__(self) + Mac.__init__(self) + Server.__init__(self) + Version.__init__(self) + + def __del__(self): + self.disconnect() + + def get_token(self): + return self.token + + def connect(self): + if self.session_handler is not None: + return True + + self.session_handler = requests.session() + self.session_handler.auth = ( + self.username, + self.password + ) + self.session_handler.verify = False + self.session_handler.headers.update( + {'Content-Type': 'application/json'} + ) + + data = { + 'ins_api': { + 'chunk': '0', + 'version': '1.0', + 'sid': '1', + 'input': 'show version', + 'type': 'cli_show', + 'output_format': 'json' + } + } + + start_time = int(time.time() * 1000) + try: + uri = 'https://%s/ins/' % (self.nexus_ip) + response = self.session_handler.request( + 'post', + uri, + data=json.dumps(data) + ) + if response.status_code == 200: + self.session_connected = True + self.token = self.session_handler.cookies.get_dict()['nxapi_auth'] + + except BaseException: + self.log.error( + 'nxapi.connect', + traceback.format_exc() + ) + self.session_connected = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.nexus( + 'connect %s' % (self.nexus_ip), + self.session_connected, + duration_ms + ) + + return self.session_connected + + def is_connected(self, autoconnect=False): + if not self.session_connected and autoconnect: + return self.connect() + + return self.session_connected + + def disconnect(self): + if not self.session_connected: + return True + + start_time = int(time.time() * 1000) + success = True + try: + self.session_handler.close() + except BaseException: + self.log.error( + 'nxapi.disconnect', + traceback.format_exc() + ) + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.nexus( + 'disconnect %s' % (self.nexus_ip), + success, + duration_ms + ) + + self.session_connected = False + self.session_handler = None + + return success + + def run_show_command(self, command, autoconnect=False): + if not self.is_connected(autoconnect=autoconnect): + return None + + data = { + 'ins_api': { + 'chunk': '0', + 'version': '1.0', + 'sid': '1', + 'input': command, + 'type': 'cli_show', + 'output_format': 'json' + } + } + + start_time = int(time.time() * 1000) + output = None + success = False + try: + uri = 'https://%s/ins/' % (self.nexus_ip) + response = self.session_handler.request( + 'post', + uri, + data=json.dumps(data) + ) + if response.status_code == 200: + output = response.json()['ins_api']['outputs']['output']['body'] + success = True + self.log.nexus_cli( + self.nexus_ip, + command.replace(' ', '_'), + output + ) + + except BaseException: + self.log.error( + 'nxapi.run_show_commnd', + 'Command failed: %s' % (command) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.nexus( + '%s %s' % (self.nexus_ip, command), + success, + duration_ms + ) + + return output diff --git a/lib/nexus/output.py b/lib/nexus/output.py new file mode 100644 index 00000000..8e487875 --- /dev/null +++ b/lib/nexus/output.py @@ -0,0 +1,24 @@ +from lib import output_helper + +from lib.nexus.lacp.output import LacpOutput +from lib.nexus.lldp.output import LldpOutput +from lib.nexus.mac.output import MacOutput +from lib.nexus.version.output import VersionOutput + + +class NexusOutput( + LacpOutput, + LldpOutput, + MacOutput, + VersionOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + LacpOutput.__init__(self) + LldpOutput.__init__(self) + MacOutput.__init__(self) + VersionOutput.__init__(self) diff --git a/lib/nexus/server/__init__.py b/lib/nexus/server/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/server/main.py b/lib/nexus/server/main.py new file mode 100644 index 00000000..04234548 --- /dev/null +++ b/lib/nexus/server/main.py @@ -0,0 +1,127 @@ +from lib import ip_helper + + +class Server(): + def __init__(self): + pass + + def get_server_mac(self, server): + mac_filter = [] + for mac_info in server['MacAddressInfo']: + if 'mac' not in mac_info: + mac_info['mac'] = None + mac_filter.append( + mac_info['MacAddress'] + ) + + object_filter = [] + object_filter.append( + 'mac:%s' % (','.join(mac_filter)) + ) + + device_macs = self.get_macs( + object_filter=object_filter + ) + + if device_macs is None: + self.log.error( + 'get_server_mac', + 'MAC info failed: %s' % (self.nexus_name) + ) + return server + + if device_macs is not None: + for mac_info in server['MacAddressInfo']: + for device_mac in device_macs: + if ip_helper.is_mac_equal(mac_info['MacAddress'], device_mac['mac_addr']): + mac_info['mac'] = device_mac + + return server + + def get_server_lacp(self, server): + mac_filter = [] + for mac_info in server['MacAddressInfo']: + if 'interface' not in mac_info: + mac_info['interface'] = None + + mac_filter.append( + mac_info['MacAddress'] + ) + + object_filter = [] + object_filter.append( + 'mac:%s' % (','.join(mac_filter)) + ) + + device_interfaces = self.get_lacps( + object_filter=object_filter + ) + + if device_interfaces is None: + self.log.error( + 'get_server_lacp', + 'LACP info failed: %s' % (self.nexus_name) + ) + return server + + for mac_info in server['MacAddressInfo']: + for device_interface in device_interfaces: + port_match = False + for port_info in device_interface['port']: + if ip_helper.is_mac_equal(mac_info['MacAddress'], port_info['partner_mac']): + port_match = True + + if port_match: + mac_info['interface'] = device_interfaces + + return server + + def get_server_lldp(self, server): + mac_filter = [] + for mac_info in server['MacAddressInfo']: + if 'adjacency' not in mac_info: + mac_info['adjacency'] = None + mac_filter.append( + mac_info['MacAddress'] + ) + + object_filter = [] + object_filter.append( + 'mac:%s' % (','.join(mac_filter)) + ) + + device_neighbors = self.get_lldps( + object_filter=object_filter + ) + + if device_neighbors is None: + self.log.error( + 'get_server_lldp', + 'LLDP info failed: %s' % (self.nexus_name) + ) + return server + + for mac_info in server['MacAddressInfo']: + for device_neighbor in device_neighbors: + if ip_helper.is_mac_equal(mac_info['MacAddress'], device_neighbor['port_id']): + mac_info['adjacency'] = device_neighbor + + return server + + def get_server_connectivity(self, server, mac_info=True, lacp_info=True, lldp_info=True): + if mac_info: + server = self.get_server_mac( + server + ) + + if lacp_info: + server = self.get_server_lacp( + server + ) + + if lldp_info: + server = self.get_server_lldp( + server + ) + + return server diff --git a/lib/nexus/settings.py b/lib/nexus/settings.py new file mode 100644 index 00000000..d35fb6ab --- /dev/null +++ b/lib/nexus/settings.py @@ -0,0 +1,239 @@ +import os +import json +import traceback + +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class NexusSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log = log_helper.Log() + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.nexus_settings_filename = os.path.join( + self.settings_dir, + 'nexus' + ) + + self.nexus_cache_directory = os.path.join( + self.settings_dir, + 'nx-device' + ) + + if not self.initialize_nexus_settings(): + raise ValueError('Nexus settings initialization failed') + + def get_nexus_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Cache'] = {} + settings['Cache']['Enabled'] = False + settings['Cache']['Ttl'] = 180 + settings['Cache']['Command'] = {} + settings['Devices'] = [] + settings['Defaults'] = {} + settings['Defaults']['Device'] = None + return settings + + def initialize_nexus_settings(self): + if not os.path.isfile(self.nexus_settings_filename): + settings = self.get_nexus_default_settings() + if not self.set_nexus_settings(settings): + return False + + if not os.path.isdir(self.nexus_cache_directory): + os.makedirs(self.nexus_cache_directory, exist_ok=True) + + return True + + def get_nexus_cache_base_directory(self): + return self.nexus_cache_directory + + def is_nexus_cache_enabled(self): + settings = self.get_nexus_cache_settings() + return settings['Enabled'] + + def get_nexus_cache_settings(self): + settings = self.get_nexus_settings() + return settings['Cache'] + + def get_nexus_settings(self): + if not os.path.isfile(self.nexus_settings_filename): + self.log.error( + 'get_nexus_settings', + 'File not found: %s' % ( + self.nexus_settings_filename + ) + ) + return None + + try: + with open(self.nexus_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_nexus_settings', traceback.format_exc()) + return None + + return settings + + def set_nexus_settings(self, settings): + try: + with open(self.nexus_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_nexus_settings', traceback.format_exc()) + return False + + return True + + def get_nexus_devices(self): + settings = self.get_nexus_settings() + if settings is None: + return None + + devices = settings['Devices'] + for device in devices: + device['cache_enabled'] = settings['Cache']['Enabled'] + device['cache_ttl'] = settings['Cache']['Ttl'] + + return devices + + def get_nexus_domain_devices(self, domain_name): + settings = self.get_nexus_settings() + if settings is None: + return None + + domain_devices = [] + for device in settings['Devices']: + if device['domain'] == domain_name: + domain_devices.append( + device + ) + + return domain_devices + + def get_nexus_device(self, nexus_name): + devices = self.get_nexus_devices() + if devices is None: + return None + + for device in devices: + if device['name'] == nexus_name: + return device + + return None + + def set_nexus_devices(self, devices): + settings = self.get_nexus_settings() + if settings is None: + return False + + settings['Devices'] = devices + return self.set_nexus_settings(settings) + + def set_nexus_device(self, nexus_name, nexus_ip, nexus_username, nexus_password, domain=''): + devices = self.get_nexus_devices() + if devices is None: + return False + + new_devices = [] + for device in devices: + if device['name'] != nexus_name: + new_devices.append(device) + + new_device = {} + new_device['name'] = nexus_name + new_device['ip'] = nexus_ip + new_device['username'] = nexus_username + new_device['password'] = nexus_password + new_device['domain'] = domain + new_devices.append(new_device) + + return self.set_nexus_devices(new_devices) + + def delete_nexus_device(self, nexus_name): + devices = self.get_nexus_devices() + if devices is None: + return False + + new_devices = [] + for device in devices: + if device['name'] != nexus_name: + new_devices.append(device) + + return self.set_nexus_devices(new_devices) + + def get_default_nexus_device(self): + settings = self.get_nexus_settings() + if settings is None: + return None + + try: + default_device_name = settings['Defaults']['Device'] + except BaseException: + default_device_name = None + + return default_device_name + + def set_default_nexus_device(self, name): + settings = self.get_nexus_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Device'] = name + return self.set_nexus_settings(settings) + + def get_nexus_device_names(self): + devices = self.get_nexus_devices() + if devices is None: + return None + + names = [] + for device in devices: + names.append( + device['name'] + ) + + return names + + def print_nexus_devices(self, devices, show_password=True): + devices = sorted(devices, key=lambda i: i['name']) + if not show_password: + for device in devices: + device['password'] = '******' + + order = [ + 'name', + 'ip', + 'username', + 'password', + 'domain' + ] + + headers = [ + 'Name', + 'IP', + 'Username', + 'Password', + 'Domain' + ] + + self.my_output.my_table( + devices, + order=order, + headers=headers, + table=True + ) diff --git a/lib/nexus/version/__init__.py b/lib/nexus/version/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nexus/version/api.py b/lib/nexus/version/api.py new file mode 100644 index 00000000..42c5eb3d --- /dev/null +++ b/lib/nexus/version/api.py @@ -0,0 +1,38 @@ +class VersionApi(): + def __init__(self): + self.version_mo = None + + def get_version_mo(self, local_cache_enabled=True, cache_enabled=True): + command = 'show version' + + if local_cache_enabled: + if self.version_mo is not None: + return self.version_mo + + if cache_enabled: + cached_mo = self.get_command_cache(command) + if cached_mo is not None: + return [cached_mo] + + if not self.connect(): + self.log.error( + 'get_version_mo', + 'API connection failed: %s' % (self.nexus_name) + ) + return None + + response = self.run_show_command(command) + if response is None: + self.log.error( + 'get_version_mo', + 'Command failed on %s: %s' % ( + self.nexus_name, + command + ) + ) + return None + + self.set_command_cache(command, response) + self.version_mo = [response] + + return self.version_mo diff --git a/lib/nexus/version/bot_output.py b/lib/nexus/version/bot_output.py new file mode 100644 index 00000000..26880777 --- /dev/null +++ b/lib/nexus/version/bot_output.py @@ -0,0 +1,59 @@ +class VersionBotOutput(): + def __init__(self): + pass + + def print_versions(self, info, title=False): + self.my_output.clear_output() + + if title: + self.my_output.my_print( + 'HW/SW Version [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.my_print('None') + return self.my_output.get_output(), None + + order = [ + 'nexus_name', + 'nxos_ver_str', + 'chassis_id', + 'uptime', + 'cpu_name', + 'memory_size' + ] + + headers = [ + 'Device', + 'SW', + 'HW', + 'Uptime', + 'CPU', + 'Memory' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True, + stream='output' + ) + + output = self.my_output.get_output() + + self.my_output.clear_output() + + self.my_output.my_table_html( + info, + order, + headers, + title='HW/SW Version' + ) + + html_output = self.my_output.get_output() + + return output, html_output diff --git a/lib/nexus/version/info.py b/lib/nexus/version/info.py new file mode 100644 index 00000000..62766dd8 --- /dev/null +++ b/lib/nexus/version/info.py @@ -0,0 +1,150 @@ +from lib import filter_helper +from lib import ip_helper +from lib import info_helper + +class VersionInfo(): + def __init__(self): + self.version = None + + def get_version_info(self, version_mo): + if version_mo is None: + return None + + # { + # "header_str": "Cisco Nexus Operating System (NX-OS) Software\nTAC support: http://www.cisco.com/tac\nCopyright (C) 2002-2022, Cisco and/or its affiliates.\nAll rights reserved.\nThe copyrights to certain works contained in this software are\nowned by other third parties and used and distributed under their own\nlicenses, such as open source. This software is provided \"as is,\" and unless\notherwise stated, there is no warranty, express or implied, including but not\nlimited to warranties of merchantability and fitness for a particular purpose.\nCertain components of this software are licensed under\nthe GNU General Public License (GPL) version 2.0 or \nGNU General Public License (GPL) version 3.0 or the GNU\nLesser General Public License (LGPL) Version 2.1 or \nLesser General Public License (LGPL) Version 2.0. \nA copy of each such license is available at\nhttp://www.opensource.org/licenses/gpl-2.0.php and\nhttp://opensource.org/licenses/gpl-3.0.html and\nhttp://www.opensource.org/licenses/lgpl-2.1.php and\nhttp://www.gnu.org/licenses/old-licenses/library.txt.\n", + # "bios_ver_str": "05.47", + # "kickstart_ver_str": "9.3(9)", + # "nxos_ver_str": "9.3(9)", + # "bios_cmpl_time": "04/28/2022", + # "kick_file_name": "bootflash:///nxos.9.3.9.bin", + # "nxos_file_name": "bootflash:///nxos.9.3.9.bin", + # "kick_cmpl_time": "2/4/2022 7:00:00", + # "nxos_cmpl_time": "2/4/2022 7:00:00", + # "kick_tmstmp": "02/04/2022 09:54:27", + # "nxos_tmstmp": "02/04/2022 09:54:27", + # "chassis_id": "Nexus9000 C9336C-FX2 Chassis", + # "cpu_name": "Intel(R) Xeon(R) CPU D-1526 @ 1.80GHz", + # "memory": 24569944, + # "mem_type": "kB", + # "proc_board_id": "FDO23490E2Y", + # "host_name": "ipn12-eu-spdc", + # "bootflash_size": 115805708, + # "kern_uptm_days": 140, + # "kern_uptm_hrs": 19, + # "kern_uptm_mins": 21, + # "kern_uptm_secs": 46, + # "rr_usecs": 933674, + # "rr_ctime": "Thu Jul 20 14:00:18 2023", + # "rr_reason": "Module PowerCycled", + # "rr_sys_ver": "", + # "rr_service": "HW check by card-client", + # "plugins": "Core Plugin, Ethernet Plugin", + # "manufacturer": "Cisco Systems, Inc.", + # "TABLE_package_list": { + # "ROW_package_list": { + # "package_id": "" + # } + # } + # } + + info = {} + info['__Output'] = {} + info['nexus_name'] = self.nexus_name + + excludeded_keys = [ + 'TABLE_package_list', + 'header_str' + ] + for key in version_mo: + if key not in excludeded_keys: + info[key] = version_mo[key] + + info['uptime'] = '' + if info['kern_uptm_days'] > 0: + info['uptime'] = '%s days ' % (info['kern_uptm_days']) + + info['uptime'] = '%s%s:%s:%s' % ( + info['uptime'], + info['kern_uptm_hrs'], + info['kern_uptm_mins'], + info['kern_uptm_secs'] + ) + + info['memory_size'] = '%s%s' % ( + info['memory'], + info['mem_type'] + ) + if info['mem_type'] == 'kB': + info['memory_size'] = self.info_handler.convert_memory( + info['memory'] * 1024 + ) + + return info + + def get_versions_info(self, local_cache_enabled=True, cache_enabled=True): + if local_cache_enabled: + if self.version is not None: + return self.version + + managed_objects = self.get_version_mo( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if managed_objects is None: + self.log.error( + 'get_versions_info', + 'No version managed objects: %s' % (self.nexus_name) + ) + return None + + self.version = [] + for managed_object in managed_objects: + self.version.append( + self.get_version_info( + managed_object + ) + ) + + return self.version + + def match_version(self, version_info, version_filter): + if version_filter is None or len(version_filter) == 0: + return True + + for ap_rule in version_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_version', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_versions(self, object_filter=None, local_cache_enabled=True, cache_enabled=True): + all_versions = self.get_versions_info( + local_cache_enabled=local_cache_enabled, + cache_enabled=cache_enabled + ) + if all_versions is None: + self.log.error( + 'get_versions', + 'Failed to get version: %s' % (self.nexus_name) + ) + return None + + versions = [] + + for version_info in all_versions: + if not self.match_version(version_info, object_filter): + continue + + versions.append( + version_info + ) + + return versions diff --git a/lib/nexus/version/main.py b/lib/nexus/version/main.py new file mode 100644 index 00000000..34ad96f3 --- /dev/null +++ b/lib/nexus/version/main.py @@ -0,0 +1,11 @@ +from lib.nexus.version.api import VersionApi +from lib.nexus.version.info import VersionInfo + + +class Version( + VersionApi, + VersionInfo + ): + def __init__(self): + VersionApi.__init__(self) + VersionInfo.__init__(self) diff --git a/lib/nexus/version/output.py b/lib/nexus/version/output.py new file mode 100644 index 00000000..92a3d944 --- /dev/null +++ b/lib/nexus/version/output.py @@ -0,0 +1,41 @@ +class VersionOutput(): + def __init__(self): + pass + + def print_versions(self, info, title=False): + if title: + self.my_output.default( + 'Version [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'nexus_name', + 'nxos_ver_str', + 'chassis_id', + 'uptime', + 'cpu_name', + 'memory_size' + ] + + headers = [ + 'Device', + 'SW', + 'HW', + 'Uptime', + 'CPU', + 'Memory' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/nexus/ws.py b/lib/nexus/ws.py new file mode 100644 index 00000000..cef7e107 --- /dev/null +++ b/lib/nexus/ws.py @@ -0,0 +1,147 @@ +import os +import json +import time +import ssl +import uuid +import threading +import websocket +import requests + + +class WebSocket(): + def __init__(self, nexus_ip, debug=False): + self.ws_nexus_ip = nexus_ip + self.ws_token = None + self.ws_monitored_objects = [] + self.ws_handler = None + self.ws_subscription_ids = '/tmp/ws_nexus_%s.json' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.ws_debug = debug + + def ws_on_open(self, ws_obj): + subscription_ids = [] + + print('Object subscriptions:') + for monitored_object in self.ws_monitored_objects: + subscription_url = 'http://%s%s.json?subscription=yes' % ( + self.ws_nexus_ip, + monitored_object + ) + if self.ws_debug: + print('- GET %s' % (subscription_url)) + + response = requests.get( + subscription_url, + headers={'Cookie': 'APIC-cookie=%s' % (self.get_token(generate_if_none=True))}, + verify=False + ) + + if self.ws_debug: + print('- Response %s' % (response.status_code)) + + if response.status_code >= 300: + print('[ERROR] object %s subscription request failed (%s)' % (monitored_object, response.status_code)) + self.ws_handler.close() + return + + subscription_id = json.loads(response.text)['subscriptionId'] + subscription_ids.append( + subscription_id + ) + print('- %s with subscription ID: %s' % ( + monitored_object, + subscription_id + )) + + with open(self.ws_subscription_ids, 'w+', encoding='utf-8') as handle: + json.dump(subscription_ids, handle) + + print('Press Ctrl-C to exit') + + def ws_on_message(self, ws_obj, ws_message): + print(ws_message) + + def ws_on_error(self, ws_obj, ws_error): + if ws_error is not None and len(str(ws_error)) > 0: + print('[ERROR] %s' % (ws_error)) + + def ws_on_close(self, ws_obj, ws_close_status_code, ws_close_msg): + os.remove(self.ws_subscription_ids) + + if ws_close_msg is None: + print('Socket closed') + if ws_close_msg is not None: + print('Socket closed (%s)' % (ws_close_msg)) + + def ws_refresh(self): + while True: + timeout_epoch = int(time.time()) + 60 + while True: + if not os.path.isfile(self.ws_subscription_ids): + print('Subscription refresh thread finished') + return + + time.sleep(5) + if int(time.time()) > timeout_epoch: + break + + if not os.path.isfile(self.ws_subscription_ids): + print('Subscription refresh thread finished') + return + + with open(self.ws_subscription_ids, "r", encoding='utf-8') as handle: + subscription_ids = json.load(handle) + + self.ws_token = self.get_token() + if self.ws_token is None: + print('[ERROR] Nexus token generation') + return + + print('Subscriptions refresh:') + for subscription_id in subscription_ids: + subscription_url = 'https://%s/api/subscriptionRefresh.json?id=%s' % (self.ws_nexus_ip, subscription_id) + response = requests.get( + subscription_url, + headers={'Cookie': 'nxapi_auth=%s' % (self.ws_token)}, + verify=False + ) + if self.ws_debug: + print('- GET %s' % (subscription_url)) + + if json.loads(response.text)['totalCount'] != '0': + print('[ERROR] subscription refresh failed (%s)' % (subscription_id)) + self.ws_handler.close() + return + + print('- subscription %s refreshed' % (subscription_id)) + + def ws_run(self, objects): + self.ws_monitored_objects = objects + with open(self.ws_subscription_ids, 'w+', encoding='utf-8') as handle: + json.dump([], handle) + + self.ws_token = self.get_token() + if self.ws_token is None: + print('[ERROR] Nexus authentication failed') + return + + # refresh_thread = threading.Thread(target=self.ws_refresh) + # refresh_thread.start() + + websocket.enableTrace(self.ws_debug) + + ws_url = 'wss://%s/socket%s' % (self.ws_nexus_ip, self.ws_token) + self.ws_handler = websocket.WebSocketApp( + ws_url, + on_message=self.ws_on_message, + on_error=self.ws_on_error, + on_close=self.ws_on_close, + on_open=self.ws_on_open, + cookie=self.ws_token + ) + + self.ws_handler.run_forever( + sslopt={ + "check_hostname": False, + "cert_reqs": ssl.CERT_NONE + } + ) diff --git a/lib/nso/__init__.py b/lib/nso/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/__pycache__/__init__.cpython-310.pyc b/lib/nso/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a2e47fab Binary files /dev/null and b/lib/nso/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/nso/__pycache__/main.cpython-310.pyc b/lib/nso/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..b9a26a8b Binary files /dev/null and b/lib/nso/__pycache__/main.cpython-310.pyc differ diff --git a/lib/nso/__pycache__/settings.cpython-310.pyc b/lib/nso/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..ee9b41a7 Binary files /dev/null and b/lib/nso/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/nso/api/__init__.py b/lib/nso/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/api/__pycache__/__init__.cpython-310.pyc b/lib/nso/api/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..2136b6ee Binary files /dev/null and b/lib/nso/api/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/nso/api/__pycache__/rest.cpython-310.pyc b/lib/nso/api/__pycache__/rest.cpython-310.pyc new file mode 100644 index 00000000..c96b231e Binary files /dev/null and b/lib/nso/api/__pycache__/rest.cpython-310.pyc differ diff --git a/lib/nso/api/rest.py b/lib/nso/api/rest.py new file mode 100644 index 00000000..7a2220aa --- /dev/null +++ b/lib/nso/api/rest.py @@ -0,0 +1,546 @@ +import time +import json +import traceback +import requests + +from lib import log_helper + + +class Rest(): + def __init__(self, protocol, ip_address, port, username, password, restconf_enabled=True, log_id=None): + self.log = log_helper.Log(log_id=log_id) + + self.session = requests.Session() + if username is not None and password is not None: + self.session.auth = (username, password) + + self.protocol = protocol + self.ip_address = ip_address + self.port = port + self.restconf_enabled = restconf_enabled + + self.get_timeout = 15 + self.patch_timeout = 15 + self.post_timeout = 15 + self.put_timeout = 15 + self.delete_timeout = 15 + + def format_url_rest(self, path, resource_type=None): + if resource_type is None: + if path is None: + url = '%s://%s:%s/api' % ( + self.protocol, + self.ip_address, + self.port + ) + else: + url = '%s://%s:%s/api/%s' % ( + self.protocol, + self.ip_address, + self.port, + path + ) + else: + if path is None: + url = '%s://%s:%s/api/%s' % ( + self.protocol, + self.ip_address, + self.port, + resource_type + ) + else: + url = '%s://%s:%s/api/%s/%s' % ( + self.protocol, + self.ip_address, + self.port, + resource_type, + path + ) + + return url + + def format_url_restconf(self, path, resource_type=None): + if resource_type is None: + if path is None: + url = '%s://%s:%s/restconf' % ( + self.protocol, + self.ip_address, + self.port + ) + else: + url = '%s://%s:%s/restconf/%s' % ( + self.protocol, + self.ip_address, + self.port, + path + ) + else: + if path is None: + url = '%s://%s:%s/restconf/data' % ( + self.protocol, + self.ip_address, + self.port + ) + else: + url = '%s://%s:%s/restconf/data/%s' % ( + self.protocol, + self.ip_address, + self.port, + path + ) + + if resource_type == 'operational': + url = '%s?content=nonconfig' % (url) + + return url + + def format_url(self, path, resource_type=None): + if self.restconf_enabled: + return self.format_url_restconf(path, resource_type=resource_type) + return self.format_url_rest(path, resource_type=resource_type) + + def get_headers_rest(self, header, media_type, output_format): + if header == 'Accept': + response = {} + response['Accept'] = '%s+%s' % (media_type, output_format) + return response + + if header == 'Content-Type': + response = {} + response['Content-Type'] = '%s+%s' % (media_type, output_format) + return response + + self.log.error( + 'get_headers', + 'Unsupported header: %s' % (header) + ) + return None + + def get_headers_restconf(self, header, media_type, output_format): + if header == 'Accept': + if media_type == 'application/vnd.yang.data': + media_type = 'application/yang-data' + + response = {} + response['Accept'] = '%s+%s' % (media_type, output_format) + return response + + if header == 'Content-Type': + if media_type == 'application/vnd.yang.data': + media_type = 'application/yang-data' + + response = {} + response['Content-Type'] = '%s+%s' % (media_type, output_format) + return response + + self.log.error( + 'nso.get_headers', + 'Unsupported header: %s' % (header) + ) + return None + + def get_headers(self, header, media_type, output_format): + if self.restconf_enabled: + return self.get_headers_restconf(header, media_type, output_format) + return self.get_headers_rest(header, media_type, output_format) + + def format_error_message(self, response): + try: + message = response.json()['errors']['error'][0]['error-message'] + except KeyError: + message = 'Failed to make request or error not returned as expected' + except BaseException: + message = 'Failed to make request or error not returned as expected' + + error_message = 'Error code %s: %s' % (response.status_code, message) + return error_message + + def get_rest(self, output_format, resource_type, header, media_type, path=None, params=None, trace=None): + url = self.format_url(path, resource_type=resource_type) + headers = self.get_headers(header, media_type, output_format) + + success = True + content = None + try: + self.log.debug( + 'nso.get_rest', + url + ) + self.log.debug( + 'nso.get_rest', + headers + ) + self.log.debug( + 'nso.get_rest', + params + ) + rest_response = self.session.get( + url, + headers=headers, + params=params, + timeout=self.get_timeout + ) + + self.log.debug( + 'nso.get_rest', + 'Response code: %s' % (rest_response.status_code) + ) + + if rest_response.status_code == 204: + content = None + self.log.debug( + 'nso.get_rest', + 'Content set to none based on status code' + ) + else: + if output_format == 'json': + content = rest_response.json() + else: + content = rest_response.content.decode('utf-8') + + rest_response.raise_for_status() + + except requests.HTTPError as err: + success = False + self.log.error( + 'nso.get_rest', + 'HTTPError exception: %s' % (url) + ) + self.log.error( + 'nso.get_rest', + 'Status code: %s' % (err.response.status_code) + ) + self.log.error( + 'nso.get_rest', + err.response.text + ) + + except BaseException: + success = False + self.log.error( + 'nso.get_rest', + 'HTTPError exception: %s' % (url) + ) + self.log.error( + 'nso.get_rest', + traceback.format_exc() + ) + + if success: + self.trace_rest( + trace, + 'GET', + url, + headers, + None, + params, + rest_response.status_code, + content + ) + + return success, content + + def post_rest(self, output_format, resource_type, header, media_type, data, path=None, params=None, timeout=None, trace=None): + url = self.format_url(path, resource_type=resource_type) + headers = self.get_headers(header, media_type, output_format) + + if timeout is None: + timeout = self.post_timeout + + success = True + content = None + try: + # curl + # -X POST + # --header "Content-Type:application/yang-data+xml" + # -u admin:admin + # -d @/tmp/ausf-vnfd.xml + # http://:8080/restconf/data/etsi-nfv-descriptors:nfv + + rest_response = self.session.post( + url, + headers=headers, + data=data, + params=params, + timeout=timeout + ) + + if rest_response.status_code == 204: + content = None + else: + if output_format == 'json': + content = rest_response.json() + else: + content = rest_response.content.decode('utf-8') + + rest_response.raise_for_status() + + except requests.HTTPError as err: + success = False + self.log.error( + 'nso.post_rest', + 'HTTP Error exception: %s' % (url) + ) + self.log.error( + 'nso.post_rest', + 'Status code: %s' % (err.response.status_code) + ) + self.log.error( + 'nso.post_rest', + err.response.text + ) + + except BaseException: + success = False + self.log.error( + 'nso.post_rest', + traceback.format_exc() + ) + + self.trace_rest( + trace, + 'POST', + url, + headers, + data, + params, + rest_response.status_code, + rest_response.text + ) + + return success, content + + def patch_rest(self, output_format, resource_type, header, media_type, data, path=None, params=None, timeout=None, trace=None): + url = self.format_url(path, resource_type=resource_type) + headers = self.get_headers(header, media_type, output_format) + + if timeout is None: + timeout = self.patch_timeout + + success = True + content = None + try: + rest_response = self.session.patch( + url, + headers=headers, + data=data, + params=params, + timeout=timeout + ) + + if rest_response.status_code == 204: + content = None + else: + if output_format == 'json': + content = rest_response.json() + else: + content = rest_response.content.decode('utf-8') + + rest_response.raise_for_status() + + except requests.HTTPError as err: + success = False + self.log.error( + 'nso.patch_rest', + 'HTTPError exception: %s' % (url) + ) + self.log.error( + 'nso.patch_rest', + 'Status code: %s' % (err.response.status_code) + ) + self.log.error( + 'nso.patch_rest', + err.response.text + ) + + except BaseException: + success = False + self.log.error( + 'nso.patch_rest', + 'Base exception: %s' % (url) + ) + self.log.error( + 'nso._patch_rest', + traceback.format_exc() + ) + + self.trace_rest( + trace, + 'PATCH', + url, + headers, + data, + params, + rest_response.status_code, + rest_response.text + ) + + return success, content + + def put_rest(self, output_format, resource_type, header, media_type, data, path=None, params=None, timeout=None, trace=None): + url = self.format_url(path, resource_type=resource_type) + headers = self.get_headers(header, media_type, output_format) + + if timeout is None: + timeout = self.put_timeout + + success = True + content = None + try: + rest_response = self.session.put( + url, + headers=headers, + data=data, + params=params, + timeout=timeout + ) + + if rest_response.status_code == 204: + content = None + else: + if output_format == 'json': + content = rest_response.json() + else: + content = rest_response.content.decode('utf-8') + + rest_response.raise_for_status() + + except requests.HTTPError as err: + success = False + self.log.error( + 'nso.put_rest', + 'HTTPError exception: %s' % (url) + ) + self.log.error( + 'nso.put_rest', + 'Status code: %s' % (err.response.status_code) + ) + self.log.error( + 'nso.put_rest', + err.response.text + ) + + except BaseException: + success = False + content = None + self.log.error( + 'nso.put_rest', + 'Base exception: %s' % (url) + ) + self.log.error( + 'nso.put_rest', + traceback.format_exc() + ) + + self.trace_rest( + trace, + 'PUT', + url, + headers, + data, + params, + rest_response.status_code, + rest_response.text + ) + + return success, content + + def delete_rest(self, output_format, resource_type, header, media_type, path=None, params=None, trace=None): + url = self.format_url(path, resource_type=resource_type) + headers = self.get_headers(header, media_type, output_format) + + success = True + content = None + try: + rest_response = self.session.delete( + url, + headers=headers, + params=params, + timeout=self.delete_timeout + ) + + if rest_response.status_code == 204: + content = None + else: + if output_format == 'json': + content = rest_response.json() + else: + content = rest_response.content.decode('utf-8') + + rest_response.raise_for_status() + + except requests.HTTPError as err: + success = False + self.log.error( + 'nso.delete_rest', + 'HTTPError exception: %s' % (url) + ) + self.log.error( + 'nso.delete_rest', + 'Status code: %s' % (err.response.status_code) + ) + self.log.error( + 'nso.delete_rest', + err.response.text + ) + + except BaseException: + success = False + self.log.error( + 'nso.delete_rest', + 'HTTPError exception: %s' % (url) + ) + self.log.error( + 'nso.delete_rest', + traceback.format_exc() + ) + + self.trace_rest( + trace, + 'DELETE', + url, + headers, + None, + params, + rest_response.status_code, + rest_response.text + ) + + return success, content + + def trace_rest(self, trace_filename, method, url, headers, data, params, response_code, response_data): + if response_data is None: + return + + if data is not None: + try: + data = data.decode('utf-8') + except BaseException: + data = str(data) + + timestamp = int(time.time() * 1000) + message = { + 'timestamp': timestamp, + 'message': method, + 'url': url, + 'headers': headers, + 'data': data, + 'params': params, + 'response_code': response_code, + 'response_data': response_data + } + + if trace_filename is not None: + self.log.adhoc( + trace_filename, + json.dumps(message, indent=4) + ) + + else: + self.log.adhoc( + 'nso.trace.%s' % (timestamp), + json.dumps( + message, + indent=4 + ) + ) diff --git a/lib/nso/cnfm/__init__.py b/lib/nso/cnfm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/cluster/__init__.py b/lib/nso/cnfm/cluster/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/cluster/api.py b/lib/nso/cnfm/cluster/api.py new file mode 100644 index 00000000..2f7ca850 --- /dev/null +++ b/lib/nso/cnfm/cluster/api.py @@ -0,0 +1,22 @@ +class NsoCnfmClusterApi(): + def __init__(self): + self.cnfm_cluster_mo = {} + + def get_cnfm_cluster_mo(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.cnfm_cluster_mo: + return self.cnfm_cluster_mo[device_name] + + device_config = self.get_device_config_mo( + device_name, + cache_enabled=cache_enabled + ) + if device_config is None: + self.log.error( + 'nso.get_cnfm_cluster_mo', + 'Failed to get device config: %s' % (device_name) + ) + return None + + self.cnfm_cluster_mo[device_name] = device_config['k8s-cnfm:clusters']['cluster'] + return self.cnfm_cluster_mo[device_name] diff --git a/lib/nso/cnfm/cluster/info.py b/lib/nso/cnfm/cluster/info.py new file mode 100644 index 00000000..87c4eb9b --- /dev/null +++ b/lib/nso/cnfm/cluster/info.py @@ -0,0 +1,80 @@ +from lib import filter_helper + + +class NsoCnfmClusterInfo(): + def __init__(self): + self.cnfm_cluster = {} + + def get_cnfm_cluster_info(self, cnfm_cluster_mo): + if cnfm_cluster_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = self.get( + cnfm_cluster_mo, + 'name' + ) + + return info + + def get_cnfm_clusters_info(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.cnfm_cluster: + return self.cnfm_cluster[device_name] + + managed_objects = self.get_cnfm_cluster_mo(device_name, cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cnfm_cluster[device_name] = [] + for managed_object in managed_objects: + cnfm_cluster_info = self.get_cnfm_cluster_info( + managed_object + ) + self.cnfm_cluster[device_name].append( + cnfm_cluster_info + ) + + return self.cnfm_cluster[device_name] + + def match_cnfm_cluster(self, cnfm_cluster_info, cnfm_cluster_filter): + if cnfm_cluster_filter is None or len(cnfm_cluster_filter) == 0: + return True + + for ap_rule in cnfm_cluster_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cnfm_cluster_info['name']): + return False + + if not key_found: + self.log.error( + 'match_cnfm_cluster', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_clusters(self, device_name, object_filter=None, cache_enabled=True): + all_cnfm_clusters = self.get_cnfm_clusters_info(device_name, cache_enabled=cache_enabled) + if all_cnfm_clusters is None: + return None + + cnfm_clusters = [] + + for cnfm_cluster_info in all_cnfm_clusters: + if not self.match_cnfm_cluster(cnfm_cluster_info, object_filter): + continue + + cnfm_clusters.append( + cnfm_cluster_info + ) + + return cnfm_clusters diff --git a/lib/nso/cnfm/cluster/main.py b/lib/nso/cnfm/cluster/main.py new file mode 100644 index 00000000..0b3851d8 --- /dev/null +++ b/lib/nso/cnfm/cluster/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.cluster.api import NsoCnfmClusterApi +from lib.nso.cnfm.cluster.info import NsoCnfmClusterInfo + + +class NsoCnfmCluster( + NsoCnfmClusterApi, + NsoCnfmClusterInfo + ): + def __init__(self): + NsoCnfmClusterApi.__init__(self) + NsoCnfmClusterInfo.__init__(self) diff --git a/lib/nso/cnfm/cnfd/__init__.py b/lib/nso/cnfm/cnfd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/cnfd/api.py b/lib/nso/cnfm/cnfd/api.py new file mode 100644 index 00000000..a99ac4e3 --- /dev/null +++ b/lib/nso/cnfm/cnfd/api.py @@ -0,0 +1,52 @@ +import time + + +class NsoCnfmCnfdApi(): + def __init__(self): + self.cnfm_cnfd_mo = None + + def get_cnfm_cnfd_mo(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_cnfd_mo is not None: + return self.cnfm_cnfd_mo + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data/cisco-cnf-descriptor:cnf/cnfd' + ) + self.log.nso( + 'get', + 'cnfd', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'cnfd', + success, + int(time.time() * 1000) - start_time + ) + + if not success: + self.log.error( + 'nso.get_cnfm_cnfd_mo', + 'Failed to get cnfd' + ) + return None + + self.cnfm_cnfd_mo = content['cisco-cnf-descriptor:cnfd'] + + self.log.nso_mo( + 'cnfd', + self.cnfm_cnfd_mo + ) + + return self.cnfm_cnfd_mo diff --git a/lib/nso/cnfm/cnfd/info.py b/lib/nso/cnfm/cnfd/info.py new file mode 100644 index 00000000..f68f12c0 --- /dev/null +++ b/lib/nso/cnfm/cnfd/info.py @@ -0,0 +1,192 @@ +from lib import filter_helper + + +class NsoCnfmCnfdInfo(): + def __init__(self): + self.cnfm_cnfd = None + + def get_cnfm_cnfd_info(self, cnfm_cnfd_mo): + if cnfm_cnfd_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = self.get( + cnfm_cnfd_mo, + 'name' + ) + + info['chart'] = self.get( + cnfm_cnfd_mo, + 'chart-name' + ) + + info['local'] = False + info['localTick'] = '\u2717' + if 'local' in cnfm_cnfd_mo: + info['local'] = True + info['localTick'] = '\u2713' + + info['version'] = [] + versions_mo = self.get( + cnfm_cnfd_mo, + 'chart-version' + ) + for version_mo in versions_mo: + version_info = {} + version_info['__Output'] = {} + version_info['version'] = self.get( + version_mo, + 'version' + ) + + version_info['app'] = self.get( + version_mo, + 'app-version' + ) + if version_info['app'] == 'None': + version_info['app'] = None + + version_info['description'] = self.get( + version_mo, + 'description' + ) + if version_info['description'] == 'None': + version_info['description'] = None + + version_info['values'] = [] + values_mo = self.get( + version_mo, + 'values:key-value' + ) + for value_mo in values_mo: + value_info = {} + value_info['key'] = value_mo['key'] + value_info['value'] = None + if 'value-str' in value_mo: + value_info['value'] = value_mo['value-str'] + if 'value-int' in value_mo: + value_info['value'] = int(value_mo['value-int']) + if 'value-bool' in value_mo: + value_info['value'] = value_mo['value-bool'] + + version_info['values'].append( + value_info + ) + + info['version'].append( + version_info + ) + + return info + + def get_cnfm_cnfds_info(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_cnfd is not None: + return self.cnfm_cnfd + + managed_objects = self.get_cnfm_cnfd_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cnfm_cnfd = [] + for managed_object in managed_objects: + cnfm_cnfd_info = self.get_cnfm_cnfd_info( + managed_object + ) + self.cnfm_cnfd.append( + cnfm_cnfd_info + ) + + return self.cnfm_cnfd + + def match_cnfm_cnfd(self, cnfm_cnfd_info, cnfm_cnfd_filter): + if cnfm_cnfd_filter is None or len(cnfm_cnfd_filter) == 0: + return True + + for ap_rule in cnfm_cnfd_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfd_info['name']): + return False + + if key == 'chart': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfd_info['chart']): + return False + + if key == 'version': + key_found = True + found = False + for version_info in cnfm_cnfd_info['version']: + if filter_helper.match_string(value, version_info['version']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_cnfm_cnfd', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_cnfds(self, object_filter=None, cnfi_info=True, cache_enabled=True): + all_cnfm_cnfds = self.get_cnfm_cnfds_info(cache_enabled=cache_enabled) + if all_cnfm_cnfds is None: + return None + + cnfm_cnfds = [] + + for cnfm_cnfd_info in all_cnfm_cnfds: + if not self.match_cnfm_cnfd(cnfm_cnfd_info, object_filter): + continue + + if cnfi_info: + for version_info in cnfm_cnfd_info['version']: + version_info['cnfi'] = self.get_cnfm_cnfis( + object_filter=[ + 'cnfd:%s' % (cnfm_cnfd_info['name']), + 'version:%s' % (version_info['version']) + ], + plan_info=True + ) + version_info['cnfi_count'] = len( + version_info['cnfi'] + ) + version_info['cnfi_ready'] = 0 + for cnfd_cnfi_info in version_info['cnfi']: + if cnfd_cnfi_info['isReady']: + version_info['cnfi_ready'] = version_info['cnfi_ready'] + 1 + + if version_info['cnfi_count'] == 0: + version_info['cnfi_summary'] = '--' + else: + version_info['cnfi_summary'] = '%s/%s' % ( + version_info['cnfi_ready'], + version_info['cnfi_count'] + ) + if version_info['cnfi_ready'] == version_info['cnfi_count']: + version_info['__Output']['cnfi_summary'] = 'Green' + else: + version_info['__Output']['cnfi_summary'] = 'Red' + + cnfm_cnfds.append( + cnfm_cnfd_info + ) + + cnfm_cnfds = sorted( + cnfm_cnfds, + key=lambda i: i['name'] + ) + + return cnfm_cnfds diff --git a/lib/nso/cnfm/cnfd/main.py b/lib/nso/cnfm/cnfd/main.py new file mode 100644 index 00000000..579d7621 --- /dev/null +++ b/lib/nso/cnfm/cnfd/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.cnfd.api import NsoCnfmCnfdApi +from lib.nso.cnfm.cnfd.info import NsoCnfmCnfdInfo + + +class NsoCnfmCnfd( + NsoCnfmCnfdApi, + NsoCnfmCnfdInfo + ): + def __init__(self): + NsoCnfmCnfdApi.__init__(self) + NsoCnfmCnfdInfo.__init__(self) diff --git a/lib/nso/cnfm/cnfd/output.py b/lib/nso/cnfm/cnfd/output.py new file mode 100644 index 00000000..fc451240 --- /dev/null +++ b/lib/nso/cnfm/cnfd/output.py @@ -0,0 +1,45 @@ +class NsoCnfmCnfdOutput(): + def __init__(self): + pass + + def print_cnfm_cnfds(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNFD [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'chart', + 'localTick', + 'version.version', + 'version.cnfi_summary' + ] + + headers = [ + 'Name', + 'Chart', + 'Local', + 'Version', + 'CNF Instance' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['version'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/nso/cnfm/cnfi/__init__.py b/lib/nso/cnfm/cnfi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/cnfi/api.py b/lib/nso/cnfm/cnfi/api.py new file mode 100644 index 00000000..7d95f513 --- /dev/null +++ b/lib/nso/cnfm/cnfi/api.py @@ -0,0 +1,52 @@ +import time + + +class NsoCnfmCnfiApi(): + def __init__(self): + self.cnfm_cnfi_mo = None + + def get_cnfm_cnfi_mo(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_cnfi_mo is not None: + return self.cnfm_cnfi_mo + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data/cisco-cnf-descriptor:cnf/cisco-cnfo:cnf-instance' + ) + self.log.nso( + 'get', + 'cnf-instance', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'cnf-instance', + success, + int(time.time() * 1000) - start_time + ) + + if not success: + self.log.error( + 'nso.get_cnfm_cnfi_mo', + 'Failed to get cnfi' + ) + return None + + self.cnfm_cnfi_mo = content['cisco-cnfo:cnf-instance'] + + self.log.nso_mo( + 'cnf-instance', + self.cnfm_cnfi_mo + ) + + return self.cnfm_cnfi_mo diff --git a/lib/nso/cnfm/cnfi/info.py b/lib/nso/cnfm/cnfi/info.py new file mode 100644 index 00000000..42aa3cdf --- /dev/null +++ b/lib/nso/cnfm/cnfi/info.py @@ -0,0 +1,281 @@ +from lib import filter_helper + + +class NsoCnfmCnfiInfo(): + def __init__(self): + self.cnfm_cnfi = None + + def get_cnfm_cnfi_info(self, cnfm_cnfi_mo): + if cnfm_cnfi_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['namespace'] = self.get( + cnfm_cnfi_mo, + 'namespace' + ) + + info['name'] = self.get( + cnfm_cnfi_mo, + 'name' + ) + + info['namespace_name'] = '%s/%s' % ( + info['namespace'], + info['name'] + ) + + info['cnfd'] = self.get( + cnfm_cnfi_mo, + 'cnfd' + ) + + info['version'] = self.get( + cnfm_cnfi_mo, + 'chart-version' + ) + + info['values'] = [] + values_mo = self.get( + cnfm_cnfi_mo, + 'values:key-value', + on_error=[], + on_none=[] + ) + for value_mo in values_mo: + value_info = {} + value_info['key'] = value_mo['key'] + value_info['value'] = None + if 'value-str' in value_mo: + value_info['value'] = value_mo['value-str'] + if 'value-int' in value_mo: + value_info['value'] = int(value_mo['value-int']) + if 'value-bool' in value_mo: + value_info['value'] = value_mo['value-bool'] + + info['values'].append( + value_info + ) + + info['custom_values'] = len(info['values']) + + if info['custom_values'] == 0: + info['cnfd_version'] = '%s:%s' % ( + info['cnfd'], + info['version'] + ) + else: + info['cnfd_version'] = '%s:%s (%s)' % ( + info['cnfd'], + info['version'], + info['custom_values'] + ) + + info['device'] = self.get( + cnfm_cnfi_mo, + 'device' + ) + + info['cluster'] = self.get( + cnfm_cnfi_mo, + 'cluster' + ) + + info['device_cluster'] = '%s:%s' % ( + info['device'], + info['cluster'] + ) + + info['onboard'] = False + info['onboardTick'] = '\u2717' + info['authgroup'] = None + + onboard_mo = self.get( + cnfm_cnfi_mo, + 'onboard' + ) + if onboard_mo is not None: + info['onboard'] = True + info['onboardTick'] = '\u2713' + info['authgroup'] = self.get( + onboard_mo, + 'authgroup' + ) + + return info + + def get_cnfm_cnfis_info(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_cnfi is not None: + return self.cnfm_cnfi + + managed_objects = self.get_cnfm_cnfi_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cnfm_cnfi = [] + for managed_object in managed_objects: + cnfm_cnfi_info = self.get_cnfm_cnfi_info( + managed_object + ) + self.cnfm_cnfi.append( + cnfm_cnfi_info + ) + + return self.cnfm_cnfi + + def match_cnfm_cnfi(self, cnfm_cnfi_info, cnfm_cnfi_filter): + if cnfm_cnfi_filter is None or len(cnfm_cnfi_filter) == 0: + return True + + for ap_rule in cnfm_cnfi_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfi_info['namespace']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_namespace_name( + value, + '%s/%s' % ( + cnfm_cnfi_info['namespace'], + cnfm_cnfi_info['name'] + ) + ): + return False + + if key == 'cluster': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfi_info['cluster']): + return False + + if key == 'cnfd': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfi_info['cnfd']): + return False + + if key == 'version': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfi_info['version']): + return False + + if key == 'device': + key_found = True + if not filter_helper.match_string(value, cnfm_cnfi_info['device']): + return False + + if not key_found: + self.log.error( + 'match_cnfm_cnfi', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_cnfis(self, object_filter=None, cnfd_info=False, plan_info=False, result_info=False, device_info=False, cache_enabled=True): + all_cnfm_cnfis = self.get_cnfm_cnfis_info(cache_enabled=cache_enabled) + if all_cnfm_cnfis is None: + return None + + cnfm_cnfis = [] + + for cnfm_cnfi_info in all_cnfm_cnfis: + if not self.match_cnfm_cnfi(cnfm_cnfi_info, object_filter): + continue + + if cnfd_info: + cnfi_cnfd_info = self.get_cnfm_cnfd( + object_filter=[ + 'name:%s' % (cnfm_cnfi_info['cnfd']), + 'version:%s' % (cnfm_cnfi_info['version']) + ], + cache_enabled=cache_enabled + ) + if cnfi_cnfd_info is None or len(cnfi_cnfd_info) != 1: + self.log.error( + 'get_cnfm_cnfis', + 'Failed to cnfd for cnfi: %s' % ( + cnfm_cnfi_info['name'] + ) + ) + cnfm_cnfi_info['cnfd'] = None + else: + cnfm_cnfi_info['cnfd'] = cnfi_cnfd_info[0] + + if plan_info: + cnfm_cnfi_info['plan'] = None + cnfm_cnfi_info['ready'] = None + + cnfm_cnfi_plan_info = self.get_cnfm_plan( + cnfm_cnfi_info['name'], + cache_enabled=cache_enabled + ) + if cnfm_cnfi_plan_info is not None: + cnfm_cnfi_info['plan'] = cnfm_cnfi_plan_info['component'] + cnfm_cnfi_info['ready'] = cnfm_cnfi_plan_info['ready'] + + cnfm_cnfi_info['isReady'] = False + if cnfm_cnfi_info['ready'] is not None: + cnfm_cnfi_info['isReady'] = True + for ready_info in cnfm_cnfi_info['ready']: + cnfm_cnfi_info['isReady'] = cnfm_cnfi_info['isReady'] and ready_info['ready'] + + if cnfm_cnfi_info['isReady']: + cnfm_cnfi_info['readyTick'] = '\u2713' + cnfm_cnfi_info['__Output']['readyTick'] = 'Green' + else: + cnfm_cnfi_info['readyTick'] = '\u2717' + cnfm_cnfi_info['__Output']['readyTick'] = 'Red' + + if result_info: + cnfm_cnfi_result = self.get_cnfm_result( + cnfm_cnfi_info['name'], + cache_enabled=cache_enabled + ) + for key in ['alive', 'aliveTick', 'k8s', 'vmi', 'pod', 'replicaset', 'deployment', 'service']: + cnfm_cnfi_info[key] = cnfm_cnfi_result[key] + + for key in cnfm_cnfi_result['__Output']: + cnfm_cnfi_info['__Output'][key] = cnfm_cnfi_result['__Output'][key] + + if device_info: + cnfm_cnfi_info['deviceTick'] = '--' + cnfm_cnfi_info['deviceSyncTick'] = '--' + if cnfm_cnfi_info['onboard']: + cnfm_cnfi_info['deviceTick'] = '\u2717' + cnfm_cnfi_info['__Output']['deviceTick'] = 'Red' + cnfm_cnfi_info['deviceSyncTick'] = '\u2717' + cnfm_cnfi_info['__Output']['deviceSyncTick'] = 'Red' + cnfm_cnfi_info['onboardDevice'] = self.get_device( + cnfm_cnfi_info['name'], + sync_info=True, + cache_enabled=cache_enabled + ) + if cnfm_cnfi_info['onboardDevice'] is not None: + cnfm_cnfi_info['deviceTick'] = '\u2713' + cnfm_cnfi_info['__Output']['deviceTick'] = 'Green' + if cnfm_cnfi_info['onboardDevice']['sync']: + cnfm_cnfi_info['deviceSyncTick'] = '\u2713' + cnfm_cnfi_info['__Output']['deviceSyncTick'] = 'Green' + + cnfm_cnfis.append( + cnfm_cnfi_info + ) + + cnfm_cnfis = sorted( + cnfm_cnfis, + key=lambda i: ( + i['namespace'], + i['name'] + ) + ) + + return cnfm_cnfis diff --git a/lib/nso/cnfm/cnfi/main.py b/lib/nso/cnfm/cnfi/main.py new file mode 100644 index 00000000..bfcea20f --- /dev/null +++ b/lib/nso/cnfm/cnfi/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.cnfi.api import NsoCnfmCnfiApi +from lib.nso.cnfm.cnfi.info import NsoCnfmCnfiInfo + + +class NsoCnfmCnfi( + NsoCnfmCnfiApi, + NsoCnfmCnfiInfo + ): + def __init__(self): + NsoCnfmCnfiApi.__init__(self) + NsoCnfmCnfiInfo.__init__(self) diff --git a/lib/nso/cnfm/cnfi/output.py b/lib/nso/cnfm/cnfi/output.py new file mode 100644 index 00000000..0d447e54 --- /dev/null +++ b/lib/nso/cnfm/cnfi/output.py @@ -0,0 +1,493 @@ +class NsoCnfmCnfiOutput(): + def __init__(self): + pass + + def print_cnfm_cnfis(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'cnfd_version', + 'device_cluster', + 'readyTick', + 'aliveTick', + 'onboardTick', + 'deviceTick', + 'deviceSyncTick' + ] + + headers = [ + 'CNF Instance', + 'CNFD', + 'Cluster', + 'Plan', + 'Result', + 'Onboard', + 'Device', + 'Sync' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_cnfm_cnfis_ready(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Instance - Ready (tailf-ncs:ready) [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'ready.type', + 'ready.name', + 'ready.status', + 'ready.age' + ] + + headers = [ + 'CNF Instance', + 'Type', + 'Name', + 'Status', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['ready'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_plan(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Instance - Plan [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = [] + for item in info: + for plan_info in item['plan']: + new_item = {} + new_item['namespace_name'] = item['namespace_name'] + for key in plan_info: + new_item[key] = plan_info[key] + new_info.append( + new_item + ) + + order = [ + 'namespace_name', + 'type', + 'name', + 'state.name', + 'state.status', + 'state.age' + ] + + headers = [ + 'CNF Instance', + 'Plan Type', + 'Plane Name', + 'State', + 'Status', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['state'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_device(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Instance - Device Onboarding [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if 'onboardDevice' not in item: + keys = [ + 'name', + 'address_port', + 'authgroup', + 'device_type', + 'ned', + 'state', + 'syncTick' + ] + item['onboardDevice'] = {} + for key in keys: + item['onboardDevice'][key] = '--' + + order = [ + 'namespace_name', + 'onboardTick', + 'onboardDevice.name', + 'onboardDevice.address_port', + 'onboardDevice.authgroup', + 'onboardDevice.device_type', + 'onboardDevice.ned', + 'onboardDevice.state', + 'onboardDevice.syncTick' + ] + + headers = [ + 'CNF Instance', + 'Onboard', + 'Device Name', + 'Address', + 'Auth', + 'Type', + 'NED', + 'State', + 'In-Sync' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True, + merge=True + ) + + def print_cnfm_cnfis_result(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Result Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'aliveTick', + 'k8s.kind', + 'k8s.summary' + ] + + headers = [ + 'CNF Instance', + 'Result', + 'Kind', + 'Summary' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['k8s'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_rs(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Result - ReplicaSet [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['replicaset']) == 0: + new_item = {} + for key in ['namespace_name', 'replicas', 'readyTick']: + new_item[key] = '--' + item['replicaset'].append( + new_item + ) + + order = [ + 'namespace_name', + 'replicaset.namespace_name', + 'replicaset.replicas', + 'replicaset.readyTick' + ] + + headers = [ + 'CNF Instance', + 'Replica Set', + 'Replicas', + 'Ready' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['replicaset'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_dep(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Result - Deployment [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['deployment']) == 0: + new_item = {} + for key in ['namespace_name', 'summary', 'readyTick']: + new_item[key] = '--' + item['deployment'].append( + new_item + ) + + order = [ + 'namespace_name', + 'deployment.namespace_name', + 'deployment.summary', + 'deployment.readyTick' + ] + + headers = [ + 'CNF Instance', + 'Deployment', + 'Replicas', + 'Ready' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['deployment'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_pod(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Result - Pod [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['pod']) == 0: + new_item = {} + for key in ['namespace_name', 'node-name', 'readyTick']: + new_item[key] = '--' + item['pod'].append( + new_item + ) + + order = [ + 'namespace_name', + 'pod.namespace_name', + 'pod.node-name', + 'pod.readyTick' + ] + + headers = [ + 'CNF Instance', + 'Pod', + 'Host', + 'Ready' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['pod'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_vmi(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Result - Virtual Machine Instance [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['vmi']) == 0: + new_item = {} + for key in ['namespace_name', 'readyTick']: + new_item[key] = '--' + item['vmi'].append( + new_item + ) + + order = [ + 'namespace_name', + 'vmi.namespace_name', + 'vmi.readyTick' + ] + + headers = [ + 'CNF Instance', + 'Virtual Machine Instance', + 'Ready' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vmi'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_cnfm_cnfis_svc(self, info, title=False): + if title: + self.my_output.default( + 'CNFM - CNF Result - Service [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if len(item['service']) == 0: + new_item = {} + for key in ['namespace_name', 'service-type', 'cluster-ip', 'ports', 'readyTick']: + new_item[key] = '--' + item['service'].append( + new_item + ) + + order = [ + 'namespace_name', + 'service.namespace_name', + 'service.service-type', + 'service.cluster-ip', + 'service.ports', + 'service.readyTick' + ] + + headers = [ + 'CNF Instance', + 'Service', + 'Type', + 'Cluster IP', + 'Port', + 'Ready' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['service'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/nso/cnfm/device/__init__.py b/lib/nso/cnfm/device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/device/api.py b/lib/nso/cnfm/device/api.py new file mode 100644 index 00000000..4738480a --- /dev/null +++ b/lib/nso/cnfm/device/api.py @@ -0,0 +1,22 @@ +class NsoCnfmDeviceApi(): + def __init__(self): + self.cnfm_device_mo = {} + + def get_cnfm_device_mo(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.cnfm_device_mo: + return self.cnfm_device_mo[device_name] + + device_config = self.get_device_config_mo( + device_name, + cache_enabled=cache_enabled + ) + if device_config is None: + self.log.error( + 'nso.get_cnfm_device_mo', + 'Failed to get device config: %s' % (device_name) + ) + return None + + self.cnfm_device_mo[device_name] = device_config + return self.cnfm_device_mo[device_name] diff --git a/lib/nso/cnfm/device/info.py b/lib/nso/cnfm/device/info.py new file mode 100644 index 00000000..577e8637 --- /dev/null +++ b/lib/nso/cnfm/device/info.py @@ -0,0 +1,192 @@ +from lib import filter_helper + + +class NsoCnfmDeviceInfo(): + def __init__(self): + self.cnfm_device = None + + def get_cnfm_device_info(self, device_name, cnfm_device_mo): + if cnfm_device_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = device_name + + info['status_code'] = [] + codes_mo = self.get( + cnfm_device_mo['core-fp-common-status-codes:status-codes'], + 'core-function-pack' + )[0] + for code_mo in codes_mo['status-code']: + info['status_code'].append( + code_mo + ) + + info['cluster'] = [] + clusters_mo = None + if 'k8s-cnfm:clusters' in cnfm_device_mo: + clusters_mo = self.get( + cnfm_device_mo['k8s-cnfm:clusters'], + 'cluster' + ) + + if clusters_mo is not None: + for cluster_mo in clusters_mo: + cluster_info = {} + cluster_info['__Output'] = {} + cluster_info['name'] = cluster_mo['name'] + cluster_config = self.get( + cluster_mo, + 'config' + ) + if cluster_config is not None: + cluster_info['type'] = 'KubeConfig' + cluster_info['access'] = None + cluster_info['namespace'] = None + + if cluster_config is None: + cluster_info['type'] = 'ServiceAccount' + cluster_info['access'] = self.get( + cluster_mo, + 'namespace-access' + ) + cluster_info['namespace'] = [] + if cluster_info['access'] == 'selective': + namespaces_mo = self.get( + cluster_mo, + 'namespace' + ) + if namespaces_mo is not None: + for namespace_mo in namespaces_mo: + cluster_info['namespace'].append( + namespace_mo['name'] + ) + + info['cluster'].append( + cluster_info + ) + + info['cluster_count'] = len(info['cluster']) + + return info + + def get_cnfm_devices_info(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_device is not None: + return self.cnfm_device + + devices = self.get_devices( + object_filter=['type:cnfm'] + ) + if devices is None: + return None + + self.cnfm_device = [] + for device in devices: + managed_object = self.get_cnfm_device_mo(device['name'], cache_enabled=cache_enabled) + if managed_object is None: + continue + + self.cnfm_device.append( + self.get_cnfm_device_info( + device['name'], + managed_object + ) + ) + + return self.cnfm_device + + def match_cnfm_device(self, cnfm_device_info, cnfm_device_filter): + if cnfm_device_filter is None or len(cnfm_device_filter) == 0: + return True + + for ap_rule in cnfm_device_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cnfm_device_info['name']): + return False + + if not key_found: + self.log.error( + 'match_cnfm_device', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_devices(self, object_filter=None, cnfi_info=False, device_info=False, cache_enabled=True): + all_cnfm_devices = self.get_cnfm_devices_info(cache_enabled=cache_enabled) + if all_cnfm_devices is None: + return None + + cnfm_devices = [] + + for cnfm_device_info in all_cnfm_devices: + if not self.match_cnfm_device(cnfm_device_info, object_filter): + continue + + cnfm_device_info['device'] = self.get_device( + cnfm_device_info['name'], + sync_info=device_info, + cache_enabled=cache_enabled + ) + + if cnfi_info: + cnfm_device_info['cnfi_count'] = 0 + cnfm_device_info['cnfi_ready'] = 0 + for cluster_info in cnfm_device_info['cluster']: + cluster_info['cnfi'] = self.get_cnfm_cnfis( + object_filter=[ + 'device:%s' % (cnfm_device_info['name']), + 'cluster:%s' % (cluster_info['name']) + ], + plan_info=True + ) + + cluster_info['cnfi_count'] = len( + cluster_info['cnfi'] + ) + cluster_info['cnfi_ready'] = 0 + for cnfd_cnfi_info in cluster_info['cnfi']: + if cnfd_cnfi_info['isReady']: + cluster_info['cnfi_ready'] = cluster_info['cnfi_ready'] + 1 + + if cluster_info['cnfi_count'] == 0: + cluster_info['cnfi_summary'] = '--' + else: + cluster_info['cnfi_summary'] = '%s/%s' % ( + cluster_info['cnfi_ready'], + cluster_info['cnfi_count'] + ) + if cluster_info['cnfi_ready'] == cluster_info['cnfi_count']: + cluster_info['__Output']['cnfi_summary'] = 'Green' + else: + cluster_info['__Output']['cnfi_summary'] = 'Red' + + cnfm_device_info['cnfi_count'] = cnfm_device_info['cnfi_count'] + cluster_info['cnfi_count'] + cnfm_device_info['cnfi_ready'] = cnfm_device_info['cnfi_ready'] + cluster_info['cnfi_ready'] + + if cnfm_device_info['cnfi_count'] == 0: + cnfm_device_info['cnfi_summary'] = '--' + else: + cnfm_device_info['cnfi_summary'] = '%s/%s' % ( + cnfm_device_info['cnfi_ready'], + cnfm_device_info['cnfi_count'] + ) + if cnfm_device_info['cnfi_ready'] == cnfm_device_info['cnfi_count']: + cnfm_device_info['__Output']['cnfi_summary'] = 'Green' + else: + cnfm_device_info['__Output']['cnfi_summary'] = 'Red' + + cnfm_devices.append( + cnfm_device_info + ) + + return cnfm_devices diff --git a/lib/nso/cnfm/device/main.py b/lib/nso/cnfm/device/main.py new file mode 100644 index 00000000..9b4cfd40 --- /dev/null +++ b/lib/nso/cnfm/device/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.device.api import NsoCnfmDeviceApi +from lib.nso.cnfm.device.info import NsoCnfmDeviceInfo + + +class NsoCnfmDevice( + NsoCnfmDeviceApi, + NsoCnfmDeviceInfo + ): + def __init__(self): + NsoCnfmDeviceApi.__init__(self) + NsoCnfmDeviceInfo.__init__(self) diff --git a/lib/nso/cnfm/device/output.py b/lib/nso/cnfm/device/output.py new file mode 100644 index 00000000..a6fe3d7a --- /dev/null +++ b/lib/nso/cnfm/device/output.py @@ -0,0 +1,113 @@ +class NsoCnfmDeviceOutput(): + def __init__(self): + pass + + def print_cnfm_state(self, info, title=False): + if title: + self.my_output.default( + 'CNFM Device - State [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'device.address_port', + 'device.authgroup', + 'device.device_type', + 'device.ned', + 'device.state', + 'device.syncTick', + 'cluster_count', + 'cnfi_summary' + ] + + headers = [ + 'Device Name', + 'Address', + 'AuthGroup', + 'Type', + 'NED', + 'State', + 'Sync', + 'Cluster', + 'Cnfi' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True, + merge=True + ) + + def print_cnfm_clusters(self, info, title=False): + if title: + self.my_output.default( + 'CNFM Device - Cluster [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + clusters = [] + for item in info: + for cluster_info in item['cluster']: + new_item = {} + new_item['cnfm'] = item['name'] + for key in cluster_info: + new_item[key] = cluster_info[key] + + if new_item['access'] is None: + new_item['access'] = '--' + + if new_item['namespace'] is None: + new_item['namespace'] = ['--'] + + clusters.append( + new_item + ) + + order = [ + 'cnfm', + 'name', + 'type', + 'access', + 'namespace', + 'cnfi_summary' + ] + + headers = [ + 'Device Name', + 'Cluster Name', + 'Type', + 'Namespace Access', + 'Namespace', + 'Cnfi' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + clusters, + order, + ['namespace'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True, + merge=True + ) diff --git a/lib/nso/cnfm/main.py b/lib/nso/cnfm/main.py new file mode 100644 index 00000000..8e465c44 --- /dev/null +++ b/lib/nso/cnfm/main.py @@ -0,0 +1,26 @@ +from lib.nso.cnfm.cluster.main import NsoCnfmCluster +from lib.nso.cnfm.cnfd.main import NsoCnfmCnfd +from lib.nso.cnfm.cnfi.main import NsoCnfmCnfi +from lib.nso.cnfm.device.main import NsoCnfmDevice +from lib.nso.cnfm.plan.main import NsoCnfmPlan +from lib.nso.cnfm.release.main import NsoCnfmRelease +from lib.nso.cnfm.result.main import NsoCnfmResult + + +class NsoCnfm( + NsoCnfmCluster, + NsoCnfmCnfd, + NsoCnfmCnfi, + NsoCnfmDevice, + NsoCnfmPlan, + NsoCnfmRelease, + NsoCnfmResult + ): + def __init__(self): + NsoCnfmCluster.__init__(self) + NsoCnfmCnfd.__init__(self) + NsoCnfmCnfi.__init__(self) + NsoCnfmDevice.__init__(self) + NsoCnfmPlan.__init__(self) + NsoCnfmRelease.__init__(self) + NsoCnfmResult.__init__(self) diff --git a/lib/nso/cnfm/output.py b/lib/nso/cnfm/output.py new file mode 100644 index 00000000..c07150ae --- /dev/null +++ b/lib/nso/cnfm/output.py @@ -0,0 +1,14 @@ +from lib.nso.cnfm.cnfd.output import NsoCnfmCnfdOutput +from lib.nso.cnfm.cnfi.output import NsoCnfmCnfiOutput +from lib.nso.cnfm.device.output import NsoCnfmDeviceOutput + + +class NsoCnfmOutput( + NsoCnfmCnfdOutput, + NsoCnfmCnfiOutput, + NsoCnfmDeviceOutput + ): + def __init__(self): + NsoCnfmCnfdOutput.__init__(self) + NsoCnfmCnfiOutput.__init__(self) + NsoCnfmDeviceOutput.__init__(self) diff --git a/lib/nso/cnfm/plan/__init__.py b/lib/nso/cnfm/plan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/plan/api.py b/lib/nso/cnfm/plan/api.py new file mode 100644 index 00000000..d61a4db9 --- /dev/null +++ b/lib/nso/cnfm/plan/api.py @@ -0,0 +1,52 @@ +import time + + +class NsoCnfmPlanApi(): + def __init__(self): + self.cnfm_plan_mo = None + + def get_cnfm_plan_mo(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_plan_mo is not None: + return self.cnfm_plan_mo + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data/cisco-cnf-descriptor:cnf/cisco-cnfo:cnf-plan' + ) + self.log.nso( + 'get', + 'cnf-plan', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'cnf-plan', + success, + int(time.time() * 1000) - start_time + ) + + if not success: + self.log.error( + 'nso.get_cnfm_plan_mo', + 'Failed to get plan' + ) + return None + + self.cnfm_plan_mo = content['cisco-cnfo:cnf-plan'] + + self.log.nso_mo( + 'cnf-plan', + self.cnfm_plan_mo + ) + + return self.cnfm_plan_mo diff --git a/lib/nso/cnfm/plan/info.py b/lib/nso/cnfm/plan/info.py new file mode 100644 index 00000000..25be23f9 --- /dev/null +++ b/lib/nso/cnfm/plan/info.py @@ -0,0 +1,193 @@ +from lib import filter_helper + + +class NsoCnfmPlanInfo(): + def __init__(self): + self.cnfm_plan = None + + def get_cnfm_plan_info(self, cnfm_plan_mo): + if cnfm_plan_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = self.get( + cnfm_plan_mo, + 'name' + ) + + info['component'] = [] + components_mo = self.get( + cnfm_plan_mo, + 'plan:component', + on_error=[], + on_none=[] + ) + for component_mo in components_mo: + component_info = {} + component_info['type'] = self.get( + component_mo, + 'type' + ) + component_info['name'] = self.get( + component_mo, + 'name' + ) + component_info['back_track'] = self.get( + component_mo, + 'back-track' + ) + + component_info['state'] = [] + component_states_mo = self.get( + component_mo, + 'state', + on_error=[], + on_none=[] + ) + for component_state_mo in component_states_mo: + component_state_info = {} + component_state_info['__Output'] = {} + component_state_info['name'] = self.get( + component_state_mo, + 'name' + ) + component_state_info['status'] = self.get( + component_state_mo, + 'status' + ) + if component_state_info['status'] == 'reached': + component_state_info['__Output']['status'] = 'Green' + else: + component_state_info['__Output']['status'] = 'Red' + + component_state_info['when'] = self.get( + component_state_mo, + 'when' + ) + component_state_info['age'] = self.convert_timestamp_to_age( + component_state_info['when'], + on_error='--' + ) + component_state_info['pre-conditions'] = self.get( + component_state_mo, + 'pre', + on_error={}, + on_none={} + ) + component_state_info['post-actions'] = self.get( + component_state_mo, + 'post', + on_error={}, + on_none={} + ) + component_info['state'].append( + component_state_info + ) + + info['component'].append( + component_info + ) + + info['ready'] = [] + for component_info in info['component']: + ready_info = {} + ready_info['__Output'] = {} + + for key in ['name', 'type', 'back_track']: + ready_info[key] = component_info[key] + + for component_state_info in component_info['state']: + if component_state_info['name'] == 'tailf-ncs:ready': + ready_info['status'] = component_state_info['status'] + ready_info['age'] = component_state_info['age'] + ready_info['when'] = self.get( + component_state_info, + 'when' + ) + ready_info['__Output']['status'] = 'Red' + ready_info['ready'] = False + if ready_info['status'] == 'reached': + ready_info['__Output']['status'] = 'Green' + ready_info['ready'] = True + + break + + info['ready'].append( + ready_info + ) + + return info + + def get_cnfm_plans_info(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_plan is not None: + return self.cnfm_plan + + managed_objects = self.get_cnfm_plan_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cnfm_plan = [] + for managed_object in managed_objects: + cnfm_plan_info = self.get_cnfm_plan_info( + managed_object + ) + self.cnfm_plan.append( + cnfm_plan_info + ) + + return self.cnfm_plan + + def match_cnfm_plan(self, cnfm_plan_info, cnfm_plan_filter): + if cnfm_plan_filter is None or len(cnfm_plan_filter) == 0: + return True + + for ap_rule in cnfm_plan_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cnfm_plan_info['name']): + return False + + if not key_found: + self.log.error( + 'match_cnfm_plan', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_plans(self, object_filter=None, cache_enabled=True): + all_cnfm_plans = self.get_cnfm_plans_info(cache_enabled=cache_enabled) + if all_cnfm_plans is None: + return None + + cnfm_plans = [] + + for cnfm_plan_info in all_cnfm_plans: + if not self.match_cnfm_plan(cnfm_plan_info, object_filter): + continue + + cnfm_plans.append( + cnfm_plan_info + ) + + return cnfm_plans + + def get_cnfm_plan(self, cnfm_instance_name, cache_enabled=True): + plans = self.get_cnfm_plans( + object_filter=[ + 'name:%s' % (cnfm_instance_name) + ], + cache_enabled=cache_enabled + ) + if plans is None or len(plans) != 1: + return None + + return plans[0] diff --git a/lib/nso/cnfm/plan/main.py b/lib/nso/cnfm/plan/main.py new file mode 100644 index 00000000..e93a2f4c --- /dev/null +++ b/lib/nso/cnfm/plan/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.plan.api import NsoCnfmPlanApi +from lib.nso.cnfm.plan.info import NsoCnfmPlanInfo + + +class NsoCnfmPlan( + NsoCnfmPlanApi, + NsoCnfmPlanInfo + ): + def __init__(self): + NsoCnfmPlanApi.__init__(self) + NsoCnfmPlanInfo.__init__(self) diff --git a/lib/nso/cnfm/release/__init__.py b/lib/nso/cnfm/release/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/release/api.py b/lib/nso/cnfm/release/api.py new file mode 100644 index 00000000..1b183206 --- /dev/null +++ b/lib/nso/cnfm/release/api.py @@ -0,0 +1,22 @@ +class NsoCnfmReleaseApi(): + def __init__(self): + self.cnfm_release_mo = {} + + def get_cnfm_release_mo(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.cnfm_release_mo: + return self.cnfm_release_mo[device_name] + + device_config = self.get_device_config_mo( + device_name, + cache_enabled=cache_enabled + ) + if device_config is None: + self.log.error( + 'nso.get_cnfm_release_mo', + 'Failed to get device config: %s' % (device_name) + ) + return None + + self.cnfm_release_mo[device_name] = device_config['k8s-cnfm:cnf']['release'] + return self.cnfm_release_mo[device_name] diff --git a/lib/nso/cnfm/release/info.py b/lib/nso/cnfm/release/info.py new file mode 100644 index 00000000..f741db72 --- /dev/null +++ b/lib/nso/cnfm/release/info.py @@ -0,0 +1,105 @@ +from lib import filter_helper + + +class NsoCnfmReleaseInfo(): + def __init__(self): + self.cnfm_release = {} + + def get_cnfm_release_info(self, cnfm_release_mo): + if cnfm_release_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['cluster'] = self.get( + cnfm_release_mo, + 'cluster' + ) + + info['namespace'] = self.get( + cnfm_release_mo, + 'namespace' + ) + + info['name'] = self.get( + cnfm_release_mo, + 'name' + ) + + info['chart'] = self.get( + cnfm_release_mo, + 'chart-name' + ) + + info['version'] = self.get( + cnfm_release_mo, + 'chart-version' + ) + + info['values'] = self.get( + cnfm_release_mo, + 'values:key-value' + ) + + return info + + def get_cnfm_releases_info(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.cnfm_release: + return self.cnfm_release[device_name] + + managed_objects = self.get_cnfm_release_mo(device_name, cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cnfm_release[device_name] = [] + for managed_object in managed_objects: + cnfm_release_info = self.get_cnfm_release_info( + managed_object + ) + self.cnfm_release[device_name].append( + cnfm_release_info + ) + + return self.cnfm_release[device_name] + + def match_cnfm_release(self, cnfm_release_info, cnfm_release_filter): + if cnfm_release_filter is None or len(cnfm_release_filter) == 0: + return True + + for ap_rule in cnfm_release_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cnfm_release_info['name']): + return False + + if not key_found: + self.log.error( + 'match_cnfm_release', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_releases(self, device_name, object_filter=None, cache_enabled=True): + all_cnfm_releases = self.get_cnfm_releases_info(device_name, cache_enabled=cache_enabled) + if all_cnfm_releases is None: + return None + + cnfm_releases = [] + + for cnfm_release_info in all_cnfm_releases: + if not self.match_cnfm_release(cnfm_release_info, object_filter): + continue + + cnfm_releases.append( + cnfm_release_info + ) + + return cnfm_releases diff --git a/lib/nso/cnfm/release/main.py b/lib/nso/cnfm/release/main.py new file mode 100644 index 00000000..00bd1419 --- /dev/null +++ b/lib/nso/cnfm/release/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.release.api import NsoCnfmReleaseApi +from lib.nso.cnfm.release.info import NsoCnfmReleaseInfo + + +class NsoCnfmRelease( + NsoCnfmReleaseApi, + NsoCnfmReleaseInfo + ): + def __init__(self): + NsoCnfmReleaseApi.__init__(self) + NsoCnfmReleaseInfo.__init__(self) diff --git a/lib/nso/cnfm/result/__init__.py b/lib/nso/cnfm/result/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/cnfm/result/api.py b/lib/nso/cnfm/result/api.py new file mode 100644 index 00000000..66e2bbaf --- /dev/null +++ b/lib/nso/cnfm/result/api.py @@ -0,0 +1,52 @@ +import time + + +class NsoCnfmResultApi(): + def __init__(self): + self.cnfm_result_mo = None + + def get_cnfm_result_mo(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_result_mo is not None: + return self.cnfm_result_mo + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data/cisco-cnf-descriptor:cnf/cisco-cnfo:cnf-result' + ) + self.log.nso( + 'get', + 'cnf-result', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'cnf-result', + success, + int(time.time() * 1000) - start_time + ) + + if not success: + self.log.error( + 'nso.get_cnfm_result_mo', + 'Failed to get result' + ) + return None + + self.cnfm_result_mo = content['cisco-cnfo:cnf-result'] + + self.log.nso_mo( + 'cnf-result', + self.cnfm_result_mo + ) + + return self.cnfm_result_mo diff --git a/lib/nso/cnfm/result/info.py b/lib/nso/cnfm/result/info.py new file mode 100644 index 00000000..6b946297 --- /dev/null +++ b/lib/nso/cnfm/result/info.py @@ -0,0 +1,580 @@ +from lib import filter_helper + + +class NsoCnfmResultInfo(): + def __init__(self): + self.cnfm_result = None + + def get_cnfm_result_vmi_info(self, info, cnfm_result_mo): + vmis_mo = self.get( + cnfm_result_mo, + 'virtualmachineinstance', + on_error=[], + on_none=[] + ) + + info['vmi'] = [] + vmi_ready = 0 + for vmi_mo in vmis_mo: + vmi_info = {} + vmi_info['__Output'] = {} + vmi_info['namespace'] = vmi_mo['namespace'] + vmi_info['name'] = vmi_mo['name'] + vmi_info['namespace_name'] = '%s/%s' % ( + vmi_info['namespace'], + vmi_info['name'] + ) + vmi_info['status'] = vmi_mo['status'] + vmi_info['labels'] = vmi_mo['labels'] + vmi_info['selector'] = vmi_mo['selector'] + for key in ['replicas']: + vmi_info[key] = vmi_mo[key] + + if vmi_info['status'] == 'alive': + vmi_info['ready'] = True + vmi_info['readyTick'] = '\u2713' + vmi_info['__Output']['readyTick'] = 'Green' + vmi_ready = vmi_ready + 1 + else: + vmi_info['ready'] = False + vmi_info['readyTick'] = '\u2717' + vmi_info['__Output']['readyTick'] = 'Red' + + info['vmi'].append( + vmi_info + ) + + found = False + for k8s_info in info['k8s']: + if k8s_info['kind'] == 'VirtualMachineInstance': + found = True + if len(info['vmi']) != k8s_info['desired']: + self.log.error( + 'get_cnfm_result_info', + 'Unexpected vmi desired value' + ) + + if not found: + k8s_info = {} + k8s_info['__Output'] = {} + k8s_info['kind'] = 'VirtualMachineInstance' + k8s_info['desired'] = len(info['vmi']) + k8s_info['available'] = vmi_ready + if k8s_info['desired'] == 0: + k8s_info['summary'] = '--' + else: + k8s_info['summary'] = '%s/%s' % ( + k8s_info['desired'], + k8s_info['available'] + ) + + if k8s_info['desired'] == k8s_info['available']: + k8s_info['__Output']['summary'] = 'Green' + else: + k8s_info['__Output']['summary'] = 'Red' + + info['k8s'].append( + k8s_info + ) + + return info + + def get_cnfm_result_pod_info(self, info, cnfm_result_mo): + pods_mo = self.get( + cnfm_result_mo, + 'pod', + on_error=[], + on_none=[] + ) + + info['pod'] = [] + pod_ready = 0 + for pod_mo in pods_mo: + pod_info = {} + pod_info['__Output'] = {} + pod_info['namespace'] = pod_mo['namespace'] + pod_info['name'] = pod_mo['name'] + pod_info['namespace_name'] = '%s/%s' % ( + pod_info['namespace'], + pod_info['name'] + ) + pod_info['status'] = pod_mo['status'] + pod_info['labels'] = pod_mo['labels'] + for key in ['ip', 'host-ip', 'node-name', 'deployment', 'replica', 'container', 'selector']: + pod_info[key] = None + if key in pod_mo: + pod_info[key] = pod_mo[key] + + if pod_info['status'] == 'alive': + pod_info['ready'] = True + pod_info['readyTick'] = '\u2713' + pod_info['__Output']['readyTick'] = 'Green' + pod_ready = pod_ready + 1 + else: + pod_info['ready'] = False + pod_info['readyTick'] = '\u2717' + pod_info['__Output']['readyTick'] = 'Red' + + info['pod'].append( + pod_info + ) + + found = False + for k8s_info in info['k8s']: + if k8s_info['kind'] == 'Pod': + found = True + if len(info['pod']) != k8s_info['desired']: + self.log.error( + 'get_cnfm_result_info', + 'Unexpected pod desired value' + ) + + if not found: + k8s_info = {} + k8s_info['__Output'] = {} + k8s_info['kind'] = 'Pod' + k8s_info['desired'] = len(info['pod']) + k8s_info['available'] = pod_ready + if k8s_info['desired'] == 0: + k8s_info['summary'] = '--' + else: + k8s_info['summary'] = '%s/%s' % ( + k8s_info['desired'], + k8s_info['available'] + ) + + if k8s_info['desired'] == k8s_info['available']: + k8s_info['__Output']['summary'] = 'Green' + else: + k8s_info['__Output']['summary'] = 'Red' + + info['k8s'].append( + k8s_info + ) + + return info + + def get_cnfm_result_replicaset_info(self, info, cnfm_result_mo): + replicasets_mo = self.get( + cnfm_result_mo, + 'replicaset', + on_error=[], + on_none=[] + ) + + info['replicaset'] = [] + replicaset_ready = 0 + for replicaset_mo in replicasets_mo: + replicaset_info = {} + replicaset_info['__Output'] = {} + replicaset_info['namespace'] = replicaset_mo['namespace'] + replicaset_info['name'] = replicaset_mo['name'] + replicaset_info['namespace_name'] = '%s/%s' % ( + replicaset_info['namespace'], + replicaset_info['name'] + ) + replicaset_info['status'] = replicaset_mo['status'] + replicaset_info['labels'] = replicaset_mo['labels'] + replicaset_info['selector'] = replicaset_mo['selector'] + for key in ['replicas']: + replicaset_info[key] = replicaset_mo[key] + + if replicaset_info['status'] == 'alive': + replicaset_info['ready'] = True + replicaset_info['readyTick'] = '\u2713' + replicaset_info['__Output']['readyTick'] = 'Green' + replicaset_ready = replicaset_ready + 1 + else: + replicaset_info['ready'] = False + replicaset_info['readyTick'] = '\u2717' + replicaset_info['__Output']['readyTick'] = 'Red' + + info['replicaset'].append( + replicaset_info + ) + + found = False + for k8s_info in info['k8s']: + if k8s_info['kind'] == 'ReplicaSet': + found = True + if len(info['replicaset']) != k8s_info['desired']: + self.log.error( + 'get_cnfm_result_info', + 'Unexpected replicaset desired value' + ) + + if not found: + k8s_info = {} + k8s_info['__Output'] = {} + k8s_info['kind'] = 'ReplicaSet' + k8s_info['desired'] = len(info['replicaset']) + k8s_info['available'] = replicaset_ready + if k8s_info['desired'] == 0: + k8s_info['summary'] = '--' + else: + k8s_info['summary'] = '%s/%s' % ( + k8s_info['desired'], + k8s_info['available'] + ) + + if k8s_info['desired'] == k8s_info['available']: + k8s_info['__Output']['summary'] = 'Green' + else: + k8s_info['__Output']['summary'] = 'Red' + + info['k8s'].append( + k8s_info + ) + + return info + + def get_cnfm_result_deployment_info(self, info, cnfm_result_mo): + deployments_mo = self.get( + cnfm_result_mo, + 'deployment', + on_error=[], + on_none=[] + ) + + info['deployment'] = [] + deployment_ready = 0 + for deployment_mo in deployments_mo: + deployment_info = {} + deployment_info['__Output'] = {} + deployment_info['namespace'] = deployment_mo['namespace'] + deployment_info['name'] = deployment_mo['name'] + deployment_info['namespace_name'] = '%s/%s' % ( + deployment_info['namespace'], + deployment_info['name'] + ) + deployment_info['status'] = deployment_mo['status'] + deployment_info['labels'] = deployment_mo['labels'] + deployment_info['selector'] = deployment_mo['selector'] + for key in ['replicas', 'updated-replicas', 'available-replicas', 'ready-replicas', 'unavailable-replicas']: + deployment_info[key] = deployment_mo[key] + + deployment_info['summary'] = '%s/%s' % ( + deployment_info['replicas'], + deployment_info['ready-replicas'] + ) + if deployment_info['replicas'] == deployment_info['ready-replicas']: + deployment_info['ready'] = True + deployment_info['readyTick'] = '\u2713' + deployment_info['__Output']['readyTick'] = 'Green' + deployment_info['__Output']['summary'] = 'Green' + deployment_ready = deployment_ready + 1 + else: + deployment_info['ready'] = False + deployment_info['readyTick'] = '\u2717' + deployment_info['__Output']['readyTick'] = 'Red' + deployment_info['__Output']['summary'] = 'Red' + + info['deployment'].append( + deployment_info + ) + + found = False + for k8s_info in info['k8s']: + if k8s_info['kind'] == 'Deployment': + found = True + if len(info['deployment']) != k8s_info['desired']: + self.log.error( + 'get_cnfm_result_info', + 'Unexpected deployment desired value' + ) + + if not found: + k8s_info = {} + k8s_info['__Output'] = {} + k8s_info['kind'] = 'Deployment' + k8s_info['desired'] = len(info['deployment']) + k8s_info['available'] = deployment_ready + if k8s_info['desired'] == 0: + k8s_info['summary'] = '--' + else: + k8s_info['summary'] = '%s/%s' % ( + k8s_info['desired'], + k8s_info['available'] + ) + + if k8s_info['desired'] == k8s_info['available']: + k8s_info['__Output']['summary'] = 'Green' + else: + k8s_info['__Output']['summary'] = 'Red' + + info['k8s'].append( + k8s_info + ) + + return info + + def get_cnfm_result_service_info(self, info, cnfm_result_mo): + services_mo = self.get( + cnfm_result_mo, + 'service', + on_error=[], + on_none=[] + ) + + info['service'] = [] + service_ready = 0 + for service_mo in services_mo: + service_info = {} + service_info['__Output'] = {} + service_info['namespace'] = service_mo['namespace'] + service_info['name'] = service_mo['name'] + service_info['namespace_name'] = '%s/%s' % ( + service_info['namespace'], + service_info['name'] + ) + service_info['status'] = service_mo['status'] + service_info['labels'] = service_mo['labels'] + service_info['selector'] = service_mo['selector'] + for key in ['service-type', 'cluster-ip', 'port']: + service_info[key] = service_mo[key] + + port_descriptions = [] + for port in service_info['port']: + if service_info['service-type'] == 'NodePort': + port['description'] = '%s:%s/%s' % ( + port['port'], + port['node-port'], + port['protocol'] + ) + if 'name' in port: + port['description'] = '%s (%s)' % ( + port['description'], + port['name'] + ) + + if service_info['service-type'] != 'NodePort': + port['description'] = '%s/%s' % ( + port['port'], + port['protocol'] + ) + if 'name' in port: + port['description'] = '%s (%s)' % ( + port['description'], + port['name'] + ) + + port_descriptions.append( + port['description'] + ) + + service_info['ports'] = ','.join(port_descriptions) + + if service_info['status'] == 'alive': + service_info['ready'] = True + service_info['readyTick'] = '\u2713' + service_info['__Output']['readyTick'] = 'Green' + service_ready = service_ready + 1 + else: + service_info['ready'] = False + service_info['readyTick'] = '\u2717' + service_info['__Output']['readyTick'] = 'Red' + + info['service'].append( + service_info + ) + + found = False + for k8s_info in info['k8s']: + if k8s_info['kind'] == 'Service': + found = True + if len(info['service']) != k8s_info['desired']: + self.log.error( + 'get_cnfm_result_info', + 'Unexpected service desired value' + ) + + if not found: + k8s_info = {} + k8s_info['__Output'] = {} + k8s_info['kind'] = 'Service' + k8s_info['desired'] = len(info['service']) + k8s_info['available'] = service_ready + if k8s_info['desired'] == 0: + k8s_info['summary'] = '--' + else: + k8s_info['summary'] = '%s/%s' % ( + k8s_info['desired'], + k8s_info['available'] + ) + + if k8s_info['desired'] == k8s_info['available']: + k8s_info['__Output']['summary'] = 'Green' + else: + k8s_info['__Output']['summary'] = 'Red' + + info['k8s'].append( + k8s_info + ) + + return info + + def get_cnfm_result_k8s_info(self, info, cnfm_result_mo): + info['k8s'] = [] + + objects_mo = self.get( + cnfm_result_mo, + 'k8s-objects:kind', + on_error=[], + on_none=[] + ) + for object_mo in objects_mo: + k8s_info = {} + k8s_info['__Output'] = {} + k8s_info['kind'] = object_mo['name'] + k8s_info['desired'] = object_mo['desired-count'] + k8s_info['available'] = object_mo['available-count'] + if k8s_info['desired'] == 0: + k8s_info['summary'] = '--' + else: + k8s_info['summary'] = '%s/%s' % ( + k8s_info['desired'], + k8s_info['available'] + ) + + if k8s_info['desired'] == k8s_info['available']: + k8s_info['__Output']['summary'] = 'Green' + else: + k8s_info['__Output']['summary'] = 'Red' + + info['k8s'].append( + k8s_info + ) + + info = self.get_cnfm_result_vmi_info( + info, + cnfm_result_mo + ) + + info = self.get_cnfm_result_pod_info( + info, + cnfm_result_mo + ) + + info = self.get_cnfm_result_replicaset_info( + info, + cnfm_result_mo + ) + + info = self.get_cnfm_result_deployment_info( + info, + cnfm_result_mo + ) + + info = self.get_cnfm_result_service_info( + info, + cnfm_result_mo + ) + + info['k8s'] = sorted( + info['k8s'], + key=lambda i: i['kind'] + ) + + return info + + def get_cnfm_result_info(self, cnfm_result_mo): + if cnfm_result_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = self.get( + cnfm_result_mo, + 'name' + ) + + info['alive'] = self.get( + cnfm_result_mo, + 'state:status' + ) + if info['alive'] == 'alive': + info['aliveTick'] = '\u2713' + info['__Output']['aliveTick'] = 'Green' + else: + info['aliveTick'] = '\u2717' + info['__Output']['aliveTick'] = 'Red' + + info = self.get_cnfm_result_k8s_info( + info, + cnfm_result_mo + ) + + return info + + def get_cnfm_results_info(self, cache_enabled=True): + if cache_enabled: + if self.cnfm_result is not None: + return self.cnfm_result + + managed_objects = self.get_cnfm_result_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.cnfm_result = [] + for managed_object in managed_objects: + cnfm_result_info = self.get_cnfm_result_info( + managed_object + ) + self.cnfm_result.append( + cnfm_result_info + ) + + return self.cnfm_result + + def match_cnfm_result(self, cnfm_result_info, cnfm_result_filter): + if cnfm_result_info is None or len(cnfm_result_filter) == 0: + return True + + for ap_rule in cnfm_result_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cnfm_result_info['name']): + return False + + if not key_found: + self.log.error( + 'match_cnfm_result', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_cnfm_results(self, object_filter=None, cache_enabled=True): + all_cnfm_results = self.get_cnfm_results_info(cache_enabled=cache_enabled) + if all_cnfm_results is None: + return None + + cnfm_results = [] + + for cnfm_result_info in all_cnfm_results: + if not self.match_cnfm_result(cnfm_result_info, object_filter): + continue + + cnfm_results.append( + cnfm_result_info + ) + + return cnfm_results + + def get_cnfm_result(self, cnfm_cnfi_name, cache_enabled=True): + cnfm_results = self.get_cnfm_results( + object_filter=[ + 'name:%s' % (cnfm_cnfi_name), + ], + cache_enabled=cache_enabled + ) + if cnfm_results is None or len(cnfm_results) != 1: + return None + + return cnfm_results[0] diff --git a/lib/nso/cnfm/result/main.py b/lib/nso/cnfm/result/main.py new file mode 100644 index 00000000..c647284c --- /dev/null +++ b/lib/nso/cnfm/result/main.py @@ -0,0 +1,11 @@ +from lib.nso.cnfm.result.api import NsoCnfmResultApi +from lib.nso.cnfm.result.info import NsoCnfmResultInfo + + +class NsoCnfmResult( + NsoCnfmResultApi, + NsoCnfmResultInfo + ): + def __init__(self): + NsoCnfmResultApi.__init__(self) + NsoCnfmResultInfo.__init__(self) diff --git a/lib/nso/cnfm/todo.md b/lib/nso/cnfm/todo.md new file mode 100644 index 00000000..7c806c33 --- /dev/null +++ b/lib/nso/cnfm/todo.md @@ -0,0 +1,70 @@ +create ocp vm + support day0 with cm + +get helm + chart + release + support day0 with cm + +get nso + cnfm + -v state (def) + add k8s events tick notifications + change cluster count to cluster names + maybe remove cnfi count as it is cluster specific + -v notification (incl live)? + -v k8s (pod, service state, pvc) + -v ... (how cnfm has been started - helm chart values) + -v ... local chart list + -v ... logs incl. live? + + chart + -v list (def) - based on the option of either local cnfm or proper repository + -v ... - get the values, helm details, test options i.e. how would the files look if they were deployed with def values or user-defined values + -v ... - timestamps of files (?) + -v ... - compare two charts, one of them can be local filesystem + create/set/delete commands + + cluster + -v state (def) for configuration and state + incl. mapping to locally defined k8s clusters (?) + -v ... k8s-objects + -v cnfi + -v notification (incl live)? + + cnfd + -v state (def) list + check display with external repos + check display with multiple chart versions + cnf instance count must be version specific + info (tick) about device(s) onboarding - not sure if tick or some details about device(s) + -v ... list of values + a way to show if these are all values or subset + -v ... + + cnfi + -v ... kubernetes state + -v ... helm state + -v ... nso state + -v ... device state + -v ... values (mark what was differnet from default cnfd values)? + -v notification (incl live)? + -v logs incl live? + + device + + vnfd + + vnfi + + nsd + + nsi + + package + +ocp + migrate + image => pvc + vnfd => cnfm (???) + openstack vm => vm/vmi yaml + vm migration (as for orange) \ No newline at end of file diff --git a/lib/nso/common.py b/lib/nso/common.py new file mode 100644 index 00000000..11a4bf8a --- /dev/null +++ b/lib/nso/common.py @@ -0,0 +1,107 @@ +import time +import datetime + + +class NsoCommon(): + def __init__(self): + pass + + def _get(self, value, key): + if value is None: + return '__ERROR' + + if ':' in key: + subkey = key.split(':')[0] + if subkey not in value: + return '__ERROR' + + new_key = ':'.join(key.split(':')[1:]) + return self._get(value[subkey], new_key) + + if key in value: + return value[key] + + return '__ERROR' + + def get(self, managed_object, key, on_error=None, on_none=None): + if managed_object is None: + return on_error + + if not isinstance(managed_object, dict): + return on_error + + value = self._get(managed_object, key) + if value == '__ERROR': + return on_error + + if value is None: + return on_none + + return value + + def convert_age(self, seconds): + if seconds > 60 * 60 * 24: + return '%sd' % (int(seconds / (60 * 60 * 24))) + + if seconds > 60 * 60: + hours = 0 + while True: + if seconds < 60 * 60: + break + + hours = hours + 1 + seconds = seconds - 60 * 60 + + return '%sh%sm' % ( + hours, + int(seconds / 60) + ) + + if seconds > 60: + return '%sm' % (int(seconds / 60)) + + return '%ss' % (seconds) + + def convert_timestamp(self, timestamp): + if timestamp is None: + return None + + new_timestamp = None + if isinstance(timestamp, str): + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f%z').timetuple())) + except BaseException: + pass + + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S%z').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp.rstrip('Z'), '%Y-%m-%dT%H:%M:%S').timetuple())) + except BaseException: + pass + + return new_timestamp + + try: + new_timestamp = int(timestamp.timestamp()) + except BaseException: + pass + + return new_timestamp + + def convert_timestamp_to_age(self, timestamp, on_error=None): + timestamp = self.convert_timestamp(timestamp) + if timestamp is None: + return on_error + + return self.convert_age(int(time.time()) - timestamp) diff --git a/lib/nso/device/__init__.py b/lib/nso/device/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/device/api.py b/lib/nso/device/api.py new file mode 100644 index 00000000..a027a92a --- /dev/null +++ b/lib/nso/device/api.py @@ -0,0 +1,154 @@ +import time +import traceback + + +class NsoDeviceApi(): + def __init__(self): + self.device_base_mo = None + self.device_sync_mo = {} + self.device_config_mo = {} + + def get_device_base_mo(self, cache_enabled=True): + if cache_enabled: + if self.device_base_mo is not None: + return self.device_base_mo + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data/tailf-ncs:devices/device', + 'fields=name;address;port;authgroup;device-type;state/admin-state' + ) + self.log.nso( + 'get', + 'device_base', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'device_base', + success, + int(time.time() * 1000) - start_time + ) + + if not success or content is None: + self.log.error( + 'nso.get_device_base_mo', + 'Failed to get device list' + ) + return None + + self.device_base_mo = content['tailf-ncs:device'] + + self.log.nso_mo( + 'device_base', + self.device_base_mo + ) + + return self.device_base_mo + + def get_device_sync_mo(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.device_sync_mo: + return self.device_sync_mo[device_name] + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.post_rest( + 'xml', + None, + 'Content-Type', + 'application/yang-data', + None, + path='data/tailf-ncs:devices/device=%s/check-sync' % (device_name) + ) + self.log.nso( + 'get', + 'device_sync', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'device_sync', + success, + int(time.time() * 1000) - start_time + ) + self.log.error( + 'get_device_sync_mo', + traceback.format_exc() + ) + + if not success: + self.log.error( + 'nso.get_device_sync', + 'Failed to get device sync state: %s' % (device_name) + ) + return None + + self.device_sync_mo[device_name] = content + + self.log.nso_mo( + 'device_sync_mo.%s' % (device_name), + self.device_sync_mo[device_name] + ) + + return self.device_sync_mo[device_name] + + def get_device_config_mo(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.device_config_mo: + return self.device_config_mo[device_name] + + try: + start_time = int(time.time() * 1000) + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data/tailf-ncs:devices/device=%s/config' % (device_name) + ) + + self.log.nso( + 'get', + 'device_config', + success, + int(time.time() * 1000) - start_time + ) + + except BaseException: + success = False + self.log.nso( + 'get', + 'device_config', + success, + int(time.time() * 1000) - start_time + ) + + if not success: + self.log.error( + 'nso.get device_config', + 'Failed to get device config: %s' % (device_name) + ) + return None + + self.device_config_mo[device_name] = content['tailf-ncs:config'] + + self.log.nso_mo( + 'device_config.%s' % (device_name), + self.device_config_mo[device_name] + ) + + return self.device_config_mo[device_name] diff --git a/lib/nso/device/info.py b/lib/nso/device/info.py new file mode 100644 index 00000000..5e27880a --- /dev/null +++ b/lib/nso/device/info.py @@ -0,0 +1,218 @@ +from lib import filter_helper + + +class NsoDeviceInfo(): + def __init__(self): + self.nso_device_base = None + self.nso_device_sync = {} + + def get_device_base_info(self, nso_device_mo): + if nso_device_mo is None: + return None + + info = {} + info['__Output'] = {} + + info['name'] = self.get( + nso_device_mo, + 'name' + ) + + info['address'] = self.get( + nso_device_mo, + 'address' + ) + + info['port'] = self.get( + nso_device_mo, + 'port' + ) + + info['address_port'] = '%s:%s' % ( + info['address'], + info['port'] + ) + + info['authgroup'] = self.get( + nso_device_mo, + 'authgroup' + ) + + device_type = info['ned-id'] = self.get( + nso_device_mo, + 'device-type' + ) + info['ned_type'] = None + info['ned_id'] = None + if 'cli' in device_type: + info['ned_type'] = 'cli' + info['ned_id'] = self.get( + nso_device_mo, + 'device-type:cli:ned-id' + ) + + if 'generic' in device_type: + info['ned_type'] = 'generic' + info['ned_id'] = self.get( + nso_device_mo, + 'device-type:generic:ned-id' + ) + if 'netconf' in device_type: + info['ned_type'] = 'netconf' + info['ned_id'] = self.get( + nso_device_mo, + 'device-type:netconf:ned-id' + ) + + if info['ned_id'] is not None: + if len(info['ned_id'].split(':')) == 2: + if info['ned_id'].split(':')[0] == info['ned_id'].split(':')[1]: + info['ned_id'] = info['ned_id'].split(':')[0] + + info['ned'] = None + if info['ned_type'] is not None and info['ned_id'] is not None: + info['ned'] = '%s:%s' % ( + info['ned_type'], + info['ned_id'] + ) + + info['device_type'] = None + if info['ned_id'].startswith('cisco-apicdc'): + info['device_type'] = 'APIC' + + if info['ned_id'].startswith('cisco-iosxr'): + info['device_type'] = 'IOS-XR' + + if info['ned_id'].startswith('cisco-ios-'): + info['device_type'] = 'IOS-XE' + + if info['ned_id'].startswith('cnfm-nc-'): + info['device_type'] = 'CNFM' + + if info['ned_id'].startswith('openstack-'): + info['device_type'] = 'OpenStack' + + if info['ned_id'].startswith('etsi-sol003-'): + info['device_type'] = 'VNFM ETSI' + + if info['ned_id'].startswith('tailf-ned-esc-'): + info['device_type'] = 'VNFM ESC' + + if info['ned_id'].startswith('juniper-junos'): + info['device_type'] = 'Junos' + + info['state'] = self.get( + nso_device_mo, + 'state:admin-state' + ) + + if info['state'] == 'unlocked': + info['__Output']['state'] = 'Green' + else: + info['__Output']['state'] = 'Red' + + return info + + def get_devices_base_info(self, cache_enabled=True): + if cache_enabled: + if self.nso_device_base is not None: + return self.nso_device_base + + managed_objects = self.get_device_base_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.nso_device_base = [] + for managed_object in managed_objects: + nso_device_base_info = self.get_device_base_info( + managed_object + ) + self.nso_device_base.append( + nso_device_base_info + ) + + return self.nso_device_base + + def match_device(self, device_base_info, device_base_filter): + if device_base_filter is None or len(device_base_filter) == 0: + return True + + for ap_rule in device_base_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, device_base_info['name']): + return False + + if key == 'type': + key_found = True + if not filter_helper.match_string(value, device_base_info['device_type']): + return False + + if not key_found: + self.log.error( + 'match_device_base', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_devices(self, object_filter=None, sync_info=False, cache_enabled=True): + all_devices = self.get_devices_base_info(cache_enabled=cache_enabled) + if all_devices is None: + return None + + devices = [] + + for device_info in all_devices: + if not self.match_device(device_info, object_filter): + continue + + if sync_info: + device_info['sync'] = self.get_device_sync(device_info['name']) + if device_info['sync']: + device_info['syncTick'] = '\u2713' + device_info['__Output']['syncTick'] = 'Green' + else: + device_info['syncTick'] = '\u2717' + device_info['__Output']['syncTick'] = 'Red' + + devices.append( + device_info + ) + + return devices + + def get_device_sync(self, device_name, cache_enabled=True): + if cache_enabled: + if device_name in self.nso_device_sync: + return self.nso_device_sync[device_name] + + sync_mo = self.get_device_sync_mo( + device_name, + cache_enabled=cache_enabled + ) + + if sync_mo is None: + return False + + in_sync = False + for line in sync_mo.split('\n'): + if '>in-sync<' in line: + in_sync = True + + return in_sync + + def get_device(self, device_name, sync_info=False, cache_enabled=True): + devices_info = self.get_devices( + object_filter=['name:%s' % (device_name)], + sync_info=sync_info, + cache_enabled=cache_enabled + ) + if devices_info is None or len(devices_info) != 1: + return None + return devices_info[0] diff --git a/lib/nso/device/main.py b/lib/nso/device/main.py new file mode 100644 index 00000000..80e19ca8 --- /dev/null +++ b/lib/nso/device/main.py @@ -0,0 +1,11 @@ +from lib.nso.device.api import NsoDeviceApi +from lib.nso.device.info import NsoDeviceInfo + + +class NsoDevice( + NsoDeviceApi, + NsoDeviceInfo + ): + def __init__(self): + NsoDeviceApi.__init__(self) + NsoDeviceInfo.__init__(self) diff --git a/lib/nso/device/output.py b/lib/nso/device/output.py new file mode 100644 index 00000000..43224a65 --- /dev/null +++ b/lib/nso/device/output.py @@ -0,0 +1,55 @@ +class NsoDeviceOutput(): + def __init__(self): + pass + + def print_devices(self, info, title=False): + if title: + self.my_output.default( + 'Device [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'address_port', + 'authgroup', + 'device_type', + 'ned', + 'state' + ] + + headers = [ + 'Name', + 'Address', + 'AuthGroup', + 'Type', + 'NED', + 'State' + ] + + updated = False + for item in info: + if 'sync' in item: + if not updated: + updated = True + order.append('syncTick') + headers.append('In-Sync') + + for key in order: + if item[key] is None: + item[key] = '--' + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/nso/main.py b/lib/nso/main.py new file mode 100644 index 00000000..73c8a704 --- /dev/null +++ b/lib/nso/main.py @@ -0,0 +1,64 @@ +from lib import log_helper + +from lib.nso.cnfm.main import NsoCnfm +from lib.nso.common import NsoCommon +from lib.nso.device.main import NsoDevice +from lib.nso.api import rest +from lib.nso.nfvo import main as nfvo_library + + +class Nso(NsoCnfm, NsoCommon, NsoDevice): + def __init__( + self, + protocol, + ip_address, + port, + username=None, + password=None, + restconf_enabled=True, + nfvo=None, + log_id=None + ): + + self.log = log_helper.Log(log_id=log_id) + + self.rest_handler = rest.Rest( + protocol, + ip_address, + port, + username, + password, + restconf_enabled=restconf_enabled, + log_id=log_id + ) + + NsoCnfm.__init__(self) + NsoCommon.__init__(self) + NsoDevice.__init__(self) + + self.nfvo_handler = None + if nfvo is not None: + if 'etsi:' in nfvo: + nfvo_etsi = True + nfvo_version = nfvo.split(':')[1] + else: + nfvo_etsi = False + nfvo_version = nfvo + + self.nfvo_handler = nfvo_library.Nfvo( + self.rest_handler, + nfvo_etsi=nfvo_etsi, + nfvo_version=nfvo_version, + log_id=log_id + ) + + def is_connected(self): + success, content = self.rest_handler.get_rest( + 'json', + None, + 'Accept', + 'application/yang-data', + 'data', + 'depth=1' + ) + return success diff --git a/lib/nso/nfvo/__init__.py b/lib/nso/nfvo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/nfvo/__pycache__/__init__.cpython-310.pyc b/lib/nso/nfvo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..cd08a500 Binary files /dev/null and b/lib/nso/nfvo/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/nso/nfvo/__pycache__/main.cpython-310.pyc b/lib/nso/nfvo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..80d1485e Binary files /dev/null and b/lib/nso/nfvo/__pycache__/main.cpython-310.pyc differ diff --git a/lib/nso/nfvo/__pycache__/vnfd.cpython-310.pyc b/lib/nso/nfvo/__pycache__/vnfd.cpython-310.pyc new file mode 100644 index 00000000..beabb89f Binary files /dev/null and b/lib/nso/nfvo/__pycache__/vnfd.cpython-310.pyc differ diff --git a/lib/nso/nfvo/__pycache__/vnfi.cpython-310.pyc b/lib/nso/nfvo/__pycache__/vnfi.cpython-310.pyc new file mode 100644 index 00000000..f6954a1c Binary files /dev/null and b/lib/nso/nfvo/__pycache__/vnfi.cpython-310.pyc differ diff --git a/lib/nso/nfvo/api/__init__.py b/lib/nso/nfvo/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/nfvo/api/main.py b/lib/nso/nfvo/api/main.py new file mode 100644 index 00000000..1d871ade --- /dev/null +++ b/lib/nso/nfvo/api/main.py @@ -0,0 +1,356 @@ +import traceback + + +class NfvoApi(): + def __init__(self, nfvo_etsi=True, nfvo_version='4.x'): + self.nfvo_etsi = nfvo_etsi + self.nfvo_version = nfvo_version + + def adhoc_get(self, path, params=None, output_format='xml', trace=None): + resource_type = 'running' + header = 'Accept' + success, response = self.rest_handler.get_rest( + output_format=output_format, + resource_type=resource_type, + header=header, + media_type='application/vnd.yang.data', + path=path, + params=params, + trace=trace + ) + + return success, response + + def adhoc_post(self, path, data, output_format='xml', timeout=None, trace=None): + resource_type = 'running' + header = 'Accept' + success, response = self.rest_handler.post_rest( + output_format=output_format, + resource_type=resource_type, + header=header, + media_type='application/vnd.yang.data', + path=path, + data=data, + params=None, + timeout=timeout, + trace=trace + ) + + return success, response + + def adhoc_patch(self, path, data, output_format='xml', timeout=None, trace=None): + resource_type = 'running' + header = 'Accept' + success, response = self.rest_handler.patch_rest( + output_format=output_format, + resource_type=resource_type, + header=header, + media_type='application/vnd.yang.data', + path=path, + data=data, + params=None, + timeout=timeout, + trace=trace + ) + + return success, response + + def adhoc_put(self, path, data, output_format='xml', timeout=None, trace=None): + resource_type = 'running' + header = 'Accept' + success, response = self.rest_handler.put_rest( + output_format=output_format, + resource_type=resource_type, + header=header, + media_type='application/vnd.yang.data', + path=path, + data=data, + params=None, + timeout=timeout, + trace=trace + ) + + return success, response + + def adhoc_delete(self, path, params=None, output_format='xml', trace=None): + resource_type = 'running' + header = 'Accept' + success, response = self.rest_handler.delete_rest( + output_format=output_format, + resource_type=resource_type, + header=header, + media_type='application/vnd.yang.data', + path=path, + params=params, + trace=trace + ) + + return success, response + + def get_rest_api_info(self, output_format='json'): + """ + Returns API information + """ + success, response = self.rest_handler.get_rest( + output_format=output_format, + resource_type=None, + media_type='application/vnd.yang.api', + header='Accept', + path=None + ) + + if success: + try: + response = response['api'] + except BaseException: + self.log.error( + 'nso.get_rest_api_info', + traceback.format_exc() + ) + + def get_data(self, output_format, datastore, data_path, header=None, media_type=None, params=None, trace=None): + """ + Get a data entry in a datastore + + :param datastore: The target datastore + :type datastore: :class:`DatastoreType` + + :param data_path: The list of paths + :type data_path: ``list`` of ``str`` or ``tuple`` + + :param header: Header name, mostly "Accept" or "Content-Type" + :type header: 'str' + """ + data_path = '/'.join(data_path) + success, response = self.rest_handler.get_rest( + output_format=output_format, + resource_type=datastore, + header=header, + media_type=media_type, + path=data_path, + params=params, + trace=trace + ) + + return success, response + + def get_datastore(self, output_format, datastore, header=None, params=None, trace=None): + """ + Get the details of a datastore + + :param datastore: The target datastore + :type datastore: :class:`DatastoreType` + """ + success, response = self.rest_handler.get_rest( + output_format=output_format, + resource_type=datastore, + header=header, + media_type='application/vnd.yang.data', + path=None, + params=params, + trace=trace + ) + + return success, response + + def create_data_value(self, output_format, datastore, data_path, data, header=None, params=None, trace=None): + """ + Create (PUT) a data entry in a datastore + + :param datastore: The target datastore + :type datastore: :class:`DatastoreType` + + :param data_path: The list of paths + :type data_path: ``list`` of ``str`` or ``tuple`` + + :param data: The new value at the given path + :type data: ``dict`` + + :param header: Header name, mostly "Accept" or "Content-Type" + :type header: 'str' + + :rtype: ``bool`` + :return: ``True`` if successful, otherwise error. + """ + data_path = '/'.join(data_path) + success, response = self.rest_handler.put_rest( + output_format=output_format, + resource_type=datastore, + header=header, + media_type='application/vnd.yang.data', + path=data_path, + data=data, + params=params, + trace=trace + ) + + return success, response + + def patch_data_value(self, output_format, datastore, data_path, data, header=None, params=None, timeout=None, trace=None): + """ + Update (POST) a data entry in a datastore + + :param datastore: The target datastore + :type datastore: :class:`DatastoreType` + + :param data_path: The list of paths + :type data_path: ``list`` of ``str`` or ``tuple`` + + :param data: The new value at the given path + :type data: ``dict`` + + :param header: Header name, mostly "Accept" or "Content-Type" + :type header: 'str' + + :rtype: ``bool`` + :return: ``True`` if successful, otherwise error. + """ + data_path = '/'.join(data_path) + success, response = self.rest_handler.patch_rest( + output_format=output_format, + resource_type=datastore, + header=header, + media_type='application/vnd.yang.data', + data=data, + path=data_path, + params=params, + timeout=timeout, + trace=trace + ) + + return success, response + + def set_data_value(self, output_format, datastore, data_path, data, header=None, params=None, timeout=None, trace=None): + data_path = '/'.join(data_path) + success, response = self.rest_handler.post_rest( + output_format=output_format, + resource_type=datastore, + header=header, + media_type='application/vnd.yang.data', + path=data_path, + data=data, + params=params, + timeout=timeout, + trace=trace + ) + + return success, response + + def delete_path(self, output_format, datastore, data_path, header=None, params=None, trace=None): + """ + Delete a data entry in a datastore + + :param datastore: The target datastore + :type datastore: :class:`DatastoreType` + + :param data_path: The list of paths + :type data_path: ``list`` of ``str`` or ``tuple`` + + :param header: Header name, mostly "Accept" or "Content-Type" + :type header: 'str' + + :rtype: ``bool`` + :return: ``True`` if successful, otherwise error. + """ + data_path = '/'.join(data_path) + success, response = self.rest_handler.delete_rest( + output_format=output_format, + resource_type=datastore, + header=header, + media_type='application/vnd.yang.data', + path=data_path, + params=params, + trace=trace + ) + + return success, response + + def get_rollbacks(self, output_format='xml', trace=None): + """ + Get a list of stored rollbacks + """ + success, response = self.rest_handler.get_rest( + output_format=output_format, + resource_type='rollbacks', + header='Accept', + media_type='application/vnd.yang.api', + trace=trace + ) + + return success, response + + def get_rollback(self, name, output_format='xml', trace=None): + """ + Get a list of stored rollbacks + """ + success, response = self.rest_handler.get_rest( + output_format=output_format, + resource_type='rollbacks', + header='Accept', + media_type='application/vnd.yang.api', + path=name, + trace=trace + ) + + return success, response + + def apply_rollback(self, datastore, name, output_format='xml', trace=None): + """ + Apply a system rollback + """ + header = 'Accept' + success, response = self.rest_handler.post_rest( + output_format=output_format, + resource_type=datastore, + media_type='application/vnd.yang.data', + header=header, + path='rollback', + data={'file': name}, + trace=trace + ) + + return success, response + + def is_nfvo_rest_api(self, output_format='json'): + success = False + if self.nfvo_version == '3.x': + if self.restconf_enabled: + success, response = self.get_data( + output_format, + 'running', + ('tailf-etsi-rel2-nfvo:nfvo', 'vnfd'), + header='Accept', + media_type='application/vnd.yang.collection', + params=None + ) + else: + success, response = self.get_data( + output_format, + 'running', + ('nfvo', 'vnfd'), + header='Accept', + media_type='application/vnd.yang.collection', + params='deep' + ) + + if self.nfvo_version == '4.x': + if self.restconf_enabled: + success, response = self.get_data( + output_format, + 'running', + ('etsi-nfv-descriptors:nfv', 'vnfd'), + header='Accept', + media_type='application/vnd.yang.collection', + params=None + ) + else: + success, response = self.get_data( + output_format, + 'running', + ('nfv', 'vnfd'), + header='Accept', + media_type='application/vnd.yang.collection', + params='deep' + ) + + return success diff --git a/lib/nso/nfvo/main.py b/lib/nso/nfvo/main.py new file mode 100644 index 00000000..9572ba60 --- /dev/null +++ b/lib/nso/nfvo/main.py @@ -0,0 +1,26 @@ +from lib import log_helper + +from lib.nso.nfvo.api.main import NfvoApi +from lib.nso.nfvo.vnfd.main import NfvoVnfd +from lib.nso.nfvo.vnfi.main import NfvoVnfi + + +class Nfvo(NfvoApi, NfvoVnfd, NfvoVnfi): + def __init__( + self, + rest_handler, + nfvo_etsi=False, + nfvo_version='3.x', + log_id=None + ): + + self.log = log_helper.Log(log_id=log_id) + self.rest_handler = rest_handler + + NfvoApi.__init__( + self, + nfvo_etsi=nfvo_etsi, + nfvo_version=nfvo_version + ) + NfvoVnfd.__init__(self) + NfvoVnfi.__init__(self) diff --git a/lib/nso/nfvo/output.py b/lib/nso/nfvo/output.py new file mode 100644 index 00000000..b1fa0dba --- /dev/null +++ b/lib/nso/nfvo/output.py @@ -0,0 +1,19 @@ +from lib import output_helper + +from lib.nso.nfvo.vnfd.output import NfvoVnfdOutput +from lib.nso.nfvo.vnfi.output import NfvoVnfiOutput + + +class NfvoOutput( + NfvoVnfdOutput, + NfvoVnfiOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + NfvoVnfdOutput.__init__(self) + NfvoVnfiOutput.__init__(self) diff --git a/lib/nso/nfvo/vnfd/__init__.py b/lib/nso/nfvo/vnfd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/nfvo/vnfd/__pycache__/__init__.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0b111009 Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/__pycache__/create.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..c2eafb3f Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/create.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/__pycache__/delete.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..0bfb84d5 Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/__pycache__/get.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/get.cpython-310.pyc new file mode 100644 index 00000000..f95c7ec1 Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/get.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/__pycache__/main.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3e937c48 Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/main.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/__pycache__/output.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..6b4c333a Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/output.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/__pycache__/print.cpython-310.pyc b/lib/nso/nfvo/vnfd/__pycache__/print.cpython-310.pyc new file mode 100644 index 00000000..34f15f4d Binary files /dev/null and b/lib/nso/nfvo/vnfd/__pycache__/print.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfd/create.py b/lib/nso/nfvo/vnfd/create.py new file mode 100644 index 00000000..cd8eb809 --- /dev/null +++ b/lib/nso/nfvo/vnfd/create.py @@ -0,0 +1,51 @@ +import time + + +class NfvoVnfdCreate(): + def __init__(self): + pass + + def create_vnfd(self, vnfd_content, output_format='xml'): + success = False + response = None + + datastore = 'running' + header = 'Content-Type' + datapath = None + if self.nfvo_version == '3.x': + if self.restconf_enabled: + datapath = ('tailf-etsi-rel2-nfvo:nfvo', ) + else: + datapath = ('nfvo', ) + + if self.nfvo_version == '4.x': + if self.restconf_enabled: + datapath = ('etsi-nfv-descriptors:nfv', ) + else: + datapath = ('nfv', ) + + if datapath is None: + self.log.error( + 'nso.create_vnfd', + 'Unsupported nso instance' + ) + return False + + trace = 'nfvo.create_vnfd.%s' % (int(time.time() * 1000)) + success, response = self.api_handler.set_data_value( + output_format, + datastore, + datapath, + vnfd_content, + header=header, + trace=trace + ) + + if not success: + self.log.error( + 'nso.create_vnfd', + 'Failure: %s' % (response) + ) + return False + + return True diff --git a/lib/nso/nfvo/vnfd/delete.py b/lib/nso/nfvo/vnfd/delete.py new file mode 100644 index 00000000..b3834212 --- /dev/null +++ b/lib/nso/nfvo/vnfd/delete.py @@ -0,0 +1,43 @@ +import time + + +class NfvoVnfdDelete(): + def __init__(self): + pass + + def delete_vnfd(self, vnfd_id, output_format='json'): + success = False + response = None + + datastore = 'running' + header = 'Accept' + + if self.nfvo_version == '3.x': + if self.restconf_enabled: + datapath = ('tailf-etsi-rel2-nfvo:nfvo', 'vnfd', vnfd_id) + else: + datapath = ('nfvo', 'vnfd', vnfd_id) + + if self.nfvo_version == '4.x': + if self.restconf_enabled: + datapath = ('etsi-nfv-descriptors:nfv', 'vnfd=%s' % (vnfd_id)) + else: + datapath = ('nfv', 'vnfd', vnfd_id) + + trace = 'nfvo.delete_vnfd.%s' % (int(time.time() * 1000)) + success, response = self.api_handler.delete_path( + output_format, + datastore, + datapath, + header=header, + trace=trace + ) + + if not success: + self.log.error( + 'nso.delete_vnfd', + 'Failure: %s' % (response) + ) + return False + + return True diff --git a/lib/nso/nfvo/vnfd/get.py b/lib/nso/nfvo/vnfd/get.py new file mode 100644 index 00000000..612d7528 --- /dev/null +++ b/lib/nso/nfvo/vnfd/get.py @@ -0,0 +1,113 @@ +import time + + +class NfvoVnfdGet(): + def __init__(self): + pass + + def is_vnfd(self, vnfd_id): + vnfd = self.get_vnfd(vnfd_id) + if vnfd is None: + return False + return True + + def get_vnfds_count(self): + vnfds = self.get_vnfds() + if vnfds is None: + return 0 + return len(vnfds) + + def get_vnfds(self, output_format='json'): + success = False + response = None + + datastore = 'running' + header = 'Accept' + media_type = 'application/vnd.yang.collection' + if self.nfvo_version == '3.x': + if self.rest_handler.restconf_enabled: + datapath = ('tailf-etsi-rel2-nfvo:nfvo', 'vnfd') + else: + datapath = ('nfvo', 'vnfd') + + if self.nfvo_version == '4.x': + if self.rest_handler.restconf_enabled: + datapath = ('etsi-nfv-descriptors:nfv', 'vnfd') + else: + datapath = ('nfv', 'vnfd') + + trace = 'nfvo.get_vnfds.%s' % (int(time.time() * 1000)) + success, response = self.rest_handler.get_data( + output_format, + datastore, + datapath, + header=header, + media_type=media_type, + params=None, + trace=trace + ) + + if not success or response is None: + self.log.error( + 'nso.get_vnfds', + 'Failure: %s' % (response) + ) + return None + + if self.nfvo_version == '3.x': + response = response['collection']['tailf-etsi-rel2-nfvo:vnfd'] + + if self.nfvo_version == '4.x': + response = response['collection']['etsi-nfv-descriptors:vnfd'] + + return response + + def get_vnfd(self, vnfd_id, output_format='xml'): + success = False + response = None + + datastore = 'running' + header = 'Accept' + params = None + + if self.nfvo_version == '3.x': + media_type = 'application/vnd.yang.data' + if self.rest_handler.restconf_enabled: + datapath = ('tailf-etsi-rel2-nfvo:nfvo', 'vnfd', vnfd_id) + else: + datapath = ('nfvo', 'vnfd', vnfd_id) + + if self.nfvo_version == '4.x': + if self.rest_handler.restconf_enabled: + media_type = 'application/vnd.yang.collection' + datapath = ('etsi-nfv-descriptors:nfv', 'vnfd=%s' % (vnfd_id)) + else: + media_type = 'application/vnd.yang.data' + datapath = ('nfv', 'vnfd', vnfd_id) + params = 'deep' + + trace = 'nfvo.get_vnfd.%s' % (int(time.time() * 1000)) + success, response = self.rest_handler.get_data( + output_format, + datastore, + datapath, + header=header, + media_type=media_type, + params=params, + trace=trace + ) + + if not success or response is None: + self.log.error( + 'nso.get_vnfd', + 'Failure: %s' % (response) + ) + return None + + if self.nfvo_version == '3.x' and output_format == 'json': + response = response['tailf-etsi-rel2-nfvo:vnfd'] + + if self.nfvo_version == '4.x' and output_format == 'json': + response = response['etsi-nfv-descriptors:vnfd'] + + return response diff --git a/lib/nso/nfvo/vnfd/main.py b/lib/nso/nfvo/vnfd/main.py new file mode 100644 index 00000000..f0798352 --- /dev/null +++ b/lib/nso/nfvo/vnfd/main.py @@ -0,0 +1,12 @@ +from lib.nso.nfvo.vnfd.create import NfvoVnfdCreate +from lib.nso.nfvo.vnfd.delete import NfvoVnfdDelete +from lib.nso.nfvo.vnfd.get import NfvoVnfdGet +from lib.nso.nfvo.vnfd.output import NfvoVnfdOutput + + +class NfvoVnfd(NfvoVnfdCreate, NfvoVnfdDelete, NfvoVnfdGet, NfvoVnfdOutput): + def __init__(self): + NfvoVnfdCreate.__init__(self) + NfvoVnfdDelete.__init__(self) + NfvoVnfdGet.__init__(self) + NfvoVnfdOutput.__init__(self) diff --git a/lib/nso/nfvo/vnfd/output.py b/lib/nso/nfvo/vnfd/output.py new file mode 100644 index 00000000..e650436b --- /dev/null +++ b/lib/nso/nfvo/vnfd/output.py @@ -0,0 +1,30 @@ +class NfvoVnfdOutput(): + def __init__(self): + pass + + def print_vnfds(self, info): + order = [ + 'id', + 'provider', + 'product-name', + 'software-version', + 'product-info-name', + 'product-info-description' + ] + + headers = [ + 'VNFD ID', + 'Provider', + 'Product Name', + 'Software Version', + 'Info Name', + 'Info Description' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/nso/nfvo/vnfi/__init__.py b/lib/nso/nfvo/vnfi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/nso/nfvo/vnfi/__pycache__/__init__.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7705689c Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/__pycache__/create.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..86cbf891 Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/create.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/__pycache__/delete.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..1a4d9a50 Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/__pycache__/get.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/get.cpython-310.pyc new file mode 100644 index 00000000..af7a4aba Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/get.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/__pycache__/main.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..fc3b29f7 Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/main.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/__pycache__/output.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..77d7fb68 Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/output.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/__pycache__/print.cpython-310.pyc b/lib/nso/nfvo/vnfi/__pycache__/print.cpython-310.pyc new file mode 100644 index 00000000..e195e424 Binary files /dev/null and b/lib/nso/nfvo/vnfi/__pycache__/print.cpython-310.pyc differ diff --git a/lib/nso/nfvo/vnfi/create.py b/lib/nso/nfvo/vnfi/create.py new file mode 100644 index 00000000..8445fc63 --- /dev/null +++ b/lib/nso/nfvo/vnfi/create.py @@ -0,0 +1,71 @@ +import time +from lib import xmltodict + + +class NfvoVnfiCreate(): + def __init__(self): + pass + + def get_vnfi_name(self, vnfi_content): + try: + content = xmltodict.parse(vnfi_content, force_cdata=True) + vnfi_name = content['vnf-info']['name']['#text'] + except BaseException: + return None + return vnfi_name + + def wait_for_vnfi_ready(self, vnfi_name, timeout=1800): + start_time = int(time.time()) + while True: + if self.is_vnfi_ready(vnfi_name, cache=False): + return True + + time.sleep(15) + if int(time.time()) - start_time > timeout: + self.log.error( + 'nso.wait_for_vnfi_ready', + 'Timeout reached: %s' % (vnfi_name) + ) + return False + + def wait_for_vnfi_defined(self, vnfi_name, timeout=30): + start_time = int(time.time()) + while True: + if self.is_vnfi(vnfi_name): + return True + + time.sleep(5) + if int(time.time()) - start_time > timeout: + self.log.error( + 'nso.wait_for_vnfi_defined', + 'Timeout reached: %s' % (vnfi_name) + ) + return False + + def create_vnfi(self, vnfi_content, output_format='xml', publish=False, trace=None): + success = False + response = None + + if self.nfvo_version == '3.x': + return False, 'Unsupported NFVO 3.x version' + + if self.nfvo_version == '4.x' and not self.restconf_enabled: + return False, 'REST API not supported for NFVO 4.x' + + success, response = self.api_handler.set_data_value( + output_format, + 'running', + ('etsi-nfv-descriptors:nfv',), + vnfi_content, + header='Content-Type', + trace=trace + ) + + if not success: + self.log.error( + 'nso.create_vnfi', + 'Failure: %s' % (response) + ) + return False + + return True diff --git a/lib/nso/nfvo/vnfi/delete.py b/lib/nso/nfvo/vnfi/delete.py new file mode 100644 index 00000000..965eb4b5 --- /dev/null +++ b/lib/nso/nfvo/vnfi/delete.py @@ -0,0 +1,33 @@ +class NfvoVnfiDelete(): + def __init__(self): + pass + + def delete_vnfi(self, vnfi_name, output_format='json', trace=None): + success = False + response = None + + if self.nfvo_version == '3.x': + return False, 'Unsupported NFVO 3.x version' + + if self.nfvo_version == '4.x' and not self.restconf_enabled: + return False, 'REST API not supported for NFVO 4.x' + + success, response = self.api_handler.delete_path( + output_format, + 'running', + ( + 'etsi-nfv-descriptors:nfv', + 'cisco-etsi-nfvo:vnf-info=%s' % (vnfi_name), + ), + header='Accept', + trace=trace + ) + + if not success: + self.log.error( + 'nso.delete_vnfi', + 'Failure: %s' % (response) + ) + return False + + return True diff --git a/lib/nso/nfvo/vnfi/get.py b/lib/nso/nfvo/vnfi/get.py new file mode 100644 index 00000000..4a543a14 --- /dev/null +++ b/lib/nso/nfvo/vnfi/get.py @@ -0,0 +1,224 @@ +class NfvoVnfiGet(): + def __init__(self): + self.vnfi_plans = None + self.vnfi = None + + def is_vnfi(self, vnfi_name): + vnfi = self.get_vnfi(vnfi_name) + if vnfi is None: + return False + return True + + def get_vnfis_count(self): + vnfis = self.get_vnfis() + if vnfis is None: + return 0 + return len(vnfis) + + def get_vnfi_info(self, vnfi_mo): + info = {} + info['__Output'] = {} + for key in vnfi_mo: + info[key] = vnfi_mo[key] + + vim_ids = [] + for vim in vnfi_mo['resource-orchestration']['vim']: + vim_ids.append( + vim['vim-id'] + ) + info['vim-ids'] = ','.join(vim_ids) + + info['ready'] = self.is_vnfi_ready(vnfi_mo['name']) + if info['ready']: + info['readyTick'] = '\u2713' + info['__Output']['readyTick'] = 'Green' + else: + info['readyTick'] = '\u2717' + info['__Output']['readyTick'] = 'Red' + + return info + + def get_vnfis_info(self): + vnfis = self.get_vnfis() + + info = [] + if vnfis is not None: + for vnfi_mo in vnfis: + info.append( + self.get_vnfi_info( + vnfi_mo + ) + ) + + return info + + def get_vnfis(self, output_format='json', cache=True, trace=None): + if cache and self.vnfi is not None: + return self.vnfi + + success = False + response = None + + datastore = 'running' + header = 'Accept' + params = None + + if self.nfvo_version == '3.x': + media_type = 'application/vnd.yang.data' + if self.restconf_enabled: + datapath = ('tailf-etsi-rel2-nfvo:nfvo', 'vnf-info') + else: + datapath = ('nfvo', 'vnf-info') + + if self.nfvo_version == '4.x': + media_type = 'application/vnd.yang.collection' + if self.restconf_enabled: + datapath = ('etsi-nfv-descriptors:nfv', 'cisco-etsi-nfvo:vnf-info') + else: + datapath = ('nfv', 'vnf-info') + params = 'deep' + + success, response = self.api_handler.get_data( + output_format, + datastore, + datapath, + header=header, + media_type=media_type, + params=params, + trace=trace + ) + + if not success or response is None: + self.log.error( + 'nso.get_vnfis', + 'Failure: %s' % (response) + ) + return None + + if self.nfvo_version == '3.x': + if 'vnf-deployment' in response['tailf-etsi-rel2-nfvo:vnf-info']['tailf-etsi-rel2-nfvo-esc:esc']: + response = response['tailf-etsi-rel2-nfvo:vnf-info']['tailf-etsi-rel2-nfvo-esc:esc']['vnf-deployment'] + else: + response = None + + if self.nfvo_version == '4.x': + response = response['collection']['cisco-etsi-nfvo:vnf-info'] + + return response + + def get_vnfi(self, vnfi_name, output_format='json', trace=None): + success = False + response = None + + if self.nfvo_version == '3.x': + return False, 'Unsupported NFVO 3.x version' + + if self.nfvo_version == '4.x' and not self.restconf_enabled: + return False, 'REST API not supported for NFVO 4.x' + + success, response = self.api_handler.get_data( + output_format, + 'running', + ( + 'etsi-nfv-descriptors:nfv', + 'cisco-etsi-nfvo:vnf-info=%s' % (vnfi_name), + ), + header='Accept', + media_type='application/vnd.yang.data', + params=None, + trace=trace + ) + + if not success or response is None: + self.log.error( + 'nso.get_vnfi', + 'Failure: %s' % (response) + ) + return None + + if self.nfvo_version == '4.x' and output_format == 'json': + response = response['cisco-etsi-nfvo:vnf-info'] + + return response + + def is_vnfi_ready(self, vnfi_name, cache=True): + plan = self.get_vnfi_plan(vnfi_name, cache=cache) + if plan is None: + return False + + ready = True + for component in plan['plan']['component']: + for state in component['state']: + if state['name'] == 'tailf-ncs:ready': + if state['status'] != 'reached': + ready = False + + return ready + + def add_vnfi_plan_output(self, plan): + for component in plan['plan']['component']: + for state in component['state']: + state['__Output'] = {} + if state['status'] == 'reached': + state['__Output']['status'] = 'Green' + else: + state['__Output']['status'] = 'Red' + return plan + + def get_vnfis_plan(self, output_format='json', trace=None, cache=True): + if cache and self.vnfi_plans is not None: + return self.vnfi_plans + + success = False + response = None + + if self.nfvo_version == '3.x': + return False, 'Unsupported NFVO 3.x version' + + if self.nfvo_version == '4.x' and not self.restconf_enabled: + return False, 'REST API not supported for NFVO 4.x' + + success, response = self.api_handler.get_data( + output_format, + 'running', + ( + 'etsi-nfv-descriptors:nfv', + 'cisco-etsi-nfvo:vnf-info-plan', + ), + header='Accept', + media_type='application/vnd.yang.data', + params=None, + trace=trace + ) + + if not success or response is None: + self.log.error( + 'nso.get_vnfis_plan', + 'Failure: %s' % (response) + ) + return None + + if self.nfvo_version == '4.x' and output_format == 'json': + self.vnfi_plans = [] + + vnfi_plans = response['cisco-etsi-nfvo:vnf-info-plan'] + if vnfi_plans is not None: + for vnfi_plan in vnfi_plans: + self.vnfi_plans.append( + self.add_vnfi_plan_output( + vnfi_plan + ) + ) + + return self.vnfi_plans + + def get_vnfi_plan(self, vnfi_name, cache=True): + plans = self.get_vnfis_plan(cache=cache) + if plans is None: + return None + + for plan in plans: + if plan['name'] == vnfi_name: + return plan + + return None diff --git a/lib/nso/nfvo/vnfi/main.py b/lib/nso/nfvo/vnfi/main.py new file mode 100644 index 00000000..0f2e528f --- /dev/null +++ b/lib/nso/nfvo/vnfi/main.py @@ -0,0 +1,12 @@ +from lib.nso.nfvo.vnfi.create import NfvoVnfiCreate +from lib.nso.nfvo.vnfi.delete import NfvoVnfiDelete +from lib.nso.nfvo.vnfi.get import NfvoVnfiGet +from lib.nso.nfvo.vnfi.output import NfvoVnfiOutput + + +class NfvoVnfi(NfvoVnfiCreate, NfvoVnfiDelete, NfvoVnfiGet, NfvoVnfiOutput): + def __init__(self): + NfvoVnfiCreate.__init__(self) + NfvoVnfiDelete.__init__(self) + NfvoVnfiGet.__init__(self) + NfvoVnfiOutput.__init__(self) diff --git a/lib/nso/nfvo/vnfi/output.py b/lib/nso/nfvo/vnfi/output.py new file mode 100644 index 00000000..757d3036 --- /dev/null +++ b/lib/nso/nfvo/vnfi/output.py @@ -0,0 +1,85 @@ +class NfvoVnfiOutput(): + def __init__(self): + pass + + def print_vnfi_plan(self, plan): + for component in plan['plan']['component']: + order = [ + 'type', + 'name', + 'back-track' + ] + + headers = [ + 'Type', + 'Name', + 'Back Track' + ] + + self.my_output.dictionary( + component, + title='Component', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + order = [ + 'name', + 'status', + 'when' + ] + + headers = [ + 'Name', + 'Status', + 'When' + ] + + self.my_output.my_table( + component['state'], + order=order, + headers=headers, + underline=True, + table=True + ) + + if 'error-info' in plan['plan']: + self.my_output.error( + plan['plan']['error-info']['message'] + ) + + def print_vnfis(self, info): + order = [ + 'name', + 'vnfd', + 'vnfd-flavour', + 'instantiation-level', + 'vnfm', + 'vnfm-type', + 'vim-type', + 'vim-ids', + 'readyTick' + ] + + headers = [ + 'VNF-INFO Name', + 'VNFD ID', + 'Flavor', + 'Level', + 'VNFM', + 'VNFM Type', + 'VIM Type', + 'VIM ID', + 'Ready' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/nso/output.py b/lib/nso/output.py new file mode 100644 index 00000000..0c41e136 --- /dev/null +++ b/lib/nso/output.py @@ -0,0 +1,22 @@ +from lib import output_helper + +from lib.nso.cnfm.output import NsoCnfmOutput +from lib.nso.device.output import NsoDeviceOutput +from lib.nso.nfvo.output import NfvoOutput + + +class NsoOutput( + NsoCnfmOutput, + NfvoOutput, + NsoDeviceOutput, + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + NsoCnfmOutput.__init__(self) + NfvoOutput.__init__(self) + NsoDeviceOutput.__init__(self) diff --git a/lib/nso/settings.py b/lib/nso/settings.py new file mode 100644 index 00000000..e2345eb9 --- /dev/null +++ b/lib/nso/settings.py @@ -0,0 +1,186 @@ +import os +import json +import traceback + +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class NsoSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log = log_helper.Log() + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.nso_settings_filename = os.path.join( + self.settings_dir, + 'nso' + ) + + if not self.initialize_nso_settings(): + raise ValueError('NSO settings initialization failed') + + def get_nso_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Defaults'] = {} + settings['Defaults']['Ncs'] = None + settings['Ncs'] = [] + return settings + + def initialize_nso_settings(self): + if not os.path.isfile(self.nso_settings_filename): + settings = self.get_nso_default_settings() + if not self.set_nso_settings(settings): + return False + return True + + def get_nso_settings(self): + if not os.path.isfile(self.nso_settings_filename): + return None + + try: + with open(self.nso_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_nso_settings', traceback.format_exc()) + return None + + return settings + + def set_nso_settings(self, settings): + try: + with open(self.nso_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_nso_settings', traceback.format_exc()) + return False + + return True + + def get_default_ncs(self): + settings = self.get_nso_settings() + if settings is None: + return None + + try: + default_ncs_name = settings['Defaults']['Ncs'] + except BaseException: + default_ncs_name = None + + return default_ncs_name + + def set_default_ncs(self, name): + settings = self.get_nso_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Ncs'] = name + return self.set_nso_settings(settings) + + def get_nso_ncss(self): + settings = self.get_nso_settings() + if settings is None: + return None + + return settings['Ncs'] + + def get_nso_ncs(self, nso_name): + ncss = self.get_nso_ncss() + if ncss is None: + return None + + for ncs in ncss: + if ncs['name'] == nso_name: + return ncs + + return None + + def set_nso_ncss(self, ncss): + settings = self.get_nso_settings() + if settings is None: + return False + + settings['Ncs'] = ncss + return self.set_nso_settings(settings) + + def set_nso_ncs(self, nso_name, rest_protocol, nso_ip, nso_port, nso_username, nso_password, restconf_enabled, nfvo): + ncss = self.get_nso_ncss() + if ncss is None: + return False + + new_ncss = [] + for ncs in ncss: + if ncs['name'] != nso_name: + new_ncss.append(ncs) + + new_ncs = {} + new_ncs['name'] = nso_name + new_ncs['protocol'] = rest_protocol + new_ncs['ip'] = nso_ip + new_ncs['port'] = nso_port + new_ncs['username'] = nso_username + new_ncs['password'] = nso_password + new_ncs['restconf_enabled'] = restconf_enabled + new_ncs['nfvo'] = nfvo + new_ncss.append(new_ncs) + + return self.set_nso_ncss(new_ncss) + + def delete_nso_ncs(self, nso_name): + ncss = self.get_nso_ncss() + if ncss is None: + return False + + new_ncss = [] + for ncs in ncss: + if ncs['name'] != nso_name: + new_ncss.append(ncs) + + return self.set_nso_ncss(new_ncss) + + def print_nso_ncss(self, ncss, show_password=True): + ncss = sorted(ncss, key=lambda i: i['name']) + if not show_password: + for ncs in ncss: + ncs['password'] = '******' + + order = [ + 'name', + 'protocol', + 'ip', + 'port', + 'username', + 'password', + 'restconf_enabled', + 'nfvo' + ] + + headers = [ + 'Name', + 'REST Protocol', + 'IP', + 'Port', + 'Username', + 'Password', + 'RESTCONF', + 'NFVO' + ] + + self.my_output.my_table( + ncss, + order=order, + headers=headers, + table=True + ) diff --git a/lib/ocp/__init__.py b/lib/ocp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/__pycache__/__init__.cpython-310.pyc b/lib/ocp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..95d10735 Binary files /dev/null and b/lib/ocp/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/common.cpython-310.pyc b/lib/ocp/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..04c5438a Binary files /dev/null and b/lib/ocp/__pycache__/common.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/create.cpython-310.pyc b/lib/ocp/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..75a536d1 Binary files /dev/null and b/lib/ocp/__pycache__/create.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/delete.cpython-310.pyc b/lib/ocp/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..e9a2ac91 Binary files /dev/null and b/lib/ocp/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/kubeconfig.cpython-310.pyc b/lib/ocp/__pycache__/kubeconfig.cpython-310.pyc new file mode 100644 index 00000000..7c38c4e5 Binary files /dev/null and b/lib/ocp/__pycache__/kubeconfig.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/main.cpython-310.pyc b/lib/ocp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e5dab018 Binary files /dev/null and b/lib/ocp/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/output.cpython-310.pyc b/lib/ocp/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..ebb0c5a5 Binary files /dev/null and b/lib/ocp/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/settings.cpython-310.pyc b/lib/ocp/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..4fc05df6 Binary files /dev/null and b/lib/ocp/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/state.cpython-310.pyc b/lib/ocp/__pycache__/state.cpython-310.pyc new file mode 100644 index 00000000..d155db4a Binary files /dev/null and b/lib/ocp/__pycache__/state.cpython-310.pyc differ diff --git a/lib/ocp/__pycache__/validate.cpython-310.pyc b/lib/ocp/__pycache__/validate.cpython-310.pyc new file mode 100644 index 00000000..12b56bc8 Binary files /dev/null and b/lib/ocp/__pycache__/validate.cpython-310.pyc differ diff --git a/lib/ocp/cluster/__init__.py b/lib/ocp/cluster/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/cluster/__pycache__/__init__.cpython-310.pyc b/lib/ocp/cluster/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e7c5ee91 Binary files /dev/null and b/lib/ocp/cluster/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/cluster/__pycache__/kubeconfig.cpython-310.pyc b/lib/ocp/cluster/__pycache__/kubeconfig.cpython-310.pyc new file mode 100644 index 00000000..b176ea9e Binary files /dev/null and b/lib/ocp/cluster/__pycache__/kubeconfig.cpython-310.pyc differ diff --git a/lib/ocp/cluster/__pycache__/main.cpython-310.pyc b/lib/ocp/cluster/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5b41955f Binary files /dev/null and b/lib/ocp/cluster/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/cluster/__pycache__/output.cpython-310.pyc b/lib/ocp/cluster/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..800eb42e Binary files /dev/null and b/lib/ocp/cluster/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/cluster/cnv/__init__.py b/lib/ocp/cluster/cnv/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/cluster/cnv/__pycache__/__init__.cpython-310.pyc b/lib/ocp/cluster/cnv/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..701689bc Binary files /dev/null and b/lib/ocp/cluster/cnv/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/cluster/cnv/__pycache__/main.cpython-310.pyc b/lib/ocp/cluster/cnv/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a76fc01b Binary files /dev/null and b/lib/ocp/cluster/cnv/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/cluster/cnv/__pycache__/output.cpython-310.pyc b/lib/ocp/cluster/cnv/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..9389c7c8 Binary files /dev/null and b/lib/ocp/cluster/cnv/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/cluster/cnv/main.py b/lib/ocp/cluster/cnv/main.py new file mode 100644 index 00000000..98fcebe3 --- /dev/null +++ b/lib/ocp/cluster/cnv/main.py @@ -0,0 +1,76 @@ +class OcpClusterCnv(): + def __init__(self): + self.ocp_cnv_namespace_name = 'openshift-cnv' + self.ocp_cnv_operator_group_name = 'kubevirt-hyperconverged-group' + self.ocp_cnv_subscription_name = 'hco-operatorhub' + self.ocp_cnv_csv_name = 'kubevirt-hyperconverged' + + def get_ocp_cnv_state(self): + info = {} + info['__Output'] = {} + + info['installed'] = False + info['namespace'] = {} + info['namespace']['name'] = self.ocp_cnv_namespace_name + info['namespace']['exists'] = self.is_namespace(self.ocp_cnv_namespace_name) + if info['namespace']['exists']: + info['__Output']['namespace.name'] = 'Green' + else: + info['__Output']['namespace.name'] = 'Red' + + info['operator'] = {} + info['operator']['name'] = self.ocp_cnv_operator_group_name + info['operator']['exists'] = False + info['__Output']['operator.name'] = 'Red' + if info['namespace']['exists']: + info['operator']['exists'] = self.k8s_handler.is_operator_group( + info['namespace']['name'], + info['operator']['name'] + ) + if info['operator']['exists']: + info['__Output']['operator.name'] = 'Green' + + info['subscription'] = {} + info['subscription']['name'] = self.ocp_cnv_subscription_name + info['subscription']['exists'] = False + info['subscription']['ready'] = False + info['subscription']['state'] = 'Not installed' + info['__Output']['subscription.name'] = 'Red' + info['__Output']['subscription.state'] = 'Red' + if info['namespace']['exists']: + subscription_info = self.k8s_handler.get_subscription( + info['namespace']['name'], + info['subscription']['name'] + ) + if subscription_info is not None: + info['subscription']['exists'] = True + info['subscription']['state'] = subscription_info['state'] + info['subscription']['spec'] = subscription_info['spec'] + if info['subscription']['exists'] and info['subscription']['state'] == 'AtLatestKnown': + info['__Output']['subscription.name'] = 'Green' + info['__Output']['subscription.state'] = 'Green' + info['subscription']['ready'] = True + + info['csv'] = {} + info['csv']['name'] = self.ocp_cnv_csv_name + info['csv']['phase'] = 'Not installed' + info['csv']['exists'] = False + info['csv']['ready'] = False + info['__Output']['csv.name'] = 'Red' + info['__Output']['csv.phase'] = 'Red' + if info['subscription']['ready']: + info['csv']['name'] = subscription_info['spec']['startingCSV'] + csv_info = self.k8s_handler.get_cluster_service_version( + info['namespace']['name'], + info['csv']['name'] + ) + if csv_info is not None: + info['csv']['exists'] = True + info['csv']['phase'] = csv_info['phase'] + if info['csv']['exists'] and info['csv']['phase'] == 'Succeeded': + info['__Output']['csv.name'] = 'Green' + info['__Output']['csv.phase'] = 'Green' + info['csv']['ready'] = True + info['installed'] = True + + return info diff --git a/lib/ocp/cluster/cnv/output.py b/lib/ocp/cluster/cnv/output.py new file mode 100644 index 00000000..a756ede0 --- /dev/null +++ b/lib/ocp/cluster/cnv/output.py @@ -0,0 +1,32 @@ +class OcpClusterCnvOutput(): + def __init__(self): + pass + + def print_ocp_cnv_state(self, info): + order = [ + 'namespace.name', + 'operator.name', + 'subscription.name', + 'subscription.state', + 'csv.name', + 'csv.phase' + ] + + headers = [ + 'Namespace', + 'Operator Group', + 'Subscription', + 'Subscription State', + 'Cluster Service Version (CSV)', + 'CSV Phase' + ] + + self.my_output.dictionary( + info, + title='Container Virtualization (CNV) State', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/ocp/cluster/console/__init__.py b/lib/ocp/cluster/console/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/cluster/console/__pycache__/__init__.cpython-310.pyc b/lib/ocp/cluster/console/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e9dbe94d Binary files /dev/null and b/lib/ocp/cluster/console/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/cluster/console/__pycache__/main.cpython-310.pyc b/lib/ocp/cluster/console/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6e60eb48 Binary files /dev/null and b/lib/ocp/cluster/console/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/cluster/console/__pycache__/output.cpython-310.pyc b/lib/ocp/cluster/console/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..e29443c7 Binary files /dev/null and b/lib/ocp/cluster/console/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/cluster/console/main.py b/lib/ocp/cluster/console/main.py new file mode 100644 index 00000000..e3f2146a --- /dev/null +++ b/lib/ocp/cluster/console/main.py @@ -0,0 +1,111 @@ +import os +import socket + +from lib import ssh +from lib import output_helper + + +class OcpClusterConsole(): + def __init__(self, log_id=None): + self.log_id = log_id + self.my_output = output_helper.OutputHelper( + log_id=log_id + ) + + def download_kubeadmin(self, installer_ip, installer_username, installer_password, silent=False): + ssh_handler = ssh.Ssh( + installer_ip, + installer_username, + password=installer_password, + log_id=self.log_id + ) + source = './install/auth/kubeadmin-password' + destination = '/tmp/kubeadmin' + success = ssh_handler.scp_file( + source, + destination, + put=False + ) + + if not success: + if not silent: + self.my_output.error('Kubeadmin download failed') + return None + + if not silent: + self.my_output.default('Kubeadmin downloaded: %s => %s' % (source, destination)) + return destination + + def is_kubeadmin_file(self, kubeadmin_filename): + return os.path.isfile(kubeadmin_filename) + + def get_kubeadmin_password(self, kubeadmin_filename): + try: + with open(kubeadmin_filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + except BaseException: + self.log.error( + 'get_kubeadmin', + 'File read failed: %s' % (kubeadmin_filename) + ) + return None + + return content + + def get_ocp_cluster_console_info(self): + info = {} + info['__Output'] = {} + info['name'] = self.ocp_cluster_settings['name'] + info['installation'] = self.ocp_cluster_settings['parameters']['ocp']['installation'] + info['release'] = self.ocp_cluster_settings['parameters']['ocp']['release'] + info['cni'] = self.ocp_cluster_settings['parameters']['cni']['type'] + + info['consoleFqdn'] = 'console-openshift-console.apps.%s.%s' % ( + self.ocp_cluster_settings['parameters']['ocp']['cluster']['name'], + self.ocp_cluster_settings['parameters']['ocp']['cluster']['domain'] + ) + info['consoleUrl'] = 'https://%s' % ( + info['consoleFqdn'] + ) + + info['authFqdn'] = 'oauth-openshift.apps.%s.%s' % ( + self.ocp_cluster_settings['parameters']['ocp']['cluster']['name'], + self.ocp_cluster_settings['parameters']['ocp']['cluster']['domain'] + ) + + info['consoleIp'] = self.ocp_cluster_settings['parameters']['ocp']['cluster']['ingress_vip'] + try: + info['consoleDns'] = socket.gethostbyname(info['consoleFqdn']) + except BaseException: + info['consoleDns'] = 'not-resolved' + + if info['consoleIp'] == info['consoleDns']: + info['__Output']['consoleIp'] = 'Green' + info['__Output']['consoleDns'] = 'Green' + else: + info['__Output']['consoleIp'] = 'Red' + info['__Output']['consoleDns'] = 'Red' + + info['authIp'] = self.ocp_cluster_settings['parameters']['ocp']['cluster']['ingress_vip'] + + try: + info['authDns'] = socket.gethostbyname(info['authFqdn']) + except BaseException: + info['authDns'] = 'not-resolved' + + if info['consoleIp'] == info['authDns']: + info['__Output']['authIp'] = 'Green' + info['__Output']['authDns'] = 'Green' + else: + info['__Output']['authIp'] = 'Red' + info['__Output']['authDns'] = 'Red' + + info['consoleUsername'] = 'kubeadmin' + info['consolePassword'] = None + if 'kubeadmin' in self.ocp_cluster_settings: + info['consolePassword'] = self.get_kubeadmin_password( + self.ocp_cluster_settings['kubeadmin'] + ) + + return info diff --git a/lib/ocp/cluster/console/output.py b/lib/ocp/cluster/console/output.py new file mode 100644 index 00000000..73ebd60c --- /dev/null +++ b/lib/ocp/cluster/console/output.py @@ -0,0 +1,71 @@ +class OcpClusterConsoleOutput(): + def __init__(self): + pass + + def print_ocp_cluster_console(self, info): + order = [ + 'name', + 'consoleUrl', + 'consoleIp', + 'consoleDns', + 'authFqdn', + 'authIp', + 'authDns', + 'consoleUsername', + 'consolePassword' + ] + + headers = [ + 'Name', + 'Console URL', + 'Expected Resolved IP', + 'DNS Resolved IP', + 'Authentication FQDN', + 'Expected Resolved IP', + 'DNS Resolved IP', + 'Username', + 'Password' + ] + + self.my_output.dictionary( + info, + title='OCP Console', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_ocp_clusters_console(self, info): + order = [ + 'name', + 'consoleUrl', + 'consoleIp', + 'consoleDns', + 'authFqdn', + 'authIp', + 'authDns', + 'consoleUsername', + 'consolePassword' + ] + + headers = [ + 'Name', + 'Console URL', + 'Expected Resolved IP', + 'DNS Resolved IP', + 'Authentication FQDN', + 'Expected Resolved IP', + 'DNS Resolved IP', + 'Username', + 'Password' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) diff --git a/lib/ocp/cluster/kubeconfig/__init__.py b/lib/ocp/cluster/kubeconfig/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/cluster/kubeconfig/__pycache__/__init__.cpython-310.pyc b/lib/ocp/cluster/kubeconfig/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..82581fbe Binary files /dev/null and b/lib/ocp/cluster/kubeconfig/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/cluster/kubeconfig/__pycache__/main.cpython-310.pyc b/lib/ocp/cluster/kubeconfig/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c3cedc9c Binary files /dev/null and b/lib/ocp/cluster/kubeconfig/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/cluster/kubeconfig/__pycache__/output.cpython-310.pyc b/lib/ocp/cluster/kubeconfig/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..994f1688 Binary files /dev/null and b/lib/ocp/cluster/kubeconfig/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/cluster/kubeconfig/main.py b/lib/ocp/cluster/kubeconfig/main.py new file mode 100644 index 00000000..eb0adf08 --- /dev/null +++ b/lib/ocp/cluster/kubeconfig/main.py @@ -0,0 +1,165 @@ +import os +import socket + +from lib import file_helper +from lib.k8s import main as k8s +from lib import ssh +from lib import output_helper + + +class OcpClusterKubeconfig(): + def __init__(self, log_id=None): + self.log_id=log_id + self.my_output = output_helper.OutputHelper( + log_id=log_id + ) + + def download_kubeconfig(self, installer_ip, installer_username, installer_password, silent=False): + ssh_handler = ssh.Ssh( + installer_ip, + installer_username, + password=installer_password, + log_id=self.log_id + ) + source = './install/auth/kubeconfig' + destination = '/tmp/kubeconfig' + success = ssh_handler.scp_file( + source, + destination, + put=False + ) + + if not success: + if not silent: + self.my_output.error('Kubeconfig download failed') + return None + + if not silent: + self.my_output.default('Kubeconfig downloaded: %s => %s' % (source, destination)) + return destination + + def is_kubeconfig_file(self, kubeconfig_filename): + return os.path.isfile(kubeconfig_filename) + + def get_cluster_name(self, content): + try: + api_server = content['clusters'][0]['cluster']['server'] + api_server_name = api_server[8:].split(':')[0] + + except BaseException: + self.log.error( + 'get_cluster_name', + 'Failed getting api server value' + ) + return None + + return api_server_name + + def check_kubeconfig(self, kubeconfig_filename, api_vip, silent=False): + if not self.is_kubeconfig_file(kubeconfig_filename): + if not silent: + self.my_output.error('Kubeconfig file not found: %s' % (kubeconfig_filename)) + return False + + content = file_helper.get_file_yaml( + kubeconfig_filename + ) + if content is None: + return False + + api_server_name = self.get_cluster_name(content) + if api_server_name is None: + return False + + try: + api_server_ip = socket.gethostbyname(api_server_name) + + except BaseException: + if not silent: + self.my_output.error('DNS resolution failed: %s' % (api_server_name)) + self.my_output.default( + 'Expected DNS resolution (%s, %s)' % ( + api_server_name, + api_vip + ) + ) + return False + + if api_server_ip != api_vip: + if not silent: + self.my_output.error( + 'DNS resolution does not match OCP cluster API VIP: (%s, %s) vs. API VIP %s' % ( + api_server_name, + api_server_ip, + api_vip + ) + ) + return False + + if not silent: + self.my_output.default('Kubeconfig validated: %s => %s' % (api_server_name, api_vip)) + return True + + def get_ocp_cluster_kubeconfig_info(self, validate=False): + info = {} + info['__Output'] = {} + + info['name'] = self.ocp_cluster_settings['name'] + info['kubeconfigFilename'] = self.ocp_cluster_settings['kubeconfig'] + info['kubeconfigFile'] = os.path.isfile( + self.ocp_cluster_settings['kubeconfig'] + ) + if info['kubeconfigFile']: + info['kubeconfigFileTick'] = '\u2713' + info['__Output']['kubeconfigFileTick'] = 'Green' + info['__Output']['kubeconfigFilename'] = 'Green' + else: + info['kubeconfigFileTick'] = '\u2717' + info['__Output']['kubeconfigFileTick'] = 'Red' + info['__Output']['kubeconfigFilename'] = 'Red' + + info['apiFqdn'] = '' + info['apiVip'] = '' + info['apiDns'] = '' + if validate: + info['kubeApi'] = False + info['kubeApiTick'] = '\u2717' + info['__Output']['kubeApiTick'] = 'Red' + + if not info['kubeconfigFile']: + return info + + kubeconfig_content = file_helper.get_file_yaml( + self.ocp_cluster_settings['kubeconfig'] + ) + if kubeconfig_content is None: + self.log.error( + 'get_ocp_cluster_kubeconfig', + 'File read failed: %s' % ( + self.ocp_cluster_settings['kubeconfig'] + ) + ) + return info + + info['apiFqdn'] = self.get_cluster_name(kubeconfig_content) + if info['apiFqdn'] is None: + return info + + try: + info['apiVip'] = socket.gethostbyname(info['apiFqdn']) + except BaseException: + info['apiVip'] = 'not-resolved' + info['__Output']['apiDns'] = 'Red' + return info + + info['__Output']['apiFqdn'] = 'Green' + info['__Output']['apiVip'] = 'Green' + + if validate: + k8s_handler = k8s.K8s(info['kubeconfigFilename']) + if k8s_handler.get_api() is not None: + info['kubeApi'] = True + info['kubeApiTick'] = '\u2713' + info['__Output']['kubeApiTick'] = 'Green' + + return info diff --git a/lib/ocp/cluster/kubeconfig/output.py b/lib/ocp/cluster/kubeconfig/output.py new file mode 100644 index 00000000..b32fefa9 --- /dev/null +++ b/lib/ocp/cluster/kubeconfig/output.py @@ -0,0 +1,69 @@ +class OcpClusterKubeconfigOutput(): + def __init__(self): + pass + + def print_ocp_cluster_kubeconfig(self, info): + order = [ + 'name', + 'kubeconfigFileTick', + 'apiFqdn', + 'apiVip' + ] + + headers = [ + 'Name', + 'Kubeconfig', + 'API FQDN', + 'API VIP' + ] + + if 'kubeApiTick' in info: + order.append('kubeApiTick') + headers.append('K8s API') + + self.my_output.dictionary( + info, + title='OCP Kubeconfig', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_ocp_clusters_kubeconfig(self, clusters, title=False): + if title: + self.my_output.default( + 'OCP Kubeconfig [#%s]' % (len(clusters)), + underline=True, + before_newline=True + ) + + if len(clusters) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'kubeconfigFilename', + 'apiFqdn', + 'apiVip', + 'kubeApiTick' + ] + + headers = [ + 'Cluster Name', + 'Kubeconfig', + 'API FQDN', + 'API VIP', + 'K8s API' + ] + + self.my_output.my_table( + clusters, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + table=True + ) diff --git a/lib/ocp/cluster/main.py b/lib/ocp/cluster/main.py new file mode 100644 index 00000000..83789cf9 --- /dev/null +++ b/lib/ocp/cluster/main.py @@ -0,0 +1,20 @@ +from lib.ocp.cluster.cnv.main import OcpClusterCnv +from lib.ocp.cluster.console.main import OcpClusterConsole +from lib.ocp.cluster.kubeconfig.main import OcpClusterKubeconfig +from lib.ocp.cluster.manager.main import OcpClusterManager +from lib.ocp.cluster.vcenter.main import OcpClusterVcenter + + +class OcpCluster( + OcpClusterCnv, + OcpClusterConsole, + OcpClusterKubeconfig, + OcpClusterManager, + OcpClusterVcenter + ): + def __init__(self): + OcpClusterCnv.__init__(self) + OcpClusterConsole.__init__(self) + OcpClusterKubeconfig.__init__(self) + OcpClusterManager.__init__(self) + OcpClusterVcenter.__init__(self) diff --git a/lib/ocp/cluster/manager/__init__.py b/lib/ocp/cluster/manager/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/cluster/manager/__pycache__/__init__.cpython-310.pyc b/lib/ocp/cluster/manager/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..de2f6cc0 Binary files /dev/null and b/lib/ocp/cluster/manager/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/cluster/manager/__pycache__/info.cpython-310.pyc b/lib/ocp/cluster/manager/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..c9cbb786 Binary files /dev/null and b/lib/ocp/cluster/manager/__pycache__/info.cpython-310.pyc differ diff --git a/lib/ocp/cluster/manager/__pycache__/main.cpython-310.pyc b/lib/ocp/cluster/manager/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9f0146d4 Binary files /dev/null and b/lib/ocp/cluster/manager/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/cluster/manager/__pycache__/output.cpython-310.pyc b/lib/ocp/cluster/manager/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..1b240940 Binary files /dev/null and b/lib/ocp/cluster/manager/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/cluster/manager/main.py b/lib/ocp/cluster/manager/main.py new file mode 100644 index 00000000..be1992b8 --- /dev/null +++ b/lib/ocp/cluster/manager/main.py @@ -0,0 +1,44 @@ +from lib import ssh + + +class OcpClusterManager(): + def __init__(self): + pass + + def get_ocp_cluster_manager_file(self, filename): + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['parameters']['installer']['vm']['ip'], + self.ocp_cluster_settings['parameters']['installer']['vm']['username'], + password=self.ocp_cluster_settings['parameters']['installer']['vm']['password'], + log_id=self.log_id + ) + return ssh_handler.get_file(filename) + + def get_ocp_cluster_manager_info(self, validate=False): + info = {} + info['__Output'] = {} + info['name'] = self.ocp_cluster_settings['name'] + info['installation'] = self.ocp_cluster_settings['parameters']['ocp']['installation'] + info['release'] = self.ocp_cluster_settings['parameters']['ocp']['release'] + info['cni'] = self.ocp_cluster_settings['parameters']['cni']['type'] + try: + info['ssh'] = {} + info['ssh']['ip'] = self.ocp_cluster_settings['parameters']['installer']['vm']['ip'] + info['ssh']['username'] = self.ocp_cluster_settings['parameters']['installer']['vm']['username'] + info['ssh']['password'] = self.ocp_cluster_settings['parameters']['installer']['vm']['password'] + except BaseException: + info['ssh'] = None + + if validate and info['ssh'] is not None: + ssh_handler = ssh.Ssh( + info['ssh']['ip'], + info['ssh']['username'], + password=info['ssh']['password'], + log_id=self.log_id + ) + info['ssh']['validated'] = ssh_handler.is_ssh() + if info['ssh']['validated']: + info['ssh']['tick'] = '\u2713' + info['__Output']['ssh.tick'] = 'Green' + + return info diff --git a/lib/ocp/cluster/manager/output.py b/lib/ocp/cluster/manager/output.py new file mode 100644 index 00000000..3d02b658 --- /dev/null +++ b/lib/ocp/cluster/manager/output.py @@ -0,0 +1,68 @@ +class OcpClusterManagerOutput(): + def __init__(self): + pass + + def print_ocp_cluster_manager(self, info): + order = [ + 'name', + 'installation', + 'release', + 'cni', + 'ssh.ip', + 'ssh.username', + 'ssh.password', + 'ssh.tick' + ] + + headers = [ + 'Name', + 'Type', + 'Release', + 'CNI', + 'IP', + 'Username', + 'Password', + 'SSH' + ] + + self.my_output.dictionary( + info, + title='OCP Installer', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + def print_ocp_clusters_manager(self, info): + order = [ + 'name', + 'installation', + 'release', + 'cni', + 'ssh.ip', + 'ssh.username', + 'ssh.password', + 'ssh.tick' + ] + + headers = [ + 'Name', + 'Type', + 'Release', + 'CNI', + 'IP', + 'Username', + 'Password', + 'Validated' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + table=True + ) diff --git a/lib/ocp/cluster/output.py b/lib/ocp/cluster/output.py new file mode 100644 index 00000000..57004e3b --- /dev/null +++ b/lib/ocp/cluster/output.py @@ -0,0 +1,130 @@ +from lib.ocp.cluster.cnv.output import OcpClusterCnvOutput +from lib.ocp.cluster.console.output import OcpClusterConsoleOutput +from lib.ocp.cluster.kubeconfig.output import OcpClusterKubeconfigOutput +from lib.ocp.cluster.manager.output import OcpClusterManagerOutput +from lib.ocp.cluster.vcenter.output import OcpClusterVcenterOutput + + +class OcpClusterOutput( + OcpClusterCnvOutput, + OcpClusterConsoleOutput, + OcpClusterKubeconfigOutput, + OcpClusterManagerOutput, + OcpClusterVcenterOutput + ): + def __init__(self): + OcpClusterCnvOutput.__init__(self) + OcpClusterConsoleOutput.__init__(self) + OcpClusterKubeconfigOutput.__init__(self) + OcpClusterManagerOutput.__init__(self) + OcpClusterVcenterOutput.__init__(self) + + def print_ocp_clusters(self, clusters): + order = [ + 'name', + 'kubeconfig', + 'virtctl.descr', + 'helm.descr', + 'tools.descr' + ] + + headers = [ + 'Name', + 'Kubeconfig', + 'Virtctl', + 'Helm', + 'Tools' + ] + + for cluster in clusters: + for key in ['virtctl', 'helm', 'tools']: + if cluster[key] is None: + cluster[key] = {} + cluster[key]['descr'] = '--' + else: + if cluster[key]['password'] is not None: + cluster[key]['descr'] = '%s@%s w/pass' % ( + cluster[key]['username'], + cluster[key]['ip'] + ) + else: + cluster[key]['descr'] = '%s@%s w/key' % ( + cluster[key]['username'], + cluster[key]['ip'] + ) + + self.my_output.my_table( + clusters, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_ocp_clusters_state(self, info): + order = [ + 'name', + 'online', + 'ocp', + 'version', + 'cni', + 'cluster.cidr', + 'cluster.hostPrefix', + 'service' + ] + + headers = [ + 'Name', + 'Online', + 'OCP', + 'Kubernetes', + 'CNI', + 'Cluster CIDR', + 'Prefix', + 'Service' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['cluster', 'service'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_ocp_clusters_iwo(self, clusters): + order = [ + 'name', + 'installation', + 'release', + 'installedTick', + 'connectedTick', + 'hostname', + 'ips' + ] + + headers = [ + 'Name', + 'Type', + 'Release', + 'Installed', + 'Connected', + 'Hostnames', + 'IP Addresses' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + clusters, + order, + ['hostname', 'ips'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) diff --git a/lib/ocp/cluster/vcenter/__init__.py b/lib/ocp/cluster/vcenter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/cluster/vcenter/__pycache__/__init__.cpython-310.pyc b/lib/ocp/cluster/vcenter/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..97f0e94b Binary files /dev/null and b/lib/ocp/cluster/vcenter/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/cluster/vcenter/__pycache__/info.cpython-310.pyc b/lib/ocp/cluster/vcenter/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..336a972e Binary files /dev/null and b/lib/ocp/cluster/vcenter/__pycache__/info.cpython-310.pyc differ diff --git a/lib/ocp/cluster/vcenter/__pycache__/main.cpython-310.pyc b/lib/ocp/cluster/vcenter/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..af072fc3 Binary files /dev/null and b/lib/ocp/cluster/vcenter/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/cluster/vcenter/__pycache__/output.cpython-310.pyc b/lib/ocp/cluster/vcenter/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..7f507046 Binary files /dev/null and b/lib/ocp/cluster/vcenter/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/cluster/vcenter/main.py b/lib/ocp/cluster/vcenter/main.py new file mode 100644 index 00000000..b9acaa41 --- /dev/null +++ b/lib/ocp/cluster/vcenter/main.py @@ -0,0 +1,114 @@ +import json + +from lib import ssh +from lib.vc import vcenter + + +class OcpClusterVcenter(): + def __init__(self): + self.ocp_vcenter_handler = None + + def get_vc_handler(self): + if self.ocp_vcenter_handler is not None: + return self.ocp_vcenter_handler + + if 'vcenter' not in self.ocp_cluster_settings['parameters']: + return None + + ocp_vcenter_settings = self.ocp_cluster_settings['parameters']['vcenter'] + self.ocp_vcenter_handler = vcenter.Vcenter( + ocp_vcenter_settings['ip'], + ocp_vcenter_settings['username'], + ocp_vcenter_settings['password'], + port=ocp_vcenter_settings['port'], + log_id=self.log_id + ) + return self.ocp_vcenter_handler + + def get_terraform_cluster_id(self): + if 'cluster_id' in self.ocp_cluster_settings: + return self.ocp_cluster_settings['cluster_id'] + + try: + key_filename = self.ocp_cluster_settings['parameters']['installer']['vm']['key_filename'] + except BaseException: + key_filename = None + + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['parameters']['installer']['vm']['ip'], + self.ocp_cluster_settings['parameters']['installer']['vm']['username'], + password=self.ocp_cluster_settings['parameters']['installer']['vm']['password'], + key_filename=key_filename, + log_id=self.log_id + ) + if ssh_handler is None: + self.log.error( + 'get_terraform_cluster_id', + 'Installation VM ssh failed' + ) + return None + + tfvars = ssh_handler.get_file( + '/root/install/terraform.tfvars.json', + convert_json=True + ) + if tfvars is None: + self.log.error( + 'get_terraform_cluster_id', + 'Failed to get /root/install/terraform.tfvars.json' + ) + return None + + self.log.debug( + 'get_terraform_cluster_id', + json.dumps(tfvars, indent=4) + ) + + if 'cluster_id' not in tfvars: + self.log.error( + 'get_terraform_cluster_id', + 'Unexpected tfvars' + ) + return None + + success = self.settings_handler.set_ocp_cluster_parameter( + self.ocp_cluster_settings['name'], + 'cluster_id', + tfvars['cluster_id'] + ) + if not success: + self.log.error( + 'get_terraform_cluster_id', + 'OCP cluster settings update failed' + ) + + self.ocp_cluster_settings['cluster_id'] = tfvars['cluster_id'] + return tfvars['cluster_id'] + + def get_ocp_cluster_vcenter_info(self): + ocp_vcenter_handler = self.get_vc_handler() + if ocp_vcenter_handler is None: + return None + + info = {} + info['__Output'] = {} + info['name'] = self.ocp_cluster_settings['name'] + info['vcenter'] = self.ocp_cluster_settings['parameters']['vcenter'] + info['installer_vm_name'] = self.ocp_cluster_settings['parameters']['installer']['vm']['name'] + info['cluster_id'] = self.get_terraform_cluster_id() + if info['cluster_id'] is None: + return None + + vm_filter = [] + vm_filter.append( + 'name:%s' % (info['cluster_id']) + ) + vm_filter.append( + 'name:%s' % (info['installer_vm_name']) + ) + + info['vms'] = ocp_vcenter_handler.get_vms( + vm_filter=vm_filter + ) + + return info diff --git a/lib/ocp/cluster/vcenter/output.py b/lib/ocp/cluster/vcenter/output.py new file mode 100644 index 00000000..ceaaabe6 --- /dev/null +++ b/lib/ocp/cluster/vcenter/output.py @@ -0,0 +1,81 @@ +class OcpClusterVcenterOutput(): + def __init__(self): + pass + + def print_ocp_clusters_vcenter(self, clusters): + order = [ + 'name', + 'vcenter.name', + 'vms.stateFlag', + 'vms.name', + 'vms.host', + 'vms.cpu.info', + 'vms.cpuUsageUnit', + 'vms.memoryUnit', + 'vms.guestMemoryUsagePct', + 'vms.numEthernetCards', + 'vms.provisionedStorageUnit', + 'vms.usedStoragePct' + ] + + headers = [ + 'Name', + 'vCenter', + 'SF', + 'VM Name', + 'Host', + 'CPU', + 'Usage', + 'Memory', + '[%]', + 'NIC', + 'Storage', + '[%]' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + clusters, + order, + ['vms'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) + + def print_ocp_cluster_vcenter(self, info): + order = [ + 'stateFlag', + 'name', + 'host', + 'cpu.info', + 'cpuUsageUnit', + 'memoryUnit', + 'guestMemoryUsagePct', + 'numEthernetCards', + 'provisionedStorageUnit', + 'usedStoragePct' + ] + + headers = [ + 'SF', + 'VM Name', + 'Host', + 'CPU', + 'Usage', + 'Memory', + '[%]', + 'NIC', + 'Storage', + '[%]' + ] + + self.my_output.my_table( + info['vms'], + order=order, + headers=headers, + allow_order_subkeys=True, + table=True + ) diff --git a/lib/ocp/lcm/__init__.py b/lib/ocp/lcm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/lcm/__pycache__/__init__.cpython-310.pyc b/lib/ocp/lcm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9f30bb1b Binary files /dev/null and b/lib/ocp/lcm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/lcm/__pycache__/common.cpython-310.pyc b/lib/ocp/lcm/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..ca9ffa66 Binary files /dev/null and b/lib/ocp/lcm/__pycache__/common.cpython-310.pyc differ diff --git a/lib/ocp/lcm/__pycache__/create.cpython-310.pyc b/lib/ocp/lcm/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..5091ede6 Binary files /dev/null and b/lib/ocp/lcm/__pycache__/create.cpython-310.pyc differ diff --git a/lib/ocp/lcm/__pycache__/delete.cpython-310.pyc b/lib/ocp/lcm/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..0fd706d2 Binary files /dev/null and b/lib/ocp/lcm/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/ocp/lcm/__pycache__/main.cpython-310.pyc b/lib/ocp/lcm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e73e12e2 Binary files /dev/null and b/lib/ocp/lcm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/lcm/__pycache__/validate.cpython-310.pyc b/lib/ocp/lcm/__pycache__/validate.cpython-310.pyc new file mode 100644 index 00000000..d6f6884d Binary files /dev/null and b/lib/ocp/lcm/__pycache__/validate.cpython-310.pyc differ diff --git a/lib/ocp/lcm/common.py b/lib/ocp/lcm/common.py new file mode 100644 index 00000000..1f98a749 --- /dev/null +++ b/lib/ocp/lcm/common.py @@ -0,0 +1,77 @@ +import os +import sys +import uuid + +from lib import file_helper +from lib import ip_helper +from lib import template + + +class OcpCommon(): + def __init__(self): + self.template_handler = template.Template( + debug=False + ) + + def get_template_dir(self): + template_dir = os.path.join( + os.path.join( + os.path.join( + file_helper.get_main_dir(), + 'templates' + ), + 'ocp' + ), + self.ocp_type + ) + return template_dir + + def get_template_filename(self, filename): + files_dir = os.path.join( + self.get_template_dir(), + 'files' + ) + template_filename = os.path.join(files_dir, filename) + if not os.path.isfile(template_filename): + self.my_output.error('Template file not found: %s' % (template_filename)) + return None + + return template_filename + + def get_template_content(self, filename, variables): + template_filename = self.get_template_filename(filename) + if template_filename is None: + return None + + content = self.template_handler.get_template( + template_filename, + variables + ) + if content is None: + self.my_output.error('Template failed: %s' % (template_filename)) + return None + + return content + + def is_template_valid(self, filename, variables): + content = self.get_template_content(filename, variables) + if content is None: + return False + return True + + def is_source_local(self, source_filename): + if source_filename.startswith('http://') or source_filename.startswith('https://'): + return False + return True + + def download_source_file(self, source_filename): + self.my_output.default('Download file', underline=True, before_newline=True, after_newline=True) + self.my_output.default('Source: %s' % (source_filename)) + destination_filename = '/tmp/%s' % (str(uuid.uuid4())) + self.my_output.default('Destination: %s' % (destination_filename)) + + if not ip_helper.download_url(source_filename, destination_filename): + self.my_output.error('Web download failed') + return None + + return destination_filename diff --git a/lib/ocp/lcm/create.py b/lib/ocp/lcm/create.py new file mode 100644 index 00000000..8c236ee5 --- /dev/null +++ b/lib/ocp/lcm/create.py @@ -0,0 +1,195 @@ +import os +import socket + +from lib import file_helper +from lib.k8s import main as k8s +from lib.ocp.cluster.console import main as ocp_cluster_console +from lib.ocp.cluster.kubeconfig import main as ocp_cluster_kubeconfig + + +class OcpCreate(): + def __init__(self): + pass + + def validate_dns_resolution(self, name, ip_address): + try: + api_resolved_ip = socket.gethostbyname(name) + + except BaseException: + self.my_output.error('DNS resolution failed: %s' % (name)) + self.my_output.default( + 'Expected DNS resolution (%s, %s)' % ( + name, + ip_address + ) + ) + return False + + if api_resolved_ip != ip_address: + self.my_output.default( + 'Expected DNS resolution (%s, %s)' % ( + name, + ip_address + ) + ) + return False + + self.my_output.default('DNS resolved: (%s, %s)' % (name, ip_address)) + return True + + def validate_dns(self, ocp_parameters): + name = 'api.%s.%s' % ( + ocp_parameters['ocp']['cluster']['name'], + ocp_parameters['ocp']['cluster']['domain'] + ) + ip_address = ocp_parameters['ocp']['cluster']['api_vip'] + + if not self.validate_dns_resolution(name, ip_address): + return False + + name = 'oauth-openshift.apps.%s.%s' % ( + ocp_parameters['ocp']['cluster']['name'], + ocp_parameters['ocp']['cluster']['domain'] + ) + ip_address = ocp_parameters['ocp']['cluster']['ingress_vip'] + + if not self.validate_dns_resolution(name, ip_address): + return False + + name = 'console-openshift-console.apps.%s.%s' % ( + ocp_parameters['ocp']['cluster']['name'], + ocp_parameters['ocp']['cluster']['domain'] + ) + ip_address = ocp_parameters['ocp']['cluster']['ingress_vip'] + + if not self.validate_dns_resolution(name, ip_address): + return False + + return True + + def validate_create(self, input_location): + self.my_output.default('Input parameters verification...') + ocp_parameters = None + + if self.ocp_type == 'vsphere-ipi': + ocp_parameters = self.validate_vsphere_ipi_create_user_input() + + if ocp_parameters is None: + return None + + if not self.validate_dns(ocp_parameters): + return None + + if ocp_parameters['cni']['type'] == 'Cilium': + cilium_config_filename = os.path.join( + input_location, + 'cilium_config.yaml' + ) + + if not os.path.isfile(cilium_config_filename): + self.my_output.error('Cilium configuration expected: %s' % (cilium_config_filename)) + return None + + cilium_config_content = file_helper.get_file_yaml(cilium_config_filename) + if cilium_config_content is None: + self.my_output.error('Cilium configuration yaml expected: %s' % (cilium_config_filename)) + return None + + self.my_output.default('Cilium configuration valid: %s' % (cilium_config_filename)) + + return ocp_parameters + + def create(self): + ocp_parameters = self.validate_create(self.ocp_user_input_location) + if ocp_parameters is None: + return False + + if self.ocp_type == 'vsphere-ipi': + success = self.vsphere_ipi_ocp_create(ocp_parameters, self.ocp_user_input_location) + if not success: + return False + + ocp_kubeconfig_handler = ocp_cluster_kubeconfig.OcpClusterKubeconfig(log_id=self.log_id) + kubeconfig_filename = ocp_kubeconfig_handler.download_kubeconfig( + ocp_parameters['installer']['vm']['ip'], + ocp_parameters['installer']['vm']['username'], + ocp_parameters['installer']['vm']['password'], + silent=True + ) + if kubeconfig_filename is None: + return False + self.my_output.default('Kubeconfig downloaded') + + if self.ocp_settings_handler.is_ocp_cluster(ocp_parameters['ocp']['name']): + success = self.ocp_settings_handler.set_ocp_cluster_kubeconfig( + ocp_parameters['ocp']['name'], + kubeconfig_filename + ) + if not success: + self.my_output.error('Failed to set ocp cluster kubeconfig locally') + return False + self.my_output.default('OCP instance configured: %s' % (ocp_parameters['ocp']['name'])) + else: + success = self.ocp_settings_handler.create_ocp_cluster( + ocp_parameters['ocp']['name'], + kubeconfig_filename + ) + if not success: + self.my_output.error('Failed to create ocp cluster locally') + return False + + self.my_output.default('OCP instance created: %s' % (ocp_parameters['ocp']['name'])) + + success = ocp_kubeconfig_handler.check_kubeconfig( + kubeconfig_filename, + ocp_parameters['ocp']['cluster']['api_vip'], + silent=False + ) + if not success: + return False + + ocp_console_handler = ocp_cluster_console.OcpClusterConsole( + log_id=self.log_id + ) + kubeadmin_filename = ocp_console_handler.download_kubeadmin( + ocp_parameters['installer']['vm']['ip'], + ocp_parameters['installer']['vm']['username'], + ocp_parameters['installer']['vm']['password'], + silent=True + ) + if kubeadmin_filename is None: + self.my_output.default('Kubeadmin download failed') + return False + self.my_output.default('Kubeadmin downloaded') + + target_filename = self.ocp_settings_handler.copy_ocp_cluster_file( + ocp_parameters['ocp']['name'], + kubeadmin_filename, + 'kubeadmin' + ) + if target_filename is None: + self.my_output.error('Kubeadmin local copy failed') + return False + self.my_output.default('Kubeadmin copied to ocp cluster location') + + success = self.ocp_settings_handler.set_ocp_cluster_parameter( + ocp_parameters['ocp']['name'], + 'kubeadmin', + target_filename + ) + if not success: + self.my_output.error('Cluster settings failed') + return False + + self.my_output.default('OCP instance configured: %s' % (ocp_parameters['ocp']['name'])) + + k8s_handler = k8s.K8s( + kubeconfig_filename, + log_id=self.log_id + ) + if not k8s_handler.get_namespaces(): + self.my_output.error('Kubernetes authentication failed') + return False + self.my_output.default('Kubernetes authentication successful with local kubeconfig') + + return True diff --git a/lib/ocp/lcm/delete.py b/lib/ocp/lcm/delete.py new file mode 100644 index 00000000..4b0cc837 --- /dev/null +++ b/lib/ocp/lcm/delete.py @@ -0,0 +1,35 @@ +class OcpDelete(): + def __init__(self): + pass + + def validate_delete(self): + self.my_output.default('Input parameters verification...') + ocp_parameters = None + + if self.ocp_type == 'vsphere-ipi': + ocp_parameters = self.validate_vsphere_ipi_delete_user_input() + + if ocp_parameters is None: + return None + + return ocp_parameters + + def delete(self): + ocp_parameters = self.validate_delete() + if ocp_parameters is None: + return False + + if self.ocp_type == 'vsphere-ipi': + success = self.vsphere_ipi_ocp_delete(ocp_parameters) + if not success: + return False + + success = self.ocp_settings_handler.delete_ocp_cluster( + ocp_parameters['ocp']['name'] + ) + if not success: + return False + + self.my_output.default('OCP instance deleted: %s' % (ocp_parameters['ocp']['name'])) + + return True diff --git a/lib/ocp/lcm/main.py b/lib/ocp/lcm/main.py new file mode 100644 index 00000000..827a0474 --- /dev/null +++ b/lib/ocp/lcm/main.py @@ -0,0 +1,30 @@ +from lib import log_helper +from lib import output_helper + +from lib.ocp.lcm.common import OcpCommon +from lib.ocp.lcm.create import OcpCreate +from lib.ocp.lcm.delete import OcpDelete +from lib.ocp.lcm.validate import OcpValidate +from lib.ocp.lcm.vsphere.main import OcpVsphere +from lib.ocp import settings as ocp_settings + + +class Ocp(OcpCommon, OcpCreate, OcpDelete, OcpValidate, OcpVsphere): + def __init__(self, verbose=False, debug=False, log_id=None): + OcpCommon.__init__(self) + OcpCreate.__init__(self) + OcpDelete.__init__(self) + OcpValidate.__init__(self) + OcpVsphere.__init__(self) + + self.verbose = verbose + self.debug = debug + self.log_id = log_id + + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + self.ocp_settings_handler = ocp_settings.OcpSettings(log_id=log_id) diff --git a/lib/ocp/lcm/validate.py b/lib/ocp/lcm/validate.py new file mode 100644 index 00000000..99a18473 --- /dev/null +++ b/lib/ocp/lcm/validate.py @@ -0,0 +1,582 @@ +import os +import json + +from lib import file_helper +from lib import ip_helper + + +class OcpValidate(): + def __init__(self): + self.ocp_type = None + self.ocp_user_input_location = None + self.ocp_user_input = None + self.ocp_token_filename = None + self.vcenter_credentials = None + + def set_ocp_type(self): + try: + installation_method = str(self.ocp_user_input['ocp']['installation']) + except BaseException: + self.my_output.error('ocp.installation property required') + self.my_output.debug(json.dumps(self.ocp_user_input, indent=4)) + return False + + supported_methods = ['vsphere-ipi', 'bm-ipi'] + if installation_method not in supported_methods: + self.my_output.error('Unsupported ocp.installation value: %s' % (installation_method)) + self.my_output.default('Supported values') + for supported_method in supported_methods: + self.my_output.default('- %s' % (supported_method)) + return False + + self.ocp_type = installation_method + return True + + def set_ocp_user_input(self, ocp_definition_location): + self.ocp_user_input_location = ocp_definition_location + if not os.path.isfile(ocp_definition_location) and not os.path.isdir(ocp_definition_location): + self.my_output.error('Specify valid location of OCP configuration') + return False + + token_filename = os.path.join(ocp_definition_location, 'secret') + token_filename = os.path.join(token_filename, 'pull-secret.txt') + if not os.path.isfile(token_filename): + self.my_output.error('Specify valid OCP secret file: %s' % (token_filename)) + return False + + self.ocp_token_filename = token_filename + + vcenter_filename = os.path.join(ocp_definition_location, 'secret') + vcenter_filename = os.path.join(vcenter_filename, 'vcenter.yaml') + if not os.path.isfile(vcenter_filename): + self.my_output.error('Specify valid vcenter credentials file: %s' % (vcenter_filename)) + return False + + self.vcenter_credentials = file_helper.get_file_yaml(vcenter_filename) + if self.vcenter_credentials is None: + self.my_output.error('Specify valid vcenter credentials file: %s' % (vcenter_filename)) + return False + + if 'username' not in self.vcenter_credentials or 'password' not in self.vcenter_credentials: + self.my_output.error('Specify valid vcenter credentials file: %s' % (vcenter_filename)) + return False + + self.ocp_user_input = self.get_input(ocp_definition_location) + if self.ocp_user_input is None: + return False + + if not self.set_ocp_type(): + return False + + self.my_output.debug('User input: %s' % (json.dumps(self.ocp_user_input, indent=4))) + return True + + def get_token(self, filename): + if not os.path.isfile(filename): + self.my_output.error('File %s not found' % (filename)) + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.readlines() + + except BaseException: + self.my_output.error('File read exception: %s' % (filename)) + return None + + return content + + def get_input(self, location): + if os.path.isfile(location): + content = file_helper.get_file_yaml(location) + if content is None: + self.log.error( + 'get_input', + 'File read failed: %s' % (location) + ) + return None + + return content + + content = {} + for filename in os.listdir(location): + content_filename = os.path.join(location, filename) + if os.path.isdir(content_filename): + continue + + part = file_helper.get_file_yaml( + content_filename + ) + if part is None: + continue + + for key in part: + if key in content: + self.my_output.error('Sections have to be defined in single file: %s' % (key)) + return None + + content[key] = part[key] + + return content + + def get_section_rules(self, section_name): + main_dir = file_helper.get_main_dir() + if main_dir is None: + self.my_output.error('Failed to get module location') + return None + + templates_dir = os.path.join(main_dir, 'templates') + ocp_templates_dir = os.path.join(templates_dir, 'ocp') + installation_method_dir = os.path.join(ocp_templates_dir, self.ocp_type) + rules_dir = os.path.join(installation_method_dir, 'rules') + rules_filename = os.path.join(rules_dir, '%s.yaml' % (section_name)) + return file_helper.get_file_yaml(rules_filename) + + def is_key_in_section(self, key, section): + try: + value = None + for field in key.split('.'): + if value is None: + value = section[field] + continue + + value = value[field] + + except BaseException: + return False + + return True + + def get_key_value(self, key, section): + try: + value = None + for field in key.split('.'): + if value is None: + value = section[field] + continue + + value = value[field] + + except BaseException: + return None + + return value + + def add_key_value(self, section, key, value): + try: + if len(key.split('.')) == 1: + section[key] = value + return section + + subsection = None + for subdict in key.split('.')[:-1]: + if subsection is None: + if subdict not in section: + section[subdict] = {} + subsection = section[subdict] + continue + + if subdict not in subsection: + subsection[subdict] = {} + subsection = subsection[subdict] + + subsection[key.split('.')[-1]] = value + + except BaseException: + return None + + return section + + def validate_key_value(self, section_name, key, rules, value): + attribute_name = '%s.%s' % (section_name, key) + + if rules['type'] not in ['str', 'int', 'bool', 'list_of_ip', 'list_of_str']: + self.my_output.error('Unsupported attribute type: %s' % (rules['type'])) + self.my_output.default('Section: %s' % (section_name)) + self.my_output.default('Key: %s' % (key)) + self.my_output.default('Rules: %s' % (rules)) + self.my_output.default('Value: %s' % (value)) + return False, None + + if rules['type'] == 'str': + if value is None and rules['check'] == 'local-file-null-accepted': + pass + else: + if not isinstance(value, str): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'int': + if not isinstance(value, int): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'bool': + if not isinstance(value, bool): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'list_of_ip': + if not isinstance(value, list): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + for item in value: + if not ip_helper.is_valid_ipv4_address(item): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'list_of_ip': + if not isinstance(value, list): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + for item in value: + if not isinstance(item, str): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['check'] is not None: + if rules['type'] == 'bool': + if rules['check'] == 'must-be-true': + if not value: + self.my_output.error('Expected attribute %s value is True: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'must-be-false': + if value: + self.my_output.error('Expected attribute %s value is False: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['type'] == 'str': + if rules['check'] == 'ipv4': + if not ip_helper.is_valid_ipv4_address(value): + self.my_output.error('Expected attribute %s value is valid IPv4 address: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'ipv4s': + for item in value.split(','): + if not ip_helper.is_valid_ipv4_address(item): + self.my_output.error('Expected attribute %s value is list of valid IPv4 addresses: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'ipv6': + if not ip_helper.is_valid_ipv6_address(value): + self.my_output.error('Expected attribute %s value is valid IPv6 address: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'cidrv4': + if not ip_helper.is_valid_ipv4_cidr(value): + self.my_output.error('Expected attribute %s value is valid IPv4 CIDR: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'cidrv6': + if not ip_helper.is_valid_ipv6_cidr(value): + self.my_output.error('Expected attribute %s value is valid IPv6 CIDR: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'url': + if not ip_helper.is_url_valid(value): + self.my_output.error('Expected attribute %s value is valid URL: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'dhcp-v4-range': + if len(value.split('-')) != 2: + self.my_output.error('Expected attribute %s value is valid IPv4 address ranges: %s' % (attribute_name, value)) + return False, None + + (start_ip, end_ip) = value.split('-') + if not ip_helper.is_valid_ipv4_address(start_ip) or not ip_helper.is_valid_ipv4_address(end_ip): + self.my_output.error('Expected attribute %s value is valid IPv4 address ranges: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['check'] == 'not-empty-no-spaces': + if value is None: + value = '' + value = value.strip() + + if len(value) == 0: + self.my_output.error('Expected attribute %s value is non-empty string without spaces: %s' % (attribute_name, value)) + return False, None + + if ' ' in value: + self.my_output.error('Expected attribute %s value is non-empty string without spaces: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['check'] == 'not-empty': + if value is None: + value = '' + value = value.strip() + + if len(value) == 0: + self.my_output.error('Expected attribute %s value is non-empty string: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['check'].startswith('values:'): + reference_values = rules['check'].lstrip('values').lstrip(':') + if value not in reference_values.split(','): + self.my_output.error('Expected attribute %s value is one of %s: %s' % (attribute_name, reference_values, value)) + return False, None + return True, value + + if rules['check'] == 'local-file': + if not os.path.isfile(value): + self.my_output.error('Expected attribute %s value is existing local file: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'local-file-null-accepted': + if value is None: + return True, None + + if len(value) == 0: + return True, None + + if not os.path.isfile(value): + self.my_output.error('Expected attribute %s value is existing local file: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['type'] == 'int': + if rules['check'] == 'port': + if value < 1 or value > 65535: + self.my_output.error('Expected attribute %s value is within TCP/UDP port range: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'host-prefix-v4': + if value < 1 or value > 30: + self.my_output.error('Expected attribute %s value is within <1,30> range: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'host-prefix-v6': + if value > 127 or value < 64: + self.my_output.error('Expected attribute %s value is within <64,127> range: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'].startswith('ge'): + reference_value = int(rules['check'].lstrip('ge')) + if value < reference_value: + self.my_output.error('Expected attribute %s value is greater or equal %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('gt'): + reference_value = int(rules['check'].lstrip('gt')) + if value <= reference_value: + self.my_output.error('Expected attribute %s value is greater than %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('le'): + reference_value = int(rules['check'].lstrip('le')) + if value > reference_value: + self.my_output.error('Expected attribute %s value is lower or equal %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('lt'): + reference_value = int(rules['check'].lstrip('lt')) + if value >= reference_value: + self.my_output.error('Expected attribute %s value is lower than %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('eq'): + reference_value = int(rules['check'].lstrip('eq')) + if value != reference_value: + self.my_output.error('Expected attribute %s value is %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + self.my_output.error('Unsupported check: %s' % (rules['check'])) + self.my_output.default('Section: %s' % (section_name)) + self.my_output.default('Key: %s' % (key)) + self.my_output.default('Rules: %s' % (rules)) + self.my_output.default('Value: %s' % (value)) + return False, None + + return True, value + + def validate_section(self, section_name, user_input): + rules = self.get_section_rules(section_name) + if rules is None: + self.my_output.error('Section %s rules not defined for installation method %s' % (section_name, self.ocp_type)) + return None + + if rules['value'] == 'dict': + if not isinstance(user_input, dict): + self.my_output.error('Section %s is expected to be dictionary' % (section_name)) + return None + + validated_input = {} + for key in rules['properties']: + if rules['properties'][key]['mandatory']: + if not self.is_key_in_section(key, user_input): + self.my_output.error('Required property %s.%s' % (section_name, key)) + return None + + success, value = self.validate_key_value( + section_name, + key, + rules['properties'][key], + self.get_key_value(key, user_input) + ) + if not success: + return None + + validated_input = self.add_key_value( + validated_input, + key, + value + ) + + if not rules['properties'][key]['mandatory']: + if self.is_key_in_section(key, user_input): + success, value = self.validate_key_value( + section_name, + key, + rules['properties'][key], + self.get_key_value(key, user_input) + ) + if not success: + return None + + validated_input = self.add_key_value( + validated_input, + key, + value + ) + else: + validated_input = self.add_key_value( + validated_input, + key, + rules['properties'][key]['default'] + ) + + if rules['value'] == 'list_of_dict': + if not isinstance(user_input, list): + self.my_output.error('Section %s is expected to be list' % (section_name)) + return None + + if 'min_length' in rules: + if len(user_input) < rules['min_length']: + self.my_output.error('Section %s is expected to be list with minimum %s elements: %s' % (section_name, rules['min_length'], len(user_input))) + return None + + if 'max_length' in rules: + if len(user_input) > rules['max_length']: + self.my_output.error('Section %s is expected to be list with maximum %s elements: %s' % (section_name, rules['max_length'], len(user_input))) + return None + + validated_input = [] + for item in user_input: + if not isinstance(item, dict): + self.my_output.error('Section %s is expected to be list of dict' % (section_name)) + return None + + validated_item = {} + for key in rules['properties']: + if rules['properties'][key]['mandatory']: + if not self.is_key_in_section(key, item): + self.my_output.error('Required property %s.%s' % (section_name, key)) + return None + + success, value = self.validate_key_value( + section_name, + key, + rules['properties'][key], + self.get_key_value(key, item) + ) + if not success: + return None + + validated_item = self.add_key_value( + validated_item, + key, + value + ) + + if not rules['properties'][key]['mandatory']: + if self.is_key_in_section(key, item): + success, value = self.validate_key_value( + section_name, + key, + rules['properties'][key], + self.get_key_value(key, item) + ) + if not success: + return None + + validated_item = self.add_key_value( + validated_item, + key, + value + ) + else: + validated_item = self.add_key_value( + validated_item, + key, + rules['properties'][key]['default'] + ) + + validated_input.append(validated_item) + + if rules['value'] == 'list_of_str': + if not isinstance(user_input, list): + self.my_output.error('Section %s is expected to be list' % (section_name)) + return None + + validated_input = [] + for value in user_input: + if not isinstance(value, str): + self.my_output.error('Section %s is expected to be list of strings' % (section_name)) + return None + + if rules['check'] is None: + validated_input.append(value) + continue + + if rules['check'] is not None: + if rules['check'] == 'ssh-public-key': + if not ip_helper.is_public_key_valid(value): + self.my_output.error('Section %s is expected to be list of ssh public keys' % (section_name)) + return None + validated_input.append(value) + continue + + self.my_output.error('Unsupported check: %s' % (rules['check'])) + return None + + return validated_input + + def validate_sections(self, mandatory, optional): + for key in mandatory: + if key not in self.ocp_user_input: + self.ocp_user_input[key] = {} + + validated_input = {} + for key in self.ocp_user_input: + if key in mandatory or key in optional: + validated_input[key] = self.validate_section(key, self.ocp_user_input[key]) + if validated_input[key] is None: + return None + + return validated_input diff --git a/lib/ocp/lcm/vsphere/__init__.py b/lib/ocp/lcm/vsphere/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/lcm/vsphere/__pycache__/__init__.cpython-310.pyc b/lib/ocp/lcm/vsphere/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9c507af7 Binary files /dev/null and b/lib/ocp/lcm/vsphere/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/__pycache__/main.cpython-310.pyc b/lib/ocp/lcm/vsphere/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4d177884 Binary files /dev/null and b/lib/ocp/lcm/vsphere/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/__pycache__/validate.cpython-310.pyc b/lib/ocp/lcm/vsphere/__pycache__/validate.cpython-310.pyc new file mode 100644 index 00000000..0e657872 Binary files /dev/null and b/lib/ocp/lcm/vsphere/__pycache__/validate.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/__init__.py b/lib/ocp/lcm/vsphere/ipi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/lcm/vsphere/ipi/__pycache__/__init__.cpython-310.pyc b/lib/ocp/lcm/vsphere/ipi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0ad91f35 Binary files /dev/null and b/lib/ocp/lcm/vsphere/ipi/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/__pycache__/create.cpython-310.pyc b/lib/ocp/lcm/vsphere/ipi/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..37ea4ec9 Binary files /dev/null and b/lib/ocp/lcm/vsphere/ipi/__pycache__/create.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/__pycache__/delete.cpython-310.pyc b/lib/ocp/lcm/vsphere/ipi/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..94f4ebfe Binary files /dev/null and b/lib/ocp/lcm/vsphere/ipi/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/__pycache__/installer.cpython-310.pyc b/lib/ocp/lcm/vsphere/ipi/__pycache__/installer.cpython-310.pyc new file mode 100644 index 00000000..5d42f7c3 Binary files /dev/null and b/lib/ocp/lcm/vsphere/ipi/__pycache__/installer.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/__pycache__/main.cpython-310.pyc b/lib/ocp/lcm/vsphere/ipi/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f59dbfcb Binary files /dev/null and b/lib/ocp/lcm/vsphere/ipi/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/__pycache__/validate.cpython-310.pyc b/lib/ocp/lcm/vsphere/ipi/__pycache__/validate.cpython-310.pyc new file mode 100644 index 00000000..c282fd57 Binary files /dev/null and b/lib/ocp/lcm/vsphere/ipi/__pycache__/validate.cpython-310.pyc differ diff --git a/lib/ocp/lcm/vsphere/ipi/create.py b/lib/ocp/lcm/vsphere/ipi/create.py new file mode 100644 index 00000000..69a1c3d1 --- /dev/null +++ b/lib/ocp/lcm/vsphere/ipi/create.py @@ -0,0 +1,497 @@ +import os +import json +import uuid + +from lib import ssh +from lib import file_helper + + +class OcpVsphereIpiCreate(): + def __init__(self): + self.ocp_parameters = None + self.input_location = None + self.installer_parameters = None + + def is_vsphere_ipi_ocp_ready(self): + ssh_handler = ssh.Ssh( + self.installer_parameters['vm']['ssh']['ip'], + self.installer_parameters['vm']['ssh']['username'], + password=self.installer_parameters['vm']['ssh']['password'], + log_id=self.log_id + ) + filename = '/root/install/.openshift_install_state.json' + return ssh_handler.is_file(filename) + + def vsphere_ipi_ocp_install(self): + filename = self.get_template_filename('packages.sh') + if not self.vcenter_handler.run_task_script(filename): + return False + + if 'dhcp' in self.ocp_parameters: + if self.ocp_parameters['dhcp']['managed']: + file_info = {} + file_info['source'] = self.get_template_filename('dhcpd.leases') + file_info['template'] = False + file_info['destination'] = '/var/lib/dhcpd/dhcpd.leases' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('dhcpd.conf') + file_info['template'] = True + file_info['destination'] = '/etc/dhcp/dhcpd.conf' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + commands = [ + 'dos2unix /etc/dhcp/dhcpd.conf', + 'dos2unix /var/lib/dhcpd/dhcpd.leases', + 'chown dhcpd:dhcpd /var/lib/dhcpd/dhcpd.leases', + 'systemctl restart dhcpd', + 'systemctl status dhcpd' + ] + for command in commands: + if not self.vcenter_handler.run_task_command(command): + return False + + if 'dns' in self.ocp_parameters: + if self.ocp_parameters['dns']['managed']: + command = 'mkdir -p /etc/named/zones' + if not self.vcenter_handler.run_task_command(command): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('dns_a') + file_info['template'] = True + file_info['destination'] = '/etc/named/zones/db.%s' % (self.ocp_parameters['ocp']['cluster']['domain']) + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('dns_arpa') + file_info['template'] = True + file_info['destination'] = '/etc/named/zones/db.reverse' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('named.conf') + file_info['template'] = True + file_info['destination'] = '/etc/named.conf' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + commands = [ + 'dos2unix /etc/named.conf', + 'dos2unix /etc/named/zones/db.reverse', + 'dos2unix /etc/named/zones/db.%s' % (self.ocp_parameters['ocp']['cluster']['domain']), + 'systemctl restart named', + 'systemctl status named', + 'rm /etc/resolv.conf' + ] + for command in commands: + if not self.vcenter_handler.run_task_command(command): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('resolv.conf') + file_info['template'] = True + file_info['destination'] = '/etc/resolv.conf' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + command = 'dos2unix /etc/resolv.conf' + if not self.vcenter_handler.run_task_command(command): + return False + + filename = self.get_template_filename('ssh-key-generation.sh') + if not self.vcenter_handler.run_task_script(filename): + return False + + file_info = {} + if self.is_source_local(self.ocp_parameters['sources']['ocp']): + delete_file = False + file_info['source'] = self.ocp_parameters['sources']['ocp'] + else: + delete_file = True + file_info['source'] = self.download_source_file(self.ocp_parameters['sources']['ocp']) + if file_info['source'] is None: + return False + + file_info['template'] = False + file_info['destination'] = '/root/openshift-install-linux.tar.gz' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if delete_file: + try: + os.remove(file_info['source']) + self.my_output.info('File removed after successful upload: %s' % (file_info['source'])) + except BaseException: + self.my_output.info('File delete failed: %s' % (file_info['source'])) + + file_info = {} + if self.is_source_local(self.ocp_parameters['sources']['oc']): + delete_file = False + file_info['source'] = self.ocp_parameters['sources']['oc'] + else: + delete_file = True + file_info['source'] = self.download_source_file(self.ocp_parameters['sources']['oc']) + if file_info['source'] is None: + return False + + file_info['template'] = False + file_info['destination'] = '/root/oc.tar.gz' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if delete_file: + try: + os.remove(file_info['source']) + self.my_output.info('File removed after successful upload: %s' % (file_info['source'])) + except BaseException: + self.my_output.info('File delete failed: %s' % (file_info['source'])) + + if self.ocp_parameters['cni']['type'] == 'Calico': + file_info = {} + delete_file = True + file_info['source'] = self.download_source_file(self.ocp_parameters['calico']['calicoctl']) + if file_info['source'] is None: + return False + + file_info['template'] = False + file_info['destination'] = '/usr/local/bin/calicoctl' + file_info['chmod'] = 744 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if delete_file: + try: + os.remove(file_info['source']) + self.my_output.info('File removed after successful upload: %s' % (file_info['source'])) + except BaseException: + self.my_output.info('File delete failed: %s' % (file_info['source'])) + + file_info = {} + file_info['source'] = self.ocp_parameters['sources']['secret'] + file_info['template'] = False + file_info['destination'] = '/root/pull-secret.txt' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + if self.installer_parameters['variables']['HTTP_PROXY_ENABLED'] == "True": + file_info['source'] = self.get_template_filename('config_proxy.yaml') + else: + file_info['source'] = self.get_template_filename('config_no_proxy.yaml') + file_info['template'] = True + file_info['destination'] = '/root/config.yaml' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if self.ocp_parameters['cni']['type'] == 'Calico': + file_info = {} + file_info['source'] = self.get_template_filename('calico_manifests.sh') + file_info['template'] = True + file_info['destination'] = '/root/calico_manifests.sh' + file_info['chmod'] = 744 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if self.ocp_parameters['cni']['type'] == 'Cilium': + file_info = {} + file_info['source'] = self.get_template_filename('cilium_manifests.sh') + file_info['template'] = True + file_info['destination'] = '/root/cilium_manifests.sh' + file_info['chmod'] = 744 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('cilium_agent.sh') + file_info['template'] = True + file_info['destination'] = '/root/cilium_agent.sh' + file_info['chmod'] = 744 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + file_info['source'] = os.path.join( + self.input_location, + 'cilium_config.yaml' + ) + file_info['template'] = False + file_info['destination'] = '/root/cilium_config.yaml' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if self.ocp_parameters['cilium']['extras']: + file_info = {} + file_info['source'] = os.path.join( + self.input_location, + 'cilium_extras.yaml' + ) + file_info['template'] = False + file_info['destination'] = '/root/cilium_extras.yaml' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + if 'bgp' in self.ocp_parameters: + file_info = {} + file_info['source'] = self.get_template_filename('bgp.yaml') + file_info['template'] = True + file_info['destination'] = '/root/bgp_configuration.yaml' + file_info['chmod'] = 744 + if not self.vcenter_handler.run_task_file(file_info): + return False + + file_info = {} + file_info['source'] = self.get_template_filename('patch.py') + file_info['template'] = True + file_info['destination'] = '/root/patch.py' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + return False + + commands = [ + 'dos2unix /root/config.yaml', + 'dos2unix /root/patch.py', + 'dos2unix /root/pull-secret.txt', + 'tar xzvf /root/openshift-install-linux.tar.gz', + 'tar xzvf /root/oc.tar.gz', + 'mv /root/kubectl /usr/local/bin', + 'mv /root/oc /usr/local/bin', + 'rm -f README.md', + 'rm -f /root/openshift-install-linux.tar.gz', + 'rm -f /root/oc.tar.gz', + 'python3 /root/patch.py', + 'rm -f /root/patch.py' + ] + if self.ocp_parameters['cni']['type'] == 'Calico': + commands.append( + 'dos2unix /root/calico_manifests.sh' + ) + + if self.ocp_parameters['cni']['type'] == 'Cilium': + commands.append( + 'dos2unix /root/cilium_manifests.sh' + ) + commands.append( + 'dos2unix /root/cilium_config.yaml' + ) + if self.ocp_parameters['cilium']['extras']: + commands.append( + 'dos2unix /root/cilium_extras.yaml' + ) + + if 'bgp' in self.ocp_parameters: + commands.append( + 'dos2unix /root/bgp_configuration.yaml' + ) + + for command in commands: + if not self.vcenter_handler.run_task_command(command): + return False + + filename = self.get_template_filename('certs.sh') + if not self.vcenter_handler.run_task_script(filename): + return False + + filename = self.get_template_filename('install.sh') + if not self.vcenter_handler.run_task_script(filename, live_output=True): + return False + + filename = self.get_template_filename('prepare_export.sh') + if not self.vcenter_handler.run_task_script(filename): + return False + + return True + + def is_vsphere_ipi_ocp_working(self): + filename = self.get_template_filename('check-ocp-nodes.sh') + if not self.vcenter_handler.run_task_script(filename): + self.my_output.error('OCP does not seem to be working fine') + return False + return True + + def is_vsphere_ipi_ocp_post_install_finished(self): + ssh_handler = ssh.Ssh( + self.installer_parameters['vm']['ssh']['ip'], + self.installer_parameters['vm']['ssh']['username'], + password=self.installer_parameters['vm']['ssh']['password'], + log_id=self.log_id + ) + filename = '/root/.post_install_finished' + return ssh_handler.is_file(filename) + + def set_vsphere_ipi_ocp_post_install_finished(self): + ssh_handler = ssh.Ssh( + self.installer_parameters['vm']['ssh']['ip'], + self.installer_parameters['vm']['ssh']['username'], + password=self.installer_parameters['vm']['ssh']['password'], + log_id=self.log_id + ) + filename = '/root/.post_install_finished' + if not ssh_handler.touch_file(filename): + self.my_output.error('Post installation flag create failed') + return False + + self.my_output.info('Post installation flag created') + return True + + def vsphere_ipi_ocp_post_install_upload(self, upload_filename, post_directory): + try: + with open(upload_filename, 'r', encoding='utf-8') as file_handler: + uploads = json.loads(file_handler.read()) + + except BaseException: + self.my_output.debug('Failed to read file: %s' % (upload_filename)) + return False + + for file_info in uploads: + file_info['source'] = os.path.join( + post_directory, + file_info['source'] + ) + if not self.vcenter_handler.run_task_file(file_info, create_directory=True): + return False + + return True + + def vsphere_ipi_ocp_post_install_commands(self, commands_filename): + try: + with open(commands_filename, 'r', encoding='utf-8') as file_handler: + commands = json.loads(file_handler.read()) + + except BaseException: + self.my_output.debug('Failed to read file: %s' % (commands_filename)) + return False + + for command in commands: + if not self.vcenter_handler.run_task_command(command): + return False + + return True + + def vsphere_ipi_ocp_post_install(self): + if self.is_vsphere_ipi_ocp_post_install_finished(): + self.my_output.info('Post install already completed') + return True + + post_directory = os.path.join( + self.input_location, + 'post' + ) + + if not os.path.isdir(post_directory): + self.my_output.info('No post installation tasks defined') + self.set_vsphere_ipi_ocp_post_install_finished() + return True + + upload_filename = os.path.join(post_directory, 'upload.json') + if os.path.isfile(upload_filename): + if not self.vsphere_ipi_ocp_post_install_upload(upload_filename, post_directory): + return False + + commands_filename = os.path.join(post_directory, 'commands.json') + if os.path.isfile(commands_filename): + if not self.vsphere_ipi_ocp_post_install_commands(commands_filename): + return False + + self.set_vsphere_ipi_ocp_post_install_finished() + return True + + def is_vsphere_ipi_ocp_parameters_ready(self): + ssh_handler = ssh.Ssh( + self.installer_parameters['vm']['ssh']['ip'], + self.installer_parameters['vm']['ssh']['username'], + password=self.installer_parameters['vm']['ssh']['password'], + log_id=self.log_id + ) + filename = '/root/.ocp_parameters.json' + return ssh_handler.is_file(filename) + + def vsphere_ipi_ocp_parameters_upload(self): + parameters_filename = '/tmp/%s.json' % (str(uuid.uuid4())) + try: + with open(parameters_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(self.ocp_parameters, indent=4)) + + except BaseException: + self.log.error( + 'vsphere_ipi_ocp_parameters_upload', + 'Local file write failed' + ) + return False + + file_info = {} + file_info['source'] = parameters_filename + file_info['template'] = False + file_info['destination'] = '/root/.ocp_parameters.json' + file_info['chmod'] = 644 + if not self.vcenter_handler.run_task_file(file_info): + os.remove(parameters_filename) + return False + + os.remove(parameters_filename) + return True + + def vsphere_ipi_ocp_create(self, ocp_parameters, input_location): + self.my_output.default('vsphere-ipi ocp creation workflow...') + + self.ocp_parameters = ocp_parameters + self.input_location = input_location + self.installer_parameters = self.get_vsphere_ipi_installer_parameters() + if self.installer_parameters is None: + return False + + self.my_output.info( + json.dumps( + self.installer_parameters, + indent=4 + ) + ) + + success = self.vcenter_handler.create_vm_deployment( + self.installer_parameters, + dry_run=False + ) + if not success: + return False + + if self.is_vsphere_ipi_ocp_ready(): + self.my_output.default('OCP already installed') + else: + if not self.vcenter_handler.check_vm_network_devices(): + return False + + if not self.vsphere_ipi_ocp_install(): + return False + + if self.is_vsphere_ipi_ocp_post_install_finished(): + self.my_output.default('OCP post installation steps already completed') + else: + if not self.is_vsphere_ipi_ocp_working(): + return False + self.my_output.default('OCP functional') + + if not self.vsphere_ipi_ocp_post_install(): + return False + + if not self.is_vsphere_ipi_ocp_parameters_ready(): + if not self.vsphere_ipi_ocp_parameters_upload(): + return False + + return True diff --git a/lib/ocp/lcm/vsphere/ipi/delete.py b/lib/ocp/lcm/vsphere/ipi/delete.py new file mode 100644 index 00000000..b92df5b6 --- /dev/null +++ b/lib/ocp/lcm/vsphere/ipi/delete.py @@ -0,0 +1,54 @@ +import json + + +class OcpVsphereIpiDelete(): + def __init__(self): + self.ocp_parameters = None + self.installer_parameters = None + + def vsphere_ipi_ocp_uninstall(self): + self.my_output.default('Check ocp installation state...') + if not self.is_vsphere_ipi_ocp_ready(): + self.my_output.default('OCP not installed') + return True + + self.my_output.default('Destroy OCP cluster...') + self.vcenter_handler.set_vm_parameters( + self.installer_parameters + ) + filename = self.get_template_filename('uninstall.sh') + if not self.vcenter_handler.run_task_script(filename, live_output=True): + return False + + return True + + def vsphere_ipi_ocp_delete(self, ocp_parameters): + self.my_output.default('vsphere-ipi ocp delete workflow...') + + self.ocp_parameters = ocp_parameters + self.installer_parameters = self.get_vsphere_ipi_installer_parameters() + if self.installer_parameters is None: + return False + + self.my_output.info( + json.dumps( + self.installer_parameters, + indent=4 + ) + ) + + self.my_output.default('Check installer virtual machine...') + + vm_name = self.installer_parameters['vm']['name'] + if not self.vcenter_handler.is_vm(vm_name): + self.my_output.default('Installer VM already deleted: %s' % (vm_name)) + return True + + if not self.vsphere_ipi_ocp_uninstall(): + return False + + if not self.vcenter_handler.delete_vm(name=vm_name): + return False + + self.my_output.default('Completed') + return True diff --git a/lib/ocp/lcm/vsphere/ipi/installer.py b/lib/ocp/lcm/vsphere/ipi/installer.py new file mode 100644 index 00000000..d10a4fcf --- /dev/null +++ b/lib/ocp/lcm/vsphere/ipi/installer.py @@ -0,0 +1,429 @@ +import json +import uuid +import datetime + +from lib import ip_helper + + +class OcpVsphereIpiInstaller(): + def __init__(self): + pass + + def get_vshpere_ipi_installer_iso(self): + ''' + "iso": { + "enabled": true, + "destination": "/linux-iso/Fedora-Server-dvd-x86_64-36-1.5.iso", + "delete_source": false, + "source": null, + "overwrite": false, + "delete_destination": false, + "folder_name": "/linux-iso/", + "file_name": "Fedora-Server-dvd-x86_64-36-1.5.iso", + "is_folder": true, + "is_file": true + }, + ''' + + iso = {} + iso['enabled'] = True + iso['source'] = self.ocp_parameters['installer']['iso']['source'] + iso['destination'] = self.ocp_parameters['installer']['iso']['destination'] + iso['delete_source'] = False + iso['overwrite'] = False + iso['delete_destination'] = False + + iso_destination = iso['destination'].rstrip('/') + iso['folder_name'] = self.vcenter_handler.get_parent_folder_name(iso_destination) + iso['file_name'] = iso_destination.split('/')[-1] + iso['destination'] = '%s%s' % (iso['folder_name'], iso['file_name']) + self.my_output.info('iso destination verified: %s' % (iso['destination'])) + + if not self.vcenter_handler.is_datastore_folder(self.ocp_parameters['vcenter']['datacenter'], self.ocp_parameters['vcenter']['datastore'], iso['folder_name']): + self.my_output.info('datastore folder not found: %s' % (iso['folder_name'])) + iso['is_folder'] = False + else: + self.my_output.info('datastore folder found: %s' % (iso['folder_name'])) + iso['is_folder'] = True + + iso['is_file'] = False + if iso['is_folder']: + files = self.vcenter_handler.get_datastore_files(self.ocp_parameters['vcenter']['datacenter'], self.ocp_parameters['vcenter']['datastore'], iso['folder_name']) + if files is not None: + for file_info in files: + if file_info['filename'] == iso['file_name']: + iso['is_file'] = True + break + + if iso['is_file']: + self.my_output.info('datastore file found: %s' % (iso['file_name'])) + else: + self.my_output.info('datastore file not found: %s' % (iso['file_name'])) + + return iso + + def get_vsphere_ipi_installer_variables(self, attributes={}): + ''' + Files e.g. kickstart or task related, can have ${VARIABLE} that will be replaced with parameters from user input (yaml) + + System generated variables + + User-defined variables - globally in 'variables' section + + Indirectly defined variables based on vm section: + + HOSTNAME - vm.settings.hostname + PASSWORD - vm.settings.password + DNS_NAMESERVER - the first item in the list vm.settings.dns.nameservers + DNS_DOMAIN - vm.settings.dns.domain + NTP_SERVER - the first item in the list vm.settings.ntp.servers + TIMEZONE - vm.settings.ntp.timezone + INTERFACE_n_IP - vm.network[n].ip + INTERFACE_n_NETMASK - vm.network[n].netmask + INTERFACE_n_GATEWAY - vm.network[n].gateway + INTERFACE_n_NETWORK - network of vm.network[n].ip + INTERFACE_n_PREFIX - prefix length based on netmask + INTERFACE_n_CIDR - IP/Prefix + INTERFACE_n_NAME - vm.network[n].interface - Linux OS specific name of interface + INTERFACE_n_REVDNS - reverse DNS style representatin of the INTERFACE_n_NETWORK + + Every variable associated with IPv4 address value will trigger generated variables + _OCTET_ + + vcenter section based parameters + + VCENTER_NAME - vcenter.name + VCENTER_IP - vcenter.ip + VCENTER_PORT - vcenter.port + VCENTER_USERNAME - vcenter.username + VCENTER_PASSWORD - vcenter.password + VCENTER_DATACENTER - vcenter.datacenter + VCENTER_DATASTORE - vcenter.datastore + VCENTER_CLUSTER - vcenter.cluster + VCENTER_FOLDER - vcenter.folder + VCENTER_NETWORK - vcenter.network + ''' + self.my_output.info('Variables generation', underline=True, before_newline=True) + + # User input related + + vcenter_section = self.ocp_parameters['vcenter'] + installer_section = self.ocp_parameters['installer'] + installer_vm_section = self.ocp_parameters['installer']['vm'] + dhcp_section = self.ocp_parameters['dhcp'] + + attributes = {} + attributes['VCENTER_NAME'] = vcenter_section['name'] + attributes['VCENTER_IP'] = vcenter_section['ip'] + attributes['VCENTER_PORT'] = vcenter_section['port'] + attributes['VCENTER_USERNAME'] = vcenter_section['username'] + attributes['VCENTER_PASSWORD'] = vcenter_section['password'] + attributes['VCENTER_DATACENTER'] = vcenter_section['datacenter'] + attributes['VCENTER_DATASTORE'] = vcenter_section['datastore'] + attributes['VCENTER_CLUSTER'] = vcenter_section['cluster'] + attributes['VCENTER_FOLDER'] = vcenter_section['folder'] + attributes['VCENTER_CLUSTER_HOST_IPS'] = ','.join(vcenter_section['host_ips']) + attributes['VCENTER_NETWORK'] = vcenter_section['network'] + + attributes['HOSTNAME'] = installer_vm_section['name'] + attributes['PASSWORD'] = installer_vm_section['password'] + + attributes['DNS_NAMESERVER'] = dhcp_section['dns']['servers'].split(',')[0] + attributes['DNS_DOMAIN'] = dhcp_section['dns']['domain'] + attributes['NTP_SERVER'] = dhcp_section['ntp']['servers'].split(',')[0] + attributes['TIMEZONE'] = dhcp_section['ntp']['timezone'] + + network_id = 0 + attributes['INTERFACE_%s_VC_NETWORK_NAME' % (network_id)] = vcenter_section['network'] + attributes['INTERFACE_%s_IP' % (network_id)] = installer_vm_section['ip'] + attributes['INTERFACE_%s_NETMASK' % (network_id)] = ip_helper.prefix_to_netmask( + int(dhcp_section['subnet'].split('/')[1]) + ) + attributes['INTERFACE_%s_PREFIX' % (network_id)] = dhcp_section['subnet'].split('/')[1] + attributes['INTERFACE_%s_CIDR' % (network_id)] = '%s/%s' % ( + installer_vm_section['ip'], + dhcp_section['subnet'].split('/')[1] + ) + attributes['INTERFACE_%s_NETWORK' % (network_id)] = ip_helper.get_network_ipv4_in_cidr( + attributes['INTERFACE_%s_CIDR' % (network_id)] + ) + attributes['INTERFACE_%s_GATEWAY' % (network_id)] = dhcp_section['gateway'] + attributes['INTERFACE_%s_NAME' % (network_id)] = installer_vm_section['interface']['name'] + attributes['INTERFACE_%s_REVDNS' % (network_id)] = '%s.%s.%s' % ( + attributes['INTERFACE_%s_NETWORK' % (network_id)].split('.')[2], + attributes['INTERFACE_%s_NETWORK' % (network_id)].split('.')[1], + attributes['INTERFACE_%s_NETWORK' % (network_id)].split('.')[0] + ) + + # Proxy + + attributes['HTTP_PROXY_ENABLED'] = 'False' + attributes['HTTP_PROXY'] = 'undefined' + attributes['HTTPS_PROXY'] = 'undefined' + attributes['USER_NO_PROXY'] = 'undefined' + + if 'proxy' in self.ocp_parameters: + if self.ocp_parameters['proxy']['enabled']: + attributes['HTTP_PROXY_ENABLED'] = "True" + attributes['HTTP_PROXY'] = self.ocp_parameters['proxy']['http'] + attributes['HTTPS_PROXY'] = self.ocp_parameters['proxy']['https'] + if self.ocp_parameters['proxy']['no_proxy'] is None: + attributes['USER_NO_PROXY'] = '' + else: + attributes['USER_NO_PROXY'] = '%s,' % (self.ocp_parameters['proxy']['no_proxy']) + + # DHCP + + attributes['MANAGED_DHCP_ENABLED'] = "False" + if 'dhcp' in self.ocp_parameters: + if self.ocp_parameters['dhcp']['managed']: + attributes['MANAGED_DHCP_ENABLED'] = "True" + + # Named + + attributes['MANAGED_DNS_ENABLED'] = "False" + if 'dns' in self.ocp_parameters: + if self.ocp_parameters['dns']['managed']: + attributes['MANAGED_DNS_ENABLED'] = "True" + + # OCP + + attributes['OCP_BASE_DOMAIN'] = self.ocp_parameters['ocp']['cluster']['domain'] + attributes['OCP_NAME'] = self.ocp_parameters['ocp']['cluster']['name'] + attributes['OCP_API_VIP'] = self.ocp_parameters['ocp']['cluster']['api_vip'] + attributes['OCP_INGRESS_VIP'] = self.ocp_parameters['ocp']['cluster']['ingress_vip'] + attributes['OCP_NODES_DHCP_START'] = self.ocp_parameters['dhcp']['range'].split('-')[0] + attributes['OCP_NODES_DHCP_END'] = self.ocp_parameters['dhcp']['range'].split('-')[1] + attributes['OCP_NODES_IPS'] = ','.join( + ip_helper.get_ipv4_addresses_in_range( + attributes['OCP_NODES_DHCP_START'], + attributes['OCP_NODES_DHCP_END'] + ) + ) + attributes['OCP_MASTER_COUNT'] = str(self.ocp_parameters['ocp']['cluster']['master']['replicas']) + attributes['OCP_WORKER_COUNT'] = str(self.ocp_parameters['ocp']['cluster']['worker']['replicas']) + + if vcenter_section['folder'] is None: + attributes['OCP_CONFIG_FOLDER'] = '' + else: + attributes['OCP_CONFIG_FOLDER'] = '/%s/vm/%s' % ( + vcenter_section['datacenter'], + vcenter_section['folder'] + ) + + # CNI + + attributes['CNI_TYPE'] = self.ocp_parameters['cni']['type'] + if attributes['CNI_TYPE'] == 'Calico': + attributes['CALICO_VERSION'] = self.ocp_parameters['calico']['version'] + + if attributes['CNI_TYPE'] == 'Cilium': + attributes['CILIUM_VERSION'] = self.ocp_parameters['cilium']['version'] + + attributes['CNI_SERVICE_V4'] = self.ocp_parameters['cni']['v4serviceNetwork'] + attributes['CNI_POD_V4'] = self.ocp_parameters['cni']['v4cidr'] + attributes['CNI_HOST_PREFIX'] = str(self.ocp_parameters['cni']['v4hostPrefix']) + + # Calico BGP + + if 'bgp' in self.ocp_parameters: + attributes['BGP_LOCAL_AS'] = str(self.ocp_parameters['bgp']['local_as']) + if self.ocp_parameters['bgp']['mesh']: + attributes['BGP_MESH'] = 'true' + else: + attributes['BGP_MESH'] = 'false' + + attributes['BGP_ADVERTISEMENTS'] = '' + if 'external_ips' in self.ocp_parameters['bgp'] and self.ocp_parameters['bgp']['external_ips'] is not None and len(self.ocp_parameters['bgp']['external_ips']) > 0: + attributes['BGP_ADVERTISEMENTS'] = ' serviceExternalIPs:\n' + is_community = False + for external_ip in self.ocp_parameters['bgp']['external_ips']: + if len(external_ip.split(',')) > 1: + is_community = True + attributes['BGP_ADVERTISEMENTS'] = '%s - cidr: %s\n' % ( + attributes['BGP_ADVERTISEMENTS'], + external_ip.split(',')[0] + ) + else: + attributes['BGP_ADVERTISEMENTS'] = '%s - cidr: %s\n' % ( + attributes['BGP_ADVERTISEMENTS'], + external_ip + ) + + if is_community: + attributes['BGP_ADVERTISEMENTS'] = '%s prefixAdvertisements:\n' % ( + attributes['BGP_ADVERTISEMENTS'] + ) + for external_ip in self.ocp_parameters['bgp']['external_ips']: + if len(external_ip.split(',')) > 1: + attributes['BGP_ADVERTISEMENTS'] = '%s - cidr: %s\n' % ( + attributes['BGP_ADVERTISEMENTS'], + external_ip.split(',')[0] + ) + attributes['BGP_ADVERTISEMENTS'] = '%s communities:\n' % ( + attributes['BGP_ADVERTISEMENTS'] + ) + for community in external_ip.split(',')[1:]: + attributes['BGP_ADVERTISEMENTS'] = '%s - %s\n' % ( + attributes['BGP_ADVERTISEMENTS'], + community + ) + attributes['BGP_ADVERTISEMENTS'] = attributes['BGP_ADVERTISEMENTS'].rstrip('\n') + + attributes['BGP_PEERS'] = '' + for peer in self.ocp_parameters['bgp']['peer']: + attributes['BGP_PEERS'] = '%s---\n' % (attributes['BGP_PEERS']) + attributes['BGP_PEERS'] = '%sapiVersion: projectcalico.org/v3\n' % (attributes['BGP_PEERS']) + attributes['BGP_PEERS'] = '%skind: BGPPeer\n' % (attributes['BGP_PEERS']) + attributes['BGP_PEERS'] = '%smetadata:\n' % (attributes['BGP_PEERS']) + attributes['BGP_PEERS'] = '%s name: %s\n' % (attributes['BGP_PEERS'], peer) + attributes['BGP_PEERS'] = '%sspec:\n' % (attributes['BGP_PEERS']) + attributes['BGP_PEERS'] = '%s asNumber: %s\n' % (attributes['BGP_PEERS'], str(self.ocp_parameters['bgp']['remote_as'])) + attributes['BGP_PEERS'] = '%s peerIP: %s\n' % (attributes['BGP_PEERS'], peer) + + # Non-user input related variables + + attributes['DNS_SERIAL'] = '%s01' % (datetime.date.today().strftime("%Y%m%d")) + + # IP address octets variables + + new_attributes = {} + for key in attributes: + if ip_helper.is_valid_ipv4_address(attributes[key]): + index = 1 + for octet in attributes[key].split('.'): + new_attributes['%s_OCTET_%s' % (key, index)] = octet + index = index + 1 + + for key in new_attributes: + if key not in attributes: + attributes[key] = new_attributes[key] + + self.my_output.info('Completed') + self.my_output.debug(json.dumps(attributes, indent=4)) + + return attributes + + def get_vsphere_ipi_installer_ks(self, variables): + if not self.is_template_valid('ip-static.ks', variables): + return None + + kickstart = {} + kickstart['enabled'] = True + kickstart['template'] = self.get_template_filename('ip-static.ks') + kickstart['delete_source'] = True + kickstart['overwrite'] = self.ocp_parameters['installer']['ks']['overwrite'] + kickstart['delete_destination'] = True + kickstart['generate'] = True + + self.my_output.info('Kickstart template verified: %s' % (kickstart['template'])) + + kickstart['source'] = '/tmp/%s.iso' % (str(uuid.uuid4())) + self.my_output.debug('Generated kickstart iso target location: %s' % (kickstart['source'])) + + if self.ocp_parameters['installer']['ks']['folder'] is None: + kickstart['folder_name'] = '/' + else: + kickstart['folder_name'] = '/%s/' % (self.ocp_parameters['installer']['ks']['folder'].rstrip('/').lstrip('/')) + kickstart['file_name'] = '%s-ks.iso' % (self.ocp_parameters['installer']['vm']['name']) + kickstart['destination'] = '%s%s' % (kickstart['folder_name'], kickstart['file_name']) + self.my_output.info('kickstart destination value verified: %s' % (kickstart['destination'])) + + success = self.vcenter_handler.is_datastore_folder( + self.ocp_parameters['vcenter']['datacenter'], + self.ocp_parameters['vcenter']['datastore'], + kickstart['folder_name'] + ) + if success: + self.my_output.debug('datastore folder found: %s' % (kickstart['folder_name'])) + kickstart['is_folder'] = True + else: + self.my_output.debug('datastore folder not found: %s' % (kickstart['folder_name'])) + kickstart['is_folder'] = False + + success = self.vcenter_handler.is_datastore_file( + self.ocp_parameters['vcenter']['datacenter'], + self.ocp_parameters['vcenter']['datastore'], + kickstart['folder_name'], + kickstart['file_name'] + ) + if success: + kickstart['is_file'] = True + self.my_output.debug('datastore file found: %s' % (kickstart['file_name'])) + else: + kickstart['is_file'] = False + self.my_output.debug('datastore file not found: %s' % (kickstart['file_name'])) + + self.my_output.info('Completed') + return kickstart + + def get_vsphere_ipi_installer_vm_parameters(self, iso, kickstart): + vm_parameters = {} + vm_parameters['datacenter_name'] = self.ocp_parameters['vcenter']['datacenter'] + vm_parameters['datastore_name'] = self.ocp_parameters['vcenter']['datastore'] + vm_parameters['host_ip'] = None + if 'host_ip' in self.ocp_parameters['vcenter']: + vm_parameters['host_ip'] = self.ocp_parameters['vcenter']['host_ip'] + vm_parameters['distribution'] = self.ocp_parameters['installer']['vm']['template'] + vm_parameters['name'] = self.ocp_parameters['installer']['vm']['name'] + vm_parameters['cpu'] = self.ocp_parameters['installer']['vm']['cpu'] + vm_parameters['memory'] = self.ocp_parameters['installer']['vm']['memory'] + vm_parameters['disk'] = [] + disk_info = {} + disk_info['size'] = self.ocp_parameters['installer']['vm']['disk']['size'] + disk_info['thin'] = False + if self.ocp_parameters['installer']['vm']['disk']['type'] == 'thin': + disk_info['thin'] = True + vm_parameters['disk'].append(disk_info) + vm_parameters['network'] = [] + network_info = {} + network_info['name'] = self.ocp_parameters['vcenter']['network'] + network_info['type'] = self.ocp_parameters['installer']['vm']['interface']['type'] + vm_parameters['network'].append(network_info) + vm_parameters['cdrom'] = [] + cdrom_info = {} + cdrom_info['datastore_name'] = self.ocp_parameters['vcenter']['datastore'] + cdrom_info['iso'] = iso['destination'] + vm_parameters['cdrom'].append(cdrom_info) + cdrom_info = {} + cdrom_info['datastore_name'] = self.ocp_parameters['vcenter']['datastore'] + cdrom_info['iso'] = kickstart['destination'] + vm_parameters['cdrom'].append(cdrom_info) + vm_parameters['ssh'] = {} + vm_parameters['ssh']['enabled'] = True + vm_parameters['ssh']['username'] = self.ocp_parameters['installer']['vm']['username'] + vm_parameters['ssh']['password'] = self.ocp_parameters['installer']['vm']['password'] + vm_parameters['ssh']['ip'] = self.ocp_parameters['installer']['vm']['ip'] + + return vm_parameters + + def get_vsphere_ipi_installer_parameters(self): + installer = {} + installer['vcenter'] = self.ocp_parameters['vcenter'] + + if 'jump' in self.ocp_parameters: + installer['jump'] = self.ocp_parameters['jump'] + installer['jump']['enabled'] = True + + installer['iso'] = self.get_vshpere_ipi_installer_iso() + if installer['iso'] is None: + return None + + installer['variables'] = self.get_vsphere_ipi_installer_variables() + if installer['variables'] is None: + return None + + installer['ks'] = self.get_vsphere_ipi_installer_ks( + installer['variables'] + ) + if installer['ks'] is None: + return None + + installer['vm'] = self.get_vsphere_ipi_installer_vm_parameters( + installer['iso'], + installer['ks'] + ) + if installer['vm'] is None: + return None + + return installer diff --git a/lib/ocp/lcm/vsphere/ipi/main.py b/lib/ocp/lcm/vsphere/ipi/main.py new file mode 100644 index 00000000..98f066d3 --- /dev/null +++ b/lib/ocp/lcm/vsphere/ipi/main.py @@ -0,0 +1,12 @@ +from lib.ocp.lcm.vsphere.ipi.create import OcpVsphereIpiCreate +from lib.ocp.lcm.vsphere.ipi.delete import OcpVsphereIpiDelete +from lib.ocp.lcm.vsphere.ipi.installer import OcpVsphereIpiInstaller +from lib.ocp.lcm.vsphere.ipi.validate import OcpVsphereIpiValidate + + +class OcpVsphereIpi(OcpVsphereIpiCreate, OcpVsphereIpiDelete, OcpVsphereIpiInstaller, OcpVsphereIpiValidate): + def __init__(self): + OcpVsphereIpiCreate.__init__(self) + OcpVsphereIpiDelete.__init__(self) + OcpVsphereIpiInstaller.__init__(self) + OcpVsphereIpiValidate.__init__(self) diff --git a/lib/ocp/lcm/vsphere/ipi/validate.py b/lib/ocp/lcm/vsphere/ipi/validate.py new file mode 100644 index 00000000..eef0d2d3 --- /dev/null +++ b/lib/ocp/lcm/vsphere/ipi/validate.py @@ -0,0 +1,174 @@ +import json +import platform + +from lib import ssh +from lib import ip_helper + + +class OcpVsphereIpiValidate(): + def __init__(self): + self.local_system_type = platform.system() + + def validate_vsphere_ipi_create_user_input(self): + mandatory_sections = ['vcenter', 'ocp', 'sources', 'installer', 'dns', 'dhcp', 'cni', 'post', 'pre', 'addons', 'calico', 'cilium'] + if self.local_system_type != 'Linux': + mandatory_sections.append('jump') + + optional_sections = ['ssh', 'proxy', 'bgp'] + if self.local_system_type == 'Linux': + optional_sections.append('jump') + + ocp_parameters = self.validate_sections( + mandatory_sections, + optional_sections + ) + if ocp_parameters is None: + return None + + # vcenter + + vcenter_definition = ocp_parameters['vcenter'] + vcenter_definition['username'] = self.vcenter_credentials['username'] + vcenter_definition['password'] = self.vcenter_credentials['password'] + + vcenter_definition = self.validate_vcenter( + vcenter_definition + ) + if vcenter_definition is None: + return None + + # jump + + if 'jump' in ocp_parameters: + self.my_output.info('Validate jump section', underline=True, before_newline=True) + + ssh_handler = ssh.Ssh( + ocp_parameters['jump']['ip'], + ocp_parameters['jump']['username'], + password=ocp_parameters['jump']['password'], + log_id=self.log_id + ) + if not ssh_handler.is_ssh(): + self.my_output.error('Jump ssh access fails') + return None + + self.my_output.info('SSH access works') + self.my_output.info('Completed') + + # installer + + self.my_output.info('Validate installer section', underline=True, before_newline=True) + + self.my_output.info('Check IP and gateway') + if not ip_helper.is_ipv4_in_cidr(ocp_parameters['installer']['vm']['ip'], ocp_parameters['dhcp']['subnet']): + self.my_output.error('Installer IP must be in DHCP subnet') + return None + self.my_output.info('Completed') + + # dhcp + + self.my_output.info('Validate dhcp section', underline=True, before_newline=True) + + self.my_output.info('Check subnet and gateway') + if not ip_helper.is_ipv4_in_cidr(ocp_parameters['dhcp']['gateway'], ocp_parameters['dhcp']['subnet']): + self.my_output.error('DHCP gateway must be in ip subnet') + return None + + self.my_output.info('Completed') + + # ocp + + self.my_output.info('Validate ocp section', underline=True, before_newline=True) + + self.my_output.info('Cross-check API VIP and DHCP subnet') + if not ip_helper.is_ipv4_in_cidr(ocp_parameters['ocp']['cluster']['api_vip'], ocp_parameters['dhcp']['subnet']): + self.my_output.error('API VIP must be part of DHCP subnet') + return None + + self.my_output.info('Cross-check ingress VIP and DHCP subnet') + if not ip_helper.is_ipv4_in_cidr(ocp_parameters['ocp']['cluster']['ingress_vip'], ocp_parameters['dhcp']['subnet']): + self.my_output.error('API VIP must be part of DHCP subnet') + return None + + self.my_output.info('Check API VIP and Ingress VIP uniqueness') + if ocp_parameters['ocp']['cluster']['ingress_vip'] == ocp_parameters['ocp']['cluster']['api_vip']: + self.my_output.error('API and Ingress VIP must be different') + return None + + # sources and version + + self.my_output.info('Validate ocp source', underline=True, before_newline=True) + + if ocp_parameters['ocp']['source'] == 'local': + self.my_output.info('Local source files expected') + if ocp_parameters['sources']['ocp'] is None: + self.my_output.error('ocp installation tarball not defined') + return None + + if ocp_parameters['sources']['ocp'] is None: + self.my_output.error('oc binary tarball not defined') + return None + + if ocp_parameters['ocp']['source'] == 'web': + self.my_output.info('Installation binaries will be downloaded') + if ocp_parameters['ocp']['release'] is None: + self.my_output.error('Define ocp.release value for installation binaries download') + return None + + ocp_parameters['sources']['ocp'] = '%s/%s/openshift-install-linux.tar.gz' % ( + ocp_parameters['sources']['ocp_base_url'], + ocp_parameters['ocp']['release'] + ) + if not ip_helper.is_url_accessible(ocp_parameters['sources']['ocp']): + self.my_output.error('Openshift installation binary not found: %s' % (ocp_parameters['sources']['ocp'])) + return None + + ocp_parameters['sources']['oc'] = '%s/%s/openshift-client-linux.tar.gz' % ( + ocp_parameters['sources']['ocp_base_url'], + ocp_parameters['ocp']['release'] + ) + if not ip_helper.is_url_accessible(ocp_parameters['sources']['oc']): + self.my_output.error('Openshift client binary not found: %s' % (ocp_parameters['sources']['oc'])) + return None + + ocp_parameters['sources']['secret'] = self.ocp_token_filename + + self.my_output.info('Completed') + + # all good ! + + self.my_output.info('User input validated and augmented with generated data') + + return ocp_parameters + + def validate_vsphere_ipi_delete_user_input(self): + mandatory_sections = ['vcenter', 'ocp', 'sources', 'installer', 'dns', 'dhcp', 'cni', 'post', 'pre', 'addons', 'calico', 'cilium'] + if self.local_system_type != 'Linux': + mandatory_sections.append('jump') + + optional_sections = ['ssh', 'proxy', 'bgp'] + if self.local_system_type == 'Linux': + optional_sections.append('jump') + + ocp_parameters = self.validate_sections( + mandatory_sections, + optional_sections + ) + if ocp_parameters is None: + return None + + # vcenter + + vcenter_definition = ocp_parameters['vcenter'] + vcenter_definition['username'] = self.vcenter_credentials['username'] + vcenter_definition['password'] = self.vcenter_credentials['password'] + + vcenter_definition = self.validate_vcenter( + vcenter_definition + ) + if vcenter_definition is None: + return None + + self.my_output.info('Validated user input: %s' % (json.dumps(ocp_parameters, indent=4))) + + return ocp_parameters diff --git a/lib/ocp/lcm/vsphere/main.py b/lib/ocp/lcm/vsphere/main.py new file mode 100644 index 00000000..1bcc3024 --- /dev/null +++ b/lib/ocp/lcm/vsphere/main.py @@ -0,0 +1,30 @@ +from lib.ocp.lcm.vsphere.ipi.main import OcpVsphereIpi +from lib.ocp.lcm.vsphere.validate import OcpVsphereValidate + +from lib.vc import vcenter + + +class OcpVsphere(OcpVsphereValidate, OcpVsphereIpi): + def __init__(self): + OcpVsphereValidate.__init__(self) + OcpVsphereIpi.__init__(self) + self.vcenter_handler = None + + def is_vcenter_connected(self): + if self.vcenter_handler is None: + return False + return self.vcenter_handler.is_vc_connected() + + def vcenter_connect(self, vcenter_parameters): + if self.vcenter_handler is None: + self.vcenter_handler = vcenter.Vcenter( + vcenter_parameters['name'], + vcenter_parameters['username'], + vcenter_parameters['password'], + port=vcenter_parameters['port'], + verbose=self.verbose, + debug=self.debug, + log_id=self.log_id + ) + + return self.is_vcenter_connected() diff --git a/lib/ocp/lcm/vsphere/validate.py b/lib/ocp/lcm/vsphere/validate.py new file mode 100644 index 00000000..8d733780 --- /dev/null +++ b/lib/ocp/lcm/vsphere/validate.py @@ -0,0 +1,110 @@ +class OcpVsphereValidate(): + def __init__(self): + pass + + def validate_vcenter_datacenter_name(self, datacenter_name): + self.my_output.debug('Getting datacenters...') + datacenters = self.vcenter_handler.get_datacenters() + if datacenters is None: + self.my_output.error('No datacenters found') + return False + + for datacenter in datacenters: + if datacenter['name'] == datacenter_name: + self.my_output.info('Datacenter found: %s' % (datacenter_name)) + return True + + self.my_output.error('Datacenter not found: %s' % (datacenter_name)) + return False + + def validate_vcenter_datastore_name(self, datacenter_name, datastore_name): + self.my_output.debug('Getting datastores available in datacenter...') + datastores = self.vcenter_handler.get_datastores(datacenter_name=datacenter_name) + + if datastores is None: + self.my_output.error('No datastores found') + return False + + for datastore in datastores: + if datastore['name'] == datastore_name: + self.my_output.info('Datastore found: %s' % (datastore_name)) + return True + + self.my_output.error('Datastore not found: %s' % (datastore_name)) + return True + + def validate_vcenter_cluster_name(self, cluster_name): + self.my_output.debug('Getting vcenter clusters...') + if not self.vcenter_handler.is_vm_cluster(cluster_name): + self.my_output.error('Cluster not found: %s' % (cluster_name)) + return False + + self.my_output.info('Cluster found: %s' % (cluster_name)) + return True + + def validate_vcenter_folder_name(self, folder_name): + self.my_output.debug('Getting vcenter folders...') + if not self.vcenter_handler.is_vm_folder(folder_name): + self.my_output.error('Folder not found: %s' % (folder_name)) + return False + + self.my_output.info('Folder found: %s' % (folder_name)) + return True + + def validate_vcenter_host_ip(self, vcenter_hosts, host_ip): + for vcenter_host in vcenter_hosts: + if vcenter_host == host_ip: + self.my_output.info('Target host found: %s' % (host_ip)) + return True + + self.my_output.error('Target host not found: %s' % (host_ip)) + return False + + def validate_vcenter_network(self, vcenter_network): + if not self.vcenter_handler.is_network(vcenter_network): + self.my_output.error('vcenter network not found: %s' % (vcenter_network)) + self.vcenter_handler.print_network_names( + title='Available networks' + ) + return False + + self.my_output.info('Network found: %s' % (vcenter_network)) + return True + + def validate_vcenter(self, vcenter_parameters): + self.my_output.info('Validate vcenter section', underline=True, before_newline=True) + + if not self.vcenter_connect(vcenter_parameters): + self.my_output.error('Failed to connect to vcenter') + return None + + if not self.validate_vcenter_datacenter_name(vcenter_parameters['datacenter']): + return None + + if not self.validate_vcenter_datastore_name(vcenter_parameters['datacenter'], vcenter_parameters['datastore']): + return None + + if not self.validate_vcenter_cluster_name(vcenter_parameters['cluster']): + return None + + host_ips = self.vcenter_handler.get_vm_cluster_hosts( + vcenter_parameters['cluster'] + ) + + self.my_output.debug('vcenter cluster hosts: %s' % (','.join(host_ips))) + vcenter_parameters['host_ips'] = host_ips + + if vcenter_parameters['host_ip'] is not None: + if not self.validate_vcenter_host_ip(vcenter_parameters['host_ips'], vcenter_parameters['host_ip']): + return None + + if vcenter_parameters['folder'] is not None: + if not self.validate_vcenter_folder_name(vcenter_parameters['folder']): + return None + + if not self.validate_vcenter_network(vcenter_parameters['network']): + return None + + self.my_output.info('Completed') + + return vcenter_parameters diff --git a/lib/ocp/main.py b/lib/ocp/main.py new file mode 100644 index 00000000..0dc3134d --- /dev/null +++ b/lib/ocp/main.py @@ -0,0 +1,52 @@ +from lib import log_helper +from lib import output_helper + +from lib.k8s import main as k8s +from lib.kubevirt import main as kubevirt + +from lib.ocp import settings + +from lib.ocp.cluster.main import OcpCluster +from lib.ocp.node.main import OcpNode +from lib.ocp.task.main import OcpTask +from lib.ocp.vm.main import OcpVm + + +class Ocp(OcpCluster, OcpNode, OcpTask, OcpVm): + def __init__(self, ocp_cluster_name, verbose=False, debug=False, log_id=None): + self.verbose = verbose + self.debug = debug + self.log_id = log_id + + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + self.log_id = log_id + + self.settings_handler = settings.OcpSettings(log_id=log_id) + self.ocp_cluster_settings = self.settings_handler.get_ocp_cluster(ocp_cluster_name) + if self.ocp_cluster_settings is None: + raise ValueError('OCP cluster handler initialization failed') + + self.k8s_handler = k8s.K8s( + self.ocp_cluster_settings['kubeconfig'], + cluster_type='ocp', + verbose=verbose, + debug=debug, + log_id=log_id + ) + + self.kubevirt_handler = kubevirt.Kubevirt( + self.ocp_cluster_settings['kubeconfig'], + verbose=verbose, + debug=debug, + log_id=log_id + ) + + OcpCluster.__init__(self) + OcpNode.__init__(self) + OcpTask.__init__(self) + OcpVm.__init__(self) diff --git a/lib/ocp/node/__init__.py b/lib/ocp/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/node/__pycache__/__init__.cpython-310.pyc b/lib/ocp/node/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..06c4b40a Binary files /dev/null and b/lib/ocp/node/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/node/__pycache__/info.cpython-310.pyc b/lib/ocp/node/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..10f8913d Binary files /dev/null and b/lib/ocp/node/__pycache__/info.cpython-310.pyc differ diff --git a/lib/ocp/node/__pycache__/linux.cpython-310.pyc b/lib/ocp/node/__pycache__/linux.cpython-310.pyc new file mode 100644 index 00000000..3e6d6f8f Binary files /dev/null and b/lib/ocp/node/__pycache__/linux.cpython-310.pyc differ diff --git a/lib/ocp/node/__pycache__/main.cpython-310.pyc b/lib/ocp/node/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0c31c2de Binary files /dev/null and b/lib/ocp/node/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/node/__pycache__/output.cpython-310.pyc b/lib/ocp/node/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..d9561121 Binary files /dev/null and b/lib/ocp/node/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/node/__pycache__/sriov.cpython-310.pyc b/lib/ocp/node/__pycache__/sriov.cpython-310.pyc new file mode 100644 index 00000000..cfb08f92 Binary files /dev/null and b/lib/ocp/node/__pycache__/sriov.cpython-310.pyc differ diff --git a/lib/ocp/node/info.py b/lib/ocp/node/info.py new file mode 100644 index 00000000..a1ce3bbb --- /dev/null +++ b/lib/ocp/node/info.py @@ -0,0 +1,179 @@ +from lib import filter_helper + + +class OcpNodeInfo(): + def __init__(self): + self.nodes = None + + def get_ocp_node_info(self, node_mo): + info = self.k8s_handler.get_node_info(node_mo) + if info is None: + return None + + # change labels from dict to list of dict + labels = [] + for key in info['label']: + label = {} + label['key'] = key + label['value'] = info['label'][key] + labels.append( + label + ) + info['labels'] = labels + + info['cluster'] = self.ocp_cluster_settings['name'] + info['mcp'] = {} + info['mcp']['current_config'] = None + info['mcp']['desired_config'] = None + info['mcp']['match'] = False + info['mcp']['tick'] = '\u2717' + info['__Output']['mcp.tick'] = 'Red' + + info['cnv'] = {} + info['cnv']['schedulable'] = False + info['cnv']['tick'] = '\u2717' + info['__Output']['cnv.tick'] = 'Red' + + for annotation in node_mo['metadata']['annotations']: + if annotation == 'machineconfiguration.openshift.io/currentConfig': + info['mcp']['current_config'] = node_mo['metadata']['annotations']['machineconfiguration.openshift.io/currentConfig'] + + if annotation == 'machineconfiguration.openshift.io/desiredConfig': + info['mcp']['desired_config'] = node_mo['metadata']['annotations']['machineconfiguration.openshift.io/desiredConfig'] + + if info['mcp']['current_config'] is not None and info['mcp']['desired_config'] is not None: + if info['mcp']['current_config'] == info['mcp']['desired_config']: + info['mcp']['match'] = True + info['mcp']['tick'] = '\u2713' + info['__Output']['mcp.tick'] = 'Green' + + for label in node_mo['metadata']['labels']: + if label == 'kubevirt.io/schedulable' and node_mo['metadata']['labels'][label] == 'true': + info['cnv']['schedulable'] = False + info['cnv']['tick'] = '\u2713' + info['__Output']['cnv.tick'] = 'Green' + + return info + + def get_ocp_nodes_info(self): + if self.nodes is not None: + return self.nodes + + nodes_mo = self.k8s_handler.get_nodes(return_mo=True) + + self.nodes = [] + for node_mo in nodes_mo: + node_info = self.get_ocp_node_info(node_mo) + if node_info is not None: + self.nodes.append( + node_info + ) + + self.nodes = sorted( + self.nodes, + key=lambda i: i['name'] + ) + + return self.nodes + + def filter_ocp_node_labels(self, node_labels, node_filter): + if node_filter is None or len(node_filter) == 0: + return node_labels + + labels = [] + + for node_label in node_labels: + match = True + for ap_rule in node_filter: + (key, value) = ap_rule.split(':') + if key == 'label': + if not filter_helper.match_string(value, node_label['key']): + match = False + break + + if match: + labels.append( + node_label + ) + + return labels + + def match_ocp_node(self, node_info, node_filter): + if node_filter is None or len(node_filter) == 0: + return True + + for ap_rule in node_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, node_info['name']): + return False + + if key == 'worker': + key_found = True + if value == 'true' and not node_info['worker']: + return False + if value == 'false' and node_info['worker']: + return False + + if key == 'master': + key_found = True + if value == 'true' and not node_info['master']: + return False + if value == 'false' and node_info['master']: + return False + + if key == 'label': + key_found = True + found = False + for label in node_info['labels']: + if filter_helper.match_string(value, label['key']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_ocp_node', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_ocp_nodes(self, node_filter=None, sriov_phy_info=False, sriov_policy_info=False, sriov_network_info=False, sriov_vf_info=False): + all_nodes = self.get_ocp_nodes_info() + + nodes = [] + for node_info in all_nodes: + if not self.match_ocp_node(node_info, node_filter): + continue + + node_info['labels'] = self.filter_ocp_node_labels(node_info['labels'], node_filter) + + if sriov_phy_info or sriov_policy_info or sriov_network_info or sriov_vf_info: + node_sriov = self.get_ocp_node_sriov( + node_info['name'], + sriov_phy_info=sriov_phy_info, + sriov_policy_info=sriov_policy_info, + sriov_network_info=sriov_network_info, + sriov_vf_info=sriov_vf_info + ) + for key in node_sriov: + node_info[key] = node_sriov[key] + + nodes.append( + node_info + ) + + nodes = sorted( + nodes, + key=lambda i: i['name'] + ) + + return nodes diff --git a/lib/ocp/node/linux.py b/lib/ocp/node/linux.py new file mode 100644 index 00000000..da32d9ec --- /dev/null +++ b/lib/ocp/node/linux.py @@ -0,0 +1,117 @@ +import copy +from lib.linux import main as linux + + +class OcpNodeLinux(): + def __init__(self): + self.node_linux_handler = {} + self.k8s_nodes = None + + def get_ocp_nodes_linux_access(self): + if 'ssh' not in self.ocp_cluster_settings: + self.log.error( + 'get_ocp_nodes_linux_access', + 'No ssh settings for ocp cluster' + ) + return None + + if self.k8s_nodes is None: + self.k8s_nodes = self.k8s_handler.get_nodes() + if self.k8s_nodes is None: + self.log.error( + 'get_ocp_nodes_linux_access', + 'Failed to get k8s nodes info' + ) + return None + + nodes = [] + for k8s_node in self.k8s_nodes: + node_access = {} + node_access['ip'] = k8s_node['ssh_ip'] + node_access['username'] = self.ocp_cluster_settings['ssh']['username'] + node_access['password'] = self.ocp_cluster_settings['ssh']['password'], + node_access['key_filename'] = self.ocp_cluster_settings['ssh']['key_filename'] + node_access['name'] = k8s_node['name'] + + nodes.append( + node_access + ) + + return nodes + + def get_ocp_nodes_linux_handlers(self): + nodes = self.get_ocp_nodes_linux_access() + if nodes is None: + self.log.error( + 'get_ocp_nodes_linux_handlers', + 'No nodes' + ) + return None + + handlers = [] + + for node in nodes: + handler = copy.deepcopy(node) + handler['handler'] = linux.Linux( + node['ip'], + node['username'], + password=node['password'], + key_filename=node['key_filename'], + verbose=False, + debug=False, + log_id=self.log_id + ) + + handlers.append( + handler + ) + + return handlers + + def get_ocp_node_linux_handler(self, node_ip=None, node_name=None): + if node_ip is None and node_name is None: + self.log.error( + 'get_ocp_node_linux_handler', + 'Define node with ip or name' + ) + return None + + if 'parameters' not in self.ocp_cluster_settings or 'nodes' not in self.ocp_cluster_settings['parameters']: + self.log.error( + 'get_ocp_node_linux_handler', + 'No nodes in ocp settings' + ) + return None + + if node_ip is None: + node_ip = self.k8s_handler.get_node_ip( + node_name + ) + if node_ip is None: + self.log.error( + 'get_ocp_node_linux_handler', + 'No node ip found: %s' % (node_name) + ) + return None + + if node_ip in self.node_linux_handler: + return self.node_linux_handler[node_ip] + + for node in self.ocp_cluster_settings['parameters']['nodes']: + if node['ip'] == node_ip: + self.node_linux_handler[node_ip] = linux.Linux( + node_ip, + node['username'], + password=node['password'], + key_filename=node['key_filename'], + verbose=False, + debug=False, + log_id=self.log_id + ) + return self.node_linux_handler[node_ip] + + self.log.error( + 'get_ocp_node_linux_handler', + 'No linux handler: %s' % (node_ip) + ) + return None diff --git a/lib/ocp/node/main.py b/lib/ocp/node/main.py new file mode 100644 index 00000000..2a244f2f --- /dev/null +++ b/lib/ocp/node/main.py @@ -0,0 +1,14 @@ +from lib.ocp.node.info import OcpNodeInfo +from lib.ocp.node.linux import OcpNodeLinux +from lib.ocp.node.sriov import OcpNodeSriov + + +class OcpNode( + OcpNodeInfo, + OcpNodeLinux, + OcpNodeSriov + ): + def __init__(self): + OcpNodeInfo.__init__(self) + OcpNodeLinux.__init__(self) + OcpNodeSriov.__init__(self) diff --git a/lib/ocp/node/sriov.py b/lib/ocp/node/sriov.py new file mode 100644 index 00000000..368a45aa --- /dev/null +++ b/lib/ocp/node/sriov.py @@ -0,0 +1,361 @@ +import copy +import json + +from lib import ip_helper + + +class OcpNodeSriov(): + def __init__(self): + self.node_sriov = {} + + def get_ocp_node_sriov_interfaces(self, node_name): + if node_name in self.node_sriov: + return self.node_sriov[node_name] + + linux_handler = self.get_ocp_node_linux_handler( + node_name=node_name + ) + if linux_handler is None: + return None + + interfaces = linux_handler.get_sriov_interfaces( + numa_info=True, + pci_info=True + ) + + for interface in interfaces: + for sriov_vf in interface['vf']: + sriov_vf['policyName'] = '' + + interface['policy'] = [] + node_policies = self.k8s_handler.get_sriov_network_node_policies_with_interface( + interface['name'] + ) + + interface['numVfs'] = 0 + interface['vfCount'] = 0 + interface['vfNetwork'] = 0 + + for node_policy in node_policies: + node_policy_info = {} + node_policy_info['name'] = node_policy['metadata']['name'] + node_policy_info['resourceName'] = node_policy['spec']['resourceName'] + node_policy_info['deviceType'] = node_policy['spec']['deviceType'] + node_policy_info['numVfs'] = node_policy['spec']['numVfs'] + node_policy_info['vfCount'] = node_policy['spec']['numVfs'] + node_policy_info['networks'] = [] + node_policy_info['selector'] = None + if 'pfNames' not in node_policy['spec']['nicSelector']: + self.log.error( + 'get_ocp_node_sriov_interfaces', + 'Unsupported nicSelector: %s' % (node_policy['spec']['nicSelector']) + ) + + if 'pfNames' in node_policy['spec']['nicSelector']: + for pf_name in node_policy['spec']['nicSelector']['pfNames']: + if len(pf_name.split('#')) == 1 and pf_name == interface['name']: + for sriov_vf in interface['vf']: + sriov_vf['policyName'] = node_policy_info['name'] + + if len(pf_name.split('#')) == 2 and pf_name.split('#')[0] == interface['name']: + node_policy_info['selector'] = pf_name + (start_vf, end_vf) = pf_name.split('#')[1].split('-') + node_policy_info['vfCount'] = int(end_vf) - int(start_vf) + 1 + + for sriov_vf in interface['vf']: + if int(start_vf) <= int(sriov_vf['index']) <= int(end_vf): + sriov_vf['policyName'] = node_policy_info['name'] + + networks = self.k8s_handler.get_sriov_networks_with_resource_name( + node_policy_info['resourceName'], + return_mo=True + ) + if networks is not None: + for network in networks: + network_info = {} + network_info['__Output'] = {} + network_info['name'] = network['metadata']['name'] + network_info['namespace'] = network['metadata']['namespace'] + network_info['networkNamespace'] = network['spec']['networkNamespace'] + network_info['namespace_name'] = '%s/%s' % ( + network_info['networkNamespace'], + network_info['name'] + ) + network_info['ipam'] = None + if 'ipam' in network['spec']: + try: + network_info['ipam'] = json.loads( + network['spec']['ipam'] + ) + except BaseException: + network_info['ipam'] = network['spec']['ipam'] + + if network_info['ipam'] is None: + network_info['ipamTick'] = '\u2717' + network_info['__Output']['ipamTick'] = 'Red' + else: + network_info['ipamTick'] = '\u2713' + network_info['__Output']['ipamTick'] = 'Green' + + network_info['vlan'] = '--' + if 'vlan' in network['spec']: + network_info['vlan'] = network['spec']['vlan'] + + node_policy_info['networks'].append( + network_info + ) + + node_policy_info['networksCount'] = len(node_policy_info['networks']) + node_policy_info['vfUsage'] = '%s/%s' % ( + node_policy_info['networksCount'], + node_policy_info['vfCount'] + ) + + interface['numVfs'] = node_policy_info['numVfs'] + interface['vfCount'] = interface['vfCount'] + node_policy_info['vfCount'] + interface['vfNetwork'] = interface['vfNetwork'] + node_policy_info['networksCount'] + + interface['policy'].append( + node_policy_info + ) + + interface['vfUsage'] = '%s/%s' % ( + interface['vfNetwork'], + interface['vfCount'] + ) + interface['policyCount'] = len( + interface['policy'] + ) + + self.node_sriov[node_name] = interfaces + self.log.debug( + 'get_ocp_node_sriov_interfaces', + json.dumps(interfaces, indent=4) + ) + + return interfaces + + def get_ocp_node_sriov_phy(self, node_name): + interfaces = self.get_ocp_node_sriov_interfaces( + node_name + ) + if interfaces is None: + return None + + info = [] + for interface in interfaces: + interface_info = {} + interface_info['__Output'] = {} + interface_info['name'] = interface['name'] + interface_info['flags'] = interface['flags'] + interface_info['mtu'] = interface['mtu'] + interface_info['state'] = interface['state'] + if interface_info['state'].lower() == 'up': + interface_info['__Output']['state'] = 'Green' + else: + interface_info['__Output']['state'] = 'Red' + interface_info['mac'] = interface['mac'] + interface_info['numa'] = interface['numa'] + interface_info['pci'] = interface['pci'] + interface_info['numVfs'] = interface['numVfs'] + interface_info['vfUsage'] = interface['vfUsage'] + interface_info['policyCount'] = interface['policyCount'] + info.append( + interface_info + ) + + info = sorted( + info, + key=lambda i: i['name'] + ) + + return info + + def get_ocp_node_sriov_policy(self, node_name): + interfaces = self.get_ocp_node_sriov_interfaces( + node_name + ) + if interfaces is None: + return None + + info = [] + for interface in interfaces: + for policy in interface['policy']: + interface_info = {} + interface_info['__Output'] = {} + interface_info['name'] = interface['name'] + interface_info['policyName'] = policy['name'] + interface_info['resourceName'] = policy['resourceName'] + interface_info['deviceType'] = policy['deviceType'] + interface_info['numVfs'] = policy['numVfs'] + interface_info['selector'] = policy['selector'] + interface_info['vfUsage'] = policy['vfUsage'] + info.append( + interface_info + ) + + info = sorted( + info, + key=lambda i: i['policyName'] + ) + + return info + + def get_ocp_node_sriov_network(self, node_name): + interfaces = self.get_ocp_node_sriov_interfaces( + node_name + ) + if interfaces is None: + return None + + info = [] + for interface in interfaces: + for policy in interface['policy']: + for network in policy['networks']: + network_info = copy.deepcopy(network) + network_info['interfaceName'] = interface['name'] + network_info['policyName'] = policy['name'] + network_info['resourceName'] = policy['resourceName'] + network_info['deviceType'] = policy['deviceType'] + network_info['selector'] = policy['selector'] + network_info['vf'] = '' + network_info['usedBy'] = '' + + vm_filter = ['multus_network:%s' % (network_info['name'])] + ocp_vms = self.get_ocp_vms(vm_filter=vm_filter) + if ocp_vms is not None and len(ocp_vms) == 1: + network_info['usedBy'] = 'VM: %s' % ( + ocp_vms[0]['namespace_name'] + ) + for vm_interface in ocp_vms[0]['interfaces']: + if vm_interface['multusNetworkName'] == network_info['name']: + network_info['usedBy'] = '%s/%s' % ( + network_info['usedBy'], + vm_interface['name'] + ) + for interface_vf in interface['vf']: + if ip_helper.is_mac_equal(interface_vf['mac'], vm_interface['mac_address']): + network_info['vf'] = interface_vf['index'] + + pod_filter = ['network:%s' % (network_info['namespace_name'])] + ocp_pods = self.k8s_handler.get_pods(pod_filter=pod_filter) + if ocp_pods is not None and len(ocp_pods) == 1: + network_info['usedBy'] = 'POD: %s/%s' % ( + ocp_pods[0]['metadata']['namespace'], + ocp_pods[0]['metadata']['name'] + ) + for pod_interface in ocp_pods[0]['networks']: + if pod_interface['name'] == network_info['namespace_name']: + network_info['usedBy'] = '%s/%s' % ( + network_info['usedBy'], + pod_interface['interface'] + ) + for interface_vf in interface['vf']: + if ip_helper.is_mac_equal(interface_vf['mac'], pod_interface['mac']): + network_info['vf'] = interface_vf['index'] + + info.append( + network_info + ) + + info = sorted( + info, + key=lambda i: i['namespace_name'] + ) + + return info + + def get_ocp_node_sriov_vf(self, node_name): + interfaces = self.get_ocp_node_sriov_interfaces( + node_name + ) + if interfaces is None: + return None + + info = [] + for interface in interfaces: + for sriov_vf in interface['vf']: + interface_info = {} + interface_info['__Output'] = {} + interface_info['name'] = interface['name'] + interface_info['index'] = sriov_vf['index'] + interface_info['mac'] = sriov_vf['mac'] + interface_info['vlan'] = '--' + if sriov_vf['vlan'] is not None: + interface_info['vlan'] = sriov_vf['vlan'] + interface_info['spoof'] = sriov_vf['spoof'] + interface_info['link'] = sriov_vf['link'] + interface_info['trust'] = sriov_vf['trust'] + interface_info['policyName'] = sriov_vf['policyName'] + + interface_info['used'] = False + interface_info['usedTick'] = '\u2717' + interface_info['networkName'] = '' + interface_info['__Output']['usedTick'] = 'Red' + interface_info['usedBy'] = '' + + vm_filter = ['mac:%s' % (sriov_vf['mac'])] + ocp_vms = self.get_ocp_vms(vm_filter=vm_filter) + if ocp_vms is not None and len(ocp_vms) == 1: + interface_info['used'] = True + interface_info['usedTick'] = '\u2713' + interface_info['__Output']['usedTick'] = 'Green' + interface_info['usedBy'] = 'VM: %s' % ( + ocp_vms[0]['namespace_name'] + ) + for vm_interface in ocp_vms[0]['interfaces']: + if ip_helper.is_mac_equal(vm_interface['mac_address'], sriov_vf['mac']): + interface_info['networkName'] = vm_interface['multusNetworkName'] + interface_info['usedBy'] = '%s/%s' % ( + interface_info['usedBy'], + vm_interface['name'] + ) + + pod_filter = ['mac:%s' % (sriov_vf['mac'])] + ocp_pods = self.k8s_handler.get_pods(pod_filter=pod_filter) + if ocp_pods is not None and len(ocp_pods) == 1: + interface_info['used'] = True + interface_info['usedTick'] = '\u2713' + interface_info['__Output']['usedTick'] = 'Green' + interface_info['usedBy'] = 'POD: %s/%s' % ( + ocp_pods[0]['metadata']['namespace'], + ocp_pods[0]['metadata']['name'] + ) + for pod_interface in ocp_pods[0]['networks']: + if ip_helper.is_mac_equal(pod_interface['mac'], sriov_vf['mac']): + interface_info['networkName'] = pod_interface['name'] + interface_info['usedBy'] = '%s/%s' % ( + interface_info['usedBy'], + pod_interface['interface'] + ) + + info.append( + interface_info + ) + + return info + + def get_ocp_node_sriov(self, node_name, sriov_phy_info=False, sriov_policy_info=False, sriov_network_info=False, sriov_vf_info=False): + info = {} + + if sriov_phy_info: + info['sriov_phy'] = self.get_ocp_node_sriov_phy( + node_name + ) + + if sriov_policy_info: + info['sriov_policy'] = self.get_ocp_node_sriov_policy( + node_name + ) + + if sriov_network_info: + info['sriov_network'] = self.get_ocp_node_sriov_network( + node_name + ) + + if sriov_vf_info: + info['sriov_vf'] = self.get_ocp_node_sriov_vf( + node_name + ) + + return info diff --git a/lib/ocp/output.py b/lib/ocp/output.py new file mode 100644 index 00000000..2c6cf031 --- /dev/null +++ b/lib/ocp/output.py @@ -0,0 +1,22 @@ +from lib import output_helper + +from lib.ocp.cluster.output import OcpClusterOutput +from lib.ocp.task.output import OcpTaskOutput +from lib.ocp.vm.output import OcpVmOutput + + +class OcpOutput( + OcpClusterOutput, + OcpTaskOutput, + OcpVmOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + OcpClusterOutput.__init__(self) + OcpTaskOutput.__init__(self) + OcpVmOutput.__init__(self) diff --git a/lib/ocp/settings.py b/lib/ocp/settings.py new file mode 100644 index 00000000..57c0839e --- /dev/null +++ b/lib/ocp/settings.py @@ -0,0 +1,448 @@ +import os +import json +import shutil +import traceback + +from lib import file_helper +from lib import filter_helper +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class OcpSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.ocp_settings_filename = os.path.join( + self.settings_dir, + 'ocp' + ) + + self.ocp_clusters_directory = os.path.join( + self.settings_dir, + 'ocp-clusters' + ) + + if not self.initialize_ocp_settings(): + raise ValueError('OCP settings initialization failed') + + def get_ocp_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Defaults'] = {} + settings['Defaults']['Cluster'] = None + settings['Clusters'] = [] + return settings + + def initialize_ocp_settings(self): + if not os.path.isfile(self.ocp_settings_filename): + settings = self.get_ocp_default_settings() + if not self.set_ocp_settings(settings): + return False + + if not os.path.isdir(self.ocp_clusters_directory): + os.makedirs( + self.ocp_clusters_directory, + exist_ok=True + ) + + fixup = False + + settings = self.get_ocp_settings() + for cluster in settings['Clusters']: + for key in ['helm', 'virtctl', 'tools', 'ssh']: + if key not in cluster: + fixup = True + cluster[key] = None + + if fixup: + return self.set_ocp_settings(settings) + + return True + + def get_ocp_settings(self): + if not os.path.isfile(self.ocp_settings_filename): + return None + + try: + with open(self.ocp_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_ocp_settings', traceback.format_exc()) + return None + + return settings + + def set_ocp_settings(self, settings): + try: + with open(self.ocp_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_ocp_settings', traceback.format_exc()) + return False + + return True + + def get_default_cluster(self): + settings = self.get_ocp_settings() + if settings is None: + return None + + try: + default_cluster_name = settings['Defaults']['Cluster'] + except BaseException: + default_cluster_name = None + + return default_cluster_name + + def set_default_cluster(self, name): + settings = self.get_ocp_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Cluster'] = name + return self.set_ocp_settings(settings) + + def get_ocp_cluster_names(self): + clusters = self.get_ocp_clusters() + if clusters is None: + return None + + names = [] + for cluster in clusters: + names.append( + cluster['name'] + ) + + return names + + def match_cluster(self, cluster_settings, cluster_filter): + if cluster_filter is None or len(cluster_filter) == 0: + return True + + for ap_rule in cluster_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cluster_settings['name']): + return False + + if not key_found: + self.log.error( + 'match_cluster', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_ocp_clusters(self, cluster_filter=None): + settings = self.get_ocp_settings() + if settings is None: + return None + + all_clusters = settings['Clusters'] + clusters = [] + for cluster in all_clusters: + if not self.match_cluster(cluster, cluster_filter): + continue + + clusters.append( + cluster + ) + + clusters = sorted( + clusters, + key=lambda i: i['name'] + ) + + return clusters + + def get_ocp_cluster(self, ocp_name, strict_match=True): + clusters = self.get_ocp_clusters() + if clusters is None: + return None + + candidates = [] + for cluster in clusters: + if cluster['name'] == ocp_name: + return cluster + + if not strict_match: + if ocp_name.lower() in cluster['name'].lower(): + candidates.append(cluster) + + if not strict_match and len(candidates) == 1: + return candidates[0] + + return None + + def is_ocp_cluster(self, ocp_name): + if self.get_ocp_cluster(ocp_name) is None: + return False + return True + + # LCM + def get_ocp_cluster_parameters(self, ocp_name): + return self.get_ocp_cluster_parameter(ocp_name, 'parameters') + + # LCM + def get_ocp_cluster_parameter(self, ocp_name, parameter_name): + clusters = self.get_ocp_clusters() + if clusters is None: + return None + + for cluster in clusters: + if cluster['name'] == ocp_name: + if parameter_name in cluster: + return cluster[parameter_name] + + return None + + # LCM, kubeadmin, cluster_id + def set_ocp_cluster_parameter(self, ocp_name, parameter_name, parameter_value): + clusters = self.get_ocp_clusters() + if clusters is None: + return None + + for cluster in clusters: + if cluster['name'] == ocp_name: + cluster[parameter_name] = parameter_value + + return self.set_ocp_clusters(clusters) + + def set_ocp_clusters(self, clusters): + settings = self.get_ocp_settings() + if settings is None: + return False + + settings['Clusters'] = clusters + return self.set_ocp_settings(settings) + + def get_ocp_cluster_directory(self, ocp_name): + cluster_directory = os.path.join( + self.ocp_clusters_directory, + ocp_name + ) + return cluster_directory + + def copy_ocp_cluster_file(self, ocp_name, source_filename, destination_filename): + if not os.path.isfile(source_filename): + self.log.error( + 'copy_ocp_cluster_file', + 'Source file not found: %s' % (source_filename) + ) + return None + + cluster_directory = self.get_ocp_cluster_directory(ocp_name) + if not os.path.isdir(cluster_directory): + self.log.error( + 'copy_ocp_cluster_file', + 'OCP directory not found: %s' % (cluster_directory) + ) + return None + + target_filename = os.path.join( + cluster_directory, + destination_filename + ) + shutil.copy( + source_filename, + target_filename + ) + if not os.path.isfile(target_filename): + self.log.error( + 'copy_ocp_cluster_file', + 'File copy failed: %s => %s' % (source_filename, target_filename) + ) + return None + + return target_filename + + def create_ocp_cluster(self, name, kubeconfig): + new_cluster = {} + new_cluster['name'] = name + new_cluster['kubeconfig'] = self.get_ocp_cluster_kubeconfig_filename(name) + for key in ['virtcl', 'helm', 'tools', 'ssh']: + new_cluster[key] = None + + clusters = self.get_ocp_clusters() + if clusters is None: + self.log.error( + 'create_ocp_cluster', + 'Failed to get clusters' + ) + return False + + clusters.append(new_cluster) + if not self.set_ocp_clusters(clusters): + self.log.error( + 'create_ocp_cluster', + 'Failed to set clusters' + ) + return False + + return self.set_ocp_cluster_kubeconfig(name, kubeconfig) + + def set_ocp_cluster(self, cluster_settings): + clusters = self.get_ocp_clusters() + if clusters is None: + self.log.error( + 'set_ocp_cluster', + 'Failed to get clusters' + ) + return False + + new_clusters = [] + for cluster in clusters: + if cluster['name'] == cluster_settings['name']: + new_clusters.append( + cluster_settings + ) + continue + + new_clusters.append( + cluster + ) + + return self.set_ocp_clusters(new_clusters) + + def get_ocp_cluster_kubeconfig_filename(self, ocp_name): + cluster_directory = self.get_ocp_cluster_directory(ocp_name) + target_kubeconfig_filename = os.path.join( + cluster_directory, + 'kubeconfig' + ) + return target_kubeconfig_filename + + def set_ocp_cluster_kubeconfig(self, ocp_name, kubeconfig_filename): + if not os.path.isfile(kubeconfig_filename): + self.log.error( + 'set_ocp_cluster_kubeconfig', + 'Kubeconfig file not found: %s' % (kubeconfig_filename) + ) + return False + + cluster = self.get_ocp_cluster(ocp_name) + if cluster is None: + self.log.error( + 'set_ocp_cluster_kubeconfig', + 'Cluster not found: %s' % (ocp_name) + ) + return False + + cluster_directory = self.get_ocp_cluster_directory(ocp_name) + if not os.path.isdir(cluster_directory): + os.makedirs( + cluster_directory, + exist_ok=True + ) + + target_kubeconfig_filename = os.path.join( + cluster_directory, + 'kubeconfig' + ) + + shutil.copy( + kubeconfig_filename, + target_kubeconfig_filename + ) + if not os.path.isfile(target_kubeconfig_filename): + self.log.error( + 'set_ocp_cluster_kubeconfig', + 'Kubeconfig file copy failed: %s => %s' % (kubeconfig_filename, target_kubeconfig_filename) + ) + return False + + return self.set_ocp_cluster(cluster) + + def set_ocp_cluster_kubeadmin(self, ocp_name, kubeadmin): + cluster = self.get_ocp_cluster(ocp_name) + if cluster is None: + self.log.error( + 'set_ocp_cluster_kubeadmin', + 'Cluster not found: %s' % (ocp_name) + ) + return False + + cluster_directory = self.get_ocp_cluster_directory(ocp_name) + if not os.path.isdir(cluster_directory): + os.makedirs( + cluster_directory, + exist_ok=True + ) + + target_kubeadmin_filename = os.path.join( + cluster_directory, + 'kubeadmin' + ) + + success = file_helper.set_file( + target_kubeadmin_filename, + kubeadmin + ) + + return success + + def set_ocp_cluster_file(self, ocp_name, filename, content): + cluster = self.get_ocp_cluster(ocp_name) + if cluster is None: + self.log.error( + 'set_ocp_cluster_kubeadmin', + 'Cluster not found: %s' % (ocp_name) + ) + return False + + cluster_directory = self.get_ocp_cluster_directory(ocp_name) + if not os.path.isdir(cluster_directory): + os.makedirs( + cluster_directory, + exist_ok=True + ) + + target_filename = os.path.join( + cluster_directory, + filename + ) + + success = file_helper.set_file( + target_filename, + content + ) + + return success + + def delete_ocp_cluster(self, ocp_name): + clusters = self.get_ocp_clusters() + if clusters is None: + return False + + new_clusters = [] + for cluster in clusters: + if cluster['name'] != ocp_name: + new_clusters.append(cluster) + + cluster_directory = os.path.join( + self.ocp_clusters_directory, + ocp_name + ) + if os.path.isdir(cluster_directory): + shutil.rmtree(cluster_directory) + + return self.set_ocp_clusters(new_clusters) diff --git a/lib/ocp/task/__init__.py b/lib/ocp/task/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/task/__pycache__/__init__.cpython-310.pyc b/lib/ocp/task/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1dbd0b2b Binary files /dev/null and b/lib/ocp/task/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/task/__pycache__/main.cpython-310.pyc b/lib/ocp/task/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a054233a Binary files /dev/null and b/lib/ocp/task/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/task/chrony/__init__.py b/lib/ocp/task/chrony/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/task/chrony/main.py b/lib/ocp/task/chrony/main.py new file mode 100644 index 00000000..e9567fe9 --- /dev/null +++ b/lib/ocp/task/chrony/main.py @@ -0,0 +1,76 @@ +class OcpTaskChrony(): + def __init__(self): + pass + + def get_ocp_chrony_mc(self): + info = [] + + machine_configs = self.k8s_handler.get_machine_configs( + object_filter=['path:/etc/chrony.conf'] + ) + for machine_config in machine_configs: + if len(machine_config['file']) == 0: + continue + + if machine_config['name'].startswith('rendered-'): + continue + + info.append( + machine_config + ) + + return info + + def get_ocp_chrony_config(self, handlers): + info = [] + + for handler in handlers: + item = {} + item['name'] = handler['name'] + item['ip'] = handler['ip'] + + chrony_config = handler['handler'].get_chrony_config_info() + if chrony_config is None: + continue + + item['config'] = chrony_config['configuration'] + info.append(item) + + return info + + def get_ocp_chrony_state(self, handlers): + info = [] + + for handler in handlers: + item = {} + item['name'] = handler['name'] + item['ip'] = handler['ip'] + + chrony_state = handler['handler'].get_chrony_tracking_info() + if chrony_state is None: + continue + + for key in chrony_state: + item[key] = chrony_state[key] + + info.append(item) + + return info + + def get_ocp_chrony_info(self, mcp=False, config=False, state=False): + info = {} + + handlers = self.get_ocp_nodes_linux_handlers() + if handlers is None: + return None + + if mcp: + info['mc'] = self.get_ocp_chrony_mc() + + if config: + info['config'] = self.get_ocp_chrony_config(handlers) + + if state: + info['state'] = self.get_ocp_chrony_state(handlers) + + return info diff --git a/lib/ocp/task/chrony/output.py b/lib/ocp/task/chrony/output.py new file mode 100644 index 00000000..474e0ade --- /dev/null +++ b/lib/ocp/task/chrony/output.py @@ -0,0 +1,91 @@ +class OcpTaskChronyOutput(): + def __init__(self): + pass + + def print_ocp_chrony_config(self, info, title=False): + if title: + self.my_output.default( + 'Chrony Configuration', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + equal = True + if len(info) > 1: + reference = '\n'.join(info[0]['config']) + for item in info: + if '\n'.join(item['config']) != reference: + equal = False + + if equal: + self.my_output.default('Configuration the same on all nodes', before_newline=True, after_newline=True) + for line in info[0]['config']: + self.my_output.default(line) + + if not equal: + for item in info: + self.my_output.default('Node %s [%s]' % (item['name'], item['ip']), after_newline=True) + for line in item['config']: + self.my_output.default(line) + + def print_ocp_chrony_state(self, info): + order = [ + 'name', + 'status', + 'reference', + 'stratum', + 'time', + 'root_delay' + ] + + headers = [ + 'Node', + 'Status', + 'Reference', + 'Stratum', + 'Time', + 'Delay' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_ocp_chrony_mc(self, info, title=False): + if title: + self.my_output.default( + 'Chrony Machine Configuration', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + self.my_output.default('Machine config: %s' % (item['name']), before_newline=True) + self.my_output.default('Node: %s' % (', '.join(item['node']))) + for file_info in item['file']: + self.my_output.default('Path: %s' % (file_info['path'])) + self.my_output.default(file_info['content']) + + def print_ocp_chrony_info(self, info): + if 'config' in info: + self.print_ocp_chrony_config(info['config'], title=True) + + if 'state' in info: + self.print_ocp_chrony_state(info['state']) + + if 'mc' in info: + self.print_ocp_chrony_mc(info['mc'], title=True) diff --git a/lib/ocp/task/container_policy/__init__.py b/lib/ocp/task/container_policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/task/container_policy/main.py b/lib/ocp/task/container_policy/main.py new file mode 100644 index 00000000..071bc869 --- /dev/null +++ b/lib/ocp/task/container_policy/main.py @@ -0,0 +1,57 @@ +class OcpTaskContainerPolicy(): + def __init__(self): + pass + + def get_ocp_container_policy_mc(self): + info = [] + + machine_configs = self.k8s_handler.get_machine_configs( + object_filter=['path:/etc/containers/policy.json'] + ) + for machine_config in machine_configs: + if len(machine_config['file']) == 0: + continue + + if machine_config['name'].startswith('rendered-'): + continue + + if machine_config['name'].endswith('-generated-registries'): + continue + + info.append( + machine_config + ) + + return info + + def get_ocp_container_policy_config(self, handlers): + info = [] + + for handler in handlers: + item = {} + item['name'] = handler['name'] + item['ip'] = handler['ip'] + + container_policy_config = handler['handler'].get_container_policy_config_info() + if container_policy_config is None: + continue + + item['config'] = container_policy_config + info.append(item) + + return info + + def get_ocp_container_policy_info(self, mcp=False, config=False, state=False): + info = {} + + handlers = self.get_ocp_nodes_linux_handlers() + if handlers is None: + return None + + if mcp: + info['mc'] = self.get_ocp_container_policy_mc() + + if config: + info['config'] = self.get_ocp_container_policy_config(handlers) + + return info diff --git a/lib/ocp/task/container_policy/output.py b/lib/ocp/task/container_policy/output.py new file mode 100644 index 00000000..53084e1b --- /dev/null +++ b/lib/ocp/task/container_policy/output.py @@ -0,0 +1,71 @@ +import json + + +class OcpTaskContainerPolicyOutput(): + def __init__(self): + pass + + def print_ocp_container_policy_config(self, info, title=False): + if title: + self.my_output.default( + 'Container Policy Configuration', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + equal = True + if len(info) > 1: + reference = '\n'.join(info[0]['config']) + for item in info: + if '\n'.join(item['config']) != reference: + equal = False + + if equal: + self.my_output.default('Configuration the same on all nodes', before_newline=True, after_newline=True) + self.my_output.default( + json.dumps( + info[0]['config'], + indent=4 + ) + ) + + if not equal: + for item in info: + self.my_output.default('Node %s [%s]' % (item['name'], item['ip']), after_newline=True) + + self.my_output.default( + json.dumps( + item['config'], + indent=4 + ) + ) + + def print_ocp_container_policy_mc(self, info, title=False): + if title: + self.my_output.default( + 'ContainerPolicy Machine Configuration', + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + self.my_output.default('Machine config: %s' % (item['name']), before_newline=True) + self.my_output.default('Node: %s' % (', '.join(item['node']))) + for file_info in item['file']: + self.my_output.default('Path: %s' % (file_info['path'])) + self.my_output.default(file_info['content']) + + def print_ocp_container_policy_info(self, info): + if 'config' in info: + self.print_ocp_container_policy_config(info['config'], title=True) + + if 'mc' in info: + self.print_ocp_container_policy_mc(info['mc'], title=True) diff --git a/lib/ocp/task/main.py b/lib/ocp/task/main.py new file mode 100644 index 00000000..77290846 --- /dev/null +++ b/lib/ocp/task/main.py @@ -0,0 +1,17 @@ +from lib.ocp.task.chrony.main import OcpTaskChrony +from lib.ocp.task.container_policy.main import OcpTaskContainerPolicy +from lib.ocp.task.node.main import OcpTaskNode +from lib.ocp.task.ssh import OcpTaskSsh + + +class OcpTask( + OcpTaskChrony, + OcpTaskContainerPolicy, + OcpTaskNode, + OcpTaskSsh + ): + def __init__(self): + OcpTaskChrony.__init__(self) + OcpTaskContainerPolicy.__init__(self) + OcpTaskNode.__init__(self) + OcpTaskSsh.__init__(self) diff --git a/lib/ocp/task/node/__init__.py b/lib/ocp/task/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/task/node/__pycache__/__init__.cpython-310.pyc b/lib/ocp/task/node/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..6981f15a Binary files /dev/null and b/lib/ocp/task/node/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/task/node/__pycache__/down.cpython-310.pyc b/lib/ocp/task/node/__pycache__/down.cpython-310.pyc new file mode 100644 index 00000000..57f63ef0 Binary files /dev/null and b/lib/ocp/task/node/__pycache__/down.cpython-310.pyc differ diff --git a/lib/ocp/task/node/__pycache__/main.cpython-310.pyc b/lib/ocp/task/node/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6a7b2375 Binary files /dev/null and b/lib/ocp/task/node/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/task/node/__pycache__/nestedhv.cpython-310.pyc b/lib/ocp/task/node/__pycache__/nestedhv.cpython-310.pyc new file mode 100644 index 00000000..f7c09f5d Binary files /dev/null and b/lib/ocp/task/node/__pycache__/nestedhv.cpython-310.pyc differ diff --git a/lib/ocp/task/node/__pycache__/up.cpython-310.pyc b/lib/ocp/task/node/__pycache__/up.cpython-310.pyc new file mode 100644 index 00000000..dc8be569 Binary files /dev/null and b/lib/ocp/task/node/__pycache__/up.cpython-310.pyc differ diff --git a/lib/ocp/task/node/down.py b/lib/ocp/task/node/down.py new file mode 100644 index 00000000..3f81768f --- /dev/null +++ b/lib/ocp/task/node/down.py @@ -0,0 +1,53 @@ +class OcpTaskNodeDown(): + def __init__(self): + pass + + def set_ocp_node_vm_down(self, ocp_node_name, node_mo, wait=True): + node_status = self.get_node_ready_status(node_mo) + node_ready = self.is_node_ready(node_mo) + self.my_output.info('Node status: %s' % (node_status)) + + node_vm_name = self.get_node_vm_name(node_mo) + if node_vm_name is None: + self.log.error( + 'ocp.set_ocp_node_down', + 'node vm unknown: %s' % (self.get_node_name(node_mo)) + ) + return False + + self.my_output.info('Node vm name: %s' % (node_vm_name)) + powered_on = self.is_ocp_node_vm_powered_on(node_vm_name) + self.my_output.info('Node vm powered on: %s' % (powered_on)) + + if not powered_on: + if node_ready: + self.my_output.default('Warning: node vm powered off but ready in kubernetes') + return True + + self.my_output.default('Node vm powered off and not ready in kubernetes') + return True + + if not self.ocp_vcenter_handler.power_off_vm(node_vm_name): + return False + self.my_output.info('Node vm powered off') + + self.my_output.default('Wait for k8s node not ready status...') + if not self.wait_node_not_ready(ocp_node_name): + self.my_output.error('K8s node status invalid or timed out reached') + return False + + self.my_output.default('Node vm powered off and not ready in kubernetes') + return True + + def set_ocp_node_down(self, ocp_node_name, wait=True): + node_mo = self.get_node_mo(ocp_node_name) + if node_mo is None: + self.my_output.error('Node not found: %s' % (ocp_node_name)) + return False + + self.my_output.default('Node found: %s' % (ocp_node_name)) + if self.is_node_vm(node_mo): + return self.set_ocp_node_vm_down(ocp_node_name, node_mo, wait=wait) + + self.my_output.error('Unsupported node type: %s' % (ocp_node_name)) + return False diff --git a/lib/ocp/task/node/main.py b/lib/ocp/task/node/main.py new file mode 100644 index 00000000..e6595fff --- /dev/null +++ b/lib/ocp/task/node/main.py @@ -0,0 +1,20 @@ +from lib.ocp.task.node.down import OcpTaskNodeDown +from lib.ocp.task.node.nestedhv import OcpTaskNestedHv +from lib.ocp.task.node.up import OcpTaskNodeUp + + +class OcpTaskNode(OcpTaskNodeDown, OcpTaskNestedHv, OcpTaskNodeUp): + def __init__(self): + OcpTaskNodeDown.__init__(self) + OcpTaskNestedHv.__init__(self) + OcpTaskNodeUp.__init__(self) + + def is_ocp_node_vm_powered_on(self, node_vm_name): + if self.ocp_vcenter_handler is None: + self.log.error( + 'ocp.is_node_vm_down', + 'vcenter connection failed' + ) + return False + + return self.ocp_vcenter_handler.is_vm_powered_on(node_vm_name) diff --git a/lib/ocp/task/node/nestedhv.py b/lib/ocp/task/node/nestedhv.py new file mode 100644 index 00000000..b5ecb978 --- /dev/null +++ b/lib/ocp/task/node/nestedhv.py @@ -0,0 +1,74 @@ +class OcpTaskNestedHv(): + def __init__(self): + pass + + def set_ocp_node_vm_nestedhv(self, ocp_node_name, node_mo, enabled=True): + if self.ocp_vcenter_handler is None: + self.my_output.error('vcenter connection failed') + return False + + node_status = self.get_node_ready_status(node_mo) + self.my_output.info('Node status: %s' % (node_status)) + + node_vm_name = self.get_node_vm_name(node_mo) + if node_vm_name is None: + self.log.error( + 'ocp.set_ocp_node_down', + 'node vm unknown: %s' % (self.get_node_name(node_mo)) + ) + return False + + self.my_output.info('Node vm name: %s' % (node_vm_name)) + powered_on = self.is_ocp_node_vm_powered_on(node_vm_name) + self.my_output.info('Node vm powered on: %s' % (powered_on)) + + nested_hv_enabled = self.ocp_vcenter_handler.get_vm_nestedhv(node_vm_name) + self.my_output.info('Nested HV: %s' % (nested_hv_enabled)) + + if enabled and nested_hv_enabled: + self.my_output.default('Nested HV is already enabled') + return True + + if not enabled and not nested_hv_enabled: + self.my_output.default('Nested HV is already disabled') + return True + + if powered_on: + if not self.ocp_vcenter_handler.power_off_vm(node_vm_name): + return False + self.my_output.default('Node vm powered off') + + self.my_output.default('Wait for k8s node not ready status...') + if not self.wait_node_not_ready(ocp_node_name): + self.my_output.error('K8s node status invalid or timed out reached') + return False + + if not self.ocp_vcenter_handler.set_vm_nestedhv(node_vm_name, enabled=enabled): + self.my_output.error('VM reconfiguration failed') + return False + self.my_output.default('VM nestedHV configured to: %s' % (enabled)) + + if not self.ocp_vcenter_handler.power_on_vm(node_vm_name): + return False + + self.my_output.default('Wait for k8s node ready status...') + if not self.wait_node_ready(ocp_node_name): + self.my_output.error('K8s node status invalid or timed out reached') + return False + + self.my_output.default('Node vm powered on and ready in kubernetes') + + return True + + def set_ocp_node_nestedhv(self, ocp_node_name, enabled=True): + node_mo = self.get_node_mo(ocp_node_name) + if node_mo is None: + self.my_output.error('Node not found: %s' % (ocp_node_name)) + return False + + self.my_output.default('Node found: %s' % (ocp_node_name)) + if self.is_node_vm(node_mo): + return self.set_ocp_node_vm_nestedhv(ocp_node_name, node_mo, enabled=enabled) + + self.my_output.error('Unsupported node type: %s' % (ocp_node_name)) + return False diff --git a/lib/ocp/task/node/up.py b/lib/ocp/task/node/up.py new file mode 100644 index 00000000..f6d81962 --- /dev/null +++ b/lib/ocp/task/node/up.py @@ -0,0 +1,52 @@ +class OcpTaskNodeUp(): + def __init__(self): + pass + + def set_ocp_node_vm_up(self, ocp_node_name, node_mo, wait=True): + node_status = self.get_node_ready_status(node_mo) + node_ready = self.is_node_ready(node_mo) + self.my_output.info('Node status: %s' % (node_status)) + + node_vm_name = self.get_node_vm_name(node_mo) + if node_vm_name is None: + self.log.error( + 'ocp.set_ocp_node_down', + 'node vm unknown: %s' % (self.get_node_name(node_mo)) + ) + return False + + self.my_output.info('Node vm name: %s' % (node_vm_name)) + powered_on = self.is_ocp_node_vm_powered_on(node_vm_name) + self.my_output.info('Node vm powered on: %s' % (powered_on)) + + if powered_on: + if not node_ready: + self.my_output.default('Warning: node vm powered on but not ready in kubernetes') + return True + + self.my_output.default('Node vm powered on and ready in kubernetes') + return True + + if not self.ocp_vcenter_handler.power_on_vm(node_vm_name): + return False + + self.my_output.default('Wait for k8s node ready status...') + if not self.wait_node_ready(ocp_node_name): + self.my_output.error('K8s node status invalid or timed out reached') + return False + + self.my_output.default('Node vm powered on and ready in kubernetes') + return True + + def set_ocp_node_up(self, ocp_node_name, wait=True): + node_mo = self.get_node_mo(ocp_node_name) + if node_mo is None: + self.my_output.error('Node not found: %s' % (ocp_node_name)) + return False + + self.my_output.default('Node found: %s' % (ocp_node_name)) + if self.is_node_vm(node_mo): + return self.set_ocp_node_vm_up(ocp_node_name, node_mo, wait=wait) + + self.my_output.error('Unsupported node type: %s' % (ocp_node_name)) + return False diff --git a/lib/ocp/task/output.py b/lib/ocp/task/output.py new file mode 100644 index 00000000..c8cd025e --- /dev/null +++ b/lib/ocp/task/output.py @@ -0,0 +1,48 @@ +from lib.ocp.task.chrony.output import OcpTaskChronyOutput +from lib.ocp.task.container_policy.output import OcpTaskContainerPolicyOutput + +class OcpTaskOutput( + OcpTaskChronyOutput, + OcpTaskContainerPolicyOutput + ): + def __init__(self): + OcpTaskChronyOutput.__init__(self) + OcpTaskContainerPolicyOutput.__init__(self) + + def print_ocp_ssh_authorized_keys(self, info): + order = [ + 'node', + 'username', + 'key', + 'mc' + ] + + headers = [ + 'Node', + 'Username', + 'Key', + 'Machine Config' + ] + + for item in info: + (key_type, key_pub, hostname) = item['key'].split(' ') + if len(key_pub) > 30: + item['key'] = '%s %s... %s' % ( + key_type, + key_pub[:30], + hostname + ) + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['node'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/ocp/task/ssh.py b/lib/ocp/task/ssh.py new file mode 100644 index 00000000..8f4b043e --- /dev/null +++ b/lib/ocp/task/ssh.py @@ -0,0 +1,215 @@ +from lib import file_helper + + +class OcpTaskSsh(): + def __init__(self): + pass + + def get_ocp_ssh_authorized_keys(self): + info = [] + + machine_configs = self.k8s_handler.get_machine_configs() + for machine_config in machine_configs: + if machine_config['owner_kind'] == 'MachineConfigPool': + continue + + for user in machine_config['users']: + for key in user['keys']: + item = {} + item['node'] = machine_config['node'] + item['username'] = user['username'] + item['key'] = key + item['mc'] = machine_config['name'] + info.append(item) + + return info + + def add_ocp_master_ssh_authorized_key(self, pubkey): + machine_config = self.k8s_handler.get_machine_config('99-master-ssh') + if machine_config is None: + self.log.error( + 'add_ocp_master_ssh_authorized_key', + 'Machine config not found: 99-master-ssh' + ) + return None + + for user_info in machine_config['users']: + if user_info['username'] == 'core': + if pubkey in user_info['keys']: + return [] + + machine_config_mo = self.k8s_handler.get_machine_config('99-master-ssh', return_mo=True) + + for user_mo in machine_config_mo['spec']['config']['passwd']['users']: + if user_mo['name'] == 'core': + user_mo['sshAuthorizedKeys'].append( + pubkey + ) + + if not self.k8s_handler.set_machine_config_mo(machine_config_mo): + self.log.error( + 'add_ocp_master_ssh_authorized_key', + 'Machine config update failed: 99-master-ssh' + ) + return None + + return ['99-master-ssh'] + + def add_ocp_worker_ssh_authorized_key(self, pubkey): + machine_config = self.k8s_handler.get_machine_config('99-worker-ssh') + if machine_config is None: + self.log.error( + 'add_ocp_worker_ssh_authorized_key', + 'Machine config not found: 99-worker-ssh' + ) + return None + + for user_info in machine_config['users']: + if user_info['username'] == 'core': + if pubkey in user_info['keys']: + return [] + + machine_config_mo = self.k8s_handler.get_machine_config('99-worker-ssh', return_mo=True) + + for user_mo in machine_config_mo['spec']['config']['passwd']['users']: + if user_mo['name'] == 'core': + user_mo['sshAuthorizedKeys'].append( + pubkey + ) + + if not self.k8s_handler.set_machine_config_mo(machine_config_mo): + self.log.error( + 'add_ocp_worker_ssh_authorized_key', + 'Machine config update failed: 99-worker-ssh' + ) + return None + + return ['99-worker-ssh'] + + def add_ocp_ssh_authorized_key(self, filename, node_role): + content = file_helper.get_file(filename).split('\n')[0].rstrip('\r') + + machine_configs = [] + if node_role in ['master', 'any']: + mcs = self.add_ocp_master_ssh_authorized_key(content) + if mcs is None: + return None + + for machine_config in mcs: + if machine_config not in machine_configs: + machine_configs.append( + machine_config + ) + + if node_role in ['worker', 'any']: + mcs = self.add_ocp_worker_ssh_authorized_key(content) + if mcs is None: + return None + + for machine_config in mcs: + if machine_config not in machine_configs: + machine_configs.append( + machine_config + ) + + return machine_configs + + def delete_ocp_master_ssh_authorized_key(self, match): + machine_config = self.k8s_handler.get_machine_config('99-master-ssh') + if machine_config is None: + self.log.error( + 'delete_ocp_master_ssh_authorized_key', + 'Machine config not found: 99-master-ssh' + ) + return None + + found = False + new_keys = [] + for user_info in machine_config['users']: + if user_info['username'] == 'core': + for key in user_info['keys']: + if match in key: + found = True + continue + new_keys.append(key) + + if not found: + return [] + + machine_config_mo = self.k8s_handler.get_machine_config('99-master-ssh', return_mo=True) + + for user_mo in machine_config_mo['spec']['config']['passwd']['users']: + if user_mo['name'] == 'core': + user_mo['sshAuthorizedKeys'] = new_keys + + if not self.k8s_handler.set_machine_config_mo(machine_config_mo): + self.log.error( + 'delete_ocp_master_ssh_authorized_key', + 'Machine config update failed: 99-master-ssh' + ) + return None + + return ['99-master-ssh'] + + def delete_ocp_worker_ssh_authorized_key(self, match): + machine_config = self.k8s_handler.get_machine_config('99-worker-ssh') + if machine_config is None: + self.log.error( + 'delete_ocp_worker_ssh_authorized_key', + 'Machine config not found: 99-worker-ssh' + ) + return None + + found = False + new_keys = [] + for user_info in machine_config['users']: + if user_info['username'] == 'core': + for key in user_info['keys']: + if match in key: + found = True + continue + new_keys.append(key) + + if not found: + return [] + + machine_config_mo = self.k8s_handler.get_machine_config('99-worker-ssh', return_mo=True) + + for user_mo in machine_config_mo['spec']['config']['passwd']['users']: + if user_mo['name'] == 'core': + user_mo['sshAuthorizedKeys'] = new_keys + + if not self.k8s_handler.set_machine_config_mo(machine_config_mo): + self.log.error( + 'delete_ocp_worker_ssh_authorized_key', + 'Machine config update failed: 99-worker-ssh' + ) + return None + + return ['99-worker-ssh'] + + def delete_ocp_ssh_authorized_key(self, match, node_role): + machine_configs = [] + if node_role in ['master', 'any']: + mcs = self.delete_ocp_master_ssh_authorized_key(match) + if mcs is None: + return None + + for machine_config in mcs: + if machine_config not in machine_configs: + machine_configs.append( + machine_config + ) + + if node_role in ['worker', 'any']: + mcs = self.delete_ocp_worker_ssh_authorized_key(match) + if mcs is None: + return None + + for machine_config in mcs: + if machine_config not in machine_configs: + machine_configs.append( + machine_config + ) + + return machine_configs diff --git a/lib/ocp/vm/__init__.py b/lib/ocp/vm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/vm/__pycache__/__init__.cpython-310.pyc b/lib/ocp/vm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..28a197f1 Binary files /dev/null and b/lib/ocp/vm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/create.cpython-310.pyc b/lib/ocp/vm/__pycache__/create.cpython-310.pyc new file mode 100644 index 00000000..2f4f87a0 Binary files /dev/null and b/lib/ocp/vm/__pycache__/create.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/day0.cpython-310.pyc b/lib/ocp/vm/__pycache__/day0.cpython-310.pyc new file mode 100644 index 00000000..07912cf0 Binary files /dev/null and b/lib/ocp/vm/__pycache__/day0.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/delete.cpython-310.pyc b/lib/ocp/vm/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..17bb8489 Binary files /dev/null and b/lib/ocp/vm/__pycache__/delete.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/disk.cpython-310.pyc b/lib/ocp/vm/__pycache__/disk.cpython-310.pyc new file mode 100644 index 00000000..430e1ecb Binary files /dev/null and b/lib/ocp/vm/__pycache__/disk.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/disks.cpython-310.pyc b/lib/ocp/vm/__pycache__/disks.cpython-310.pyc new file mode 100644 index 00000000..5280a2c8 Binary files /dev/null and b/lib/ocp/vm/__pycache__/disks.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/image.cpython-310.pyc b/lib/ocp/vm/__pycache__/image.cpython-310.pyc new file mode 100644 index 00000000..df8609b2 Binary files /dev/null and b/lib/ocp/vm/__pycache__/image.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/info.cpython-310.pyc b/lib/ocp/vm/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..1530f96c Binary files /dev/null and b/lib/ocp/vm/__pycache__/info.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/instance.cpython-310.pyc b/lib/ocp/vm/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..9e9a65eb Binary files /dev/null and b/lib/ocp/vm/__pycache__/instance.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/main.cpython-310.pyc b/lib/ocp/vm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..7a8e9944 Binary files /dev/null and b/lib/ocp/vm/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/mo.cpython-310.pyc b/lib/ocp/vm/__pycache__/mo.cpython-310.pyc new file mode 100644 index 00000000..8bbd629c Binary files /dev/null and b/lib/ocp/vm/__pycache__/mo.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/net.cpython-310.pyc b/lib/ocp/vm/__pycache__/net.cpython-310.pyc new file mode 100644 index 00000000..b0e35e8a Binary files /dev/null and b/lib/ocp/vm/__pycache__/net.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/output.cpython-310.pyc b/lib/ocp/vm/__pycache__/output.cpython-310.pyc new file mode 100644 index 00000000..88925742 Binary files /dev/null and b/lib/ocp/vm/__pycache__/output.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/pod.cpython-310.pyc b/lib/ocp/vm/__pycache__/pod.cpython-310.pyc new file mode 100644 index 00000000..0619e374 Binary files /dev/null and b/lib/ocp/vm/__pycache__/pod.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/report.cpython-310.pyc b/lib/ocp/vm/__pycache__/report.cpython-310.pyc new file mode 100644 index 00000000..23eed156 Binary files /dev/null and b/lib/ocp/vm/__pycache__/report.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/ssh.cpython-310.pyc b/lib/ocp/vm/__pycache__/ssh.cpython-310.pyc new file mode 100644 index 00000000..e7601e50 Binary files /dev/null and b/lib/ocp/vm/__pycache__/ssh.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/svc.cpython-310.pyc b/lib/ocp/vm/__pycache__/svc.cpython-310.pyc new file mode 100644 index 00000000..340f625e Binary files /dev/null and b/lib/ocp/vm/__pycache__/svc.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/task.cpython-310.pyc b/lib/ocp/vm/__pycache__/task.cpython-310.pyc new file mode 100644 index 00000000..3661040b Binary files /dev/null and b/lib/ocp/vm/__pycache__/task.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/validate.cpython-310.pyc b/lib/ocp/vm/__pycache__/validate.cpython-310.pyc new file mode 100644 index 00000000..8ab55365 Binary files /dev/null and b/lib/ocp/vm/__pycache__/validate.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/vm.cpython-310.pyc b/lib/ocp/vm/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..8acb21a4 Binary files /dev/null and b/lib/ocp/vm/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/vm_mo.cpython-310.pyc b/lib/ocp/vm/__pycache__/vm_mo.cpython-310.pyc new file mode 100644 index 00000000..c92598da Binary files /dev/null and b/lib/ocp/vm/__pycache__/vm_mo.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/vmi.cpython-310.pyc b/lib/ocp/vm/__pycache__/vmi.cpython-310.pyc new file mode 100644 index 00000000..49c88534 Binary files /dev/null and b/lib/ocp/vm/__pycache__/vmi.cpython-310.pyc differ diff --git a/lib/ocp/vm/__pycache__/vmi_mo.cpython-310.pyc b/lib/ocp/vm/__pycache__/vmi_mo.cpython-310.pyc new file mode 100644 index 00000000..c89fdb44 Binary files /dev/null and b/lib/ocp/vm/__pycache__/vmi_mo.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__init__.py b/lib/ocp/vm/create/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/vm/create/__pycache__/__init__.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c79a9fb9 Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/day0.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/day0.cpython-310.pyc new file mode 100644 index 00000000..e9d4c83e Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/day0.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/deployment.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/deployment.cpython-310.pyc new file mode 100644 index 00000000..bca55932 Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/deployment.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/image.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/image.cpython-310.pyc new file mode 100644 index 00000000..3fdfcbe7 Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/image.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/main.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c042f8d4 Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/network.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/network.cpython-310.pyc new file mode 100644 index 00000000..5931c9e7 Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/network.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/policy.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/policy.cpython-310.pyc new file mode 100644 index 00000000..76e8f76d Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/policy.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/service.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/service.cpython-310.pyc new file mode 100644 index 00000000..ed100443 Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/service.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/vm.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..281a691b Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/__pycache__/vmi.cpython-310.pyc b/lib/ocp/vm/create/__pycache__/vmi.cpython-310.pyc new file mode 100644 index 00000000..017e27ef Binary files /dev/null and b/lib/ocp/vm/create/__pycache__/vmi.cpython-310.pyc differ diff --git a/lib/ocp/vm/create/day0.py b/lib/ocp/vm/create/day0.py new file mode 100644 index 00000000..9eb4b894 --- /dev/null +++ b/lib/ocp/vm/create/day0.py @@ -0,0 +1,325 @@ +import os +import time +import uuid +import subprocess +import yaml + +from lib import ssh + + +class OcpVmCreateDay0(): + def __init__(self): + pass + + def create_day0(self): + if self.user_input['deployment']['day0']['enabled']: + day0_dv_filename = self.user_input['deployment']['day0']['dv'] + if day0_dv_filename is None: + self.my_output.error( + 'Define deployment.day.dv value' + ) + return False + + yaml_content = self.user_input['files'][day0_dv_filename] + dv_content = yaml.safe_load(yaml_content) + if dv_content is None or len(dv_content) == 0: + self.my_output.error( + 'Day0 data volume yaml not found' + ) + return False + + source_filename = self.user_input['deployment']['day0']['source'] + day0_content = self.user_input['files'][source_filename] + if day0_content is None or len(day0_content) == 0: + self.my_output.error( + 'Day0 configuration not found' + ) + return False + + if self.is_ocp_vm_day0_dv(dv_content): + return True + + success = self.create_ocp_vm_day0( + self.user_input['deployment']['day0']['filename'], + day0_content, + self.user_input['deployment']['day0']['destination'], + dv_content, + reuse=self.user_input['deployment']['day0']['reuse'], + must_bound=self.user_input['deployment']['day0']['must_bound'] + ) + if not success: + return False + + return True + + def create_ocp_vm_day0_iso(self, day0_filepath, iso_filepath): + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['tools']['ip'], + self.ocp_cluster_settings['tools']['username'], + password=self.ocp_cluster_settings['tools']['password'], + key_filename=self.ocp_cluster_settings['tools']['key_filename'], + log_id=self.log_id + ) + self.my_output.default( + 'Day0 generation done via tools' + ) + + remote_directory = '/tmp/%s' % (str(uuid.uuid4())) + if not ssh_handler.create_directory(remote_directory): + self.my_output.error( + 'Upload directory create failed: %s' % (remote_directory) + ) + return False + + remote_filename = '%s/%s' % ( + remote_directory, + os.path.basename(day0_filepath) + ) + + success = ssh_handler.scp_file( + day0_filepath, + remote_filename, + put=True + ) + if not success: + self.my_output.error( + 'Day0 configuration upload failed' + ) + return False + + self.my_output.default( + 'Day0 configuration uploaded: %s => %s' % ( + day0_filepath, + remote_filename + ) + ) + + remote_iso_filename = '%s/%s' % ( + remote_directory, + os.path.basename(iso_filepath) + ) + command = 'genisoimage -r -o %s %s' % ( + remote_iso_filename, + remote_filename + ) + self.my_output.default( + 'Generate iso: %s' % (command) + ) + success, output, error = ssh_handler.run_cmd( + command, + live_output=False + ) + if not success: + self.my_output.error( + 'Day0 iso generation failed' + ) + return False + + self.my_output.default( + 'Day0 iso generated: %s' % ( + remote_iso_filename + ) + ) + + success = ssh_handler.scp_file( + remote_iso_filename, + iso_filepath, + put=False + ) + if not success: + self.my_output.error( + 'Day0 iso download failed: %s => %s' % (remote_iso_filename, iso_filepath) + ) + return False + + self.my_output.default( + 'Day0 downloaded: %s => %s' % ( + remote_iso_filename, + iso_filepath + ) + ) + + return True + + def is_ocp_vm_day0_dv(self, data_volume): + data_volume_namespace = data_volume['metadata']['namespace'] + data_volume_name = data_volume['metadata']['name'] + if self.k8s_handler.is_data_volume(data_volume_namespace, data_volume_name): + self.my_output.default( + 'Day0 data volume already exists: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return True + + if self.k8s_handler.is_pvc(data_volume_namespace, data_volume_name): + self.my_output.default( + 'Day0 pvc already exists: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return True + + self.my_output.default( + 'Day0 data volume will be created: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + + return False + + def create_ocp_vm_day0(self, day0_filename, day0_content, iso_filename, data_volume, reuse=False, must_bound=True): + data_volume_namespace = data_volume['metadata']['namespace'] + data_volume_name = data_volume['metadata']['name'] + + if self.k8s_handler.is_data_volume(data_volume_namespace, data_volume_name): + if not reuse: + self.my_output.error( + 'Day0 data volume already exists: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return False + + self.my_output.default( + 'Day0 data volume already exists with reuse enabled: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return True + + # Step 1: Prepare ISO in local_directory/iso_filename + + local_directory = '/tmp/%s' % (str(uuid.uuid4())) + os.makedirs(local_directory, exist_ok=True) + + day0_filepath = '%s/%s' % ( + local_directory, + day0_filename + ) + with open(day0_filepath, 'w', encoding='utf-8') as file_handler: + file_handler.write(day0_content) + + iso_filepath = '%s/%s' % ( + local_directory, + iso_filename + ) + + success = self.create_ocp_vm_day0_iso( + day0_filepath, + iso_filepath + ) + + if not success: + return False + + # Step 2: upload iso to virtctl-ready linux + + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['virtctl']['ip'], + self.ocp_cluster_settings['virtctl']['username'], + password=self.ocp_cluster_settings['virtctl']['password'], + key_filename=self.ocp_cluster_settings['virtctl']['key_filename'], + log_id=self.log_id + ) + + remote_iso_filepath = '/tmp/%s' % (iso_filename) + success = ssh_handler.scp_file( + iso_filepath, + remote_iso_filepath, + put=True + ) + if not success: + self.my_output.error( + 'Day0 iso upload to installer failed' + ) + return False + + self.my_output.debug( + 'Day0 uploaded for virctl upload: %s => %s' % ( + iso_filepath, + remote_iso_filepath + ) + ) + + # Step 3: create data volume + + success = self.k8s_handler.create_data_volume( + data_volume + ) + if not success: + self.my_output.error( + 'Data volume create failed: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + return False + + self.my_output.debug( + 'Data volume created: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + + self.my_output.debug( + 'Wait till dv %s/%s is upload ready' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + if not self.k8s_handler.wait_data_volume_upload_ready(data_volume['metadata']['namespace'], data_volume['metadata']['name'], log_error_on_timeout=must_bound): + if must_bound: + self.my_output.error( + 'Day0 dv did not reach upload ready state' + ) + return False + + self.my_output.default( + 'Day0 dv did not reach upload ready state however must_bound set to False... continue' + ) + + # Step 4: upload iso to data volume' + + attempt = 1 + while True: + time.sleep(5) + + command = 'virtctl image-upload dv %s -n %s --no-create --insecure --image-path %s' % ( + data_volume['metadata']['name'], + data_volume['metadata']['namespace'], + remote_iso_filepath + ) + self.my_output.debug( + 'Upload iso to data volume: %s' % (command) + ) + + success, output, error = ssh_handler.run_cmd( + command, + live_output=True + ) + if not success: + self.my_output.error( + 'Upload iso to data volume failed' + ) + attempt = attempt + 1 + if attempt > 5: + return False + + if success: + break + + self.my_output.default( + 'Upload iso to data volume completed: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + + return True diff --git a/lib/ocp/vm/create/deployment.py b/lib/ocp/vm/create/deployment.py new file mode 100644 index 00000000..137e2ba3 --- /dev/null +++ b/lib/ocp/vm/create/deployment.py @@ -0,0 +1,80 @@ +import time + + +class OcpVmCreateDeployment(): + def __init__(self): + pass + + def create_vm_deployment(self, user_input, report=False): + self.set_user_input(user_input) + + namespace = self.user_input['deployment']['namespace'] + name = self.user_input['deployment']['name'] + + self.my_output.default( + 'Check virtual machine state: %s/%s' % ( + namespace, + name + ) + ) + + if self.k8s_handler.is_virtual_machine_instance(namespace, name, cache_enabled=False): + self.my_output.default( + 'Virtual machine already exists' + ) + created = False + else: + self.my_output.default( + 'Virtual machine does not exist yet' + ) + + created = True + + if not self.create_image(): + return False + + if not self.create_day0(): + return False + + if not self.create_sriov_policy(): + return False + + if not self.create_sriov_network(): + return False + + if not self.create_multus_network(): + return False + + if not self.create_vm(): + return False + + if not self.create_deployment_services(self.user_input): + return False + + if self.user_input['ready']['enabled']: + if not self.wait_ocp_vm_ready(self.user_input): + return False + + if report: + if not self.user_input['running']['wait']: + self.my_output.error('Report required running wait enabled') + return True + + if not self.user_input['ready']['enabled']: + self.my_output.error('Report required ready enabled') + return True + + if user_input['report']['enabled']: + if created: + if 'sleep' in user_input['ready']: + self.my_output.default( + 'Wait for %s seconds before collecting report...' % ( + user_input['ready']['sleep'] + ) + ) + time.sleep(user_input['ready']['sleep']) + + if not self.create_vm_state_report(self.user_input): + return False + + return True diff --git a/lib/ocp/vm/create/image.py b/lib/ocp/vm/create/image.py new file mode 100644 index 00000000..64479b1c --- /dev/null +++ b/lib/ocp/vm/create/image.py @@ -0,0 +1,230 @@ +import os +import time +import yaml + +from lib import ssh + + +class OcpVmCreateImage(): + def __init__(self): + pass + + def create_image(self): + if self.user_input['deployment']['image']['enabled']: + image_dv_filename = self.user_input['deployment']['image']['dv'] + if image_dv_filename is not None: + yaml_content = self.user_input['files'][image_dv_filename] + content = yaml.safe_load(yaml_content) + + if self.user_input['deployment']['image']['ip'] is None: + self.log.error( + 'create_image', + 'Image repository IP not defined in deployment file' + ) + return False + + if self.user_input['deployment']['image']['username'] is None: + self.log.error( + 'create_image', + 'Image repository username not defined in deployment file' + ) + return False + + success = self.create_ocp_vm_image( + self.user_input['deployment']['image']['source'], + self.user_input['deployment']['image']['ip'], + self.user_input['deployment']['image']['username'], + self.user_input['deployment']['image']['password'], + self.user_input['deployment']['image']['key_filename'], + self.user_input['deployment']['image']['path'], + content, + reuse=self.user_input['deployment']['image']['reuse'], + must_bound=self.user_input['deployment']['image']['must_bound'] + ) + if not success: + return False + + return True + + def create_ocp_vm_image(self, image_source, server_ip, server_username, server_password, server_key_filename, image_filename, data_volume, reuse=False, must_bound=True): + data_volume_namespace = data_volume['metadata']['namespace'] + data_volume_name = data_volume['metadata']['name'] + + if self.k8s_handler.is_data_volume(data_volume_namespace, data_volume_name): + if not reuse: + self.my_output.error( + 'Image data volume already exists: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return False + + self.my_output.default( + 'Image data volume already exists with reuse enabled: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return True + + if self.k8s_handler.is_pvc(data_volume_namespace, '%s-scratch' % (data_volume_name)): + self.my_output.error( + 'Image scratch pvc exists: %s/%s' % ( + data_volume_namespace, + '%s-scratch' % (data_volume_name) + ) + ) + return False + + if self.k8s_handler.is_pvc(data_volume_namespace, data_volume_name): + self.my_output.default( + 'Image pvc already exists: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + return True + + self.my_output.default( + 'Image data volume will be created: %s/%s' % ( + data_volume_namespace, + data_volume_name + ) + ) + + if image_source == 'file': + self.my_output.default( + 'Download image from %s@%s:%s' % ( + server_username, + server_ip, + image_filename + ) + ) + + ssh_handler = ssh.Ssh( + server_ip, + server_username, + password=server_password, + key_filename=server_key_filename, + log_id=self.log_id + ) + + destination = '/tmp/%s' % ( + os.path.basename( + image_filename + ) + ) + success = ssh_handler.scp_file( + image_filename, + destination, + put=False + ) + if not success: + self.my_output.error( + 'Image download failed' + ) + return False + self.my_output.default( + 'Image downloaded: %s' % (destination) + ) + + self.my_output.default( + 'Image upload to virtctl-ready host...' + ) + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['virtctl']['ip'], + self.ocp_cluster_settings['virtctl']['username'], + password=self.ocp_cluster_settings['virtctl']['password'], + key_filename=self.ocp_cluster_settings['virtctl']['key_filename'], + log_id=self.log_id + ) + + success = ssh_handler.scp_file( + destination, + destination, + put=True + ) + if not success: + self.my_output.error( + 'Image upload to installer failed' + ) + return False + + self.my_output.default( + 'Image uploaded to installer: %s' % ( + '/tmp/%s' % (destination) + ) + ) + + success = self.k8s_handler.create_data_volume( + data_volume + ) + if not success: + self.my_output.error( + 'Data volume create failed: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + return False + + self.my_output.default( + 'Data volume created: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + + self.my_output.default( + 'Wait till pvc %s/%s reaches bound state' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + if not self.k8s_handler.wait_pvc_bound(data_volume['metadata']['namespace'], data_volume['metadata']['name'], log_error_on_timeout=must_bound): + if must_bound: + self.my_output.error( + 'Image PVC did not reach bound state' + ) + return False + + self.my_output.default( + 'Image PVC did not reach bound state however must_bound set to False' + ) + + if image_source == 'file': + attempt = 1 + while True: + time.sleep(5) + + command = 'virtctl image-upload dv %s --no-create --insecure --image-path %s' % ( + data_volume['metadata']['name'], + destination, + ) + self.my_output.default( + 'Upload image to data volume: %s' % (command) + ) + success, output, error = ssh_handler.run_cmd( + command, + live_output=True + ) + if not success: + self.my_output.error( + 'Upload image to data volume failed' + ) + attempt = attempt + 1 + if attempt > 5: + return False + + if success: + break + + self.my_output.default( + 'Upload image to data volume completed: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + + return True diff --git a/lib/ocp/vm/create/main.py b/lib/ocp/vm/create/main.py new file mode 100644 index 00000000..89e97973 --- /dev/null +++ b/lib/ocp/vm/create/main.py @@ -0,0 +1,26 @@ +from lib.ocp.vm.create.day0 import OcpVmCreateDay0 +from lib.ocp.vm.create.deployment import OcpVmCreateDeployment +from lib.ocp.vm.create.image import OcpVmCreateImage +from lib.ocp.vm.create.network import OcpVmCreateNetwork +from lib.ocp.vm.create.policy import OcpVmCreatePolicy +from lib.ocp.vm.create.service import OcpVmCreateService +from lib.ocp.vm.create.vm import OcpVmCreateVm + + +class OcpVmCreate( + OcpVmCreateDay0, + OcpVmCreateDeployment, + OcpVmCreateImage, + OcpVmCreateNetwork, + OcpVmCreatePolicy, + OcpVmCreateService, + OcpVmCreateVm + ): + def __init__(self): + OcpVmCreateDay0.__init__(self) + OcpVmCreateDeployment.__init__(self) + OcpVmCreateImage.__init__(self) + OcpVmCreateNetwork.__init__(self) + OcpVmCreatePolicy.__init__(self) + OcpVmCreateService.__init__(self) + OcpVmCreateVm.__init__(self) diff --git a/lib/ocp/vm/create/network.py b/lib/ocp/vm/create/network.py new file mode 100644 index 00000000..e0ed85d3 --- /dev/null +++ b/lib/ocp/vm/create/network.py @@ -0,0 +1,72 @@ +import yaml + + +class OcpVmCreateNetwork(): + def __init__(self): + pass + + def create_sriov_network(self): + if self.user_input['deployment']['sriov']['enabled']: + if self.user_input['deployment']['sriov']['network'] is not None: + for network_filename in self.user_input['deployment']['sriov']['network']: + yaml_content = self.user_input['files'][network_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if self.k8s_handler.is_sriov_network(name, namespace=namespace): + self.my_output.default( + 'SRIOV network already exists: %s/%s' % ( + namespace, + name + ) + ) + continue + + self.my_output.default( + 'SRIOV network will be created: %s/%s' % ( + namespace, + name + ) + ) + + success = self.k8s_handler.create_sriov_network( + content + ) + if not success: + return False + + return True + + def create_multus_network(self): + if self.user_input['deployment']['multus']['enabled']: + if self.user_input['deployment']['multus']['network'] is not None: + for network_filename in self.user_input['deployment']['multus']['network']: + yaml_content = self.user_input['files'][network_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if self.k8s_handler.is_nad(namespace, name): + self.my_output.default( + 'Multus network already exists: %s/%s' % ( + namespace, + name + ) + ) + continue + + self.my_output.default( + 'Multus network will be created: %s/%s' % ( + namespace, + name + ) + ) + + success = self.k8s_handler.create_nad( + content + ) + if not success: + return False + + return True diff --git a/lib/ocp/vm/create/policy.py b/lib/ocp/vm/create/policy.py new file mode 100644 index 00000000..ae7a75af --- /dev/null +++ b/lib/ocp/vm/create/policy.py @@ -0,0 +1,39 @@ +import yaml + + +class OcpVmCreatePolicy(): + def __init__(self): + pass + + def create_sriov_policy(self): + if self.user_input['deployment']['sriov']['enabled']: + if self.user_input['deployment']['sriov']['policy'] is not None: + for policy_filename in self.user_input['deployment']['sriov']['policy']: + yaml_content = self.user_input['files'][policy_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if self.k8s_handler.is_sriov_network_node_policy(name, cache_enabled=False): + self.my_output.default( + 'SRIOV network node policy already exists: %s/%s' % ( + namespace, + name + ) + ) + continue + + self.my_output.default( + 'SRIOV network node policy will be created: %s/%s' % ( + namespace, + name + ) + ) + + success = self.k8s_handler.create_sriov_network_node_policy( + content + ) + if not success: + return False + + return True diff --git a/lib/ocp/vm/create/service.py b/lib/ocp/vm/create/service.py new file mode 100644 index 00000000..c9d4398d --- /dev/null +++ b/lib/ocp/vm/create/service.py @@ -0,0 +1,41 @@ +import yaml + + +class OcpVmCreateService(): + def __init__(self): + pass + + def create_deployment_services(self, deployment): + print(deployment['deployment']['service']) + if deployment['deployment']['service'] is not None: + for key in deployment['deployment']['service']: + service_filename = deployment['deployment']['service'][key] + if service_filename is not None: + yaml_content = self.user_input['files'][service_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + self.my_output.default( + 'Preparing %s service: %s/%s...' % ( + key, + namespace, + name + ) + ) + + service_mo = self.k8s_handler.get_service( + namespace, + name, + cache_enabled=False, + return_mo=True + ) + if service_mo is not None: + self.my_output.default('Service already exists') + continue + + if not self.k8s_handler.create_namespaced_service(content): + self.my_output.error('Service create failed') + return False + + return True diff --git a/lib/ocp/vm/create/vm.py b/lib/ocp/vm/create/vm.py new file mode 100644 index 00000000..da01a893 --- /dev/null +++ b/lib/ocp/vm/create/vm.py @@ -0,0 +1,44 @@ +import yaml + + +class OcpVmCreateVm(): + def __init__(self): + pass + + def create_vm(self): + vm_filename = self.user_input['deployment']['vm'] + vm_yaml = yaml.safe_load(self.user_input['files'][vm_filename]) + + namespace = vm_yaml['metadata']['namespace'] + name = vm_yaml['metadata']['name'] + + if not self.kubevirt_handler.create_namespaced_virtual_machine(vm_yaml): + self.my_output.error( + 'Create virtual machine request failed' + ) + return False + + self.my_output.default( + 'Virtual machine %s/%s created' % ( + namespace, + name + ) + ) + + if not self.user_input['running']['wait']: + self.my_output.default('Wait for virtual machine running disabled') + return True + + if vm_yaml['spec']['running']: + self.my_output.default('Wait for virtual machine running...') + if not self.kubevirt_handler.wait_virtual_machine_running(namespace, name, output_handler=self.my_output): + self.my_output.error('Timed out') + return False + + if not vm_yaml['spec']['running']: + self.my_output.default('Wait for virtual machine stopped...') + if not self.kubevirt_handler.wait_virtual_machine_stopped(namespace, name): + self.my_output.error('Timed out') + return False + + return True diff --git a/lib/ocp/vm/delete/__init__.py b/lib/ocp/vm/delete/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/vm/delete/__pycache__/__init__.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..0ccba4f2 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/day0.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/day0.cpython-310.pyc new file mode 100644 index 00000000..aeba1136 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/day0.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/deployment.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/deployment.cpython-310.pyc new file mode 100644 index 00000000..fc03997d Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/deployment.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/image.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/image.cpython-310.pyc new file mode 100644 index 00000000..906c2a53 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/image.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/main.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4034c847 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/network.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/network.cpython-310.pyc new file mode 100644 index 00000000..8a1abdb1 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/network.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/policy.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/policy.cpython-310.pyc new file mode 100644 index 00000000..fdc5679e Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/policy.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/service.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/service.cpython-310.pyc new file mode 100644 index 00000000..78f09ff3 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/service.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/vm.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..b4f73ed8 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/__pycache__/vmi.cpython-310.pyc b/lib/ocp/vm/delete/__pycache__/vmi.cpython-310.pyc new file mode 100644 index 00000000..8491b4f7 Binary files /dev/null and b/lib/ocp/vm/delete/__pycache__/vmi.cpython-310.pyc differ diff --git a/lib/ocp/vm/delete/day0.py b/lib/ocp/vm/delete/day0.py new file mode 100644 index 00000000..ffb80323 --- /dev/null +++ b/lib/ocp/vm/delete/day0.py @@ -0,0 +1,51 @@ +import yaml + + +class OcpVmDeleteDay0(): + def __init__(self): + pass + + def delete_day0(self): + if self.user_input['deployment']['day0']['enabled']: + day0_dv_filename = self.user_input['deployment']['day0']['dv'] + if day0_dv_filename is not None: + yaml_content = self.user_input['files'][day0_dv_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + + if self.k8s_handler.is_data_volume(namespace, name, cache_enabled=False): + self.my_output.default( + 'Day0 dv will be deleted: %s/%s' % ( + namespace, + name + ) + ) + success = self.k8s_handler.delete_data_volume( + namespace, + name + ) + return success + + if self.k8s_handler.is_pvc(namespace, name, cache_enabled=False): + self.my_output.default( + 'Day0 pvc will be deleted: %s/%s' % ( + namespace, + name + ) + ) + success = self.k8s_handler.delete_namespaced_pvc( + namespace, + name + ) + return success + + self.my_output.default( + 'Day0 dv/pvc already deleted: %s/%s' % ( + namespace, + name + ) + ) + + return True diff --git a/lib/ocp/vm/delete/deployment.py b/lib/ocp/vm/delete/deployment.py new file mode 100644 index 00000000..2085c343 --- /dev/null +++ b/lib/ocp/vm/delete/deployment.py @@ -0,0 +1,67 @@ +import yaml + + +class OcpVmDeleteDeployment(): + def __init__(self): + self.user_input = None + + def delete_vm_deployment(self, user_input, include_sriov_policy=False, include_image=False): + self.user_input = user_input + + if not self.delete_service(): + return False + + if not self.delete_vm(): + return False + + if not self.delete_multus_network(): + return False + + if not self.delete_sriov_network(): + return False + + if include_sriov_policy: + if not self.delete_sriov_policy(): + return False + else: + if self.user_input['deployment']['sriov']['enabled']: + if self.user_input['deployment']['sriov']['policy'] is not None: + for policy_filename in self.user_input['deployment']['sriov']['policy']: + yaml_content = self.user_input['files'][policy_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if self.k8s_handler.is_sriov_network_node_policy(name, cache_enabled=False): + self.my_output.default( + 'SRIOV network node policy remains: %s/%s' % ( + namespace, + name + ) + ) + + if not self.delete_day0(): + return False + + if include_image: + if not self.delete_image(): + return False + else: + if self.user_input['deployment']['image']['enabled']: + image_dv_filename = self.user_input['deployment']['image']['dv'] + if image_dv_filename is not None: + yaml_content = self.user_input['files'][image_dv_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + + if self.k8s_handler.is_data_volume(namespace, name, cache_enabled=False) or self.k8s_handler.is_pvc(namespace, name, cache_enabled=False): + self.my_output.default( + 'Image remains: %s/%s' % ( + namespace, + name + ) + ) + + return True diff --git a/lib/ocp/vm/delete/image.py b/lib/ocp/vm/delete/image.py new file mode 100644 index 00000000..1a9a5328 --- /dev/null +++ b/lib/ocp/vm/delete/image.py @@ -0,0 +1,97 @@ +import time +import traceback +import yaml + + +class OcpVmDeleteImage(): + def __init__(self): + pass + + def delete_image(self): + if self.user_input['deployment']['image']['enabled']: + image_dv_filename = self.user_input['deployment']['image']['dv'] + if image_dv_filename is not None: + yaml_content = self.user_input['files'][image_dv_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + + if self.k8s_handler.is_data_volume(namespace, name, cache_enabled=False): + self.my_output.default( + 'Image dv will be deleted: %s/%s' % ( + namespace, + name + ) + ) + success = self.k8s_handler.delete_data_volume( + namespace, + name + ) + return success + + if self.k8s_handler.is_pvc(namespace, name, cache=False): + self.my_output.default( + 'Image pvc will be deleted: %s/%s' % ( + namespace, + name + ) + ) + success = self.k8s_handler.delete_namespaced_pvc( + namespace, + name + ) + return success + + self.my_output.default( + 'Image dv/pvc already deleted: %s/%s' % ( + namespace, + name + ) + ) + + return True + + def delete_ocp_dv_vm_image(self, label_special, cache=True): + data_volumes = self.get_ocp_dv_vm_image(label_special, cache=cache) + if len(data_volumes) == 0: + return True + + delete_success = True + + for data_volume in data_volumes: + try: + start_time = int(time.time() * 1000) + obj_list = self.api.resources.get(api_version='cdi.kubevirt.io/v1beta1', kind='DataVolume') + success = obj_list.delete( + namespace=data_volume['metadata']['namespace'], + name=data_volume['metadata']['name'] + ) + except BaseException: + success = False + self.log.error('ocp.delete_ocp_dv_vm_image', traceback.format_exc()) + + self.log.ocp( + 'delete', + 'dv', + success, + int(time.time() * 1000) - start_time + ) + + if success: + self.my_output.default( + 'Delete data volume: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + else: + self.my_output.error( + 'Delete data volume failed: %s/%s' % ( + data_volume['metadata']['namespace'], + data_volume['metadata']['name'] + ) + ) + delete_success = False + + return delete_success diff --git a/lib/ocp/vm/delete/main.py b/lib/ocp/vm/delete/main.py new file mode 100644 index 00000000..71f38105 --- /dev/null +++ b/lib/ocp/vm/delete/main.py @@ -0,0 +1,26 @@ +from lib.ocp.vm.delete.day0 import OcpVmDeleteDay0 +from lib.ocp.vm.delete.deployment import OcpVmDeleteDeployment +from lib.ocp.vm.delete.image import OcpVmDeleteImage +from lib.ocp.vm.delete.network import OcpVmDeleteNetwork +from lib.ocp.vm.delete.policy import OcpVmDeletePolicy +from lib.ocp.vm.delete.service import OcpVmDeleteService +from lib.ocp.vm.delete.vm import OcpVmDeleteVm + + +class OcpVmDelete( + OcpVmDeleteDay0, + OcpVmDeleteDeployment, + OcpVmDeleteImage, + OcpVmDeleteNetwork, + OcpVmDeletePolicy, + OcpVmDeleteService, + OcpVmDeleteVm + ): + def __init__(self): + OcpVmDeleteDay0.__init__(self) + OcpVmDeleteDeployment.__init__(self) + OcpVmDeleteImage.__init__(self) + OcpVmDeleteNetwork.__init__(self) + OcpVmDeletePolicy.__init__(self) + OcpVmDeleteService.__init__(self) + OcpVmDeleteVm.__init__(self) diff --git a/lib/ocp/vm/delete/network.py b/lib/ocp/vm/delete/network.py new file mode 100644 index 00000000..4bd7f262 --- /dev/null +++ b/lib/ocp/vm/delete/network.py @@ -0,0 +1,74 @@ +import yaml + + +class OcpVmDeleteNetwork(): + def __init__(self): + pass + + def delete_sriov_network(self): + if self.user_input['deployment']['sriov']['enabled']: + if self.user_input['deployment']['sriov']['network'] is not None: + for network_filename in self.user_input['deployment']['sriov']['network']: + yaml_content = self.user_input['files'][network_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if not self.k8s_handler.is_sriov_network(name): + self.my_output.default( + 'SRIOV network already deleted: %s/%s' % ( + namespace, + name + ) + ) + continue + + self.my_output.default( + 'SRIOV network will be deleted: %s/%s' % ( + namespace, + name + ) + ) + + success = self.k8s_handler.delete_sriov_network( + namespace, + name + ) + if not success: + return False + + return True + + def delete_multus_network(self): + if self.user_input['deployment']['multus']['enabled']: + if self.user_input['deployment']['multus']['network'] is not None: + for network_filename in self.user_input['deployment']['multus']['network']: + yaml_content = self.user_input['files'][network_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if not self.k8s_handler.is_nad(namespace, name): + self.my_output.default( + 'Multus network already deleted: %s/%s' % ( + namespace, + name + ) + ) + continue + + self.my_output.default( + 'Multus network will be deleted: %s/%s' % ( + namespace, + name + ) + ) + + success = self.k8s_handler.delete_nad( + namespace, + name + ) + if not success: + return False + + return True diff --git a/lib/ocp/vm/delete/policy.py b/lib/ocp/vm/delete/policy.py new file mode 100644 index 00000000..6887b281 --- /dev/null +++ b/lib/ocp/vm/delete/policy.py @@ -0,0 +1,40 @@ +import yaml + + +class OcpVmDeletePolicy(): + def __init__(self): + pass + + def delete_sriov_policy(self): + if self.user_input['deployment']['sriov']['enabled']: + if self.user_input['deployment']['sriov']['policy'] is not None: + for policy_filename in self.user_input['deployment']['sriov']['policy']: + yaml_content = self.user_input['files'][policy_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + if not self.k8s.handler.is_sriov_network_node_policy(name, cache_enabled=False): + self.my_output.default( + 'SRIOV network node policy already deleted: %s/%s' % ( + namespace, + name + ) + ) + continue + + self.my_output.default( + 'SRIOV network node policy will be deleted: %s/%s' % ( + namespace, + name + ) + ) + + success = self.k8s_handler.delete_sriov_network_node_policy( + namespace, + name + ) + if not success: + return False + + return True diff --git a/lib/ocp/vm/delete/service.py b/lib/ocp/vm/delete/service.py new file mode 100644 index 00000000..846619b7 --- /dev/null +++ b/lib/ocp/vm/delete/service.py @@ -0,0 +1,59 @@ +import yaml + + +class OcpVmDeleteService(): + def __init__(self): + pass + + def delete_ocp_vm_services(self, label_special): + services_info = self.k8s_handler.get_services_with_special_label( + label_special + ) + + if services_info is not None and len(services_info) > 0: + for service_info in services_info: + if not self.k8s_handler.delete_namespaced_service(service_info['namespace'], service_info['name']): + self.log.error( + 'delete_ocp_vm_service', + 'Service delete failed: %s/%s' % (service_info['namespace'], service_info['name']) + ) + return False + + self.log.debug( + 'delete_ocp_vm_service', + 'Service deleted: %s/%s' % (service_info['namespace'], service_info['name']) + ) + + self.my_output.default( + 'Service %s/%s deleted' % (service_info['namespace'], service_info['name']) + ) + + return True + + def delete_service(self): + vm_filename = self.user_input['deployment']['vm'] + yaml_content = self.user_input['files'][vm_filename] + content = yaml.safe_load(yaml_content) + + label_special = None + if 'spec' in content: + if 'special' in content['spec']['template']['metadata']['labels']: + label_special = content['spec']['template']['metadata']['labels']['special'] + is_service = self.k8s_handler.is_service_with_special_label( + label_special + ) + + if not is_service: + self.my_output.default('No virtual machine service found with label: %s' % (label_special)) + + if is_service: + self.my_output.default('Deleting virtual machine services...') + success = self.delete_ocp_vm_services(label_special) + + if not success: + self.my_output.error('Virtual machine services delete failed') + return False + + self.my_output.default('Virtual machine services deleted') + + return True diff --git a/lib/ocp/vm/delete/vm.py b/lib/ocp/vm/delete/vm.py new file mode 100644 index 00000000..5d402ce8 --- /dev/null +++ b/lib/ocp/vm/delete/vm.py @@ -0,0 +1,77 @@ +import yaml + + +class OcpVmDeleteVm(): + def __init__(self): + pass + + def delete_vm(self): + vm_filename = self.user_input['deployment']['vm'] + yaml_content = self.user_input['files'][vm_filename] + content = yaml.safe_load(yaml_content) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + + is_running = self.k8s_handler.is_virtual_machine_instance( + namespace, + name, + cache_enabled=False + ) + + is_defined = self.k8s_handler.is_virtual_machine( + namespace, + name, + cache_enabled=False + ) + + if not is_running: + self.my_output.default( + 'Virtual machine instance %s/%s does not exist' % ( + namespace, + name + ) + ) + + if is_running: + self.my_output.default( + 'Stopping virtual machine %s/%s...' % ( + namespace, + name + ) + ) + if not self.kubevirt_handler.stop_virtual_machine(namespace, name): + self.my_output.error('Virtual machine stop failed') + return False + + self.my_output.default('Wait for virtual machine stopped...') + if not self.kubevirt_handler.wait_virtual_machine_stopped(namespace, name): + self.my_output.error('Timed out') + return False + + if not is_defined: + self.my_output.default( + 'Virtual machine not defined %s/%s' % ( + namespace, + name + ) + ) + + if is_defined: + self.my_output.default( + 'Deleting virtual machine %s/%s...' % ( + namespace, + name + ) + ) + success = self.kubevirt_handler.delete_namespaced_virtual_machine( + namespace, + name + ) + if not success: + self.my_output.error('Virtual machine delete failed') + return False + + self.my_output.default('Virtual machine deleted') + + return True diff --git a/lib/ocp/vm/doc/disks.md b/lib/ocp/vm/doc/disks.md new file mode 100644 index 00000000..516b36ac --- /dev/null +++ b/lib/ocp/vm/doc/disks.md @@ -0,0 +1,53 @@ +# Disk + +Like all other vmi devices a spec.domain.devices.disks element has a mandatory name, and furthermore, the disk's name must reference the name of a volume inside spec.volumes. + +A disk can be made accessible via four different types: +- lun +- disk +- cdrom + +# Volumes + +Supported volume sources are +- cloudInitNoCloud +- cloudInitConfigDrive +- persistentVolumeClaim +- dataVolume +- ephemeral +- containerDisk +- emptyDisk +- hostDisk +- configMap +- secret +- serviceAccount +- downwardMetrics + +# ToDo + +## CDROM device + +``` +metadata: + name: testvmi-cdrom +apiVersion: kubevirt.io/v1 +kind: VirtualMachineInstance +spec: + domain: + resources: + requests: + memory: 64M + devices: + disks: + - name: mypvcdisk + # This makes it a cdrom + cdrom: + # This makes the cdrom writeable + readOnly: false + # This makes the cdrom be exposed as SATA device + bus: sata + volumes: + - name: mypvcdisk + persistentVolumeClaim: + claimName: mypvc +``` diff --git a/lib/ocp/vm/get/__init__.py b/lib/ocp/vm/get/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ocp/vm/get/__pycache__/__init__.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..17df90d1 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/bgp.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/bgp.cpython-310.pyc new file mode 100644 index 00000000..7d45fcce Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/bgp.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/day0.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/day0.cpython-310.pyc new file mode 100644 index 00000000..9211e033 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/day0.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/disk.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/disk.cpython-310.pyc new file mode 100644 index 00000000..f98bb1f0 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/disk.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/fabric.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/fabric.cpython-310.pyc new file mode 100644 index 00000000..8d0908d4 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/fabric.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/image.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/image.cpython-310.pyc new file mode 100644 index 00000000..13ee400e Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/image.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/info.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/info.cpython-310.pyc new file mode 100644 index 00000000..ebf27dac Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/info.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/main.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3ef5acf8 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/main.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/network.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/network.cpython-310.pyc new file mode 100644 index 00000000..0bbcd509 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/network.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/node.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/node.cpython-310.pyc new file mode 100644 index 00000000..85f2d626 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/node.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/pod.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/pod.cpython-310.pyc new file mode 100644 index 00000000..7065fa35 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/pod.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/service.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/service.cpython-310.pyc new file mode 100644 index 00000000..65c7af3c Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/service.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/sriov.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/sriov.cpython-310.pyc new file mode 100644 index 00000000..b12092eb Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/sriov.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/ssh.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/ssh.cpython-310.pyc new file mode 100644 index 00000000..3c0ed0ca Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/ssh.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/vm.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..a7cf31c9 Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/vm.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/__pycache__/vmi.cpython-310.pyc b/lib/ocp/vm/get/__pycache__/vmi.cpython-310.pyc new file mode 100644 index 00000000..ed675bce Binary files /dev/null and b/lib/ocp/vm/get/__pycache__/vmi.cpython-310.pyc differ diff --git a/lib/ocp/vm/get/bgp.py b/lib/ocp/vm/get/bgp.py new file mode 100644 index 00000000..e7bfe092 --- /dev/null +++ b/lib/ocp/vm/get/bgp.py @@ -0,0 +1,81 @@ +class OcpVmGetBgp(): + def __init__(self): + pass + + def get_ocp_vm_bgp_neighbor_info(self, fabric_info, bgp_neighbor): + bgp_neighbor_info = {} + bgp_neighbor_info['__Output'] = {} + bgp_neighbor_info['name'] = fabric_info['name'] + bgp_neighbor_info['sriovTick'] = fabric_info['sriovTick'] + bgp_neighbor_info['__Output']['sriovTick'] = fabric_info['__Output']['sriovTick'] + bgp_neighbor_info['type'] = fabric_info['type'] + bgp_neighbor_info['controller'] = fabric_info['controller'] + bgp_neighbor_info['type_controller'] = '%s:%s' % ( + bgp_neighbor_info['type'], + bgp_neighbor_info['controller'] + ) + bgp_neighbor_info['pod_node_name'] = bgp_neighbor['pod_node_name'] + bgp_neighbor_info['bgpDomainName'] = bgp_neighbor['bgpDomainName'] + bgp_neighbor_info['asn'] = bgp_neighbor['asn'] + bgp_neighbor_info['addr'] = bgp_neighbor['state']['addr'] + bgp_neighbor_info['nbrType'] = bgp_neighbor['state']['type'] + bgp_neighbor_info['state'] = bgp_neighbor['state']['operSt'] + bgp_neighbor_info['paths'] = bgp_neighbor['state']['af-ipv4-ucast']['acceptedPaths'] + + return bgp_neighbor_info + + def get_ocp_vm_bgp_info(self, vm_info): + if self.fabric_handler is None: + self.log.error( + 'get_ocp_vm_bgp_info', + 'Fabric info should be collected first' + ) + return vm_info + + vm_info['bgp'] = [] + for interface_info in vm_info['interfaces']: + if not interface_info['sriovEnabled']: + continue + + for fabric_info in vm_info['fabric']: + if fabric_info['name'] != interface_info['name']: + continue + + my_fabric_handler = None + for fabric_handler in self.fabric_handler: + if fabric_handler['type'] == fabric_info['type']: + if fabric_handler['controller'] == fabric_info['controller']: + my_fabric_handler = fabric_handler['handler'] + + if my_fabric_handler is None: + continue + + for fabric_interface_info in fabric_info['interface']: + for ip_address in fabric_info['ip']: + bgp_filter = [] + bgp_filter.append( + 'vrf:%s:%s' % ( + fabric_info['vrfTenant'], + fabric_info['vrfCtx'] + ) + ) + bgp_filter.append('nbp-ip:%s' % (ip_address)) + + node_bgp_info = my_fabric_handler.get_protocol_bgp( + fabric_interface_info['pod_id'], + fabric_interface_info['node_id'], + bgp_filter=bgp_filter + ) + if node_bgp_info is not None: + if 'neighbors' in node_bgp_info: + for bgp_neighbor in node_bgp_info['neighbors']: + if bgp_neighbor['state']['addr'] == ip_address: + bgp_neighbor_info = self.get_ocp_vm_bgp_neighbor_info( + fabric_info, + bgp_neighbor + ) + vm_info['bgp'].append( + bgp_neighbor_info + ) + + return vm_info diff --git a/lib/ocp/vm/get/disk.py b/lib/ocp/vm/get/disk.py new file mode 100644 index 00000000..ef63f55e --- /dev/null +++ b/lib/ocp/vm/get/disk.py @@ -0,0 +1,116 @@ +# https://kubevirt.io/user-guide/virtual_machines/disks_and_volumes/ + + +class OcpVmGetDisk(): + def __init__(self): + self.lvm = {} + + def get_ocp_vm_disks_info(self, vm_info, vmi_info): + disks = vm_info['disks'] + + if vmi_info is not None and vmi_info['volume_status'] is not None: + for volume_status in vmi_info['volume_status']: + for disk in disks: + if volume_status['name'] == disk['name']: + for key in ['persistent_volume_claim_info', 'target', 'storage']: + disk[key] = volume_status[key] + + disk['info'] = '%s/%s - %s' % ( + disk['name'], + disk['target'], + disk['storage'] + ) + + for disk in disks: + disk['__Output'] = {} + disk['pvc_name'] = '' + disk['storage_class_name'] = '' + disk['pod_name'] = '' + + if disk['volume']['type'] == 'dataVolume': + pvc_name = disk['volume']['attributes']['name'] + pvc_namespace = vm_info['namespace'] + + pvc_info = self.k8s_handler.get_pvc( + pvc_namespace, + pvc_name + ) + + if pvc_info is not None: + disk['pvc_name'] = pvc_info['volume_name'] + if pvc_info['phase'] == 'Bound': + disk['__Output']['pvc_name'] = 'Green' + else: + disk['__Output']['pvc_name'] = 'Red' + + disk['storage_class_name'] = pvc_info['storage_class_name'] + + if pvc_info['pod'] is not None: + disk['pod_name'] = pvc_info['pod']['name'] + if 'phase' in pvc_info['pod'] and pvc_info['pod']['phase'] == 'Succeeded': + disk['__Output']['pod_name'] = 'Green' + else: + disk['__Output']['pod_name'] = 'Red' + + if disk['volume']['type'] == 'persistentVolumeClaim': + pvc_name = disk['volume']['attributes']['claim_name'] + pvc_namespace = vm_info['namespace'] + + pvc_info = self.k8s_handler.get_pvc( + pvc_namespace, + pvc_name + ) + + if pvc_info is not None: + disk['pvc_name'] = pvc_info['volume_name'] + if pvc_info['phase'] == 'Bound': + disk['__Output']['pvc_name'] = 'Green' + else: + disk['__Output']['pvc_name'] = 'Red' + + disk['storage_class_name'] = pvc_info['storage_class_name'] + + if pvc_info['pod'] is not None: + disk['pod_name'] = pvc_info['pod']['name'] + if pvc_info['pod']['phase'] == 'Succeeded': + disk['__Output']['pod_name'] = 'Green' + else: + disk['__Output']['pod_name'] = 'Red' + + disk['pv'] = self.k8s_handler.get_pv( + disk['pvc_name'] + ) + + return disks + + def get_ocp_node_lvms(self, node_name): + if node_name in self.lvm: + return self.lvm[node_name] + + linux_handler = self.get_ocp_node_linux_handler( + node_name=node_name + ) + if linux_handler is None: + return None + + self.lvm[node_name] = linux_handler.get_lvms() + return self.lvm[node_name] + + def get_ocp_vm_disks_csi_info(self, vm_info): + lvms = self.get_ocp_node_lvms(vm_info['node_name']) + if lvms is None: + self.log.error( + 'get_ocp_vm_disks_csi_info', + 'No lvms info' + ) + return vm_info + + for disk in vm_info['disks']: + disk['lvm'] = None + for lvm in lvms: + if lvm['name'] is not None: + if disk['pv'] is not None: + if lvm['name'] == disk['pv']['csi_handle']: + disk['lvm'] = lvm + + return vm_info diff --git a/lib/ocp/vm/get/fabric.py b/lib/ocp/vm/get/fabric.py new file mode 100644 index 00000000..f61dc97b --- /dev/null +++ b/lib/ocp/vm/get/fabric.py @@ -0,0 +1,87 @@ +from lib.xd import aci + + +class OcpVmGetFabric(): + def __init__(self): + self.fabric_handler = None + + def load_ocp_vm_fabric_handlers(self, fabric_hints): + if self.fabric_handler is not None: + return + + self.fabric_handler = [] + for fabric_hint in fabric_hints: + if fabric_hint['type'] == 'aci': + aci_handler = aci.get_aci_handler( + fabric_hint['controller'], + log_id=self.log_id + ) + if aci_handler is None: + self.log.error( + 'get_ocp_vm_fabric_handlers', + 'Failed to get aci handler: %s' % (fabric_hint['controller']) + ) + continue + + handler = {} + handler['type'] = 'aci' + handler['controller'] = fabric_hint['controller'] + handler['handler'] = aci_handler + self.fabric_handler.append( + handler + ) + + def get_ocp_vm_aci_endpoint_info(self, interface_info, apic_name, endpoint_info): + fabric_info = {} + fabric_info['__Output'] = {} + fabric_info['name'] = interface_info['name'] + fabric_info['sriovTick'] = interface_info['sriovTick'] + fabric_info['__Output']['sriovTick'] = interface_info['__Output']['sriovTick'] + fabric_info['type'] = 'aci' + fabric_info['controller'] = apic_name + fabric_info['type_controller'] = '%s:%s' % ( + fabric_info['type'], + fabric_info['controller'] + ) + fabric_info['encap'] = endpoint_info['encap'] + fabric_info['mac'] = endpoint_info['mac'] + fabric_info['vrfTenant'] = endpoint_info['vrfTenant'] + fabric_info['vrfCtx'] = endpoint_info['vrfName'] + + fabric_info['ip'] = [] + for fv_ip in endpoint_info['fvIp']: + fabric_info['ip'].append(fv_ip['addr']) + fabric_info['ips'] = ','.join(fabric_info['ip']) + + fabric_info['interface'] = [] + interfaces = [] + for fabric_interface_info in endpoint_info['fabric']: + fabric_info['interface'].append(fabric_interface_info) + interfaces.append(fabric_interface_info['ep']) + fabric_info['interfaces'] = ','.join(interfaces) + + return fabric_info + + def get_ocp_vm_fabric_info(self, vm_info): + vm_info['fabric'] = [] + for interface_info in vm_info['interfaces']: + if interface_info['sriovEnabled']: + for fabric_handler in self.fabric_handler: + if fabric_handler['type'] == 'aci': + endpoint_filter = ['mac:%s' % interface_info['mac_address']] + endpoints = fabric_handler['handler'].get_endpoints( + endpoint_filter=endpoint_filter, + fabric_info=True + ) + if endpoints is not None: + for endpoint_info in endpoints: + fabric_info = self.get_ocp_vm_aci_endpoint_info( + interface_info, + fabric_handler['controller'], + endpoint_info + ) + vm_info['fabric'].append( + fabric_info + ) + + return vm_info diff --git a/lib/ocp/vm/get/image.py b/lib/ocp/vm/get/image.py new file mode 100644 index 00000000..7d1e3acf --- /dev/null +++ b/lib/ocp/vm/get/image.py @@ -0,0 +1,40 @@ +class OcpVmGetImage(): + def __init__(self): + pass + + def is_ocp_dv_vm_image(self, label_special, cache=True): + dvs_mo = self.get_ocp_dv_vm_image( + label_special, + cache=cache + ) + if dvs_mo is None or len(dvs_mo) == 0: + return False + return True + + def get_ocp_dv_vm_image(self, image_filename, cache=True): + data_volumes = self.k8s_handler.get_data_volumes(return_mo=True, cache_enabled=cache) + if data_volumes is None: + return [] + + image_mo = [] + for dv_mo in data_volumes: + if 'labels' not in dv_mo['metadata']: + continue + + if 'type' not in dv_mo['metadata']['labels']: + continue + + if dv_mo['metadata']['labels']['type'] != 'image': + continue + + if 'filename' not in dv_mo['metadata']['labels']: + continue + + if dv_mo['metadata']['labels']['filename'] != image_filename: + continue + + image_mo.append( + dv_mo + ) + + return image_mo diff --git a/lib/ocp/vm/get/info.py b/lib/ocp/vm/get/info.py new file mode 100644 index 00000000..acd01f50 --- /dev/null +++ b/lib/ocp/vm/get/info.py @@ -0,0 +1,210 @@ +from lib import filter_helper +from lib import ip_helper + + +class OcpVmGetInfo(): + def __init__(self): + self.virtual_machine = None + + def get_ocp_vm_info(self, vm_info, vmi_info): + info = {} + info['__Output'] = {} + + vm_keys = [ + 'namespace', + 'name', + 'namespace_name', + 'vm_id', + 'special', + 'cpu', + 'memory', + 'state', + 'networks', + 'ready', + 'readyTick', + 'liveMigration', + 'liveMigrationTick', + 'failures', + 'failure', + 'failureTick' + ] + for vm_key in vm_keys: + info[vm_key] = vm_info[vm_key] + + for key in vm_info['__Output']: + info['__Output'][key] = vm_info['__Output'][key] + + vmi_keys = [ + 'vmi_id', + 'cpu', + 'node_name', + 'guest_os_info', + 'state_transitions', + 'age' + ] + for vmi_key in vmi_keys: + if vmi_key not in info: + info[vmi_key] = None + + if vmi_info is not None: + info[vmi_key] = vmi_info[vmi_key] + + if vmi_info is not None: + for key in vmi_info['__Output']: + info['__Output'][key] = vmi_info['__Output'][key] + + info['disks'] = self.get_ocp_vm_disks_info(vm_info, vmi_info) + info['interfaces'] = self.get_ocp_vm_interfaces_info(vm_info, vmi_info) + info['sriov_enabled'] = self.get_ocp_vm_interfaces_sriov_enabled( + info['interfaces'] + ) + info['sriov_count'] = self.get_ocp_vm_interfaces_sriov_count( + info['interfaces'] + ) + + info['services'] = self.k8s_handler.get_services( + object_filter=['special:%s' % (info['special'])] + ) + + info['ports'] = [] + if info['services'] is not None: + for service in info['services']: + service['vm_namespace_name'] = info['namespace_name'] + for port in service['port']: + info['ports'].append(port) + + return info + + def get_ocp_vms_info(self, cache=True): + if cache and self.virtual_machine is not None: + return self.virtual_machine + + vms_info = self.kubevirt_handler.get_virtual_machines( + cache_enabled=cache + ) + if vms_info is None: + return None + + self.virtual_machine = [] + for vm_info in vms_info: + vmi_info = self.kubevirt_handler.get_virtual_machine_instance( + vm_info['namespace'], + vm_info['name'], + cache_enabled=cache + ) + + ocp_vm_info = self.get_ocp_vm_info( + vm_info, + vmi_info + ) + + self.virtual_machine.append(ocp_vm_info) + + self.log.kubevirt_mo( + 'ocp.vm.info', + self.virtual_machine + ) + + return self.virtual_machine + + def match_ocp_vm(self, vm_info, vm_filter): + if vm_filter is None or len(vm_filter) == 0: + return True + + for ap_rule in vm_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, vm_info['name']): + return False + + if key == 'namespace': + key_found = True + if not filter_helper.match_string(value, vm_info['namespace']): + return False + + if key == 'node': + key_found = True + if not filter_helper.match_string(value, vm_info['node_name']): + return False + + if key == 'sriov': + key_found = True + if value == 'enabled' and not vm_info['sriov_enabled']: + return False + + if value == 'disabled' and vm_info['sriov_enabled']: + return False + + if key == 'mac': + key_found = True + found = False + for interface_info in vm_info['interfaces']: + if ip_helper.is_mac_match(value, interface_info['mac_address']): + found = True + break + + if not found: + return False + + if key == 'multus_network': + key_found = True + found = False + for interface_info in vm_info['interfaces']: + if filter_helper.match_string(value, interface_info['multusNetworkName']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_ocp_vm', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_ocp_vms(self, vm_filter=None, csi_info=False, sriov_info=False, fabric_info=False, bgp_info=False, fabric_hint=None, cache=True): + all_vms = self.get_ocp_vms_info(cache=cache) + if all_vms is None: + return None + + if fabric_hint is not None: + self.load_ocp_vm_fabric_handlers(fabric_hint) + + vms = [] + for vm_info in all_vms: + if not self.match_ocp_vm(vm_info, vm_filter=vm_filter): + continue + + if csi_info: + vm_info = self.get_ocp_vm_disks_csi_info(vm_info) + + if sriov_info: + vm_info = self.get_ocp_vm_sriov_info(vm_info) + + if fabric_info or bgp_info: + vm_info = self.get_ocp_vm_fabric_info(vm_info) + + if bgp_info: + vm_info = self.get_ocp_vm_bgp_info(vm_info) + + vms.append( + vm_info + ) + + vms = sorted( + vms, + key=lambda i: ( + i['namespace'], + i['name'] + ) + ) + + return vms diff --git a/lib/ocp/vm/get/main.py b/lib/ocp/vm/get/main.py new file mode 100644 index 00000000..cc425f5b --- /dev/null +++ b/lib/ocp/vm/get/main.py @@ -0,0 +1,29 @@ +from lib.ocp.vm.get.bgp import OcpVmGetBgp +from lib.ocp.vm.get.disk import OcpVmGetDisk +from lib.ocp.vm.get.fabric import OcpVmGetFabric +from lib.ocp.vm.get.image import OcpVmGetImage +from lib.ocp.vm.get.info import OcpVmGetInfo +from lib.ocp.vm.get.network import OcpVmGetNetwork +from lib.ocp.vm.get.sriov import OcpVmGetSriov +from lib.ocp.vm.get.ssh import OcpVmGetSsh + + +class OcpVmGet( + OcpVmGetBgp, + OcpVmGetDisk, + OcpVmGetFabric, + OcpVmGetImage, + OcpVmGetInfo, + OcpVmGetNetwork, + OcpVmGetSsh, + OcpVmGetSriov + ): + def __init__(self): + OcpVmGetBgp.__init__(self) + OcpVmGetDisk.__init__(self) + OcpVmGetFabric.__init__(self) + OcpVmGetImage.__init__(self) + OcpVmGetInfo.__init__(self) + OcpVmGetNetwork.__init__(self) + OcpVmGetSsh.__init__(self) + OcpVmGetSriov.__init__(self) diff --git a/lib/ocp/vm/get/network.py b/lib/ocp/vm/get/network.py new file mode 100644 index 00000000..662f0464 --- /dev/null +++ b/lib/ocp/vm/get/network.py @@ -0,0 +1,84 @@ +class OcpVmGetNetwork(): + def __init__(self): + pass + + def get_ocp_vm_interfaces_sriov_enabled(self, interfaces_info): + sriov_enabled = False + for interface_info in interfaces_info: + if 'sriov' in interface_info: + if interface_info['sriov'] is not None: + sriov_enabled = True + return sriov_enabled + + def get_ocp_vm_interfaces_sriov_count(self, interfaces_info): + sriov_count = 0 + for interface_info in interfaces_info: + if 'sriov' in interface_info: + if interface_info['sriov'] is not None: + sriov_count = sriov_count + 1 + return sriov_count + + def get_ocp_vm_interfaces_info(self, vm_info, vmi_info): + info = vm_info['interfaces'] + if vmi_info is not None and vmi_info['interfaces'] is not None: + for interface in info: + interface['ip_address'] = None + for interface_state in vmi_info['interfaces']: + if interface['name'] == interface_state['name']: + keys = ['info_source', 'ip_address', 'ip_addresses'] + for key in keys: + if key in interface_state: + interface[key] = interface_state[key] + + for interface in info: + interface['info'] = '' + interface['vlan'] = '' + interface['resourceName'] = '' + interface['policyName'] = '' + interface['sriovDeviceType'] = '' + interface['sriovNic'] = '' + + if interface['name'] == 'default': + if 'ip_address' in interface and interface['ip_address'] is not None: + if interface['masquerade'] is not None: + interface['info'] = '%s (masq)' % (interface['ip_address']) + else: + interface['info'] = interface['ip_address'] + continue + + if 'ip_address' in interface and interface['ip_address'] is not None: + if interface['sriov'] is not None: + interface['info'] = '%s (sriov)' % (interface['ip_address']) + else: + interface['info'] = interface['ip_address'] + continue + + if interface['sriov'] is not None: + interface['info'] = '%s (sriov)' % (interface['name']) + else: + interface['info'] = interface['name'] + + if interface['multusNetworkName'] != '' and interface['sriovEnabled']: + sriov_network_mo = self.k8s_handler.get_sriov_network( + interface['multusNetworkName'], + return_mo=True + ) + if sriov_network_mo is not None: + if 'resourceName' in sriov_network_mo['spec']: + interface['resourceName'] = sriov_network_mo['spec']['resourceName'] + if 'vlan' in sriov_network_mo['spec']: + interface['vlan'] = sriov_network_mo['spec']['vlan'] + + if interface['resourceName'] is not None: + sriov_node_policy = self.k8s_handler.get_sriov_network_node_policy_with_resource_name( + interface['resourceName'], + return_mo=True + ) + + if sriov_node_policy is not None: + interface['policyName'] = sriov_node_policy['metadata']['name'] + interface['sriovDeviceType'] = sriov_node_policy['spec']['deviceType'] + if 'pfNames' in sriov_node_policy['spec']['nicSelector']: + interface['sriovNic'] = sriov_node_policy['spec']['nicSelector']['pfNames'] + + return info diff --git a/lib/ocp/vm/get/report.py b/lib/ocp/vm/get/report.py new file mode 100644 index 00000000..6a771ef6 --- /dev/null +++ b/lib/ocp/vm/get/report.py @@ -0,0 +1,753 @@ +import platform +import traceback +import xml.dom.minidom +import webbrowser +import yaml + +from ncclient import manager as nc_manager + +from lib import file_helper +from lib import ssh +from lib.xd import ocp2fabric + + +class OcpVmReport(): + def __init__(self): + self.report_html = None + self.report_vm_name = None + self.report_vm_namespace = None + + def get_report_html_textarea(self, output): + lines = min(len(output.split('\n')) + 1, 30) + max_col = 0 + for line in output.split('\n'): + max_col = max(max_col, len(line)) + columns = min(max_col + 3, 256) + + textarea = '' % ( + lines, + columns, + output + ) + + return textarea + + def get_vm_state_report_oc_commands(self, commands): + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['parameters']['installer']['vm']['ip'], + self.ocp_cluster_settings['parameters']['installer']['vm']['username'], + password=self.ocp_cluster_settings['parameters']['installer']['vm']['password'], + key_filename=self.ocp_cluster_settings['parameters']['installer']['vm']['key_filename'], + log_id=self.log_id + ) + + for key in commands: + if key == 'oc.vmi': + self.report_html = '%s\n

Section: OpenShift Virtual Machine Instance

' % (self.report_html) + + if key == 'oc.vm': + self.report_html = '%s\n

Section: OpenShift Virtual Machine

' % (self.report_html) + + if key == 'oc.pod': + self.report_html = '%s\n

Section: OpenShift POD

' % (self.report_html) + + if key == 'oc.svc': + self.report_html = '%s\n

Section: OpenShift Service

' % (self.report_html) + + if key == 'oc.dv': + self.report_html = '%s\n

Section: OpenShift Data Volume

' % (self.report_html) + + if key == 'oc.pvc': + self.report_html = '%s\n

Section: OpenShift Persistent Volume Claim

' % (self.report_html) + + if key == 'oc.pv': + self.report_html = '%s\n

Section: OpenShift Persistent Volume

' % (self.report_html) + + if key == 'oc.pv': + self.report_html = '%s\n

Section: KVM

' % (self.report_html) + + for command in commands[key]: + success, output, error = ssh_handler.run_cmd(command, max_attempts=3) + if success: + report = '# %s\n%s\n\n' % ( + command, + output + ) + self.log.adhoc( + 'report.%s' % (key), + report + ) + + self.report_html = '%s\nCommand: %s

%s

' % ( + self.report_html, + command, + self.get_report_html_textarea(output) + ) + + else: + self.my_output.error( + 'Command failed: %s' % (command) + ) + self.log.error( + 'get_vm_state_report_oc_commands', + error + ) + return False + + return True + + def create_vm_state_report_oc_dv(self): + # DVS + # oc get dvs -n + # oc get dvs -n -o yaml + + self.my_output.default('Report: oc dv') + + commands = {} + report_name = 'oc.dv' + commands[report_name] = [] + + disks_info = self.get_ocp_vm_disks_info( + self.report_vm_namespace, + self.report_vm_name + ) + for disk in disks_info['disks']: + if disk['volume']['type'] == 'dataVolume': + dv_name = disk['volume']['info']['name'] + + if self.k8s_handler.is_data_volume(self.report_vm_namespace, dv_name): + commands[report_name].append( + 'oc get dvs -n %s %s' % ( + self.report_vm_namespace, + dv_name + ) + ) + commands[report_name].append( + 'oc get dvs -n %s %s -o yaml' % ( + self.report_vm_namespace, + dv_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc_pvc(self): + self.my_output.default('Report: oc pvc') + + commands = {} + report_name = 'oc.pvc' + commands[report_name] = [] + + disks_info = self.get_ocp_vm_disks_info( + self.report_vm_namespace, + self.report_vm_name + ) + + for disk in disks_info['disks']: + if 'persistent_volume_claim_info' in disk and disk['persistent_volume_claim_info'] is not None: + + # PVC + # oc get pvc -n + # oc get pvc -n -o yaml + + pvc_namespace = disk['persistent_volume_claim_info']['namespace'] + pvc_name = disk['persistent_volume_claim_info']['name'] + + if self.k8s_handler.is_pvc(pvc_namespace, pvc_name): + commands[report_name].append( + 'oc get pvc -n %s %s' % ( + pvc_namespace, + pvc_name + ) + ) + commands[report_name].append( + 'oc get pvc -n %s %s -o yaml' % ( + pvc_namespace, + pvc_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc_pv(self): + self.my_output.default('Report: oc pv') + + commands = {} + report_name = 'oc.pv' + commands[report_name] = [] + + disks_info = self.get_ocp_vm_disks_info( + self.report_vm_namespace, + self.report_vm_name + ) + + for disk in disks_info['disks']: + if 'persistent_volume_claim_info' in disk and disk['persistent_volume_claim_info'] is not None: + + # PV + # oc get pv -n + # oc get pv -n -o yaml + + pv_namespace = disk['persistent_volume_claim_info']['namespace'] + pv_name = disk['persistent_volume_claim_info']['volume_name'] + + if self.k8s_handler.is_pvc(pv_namespace, pv_name): + commands[report_name].append( + 'oc get pv -n %s %s' % ( + pv_namespace, + pv_name + ) + ) + commands[report_name].append( + 'oc get pv -n %s %s -o yaml' % ( + pv_namespace, + pv_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc_pod(self): + # POD (Launcher) - matedata.labels.kubevirt.io/domain + # oc get pod -n + # oc get pod -n -o yaml + + self.my_output.default('Report: oc pod') + + pod_mo = self.k8s_handler.get_pod_with_label( + 'kubevirt.io/domain', + self.report_vm_name, + namespace=self.report_vm_namespace + ) + if pod_mo is not None: + pod_namespace = pod_mo['metadata']['namespace'] + pod_name = pod_mo['metadata']['name'] + + report_name = 'oc.pod' + + commands = {} + commands[report_name] = [] + commands[report_name].append( + 'oc get pod -n %s %s -o wide' % ( + pod_namespace, + pod_name + ) + ) + commands[report_name].append( + 'oc get pod -n %s %s -o yaml' % ( + pod_namespace, + pod_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc_srv(self, deployment): + # oc get service -n + # oc get service -n -o yaml + if deployment['deployment']['service'] is not None: + self.my_output.default('Report: oc service') + report_name = 'oc.svc' + commands = {} + commands[report_name] = [] + + for key in deployment['deployment']['service']: + yaml_content = deployment['deployment']['service'][key] + if yaml_content is None: + continue + + content = yaml.safe_load(yaml_content) + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + + commands[report_name].append( + 'oc get service -n %s %s' % ( + namespace, + name + ) + ) + commands[report_name].append( + 'oc get service -n %s %s -o yaml' % ( + namespace, + name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc_vm(self): + self.my_output.default('Report: oc vm') + + commands = {} + report_name = 'oc.vm' + + commands[report_name] = [] + commands[report_name].append( + 'oc get vm -n %s %s' % ( + self.report_vm_namespace, + self.report_vm_name + ) + ) + commands[report_name].append( + 'oc get vm -n %s %s -o yaml' % ( + self.report_vm_namespace, + self.report_vm_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc_vmi(self): + self.my_output.default('Report: oc vmi') + + commands = {} + report_name = 'oc.vmi' + + commands[report_name] = [] + commands[report_name].append( + 'oc get vmi -n %s %s' % ( + self.report_vm_namespace, + self.report_vm_name + ) + ) + commands[report_name].append( + 'oc get vmi -n %s %s -o yaml' % ( + self.report_vm_namespace, + self.report_vm_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_oc(self, deployment): + if not self.create_vm_state_report_oc_vmi(): + return False + + if not self.create_vm_state_report_oc_vm(): + return False + + if not self.create_vm_state_report_oc_srv(deployment): + return False + + if not self.create_vm_state_report_oc_pod(): + return False + + if not self.create_vm_state_report_oc_dv(): + return False + + if not self.create_vm_state_report_oc_pvc(): + return False + + if not self.create_vm_state_report_oc_pv(): + return False + + return True + + def create_vm_state_report_kvm(self): + # KVM - via installer => node + # /var/lib/kubelet/pods//volumes/kubernetes.io~empty-dir/private/libvirt/qemu/_.xml + + self.my_output.default('Report: kvm') + + pod_mo = self.k8s_handler.get_pod_with_label( + 'kubevirt.io/domain', + self.report_vm_name, + namespace=self.report_vm_namespace + ) + if pod_mo is not None: + pod_uid = pod_mo['metadata']['uid'] + host_ip = pod_mo['status']['host_ip'] + + report_name = 'oc.kvm' + + commands = {} + commands[report_name] = [] + if self.ocp_cluster_settings['parameters']['installer']['vm']['ip'] == host_ip: + commands[report_name].append( + 'sudo cat /var/lib/kubelet/pods/%s/volumes/kubernetes.io~empty-dir/private/libvirt/qemu/%s_%s.xml' % ( + pod_uid, + self.report_vm_namespace, + self.report_vm_name + ) + ) + else: + commands[report_name].append( + 'ssh core@%s sudo cat /var/lib/kubelet/pods/%s/volumes/kubernetes.io~empty-dir/private/libvirt/qemu/%s_%s.xml' % ( + host_ip, + pod_uid, + self.report_vm_namespace, + self.report_vm_name + ) + ) + + if not self.get_vm_state_report_oc_commands(commands): + return False + + return True + + def create_vm_state_report_ssh(self, deployment): + ssh_handler = self.get_ocp_vm_ssh_handler(deployment) + if ssh_handler is None: + return False + + self.report_html = '%s\n

Section: Virtual Machine SSH Commands

' % (self.report_html) + + for key in deployment['report']['ssh']: + commands_output = '' + for command in deployment['report']['ssh'][key]: + self.my_output.default('Command: %s' % (command)) + success, output, error = ssh_handler.run_cmd(command, max_attempts=3) + if not success: + self.my_output.error( + 'Command failed: %s' % (command) + ) + self.log.error( + 'create_vm_state_report_ssh', + error + ) + return False + + output = output.replace('\r\n', '\n').lstrip('\n') + + self.report_html = '%s\nCommand: %s

%s

' % ( + self.report_html, + command, + self.get_report_html_textarea(output) + ) + + commands_output = '%s# %s%s\n\n' % ( + commands_output, + command, + output + ) + + self.log.adhoc( + 'report.ssh.%s' % (key), + commands_output + ) + + return True + + def create_vm_state_report_snmp(self, deployment): + if deployment['tools'] is not None and deployment['tools']['enabled']: + ssh_handler = ssh.Ssh( + deployment['tools']['ip'], + deployment['tools']['username'], + password=deployment['tools']['password'], + key_filename=deployment['tools']['key_filename'], + log_id=self.log_id + ) + else: + ssh_handler = ssh.Ssh( + self.ocp_cluster_settings['parameters']['installer']['vm']['ip'], + self.ocp_cluster_settings['parameters']['installer']['vm']['username'], + password=self.ocp_cluster_settings['parameters']['installer']['vm']['password'], + key_filename=self.ocp_cluster_settings['parameters']['installer']['vm']['key_filename'], + log_id=self.log_id + ) + + filename = deployment['deployment']['service']['snmp'] + service_yaml = yaml.safe_load( + deployment['files'][filename] + ) + + node_ip, node_port = self.k8s_handler.get_service_node_ip_port( + service_yaml['metadata']['namespace'], + service_yaml['metadata']['name'] + ) + if node_ip is None or node_port is None: + return False + + self.report_html = '%s\n

Section: SNMP

' % (self.report_html) + + for key in deployment['report']['snmp']: + commands_output = '' + for oid in deployment['report']['snmp'][key]: + command = 'snmpwalk -v %s -c %s %s:%s %s' % ( + deployment['snmp']['version'], + deployment['snmp']['community'], + node_ip, + node_port, + oid + ) + self.my_output.default('Command: %s' % (command)) + success, output, error = ssh_handler.run_cmd(command, max_attempts=3) + if not success: + self.my_output.error( + 'Command failed: %s' % (command) + ) + self.log.error( + 'create_vm_state_report_snmp', + error + ) + return False + + commands_output = '%s# %s%s\n\n' % ( + commands_output, + command, + output + ) + + self.log.adhoc( + 'report.snmp.%s' % (key), + commands_output + ) + + self.report_html = '%s\n%s

' % ( + self.report_html, + self.get_report_html_textarea(commands_output) + ) + + return True + + def create_vm_state_report_netconf(self, deployment): + filename = deployment['deployment']['service']['netconf'] + service_yaml = yaml.safe_load( + deployment['files'][filename] + ) + if service_yaml is None: + self.log.error( + 'create_vm_state_report_netconf', + 'File read failed: %s' % (deployment['files'][filename]) + ) + return False + + node_ip, node_port = self.k8s_handler.get_service_node_ip_port( + service_yaml['metadata']['namespace'], + service_yaml['metadata']['name'] + ) + + if node_ip is None or node_port is None: + return False + + self.my_output.default( + 'Netconf %s:%s with (%s,%s)' % ( + node_ip, + node_port, + deployment['netconf']['username'], + deployment['netconf']['password'] + ) + ) + + self.report_html = '%s\n

Section: Netconf

' % (self.report_html) + + try: + nc_handler = nc_manager.connect( + host=node_ip, + port=node_port, + username=deployment['netconf']['username'], + password=deployment['netconf']['password'], + hostkey_verify=False, + allow_agent=False, + look_for_keys=False + ) + except BaseException: + self.my_output.error( + 'Netconf connection failed' + ) + self.my_output.error( + traceback.format_exc() + ) + return False + + if 'capabilities' in deployment['report']['netconf']: + capabilities = '' + for capability in nc_handler.server_capabilities: + capabilities = '%s%s\n' % ( + capabilities, + capability + ) + + self.log.adhoc( + 'report.netconf.capabilities', + capabilities + ) + + self.report_html = '%s\nCapabilities

%s

' % ( + self.report_html, + self.get_report_html_textarea(capabilities) + ) + + if 'configuration' in deployment['report']['netconf']: + xml_config = nc_handler.get_config(source='running').data_xml + output = xml.dom.minidom.parseString(xml_config).toprettyxml() + self.log.adhoc( + 'report.netconf.configuration', + output + ) + + self.report_html = '%s\nConfiguration

%s

' % ( + self.report_html, + self.get_report_html_textarea(output) + ) + + return True + + def create_vm_state_report_info(self): + info = self.get_ocp_vms_info( + name=self.report_vm_name, + namespace=self.report_vm_namespace + ) + + self.my_output.clear_output() + self.print_ocp_vm_info( + info, + stream='output' + ) + + self.report_html = '%s\n

Section: Virtual Machine State Information

' % (self.report_html) + self.report_html = '%s\n
%s

' % ( + self.report_html, + self.get_report_html_textarea( + self.my_output.get_output() + ) + ) + + def create_vm_state_report_disk(self): + info = self.get_ocp_vm_disks_info( + self.report_vm_namespace, + self.report_vm_name + ) + + self.my_output.clear_output() + self.print_ocp_vm_disks_info( + info, + show_vm_info=False, + stream='output' + ) + + self.report_html = '%s\n

Section: Virtual Machine Disks

' % (self.report_html) + self.report_html = '%s\n
%s

' % ( + self.report_html, + self.get_report_html_textarea( + self.my_output.get_output() + ) + ) + + def create_vm_state_report_net(self): + info = self.get_ocp_vm_net_info( + self.report_vm_namespace, + self.report_vm_name + ) + + self.my_output.clear_output() + + self.print_ocp_vm_net_info( + info, + show_vm_info=False, + stream='output' + ) + + self.my_output.my_print( + ocp2fabric.print_ocp_vm_net_fabric_info( + info['interfaces'], + stream='output' + ) + ) + + self.report_html = '%s\n

Section: Virtual Machine Interfaces

' % (self.report_html) + self.report_html = '%s\n
%s

' % ( + self.report_html, + self.get_report_html_textarea( + self.my_output.get_output() + ) + ) + + def create_vm_state_report(self, deployment, sections=['all']): + if not deployment['report']['enabled']: + return True + + vm_filename = deployment['deployment']['vm'] + filename = deployment['files'][vm_filename] + vm_yaml = yaml.safe_load( + filename + ) + if vm_yaml is None: + self.log.error( + 'create_vm_state_report', + 'File read failed: %s' % (filename) + ) + return False + + self.report_vm_namespace = vm_yaml['metadata']['namespace'] + self.report_vm_name = vm_yaml['metadata']['name'] + + self.report_html = '' + self.report_html = '%s\n' % (self.report_html) + self.report_html = '%s\nVM Report' % (self.report_html) + self.report_html = '%s\n' % (self.report_html) + self.report_html = '%s\n

OCP Virtual Machine State Report

' % (self.report_html) + + self.my_output.default('Collect virtual machine report data...') + if 'all' in sections: + sections = ['oc', 'kvm', 'ssh', 'snmp', 'netconf'] + + self.create_vm_state_report_info() + self.create_vm_state_report_disk() + self.create_vm_state_report_net() + + if 'oc' in sections: + if not self.create_vm_state_report_oc(deployment): + return False + + if 'kvm' in sections: + if not self.create_vm_state_report_kvm(): + return False + + if 'ssh' in sections: + if 'ssh' in deployment['report']: + self.my_output.default('Collect virtual machine ssh/cli data...') + if not self.create_vm_state_report_ssh(deployment): + return False + + if 'snmp' in sections: + if 'snmp' in deployment['report']: + self.my_output.default('Collect virtual machine snmp data...') + if not self.create_vm_state_report_snmp(deployment): + return False + + if 'netconf' in sections: + if 'netconf' in deployment['report']: + self.my_output.default('Collect virtual machine netconf data...') + if not self.create_vm_state_report_netconf(deployment): + return False + + self.report_html = '%s' % (self.report_html) + self.report_html = '%s' % (self.report_html) + + filename = self.log.adhoc( + 'report.html', + self.report_html + ) + + my_os = platform.system() + if my_os == 'Windows': + link = 'file://C:%s' % (filename) + else: + link = 'file://%s' % (filename) + + self.my_output.default('Report: %s' % (link)) + webbrowser.open(link) + + return True diff --git a/lib/ocp/vm/get/sriov.py b/lib/ocp/vm/get/sriov.py new file mode 100644 index 00000000..1da7ba37 --- /dev/null +++ b/lib/ocp/vm/get/sriov.py @@ -0,0 +1,40 @@ +class OcpVmGetSriov(): + def __init__(self): + pass + + def get_ocp_vm_sriov_info(self, vm_info): + linux_handler = self.get_ocp_node_linux_handler( + node_name=vm_info['node_name'] + ) + if linux_handler is None: + return vm_info + + for interface_info in vm_info['interfaces']: + interface_info['hostIf'] = {} + if interface_info['sriovEnabled']: + host_interface = linux_handler.get_interface( + interface_info['mac_address'], + cache=True + ) + if host_interface is not None: + interface_info['hostIf']['index'] = host_interface['index'] + interface_info['hostIf']['name'] = host_interface['name'] + interface_info['hostIf']['flags'] = host_interface['flags'] + interface_info['hostIf']['mtu'] = host_interface['mtu'] + interface_info['hostIf']['state'] = host_interface['state'] + interface_info['hostIf']['mac'] = host_interface['mac'] + interface_info['hostIf']['vf'] = {} + for vf_info in host_interface['vf']: + if vf_info['mac'] == interface_info['mac_address']: + interface_info['hostIf']['vf']['index'] = vf_info['index'] + interface_info['hostIf']['vf']['mac_address'] = vf_info['mac'] + interface_info['hostIf']['vf']['vlan'] = vf_info['vlan'] + interface_info['hostIf']['vf']['spoof'] = vf_info['spoof'] + interface_info['hostIf']['vf']['link'] = vf_info['link'] + interface_info['hostIf']['vf']['trust'] = vf_info['trust'] + + interface_info['hostIf']['numa'] = linux_handler.get_interface_numa( + host_interface['name'] + ) + + return vm_info diff --git a/lib/ocp/vm/get/ssh.py b/lib/ocp/vm/get/ssh.py new file mode 100644 index 00000000..f3d8dd9d --- /dev/null +++ b/lib/ocp/vm/get/ssh.py @@ -0,0 +1,86 @@ +import yaml + +from lib import ssh + + +class OcpVmGetSsh(): + def __init__(self): + pass + + def get_ocp_vm_ssh_handler(self, deployment): + service_filename = deployment['deployment']['service']['ssh'] + yaml_content = deployment['files'][service_filename] + content = yaml.safe_load( + yaml_content + ) + + namespace = content['metadata']['namespace'] + name = content['metadata']['name'] + + node_ip, node_port = self.k8s_handler.get_service_node_ip_port( + namespace, + name, + cache_enabled=False + ) + if node_ip is None or node_port is None: + return None + + ssh_handler = ssh.Ssh( + node_ip, + deployment['ssh']['username'], + port=node_port, + password=deployment['ssh']['password'], + endpoint_type=deployment['ssh']['type'], + log_id=self.log_id + ) + if ssh_handler is None: + self.my_output.error( + 'Failed to initialize ssh session' + ) + return ssh_handler + + def wait_ocp_vm_ssh_ready(self, deployment): + self.my_output.default('Wait till virtual machine is ssh ready...') + + ssh_handler = self.get_ocp_vm_ssh_handler(deployment) + if ssh_handler is None: + return False + + self.my_output.default( + 'SSH check: (%s, %s) at %s:%s with timeout %s' % ( + ssh_handler.username, + ssh_handler.password, + ssh_handler.ip_address, + ssh_handler.port, + deployment['ready']['timeout'] + ) + ) + + if not ssh_handler.wait_ssh(timeout=deployment['ready']['timeout']): + self.my_output.error( + 'SSH check timed out' + ) + return False + + self.my_output.default( + 'SSH works' + ) + + return True + + def wait_ocp_vm_ready(self, deployment): + if not deployment['ready']['enabled']: + return True + + if deployment['ready']['type'] not in ['ssh']: + self.my_output.error( + 'Unsupported readiness type: %s' % ( + deployment['ready']['type'] + ) + ) + return False + + if deployment['ready']['type'] == 'ssh': + return self.wait_ocp_vm_ssh_ready(deployment) + + return True diff --git a/lib/ocp/vm/main.py b/lib/ocp/vm/main.py new file mode 100644 index 00000000..95d0f954 --- /dev/null +++ b/lib/ocp/vm/main.py @@ -0,0 +1,19 @@ +from lib.ocp.vm.create.main import OcpVmCreate +from lib.ocp.vm.delete.main import OcpVmDelete +from lib.ocp.vm.get.main import OcpVmGet + + +class OcpVm( + OcpVmCreate, + OcpVmDelete, + OcpVmGet + ): + def __init__(self): + OcpVmCreate.__init__(self) + OcpVmDelete.__init__(self) + OcpVmGet.__init__(self) + + self.user_input = None + + def set_user_input(self, user_input): + self.user_input = user_input diff --git a/lib/ocp/vm/output.py b/lib/ocp/vm/output.py new file mode 100644 index 00000000..27f12036 --- /dev/null +++ b/lib/ocp/vm/output.py @@ -0,0 +1,579 @@ +class OcpVmOutput(): + def __init__(self): + pass + + def print_ocp_vm_base_info(self, info, stream='default'): + order = [ + 'namespace', + 'name', + 'node_name', + 'cpu.cores', + 'memory', + 'state', + 'readyTick', + 'failureTick', + 'liveMigrationTick', + 'age' + ] + + headers = [ + 'Namespace', + 'Name', + 'Node', + 'CPU', + 'Memory', + 'State', + 'Ready', + 'Failure', + 'LM', + 'Age' + ] + + self.my_output.dictionary( + info, + title='OCP Virtual Machine', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers, + stream=stream + ) + + def print_ocp_vm_info(self, info, stream='default'): + self.print_ocp_vm_base_info(info, stream=stream) + + if len(info['failures']) > 0: + for failure in info['failures']: + self.my_output.default( + 'Failure: %s' % (failure['reason']), + before_newline=True + ) + self.my_output.default( + failure['message'] + ) + + def print_ocp_vm_disks_info(self, info, show_vm_info=True, stream='default'): + if show_vm_info: + self.print_ocp_vm_base_info(info, stream=stream) + + order = [ + 'name', + 'type', + 'bus', + 'target', + 'volume.type', + 'persistent_volume_claim_info.name', + 'persistent_volume_claim_info.phase', + 'persistent_volume_claim_info.storage_class_name', + 'persistent_volume_claim_info.access_modes_string', + 'persistent_volume_claim_info.capacity.storage', + 'persistent_volume_claim_info.volume_mode' + ] + + headers = [ + 'Name', + 'Type', + 'Bus', + 'Target', + 'Volume Type', + 'Volume Name', + 'Volume State', + 'SC', + 'Access Modes', + 'Storage', + 'Volume Mode' + ] + + self.my_output.my_table( + info['disks'], + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True, + stream=stream + ) + + def print_ocp_vm_net_info(self, info, show_vm_info=True, stream='default'): + if show_vm_info: + self.print_ocp_vm_base_info(info, stream=stream) + + order = [ + 'name', + 'info.order', + 'info.network_type', + 'info.network_name', + 'ips', + 'mac_address', + 'info.pci', + 'info.host_interface.name', + 'info.host_interface.vf_info.index', + 'info.host_interface.vf_info.vlan' + ] + + headers = [ + 'Name', + 'Order', + 'Type', + 'Network', + 'IP', + 'MAC', + 'PCI', + 'Host Interface', + 'VF ID', + 'VF VLAN' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info['interfaces'], + order, + ['ips'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + row_separator=True, + underline=True, + table=True, + stream=stream + ) + + def print_ocp_vm_pod_info(self, info, show_vm_info=True): + if show_vm_info: + self.print_ocp_vm_base_info(info) + + def print_deployment_service_access_info(self, info): + order = [ + 'namespace', + 'name', + 'ip', + 'port', + 'auth' + ] + + headers = [ + 'Service Namespace', + 'Service Name', + 'Node IP', + 'Node Port', + 'Authentication Info' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + table=True + ) + + def print_ocp_vms(self, info, title=False): + if title: + self.my_output.default( + 'OCP VM [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'namespace_name', + 'node_name', + 'cpu.cores', + 'memory', + 'disks.info', + 'interfaces.info', + 'state', + 'readyTick', + 'failures', + 'services.namespace_name', + 'services.ports', + 'liveMigrationTick', + 'age' + ] + + headers = [ + 'VM', + 'Node', + 'CPU', + 'Memory', + 'Disks', + 'Interfaces', + 'State', + 'Ready', + 'Failure', + 'Service', + 'NodePort', + 'LM', + 'Age' + ] + + for item in info: + if len(item['failures']) == 0: + item['failures'].append('--') + + if len(item['services']) == 0: + item['services'].append( + dict( + namespace_name='--', + ports='--' + ) + ) + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disks', 'interfaces', 'services', 'failures'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + table=True + ) + + def print_ocp_vms_intf(self, info, title=False): + if title: + self.my_output.default('Kubernetes Networking', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'interfaces.name', + 'interfaces.mac_address', + 'interfaces.ip_address', + 'interfaces.masqueradeTick', + 'interfaces.podTick', + 'interfaces.sriovTick', + 'interfaces.multusTick', + 'interfaces.multusNetworkName', + 'interfaces.vlan', + 'interfaces.resourceName', + 'interfaces.policyName', + 'interfaces.sriovDeviceType', + 'interfaces.sriovNic' + ] + + headers = [ + 'VM', + 'Interface', + 'MAC', + 'IP', + 'Masq', + 'Pod', + 'SRIOV', + 'Multus', + 'Network', + 'VLAN Tag', + 'Resource', + 'Policy', + 'Device Type', + 'NIC' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interfaces'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) + + def print_ocp_vms_sriov(self, info, title=False): + if title: + self.my_output.default('SR-IOV Host Networking', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'interfaces.name', + 'interfaces.hostIf.name', + 'interfaces.hostIf.numa', + 'interfaces.hostIf.index', + 'interfaces.hostIf.flags', + 'interfaces.hostIf.mtu', + 'interfaces.hostIf.state', + 'interfaces.hostIf.mac', + 'interfaces.hostIf.vf.index', + 'interfaces.hostIf.vf.vlan', + 'interfaces.hostIf.vf.spoof', + 'interfaces.hostIf.vf.link', + 'interfaces.hostIf.vf.trust' + ] + + headers = [ + 'VM', + 'VM Interface', + 'Host Interface', + 'Numa', + 'ifIndex', + 'Flags', + 'MTU', + 'State', + 'MAC', + 'VF Index', + 'VF VLAN', + 'VF Spoof', + 'VF Link', + 'VF Trust' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interfaces'], + filtering_rules=[ + 'sriovEnabled:bool:false' + ], + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) + + def print_ocp_vms_fabric(self, info, title=False): + if title: + self.my_output.default('SR-IOV Fabric Connectivity', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'fabric.name', + 'fabric.type_controller', + 'fabric.mac', + 'fabric.encap', + 'fabric.vrf', + 'fabric.ips', + 'fabric.interfaces' + ] + + headers = [ + 'VM', + 'VM Interface', + 'Fabric', + 'MAC', + 'Encapsulation', + 'VRF', + 'IP Address', + 'Interface' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fabric'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) + + def print_ocp_vms_bgp(self, info, title=False): + if title: + self.my_output.default('BGP Sessions', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'bgp.name', + 'bgp.type_controller', + 'bgp.pod_node_name', + 'bgp.bgpDomainName', + 'bgp.asn', + 'bgp.addr', + 'bgp.nbrType', + 'bgp.state', + 'bgp.paths' + ] + + headers = [ + 'VM', + 'VM Interface', + 'Fabric', + 'Node', + 'VRF', + 'ASN', + 'Address', + 'Type', + 'State', + 'Paths (AF IPv4)' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['bgp'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) + + def print_ocp_vms_service(self, info, title=False): + if title: + self.my_output.default('Kubernetes Services', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'services.specialT', + 'services.namespace_name', + 'services.type', + 'services.cluster_ip', + 'services.external_traffic_policy', + 'services.ports', + 'services.age' + ] + + headers = [ + 'VM', + 'Selector', + 'Service', + 'Type', + 'Cluster IP', + 'External Traffic Policy', + 'Port', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['services'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) + + def print_ocp_vms_disk(self, info, title=False): + if title: + self.my_output.default('Disks', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'disks.name', + 'disks.type', + 'disks.bus', + 'disks.volume.type', + 'disks.volume.name', + 'disks.persistent_volume_claim_info.capacity.storage', + 'disks.pvc_name', + 'disks.persistent_volume_claim_info.access_modes', + 'disks.persistent_volume_claim_info.volume_mode', + 'disks.storage_class_name', + 'disks.pod_name' + ] + + headers = [ + 'VM', + 'Disk Name', + 'Type', + 'Bus', + 'Volume Type', + 'Volume', + 'Size', + 'PVC', + 'PVC Access', + 'PVC Mode', + 'Storage Class', + 'POD' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disks'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) + + def print_ocp_vms_csi(self, info, title=False): + if title: + self.my_output.default('CSI', underline=True, before_newline=True) + + order = [ + 'namespace_name', + 'disks.name', + 'disks.type', + 'disks.pv.csi_driver', + 'disks.lvm.path', + 'disks.lvm.vg', + 'disks.lvm.access', + 'disks.lvm.pool', + 'disks.lvm.status', + 'disks.lvm.size', + 'disks.lvm.mapped' + ] + + headers = [ + 'VM', + 'Disk Name', + 'Type', + 'CSI Driver', + 'LVM Path', + 'VG Name', + 'LV Write Access', + 'LV Pool', + 'LV Status', + 'LV Size', + 'Mapped Size' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['disks'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + remove_empty_columns=False, + cast_none=True, + table=True + ) diff --git a/lib/ocp/vm/validate.py b/lib/ocp/vm/validate.py new file mode 100644 index 00000000..58d19e20 --- /dev/null +++ b/lib/ocp/vm/validate.py @@ -0,0 +1,278 @@ +import os +import yaml + +from lib import file_helper +from lib import template + +from lib import log_helper +from lib import output_helper + + +class OcpDeploymentValidate(): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + + self.template_handler = template.Template( + log_id=log_id + ) + self.template_subdirectory = 'ocp/kubevirt' + self.variables = None + + def get_deployment_yaml(self, filename): + content = file_helper.get_file_yaml(filename) + if content is None: + self.log.error( + 'get_deployment_yaml', + 'File read failed: %s' % (filename) + ) + return None + + self.variables = None + if 'variables' in content: + self.variables = content['variables'] + + content = self.template_handler.get_template( + filename, + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_conversion=True + ) + if content is None: + self.log.error( + 'get_deployment_yaml', + 'File parse failed: %s' % (filename) + ) + + return content + + def validate(self, deployment_filename, chdir=None): + data = self.get_deployment_yaml(deployment_filename) + if data is None: + return None + + validated_data = self.template_handler.validate_input( + self.template_subdirectory, + 'deployment', + data + ) + + if validated_data is None: + return None + + if chdir is None: + base_directory = os.path.dirname(deployment_filename) + else: + base_directory = chdir + + validated_data['files'] = {} + + filename = validated_data['deployment']['vm'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + + vm_yaml = yaml.safe_load( + validated_data['files'][filename] + ) + if vm_yaml is None: + self.log.error( + 'validate', + 'Yaml load failed: %s' % (validated_data['files'][filename]) + ) + return None + + for key in ['namespace', 'name']: + if key not in vm_yaml['metadata']: + self.my_output.error( + 'Attribute metadata.%s is mandatory in %s' % ( + key, + filename + ) + ) + return None + + if validated_data['deployment'][key] != vm_yaml['metadata'][key]: + self.my_output.error( + 'Attribute metadata.%s must be the same in %s and %s' % ( + key, + deployment_filename, + filename + ) + ) + return None + + if validated_data['deployment']['image']['dv'] is not None: + filename = validated_data['deployment']['image']['dv'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['day0']['filename'] is not None: + filename = validated_data['deployment']['day0']['filename'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['day0']['dv'] is not None: + filename = validated_data['deployment']['day0']['dv'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['sriov']['policy'] is not None: + for filename in validated_data['deployment']['sriov']['policy']: + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['sriov']['network'] is not None: + for filename in validated_data['deployment']['sriov']['network']: + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['multus']['network'] is not None: + for filename in validated_data['deployment']['multus']['network']: + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['service']['ssh'] is not None: + filename = validated_data['deployment']['service']['ssh'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['service']['snmp'] is not None: + filename = validated_data['deployment']['service']['snmp'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['service']['netconf'] is not None: + filename = validated_data['deployment']['service']['netconf'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + if validated_data['deployment']['service']['ui'] is not None: + filename = validated_data['deployment']['service']['ui'] + validated_data['files'][filename] = self.template_handler.get_template( + os.path.join( + base_directory, + filename + ), + self.variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_check=True, + yaml_conversion=False + ) + if validated_data['files'][filename] is None: + return None + + return validated_data diff --git a/lib/openshift/__init__.py b/lib/openshift/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/accountsmgmt/__init__.py b/lib/openshift/accountsmgmt/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/accountsmgmt/api.py b/lib/openshift/accountsmgmt/api.py new file mode 100644 index 00000000..0137b89b --- /dev/null +++ b/lib/openshift/accountsmgmt/api.py @@ -0,0 +1,36 @@ +class AccountsMgmtApi(): + def __init__(self): + self.accounts_mgmt_url = 'accounts_mgmt' + + def get_accounts_mgmt_mo(self, url_suffix, extra_headers=None, params=None): + url = '%s/%s' % ( + self.accounts_mgmt_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.get_query(url, extra_headers=extra_headers, params=params) + return response + + def post_accounts_mgmt_mo(self, url_suffix, extra_headers=None, data=None): + url = '%s/%s' % ( + self.accounts_mgmt_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.post_query(url, extra_headers=extra_headers, data=data) + return response + + def delete_accounts_mgmt_mo(self, url_suffix, extra_headers=None): + url = '%s/%s' % ( + self.accounts_mgmt_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.delete_query(url, extra_headers=extra_headers) + return response diff --git a/lib/openshift/accountsmgmt/main.py b/lib/openshift/accountsmgmt/main.py new file mode 100644 index 00000000..79a8e1e9 --- /dev/null +++ b/lib/openshift/accountsmgmt/main.py @@ -0,0 +1,11 @@ +from lib.openshift.accountsmgmt.api import AccountsMgmtApi +from lib.openshift.accountsmgmt.subscription.main import AccountsMgmtSubscription + + +class AccountsMgmt( + AccountsMgmtApi, + AccountsMgmtSubscription + ): + def __init__(self): + AccountsMgmtApi.__init__(self) + AccountsMgmtSubscription.__init__(self) diff --git a/lib/openshift/accountsmgmt/output.py b/lib/openshift/accountsmgmt/output.py new file mode 100644 index 00000000..c3de97c1 --- /dev/null +++ b/lib/openshift/accountsmgmt/output.py @@ -0,0 +1,36 @@ +import json + + +class AccountsManagementOutput(): + def __init__(self): + pass + + def print_accounts_management_subscription(self, info, title=False): + if title: + self.my_output.default( + 'Accounts Management - Subscription [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name' + ] + + headers = [ + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/openshift/accountsmgmt/subscription/__init__.py b/lib/openshift/accountsmgmt/subscription/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/accountsmgmt/subscription/api.py b/lib/openshift/accountsmgmt/subscription/api.py new file mode 100644 index 00000000..ba77d47b --- /dev/null +++ b/lib/openshift/accountsmgmt/subscription/api.py @@ -0,0 +1,25 @@ +class AccountsMgmtSubscriptionApi(): + def __init__(self): + self.accounts_mgmt_subscription_mo = None + + self.accounts_mgmt_subscription_api_version = 'v1' + self.accounts_mgmt_subscription_url = '%s/subscriptions' % ( + self.accounts_mgmt_subscription_api_version + ) + + def get_accounts_mgmt_subscription_mo(self, cache_enabled=True): + if cache_enabled and self.accounts_mgmt_subscription_mo is not None: + return self.accounts_mgmt_subscription_mo + + params = {} + params['search'] = 'status NOT IN (\'Deprovisioned\', \'Archived\')' + + response = self.get_accounts_mgmt_mo( + self.accounts_mgmt_subscription_url, + params=params + ) + + if response is None: + return None + + return response['items'] diff --git a/lib/openshift/accountsmgmt/subscription/info.py b/lib/openshift/accountsmgmt/subscription/info.py new file mode 100644 index 00000000..76c8eb2c --- /dev/null +++ b/lib/openshift/accountsmgmt/subscription/info.py @@ -0,0 +1,3 @@ +class AccountsMgmtSubscriptionInfo(): + def __init__(self): + pass diff --git a/lib/openshift/accountsmgmt/subscription/main.py b/lib/openshift/accountsmgmt/subscription/main.py new file mode 100644 index 00000000..86a33c32 --- /dev/null +++ b/lib/openshift/accountsmgmt/subscription/main.py @@ -0,0 +1,11 @@ +from lib.openshift.accountsmgmt.subscription.api import AccountsMgmtSubscriptionApi +from lib.openshift.accountsmgmt.subscription.info import AccountsMgmtSubscriptionInfo + + +class AccountsMgmtSubscription( + AccountsMgmtSubscriptionApi, + AccountsMgmtSubscriptionInfo + ): + def __init__(self): + AccountsMgmtSubscriptionApi.__init__(self) + AccountsMgmtSubscriptionInfo.__init__(self) diff --git a/lib/openshift/api.py b/lib/openshift/api.py new file mode 100644 index 00000000..9738f58a --- /dev/null +++ b/lib/openshift/api.py @@ -0,0 +1,433 @@ +import time +import traceback +import requests + +from lib import log_helper + + +class Api(): + def __init__(self, token, log_id=None): + self.authentication_token = token + self.access_token = None + self.access_token_timestamp = None + self.access_token_ttl = 240 + + self.authentication_request_timeout = 5 + self.get_request_timeout = 5 + self.patch_request_timeout = 5 + self.post_request_timeout = 5 + self.delete_request_timeout = 5 + + self.log = log_helper.Log(log_id=log_id) + + def generate_access_token(self): + url = 'https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token' + headers = {} + headers['Content-Type'] = 'application/x-www-form-urlencoded' + + data = {} + data['grant_type'] = 'refresh_token' + data['client_id'] = 'cloud-services' + data['refresh_token'] = self.authentication_token + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + try: + response = requests.post( + url, + data=data, + headers=headers, + verify=False, + timeout=self.authentication_request_timeout + ) + if response.status_code < 300: + self.access_token = response.json()['access_token'] + self.access_token_timestamp = start_time + authenticated = True + + if response.status_code >= 300: + self.log.error( + 'generate_access_token', + 'Response code %s body %s' % ( + response.status_code, + response.content.decode('utf-8') + ) + ) + authenticated = False + self.access_token = None + self.access_token_timestamp = None + + except BaseException: + self.log.error( + 'generate_access_token', + traceback.format_exc() + ) + authenticated = False + self.access_token = None + self.access_token_timestamp = None + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.openshift( + 'authenticate', + authenticated, + duration_ms + ) + + def is_access_token_valid(self): + if self.access_token is None: + return False + + if int(time.time() * 1000) - self.access_token_timestamp > self.access_token_ttl * 1000: + return False + + return True + + def get_access_token(self): + if self.is_access_token_valid(): + return self.access_token + + self.generate_access_token() + return self.access_token + + def get_query(self, url_suffix, extra_headers=None, params=None): + token = self.get_access_token() + if token is None: + self.log.error( + 'get_query', + 'Failed to get access token' + ) + return None + + url = 'https://api.openshift.com/api/%s' % (url_suffix) + + headers = {} + headers['Content-Type'] = 'application/json' + headers['Authorization'] = 'Bearer %s' % (token) + + if extra_headers is not None: + for key in extra_headers: + headers[key] = extra_headers[key] + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + try: + if params is not None: + self.log.debug( + 'get_query', + 'URL [%s] Headers [%s] Params [%s]' % ( + url, + headers, + params + ) + ) + response = requests.get( + url, + headers=headers, + params=params, + verify=False, + timeout=self.get_request_timeout + ) + else: + self.log.debug( + 'get_query', + 'URL [%s] Headers [%s]' % ( + url, + headers + ) + ) + response = requests.get( + url, + headers=headers, + verify=False, + timeout=self.get_request_timeout + ) + + if response.status_code < 300: + get_response = response.json() + success = True + + if response.status_code >= 300: + self.log.error( + 'get_query', + 'Response code %s body %s' % ( + response.status_code, + response.content.decode('utf-8') + ) + ) + get_response = None + success = False + + except BaseException: + self.log.error( + 'get_query', + traceback.format_exc() + ) + get_response = None + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.openshift( + url, + success, + duration_ms + ) + + return get_response + + def patch_query(self, url_suffix, extra_headers=None, data=None, content_type='application/json'): + token = self.get_access_token() + if token is None: + self.log.error( + 'patch_query', + 'Failed to get access token' + ) + return None + + url = 'https://api.openshift.com/api/%s' % (url_suffix) + + headers = {} + headers['Content-Type'] = content_type + headers['Authorization'] = 'Bearer %s' % (token) + + if extra_headers is not None: + for key in extra_headers: + headers[key] = extra_headers[key] + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + try: + if data is not None: + self.log.debug( + 'patch_query', + 'URL [%s]' % ( + url + ) + ) + self.log.debug( + 'patch_query', + 'Headers [%s]' % ( + headers + ) + ) + self.log.debug( + 'patch_query', + 'Payload [%s]' % ( + data + ) + ) + response = requests.patch( + url, + headers=headers, + data=data, + verify=False, + timeout=self.patch_request_timeout + ) + else: + self.log.debug( + 'patch_query', + 'URL [%s]' % ( + url + ) + ) + self.log.debug( + 'patch_query', + 'Headers [%s]' % ( + headers + ) + ) + response = requests.post( + url, + headers=headers, + verify=False, + timeout=self.patch_request_timeout + ) + + if response.status_code < 300: + try: + patch_response = response.json() + except BaseException: + patch_response = 'non json response' + success = True + + if response.status_code >= 300: + self.log.error( + 'patch_query', + 'Response code %s body %s' % ( + response.status_code, + response.content.decode('utf-8') + ) + ) + patch_response = None + success = False + + except BaseException: + self.log.error( + 'patch_query', + traceback.format_exc() + ) + patch_response = None + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.openshift( + url, + success, + duration_ms + ) + + return patch_response + + def post_query(self, url_suffix, extra_headers=None, data=None): + token = self.get_access_token() + if token is None: + self.log.error( + 'post_query', + 'Failed to get access token' + ) + return None + + url = 'https://api.openshift.com/api/%s' % (url_suffix) + + headers = {} + headers['Content-Type'] = 'application/json' + headers['Authorization'] = 'Bearer %s' % (token) + + if extra_headers is not None: + for key in extra_headers: + headers[key] = extra_headers[key] + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + try: + if data is not None: + self.log.debug( + 'post_query', + 'URL [%s] Headers [%s] Payload [%s]' % ( + url, + headers, + data + ) + ) + response = requests.post( + url, + headers=headers, + data=data, + verify=False, + timeout=self.post_request_timeout + ) + else: + self.log.debug( + 'post_query', + 'URL [%s] Headers [%s]' % ( + url, + headers + ) + ) + response = requests.post( + url, + headers=headers, + verify=False, + timeout=self.post_request_timeout + ) + + if response.status_code < 300: + post_response = response.json() + success = True + + if response.status_code >= 300: + self.log.error( + 'post_query', + 'Response code %s body %s' % ( + response.status_code, + response.content.decode('utf-8') + ) + ) + post_response = None + success = False + + except BaseException: + self.log.error( + 'post_query', + traceback.format_exc() + ) + post_response = None + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.openshift( + url, + success, + duration_ms + ) + + return post_response + + def delete_query(self, url_suffix, extra_headers=None): + token = self.get_access_token() + if token is None: + self.log.error( + 'delete_query', + 'Failed to get access token' + ) + return None + + url = 'https://api.openshift.com/api/%s' % (url_suffix) + + headers = {} + headers['Content-Type'] = 'application/json' + headers['Authorization'] = 'Bearer %s' % (token) + + if extra_headers is not None: + for key in extra_headers: + headers[key] = extra_headers[key] + + requests.packages.urllib3.disable_warnings() + start_time = int(time.time() * 1000) + try: + self.log.debug( + 'delete_query', + 'URL [%s] Headers [%s]' % ( + url, + headers + ) + ) + response = requests.delete( + url, + headers=headers, + verify=False, + timeout=self.delete_request_timeout + ) + + if response.status_code < 300: + success = True + + if response.status_code >= 300: + self.log.error( + 'delete_query', + 'Response code %s body %s' % ( + response.status_code, + response.content.decode('utf-8') + ) + ) + success = False + + except BaseException: + self.log.error( + 'post_query', + traceback.format_exc() + ) + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.openshift( + url, + success, + duration_ms + ) + + return success diff --git a/lib/openshift/assistedinstall/__init__.py b/lib/openshift/assistedinstall/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/assistedinstall/api.py b/lib/openshift/assistedinstall/api.py new file mode 100644 index 00000000..3f1070b6 --- /dev/null +++ b/lib/openshift/assistedinstall/api.py @@ -0,0 +1,47 @@ +class AssistedInstallApi(): + def __init__(self): + self.assisted_install_url = 'assisted-install' + + def get_assisted_install_mo(self, url_suffix, extra_headers=None, params=None): + url = '%s/%s' % ( + self.assisted_install_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.get_query(url, extra_headers=extra_headers, params=params) + return response + + def patch_assisted_install_mo(self, url_suffix, extra_headers=None, data=None, content_type='application/json'): + url = '%s/%s' % ( + self.assisted_install_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.patch_query(url, extra_headers=extra_headers, data=data, content_type=content_type) + return response + + def post_assisted_install_mo(self, url_suffix, extra_headers=None, data=None): + url = '%s/%s' % ( + self.assisted_install_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.post_query(url, extra_headers=extra_headers, data=data) + return response + + def delete_assisted_install_mo(self, url_suffix, extra_headers=None): + url = '%s/%s' % ( + self.assisted_install_url, + url_suffix + ) + if self.api_handler is None: + return None + + response = self.api_handler.delete_query(url, extra_headers=extra_headers) + return response diff --git a/lib/openshift/assistedinstall/cluster/__init__.py b/lib/openshift/assistedinstall/cluster/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/assistedinstall/cluster/api.py b/lib/openshift/assistedinstall/cluster/api.py new file mode 100644 index 00000000..daa950a3 --- /dev/null +++ b/lib/openshift/assistedinstall/cluster/api.py @@ -0,0 +1,169 @@ +import json +from lib import ip_helper + + +class AssistedInstallClusterApi(): + def __init__(self): + self.assisted_install_cluster_mo = None + self.assisted_install_cluster_install_config_mo = {} + self.assisted_install_cluster_credentials_mo = {} + self.assisted_install_cluster_kubeconfig_mo = {} + + self.assisted_install_cluster_api_version = 'v2' + self.assisted_install_cluster_url = '%s/clusters' % ( + self.assisted_install_cluster_api_version + ) + + def get_assisted_install_cluster_mo(self, cache_enabled=True): + if cache_enabled and self.assisted_install_cluster_mo is not None: + return self.assisted_install_cluster_mo + + params = {} + params['with_hosts'] = True + + self.assisted_install_cluster_mo = self.get_assisted_install_mo( + self.assisted_install_cluster_url, + params=params + ) + + self.log.openshift_mo( + 'assisted_install_cluster.mo', + self.assisted_install_cluster_mo + ) + + return self.assisted_install_cluster_mo + + def get_assisted_install_cluster_install_config_mo(self, cluster_id, cache_enabled=True): + if cache_enabled and cluster_id in self.assisted_install_cluster_install_config_mo: + return self.assisted_install_cluster_install_config_mo[cluster_id] + + url = '%s/%s/install-config' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + self.assisted_install_cluster_install_config_mo[cluster_id] = self.get_assisted_install_mo( + url + ) + + return self.assisted_install_cluster_install_config_mo[cluster_id] + + def get_assisted_install_cluster_credentials_mo(self, cluster_id, cache_enabled=True): + if cache_enabled and cluster_id in self.assisted_install_cluster_credentials_mo: + return self.assisted_install_cluster_credentials_mo[cluster_id] + + url = '%s/%s/credentials' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + self.assisted_install_cluster_credentials_mo[cluster_id] = self.get_assisted_install_mo( + url + ) + + return self.assisted_install_cluster_credentials_mo[cluster_id] + + def get_assisted_install_cluster_kubeconfig_mo(self, cluster_id, cache_enabled=True): + if cache_enabled and cluster_id in self.assisted_install_cluster_kubeconfig_mo: + return self.assisted_install_cluster_kubeconfig_mo[cluster_id] + + params = {} + params['file_name'] = 'kubeconfig' + + url = '%s/%s/downloads/credentials-presigned' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + response = self.get_assisted_install_mo( + url, + params=params + ) + + if response is None: + return None + + filename = '/tmp/%s.kubeconfig' % (cluster_id) + response = ip_helper.download_url(response['url'], filename) + if response is None: + return None + + return filename + + def create_assisted_install_cluster(self, data): + response = self.post_assisted_install_mo( + self.assisted_install_cluster_url, + data=json.dumps(data) + ) + + if response is None: + return None + + return response['id'] + + def patch_assisted_install_cluster(self, cluster_id, data): + url = '%s/%s' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + response = self.patch_assisted_install_mo( + url, + data=json.dumps(data) + ) + return response + + def patch_assisted_install_cluster_install_config(self, cluster_id, data): + url = '%s/%s/install-config' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + response = self.patch_assisted_install_mo( + url, + data=data + ) + return response + + def action_assisted_install_cluster_install(self, cluster_id): + url = '%s/%s/actions/install' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + response = self.post_assisted_install_mo( + url + ) + if response is None: + return False + + return True + + def post_assisted_install_cluster(self, cluster_id, data=None): + url = '%s/%s' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + if data is None: + response = self.post_assisted_install_mo( + url, + data=json.dumps(data) + ) + else: + response = self.post_assisted_install_mo( + url + ) + + return response + + def delete_assisted_install_cluster(self, cluster_id): + url = '%s/%s' % ( + self.assisted_install_cluster_url, + cluster_id + ) + + success = self.delete_assisted_install_mo( + url + ) + return success diff --git a/lib/openshift/assistedinstall/cluster/info.py b/lib/openshift/assistedinstall/cluster/info.py new file mode 100644 index 00000000..12b8e98b --- /dev/null +++ b/lib/openshift/assistedinstall/cluster/info.py @@ -0,0 +1,468 @@ +import time +import json + +from lib import filter_helper + + +class AssistedInstallClusterInfo(): + def __init__(self): + self.assisted_install_cluster = None + self.assisted_install_cluster_install_config = {} + + def get_assisted_install_cluster_install_config(self, cluster_id, cache_enabled=True): + if cache_enabled and cluster_id in self.assisted_install_cluster_install_config: + return self.assisted_install_cluster_install_config[cluster_id] + + config_mo = self.get_assisted_install_cluster_install_config_mo(cluster_id, cache_enabled=cache_enabled) + if config_mo is None: + return None + + self.assisted_install_cluster_install_config[cluster_id] = json.loads(config_mo) + return self.assisted_install_cluster_install_config[cluster_id] + + def get_assisted_install_cluster_host_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key not in ['inventory', 'ntp_sources', 'validations_info', 'domain_name_resolutions']: + info[key] = managed_object[key] + + try: + info['inventory'] = json.loads(managed_object['inventory']) + except BaseException: + info['inventory'] = None + + info['hostname'] = None + if 'requested_hostname' in info: + info['hostname'] = info['requested_hostname'] + + if info['inventory'] is not None: + if info['hostname'] is None: + info['hostname'] = info['inventory']['hostname'] + + for disk_info in info['inventory']['disks']: + disk_info['target'] = False + disk_info['target_tick'] = '' + if disk_info['path'] == info['installation_disk_path']: + disk_info['target_tick'] = '\u2713' + + info['is_valid'] = {} + info['is_valid']['hardware'] = True + info['is_valid']['hardware_tick'] = '\u2713' + info['__Output']['is_valid.hardware_tick'] = 'Green' + info['is_valid']['network'] = True + info['is_valid']['network_tick'] = '\u2713' + info['__Output']['is_valid.network_tick'] = 'Green' + info['is_valid']['operators'] = True + info['is_valid']['operators_tick'] = '\u2713' + info['__Output']['is_valid.operators_tick'] = 'Green' + + try: + validations_info = json.loads(managed_object['validations_info']) + info['validations_info'] = [] + for key in ['hardware', 'network', 'operators']: + for item in validations_info[key]: + item['__Output'] = {} + item['type'] = key + if item['status'] == 'success': + item['__Output']['status'] = 'Green' + if item['status'] == 'failure': + item['__Output']['status'] = 'Red' + info['is_valid'][key] = False + info['__Output']['is_valid.%s_tick' % (key)] = 'Red' + + info['validations_info'].append( + item + ) + + info['valid'] = info['is_valid']['hardware'] and info['is_valid']['network'] and info['is_valid']['operators'] + + except BaseException: + info['validations_info'] = None + info['is_valid']['hardware'] = False + info['is_valid']['network'] = False + info['is_valid']['operators'] = False + info['is_valid']['hardware_tick'] = '\u2717' + info['is_valid']['network_tick'] = '\u2717' + info['is_valid']['operators_tick'] = '\u2717' + info['__Output']['is_valid.hardware_tick'] = 'Red' + info['__Output']['is_valid.network_tick'] = 'Red' + info['__Output']['is_valid.operators_tick'] = 'Red' + info['valid'] = False + + try: + info['domain_name_resolutions'] = json.loads(managed_object['domain_name_resolutions']) + except BaseException: + info['domain_name_resolutions'] = None + + try: + info['ntp_sources'] = json.loads(managed_object['ntp_sources']) + except BaseException: + info['ntp_sources'] = None + + info['ntp_ready'] = False + info['ntp_ready_tick'] = '\u2717' + info['__Output']['ntp_ready_tick'] = 'Red' + if info['ntp_sources'] is not None: + for ntp_source in info['ntp_sources']: + ntp_source['__Output'] = {} + ntp_source['reachable_tick'] = '\u2717' + ntp_source['__Output']['reachable_tick'] = 'Red' + if ntp_source['source_state'] == 'reachable': + info['ntp_ready'] = True + info['ntp_ready_tick'] = '\u2713' + info['__Output']['ntp_ready_tick'] = 'Green' + ntp_source['reachable_tick'] = '\u2713' + ntp_source['__Output']['reachable_tick'] = 'Green' + + if info['status'] is not None and info['status'] == 'Cluster is installed': + info['__Output']['status'] = 'Green' + + return info + + def get_assisted_install_cluster_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + if key not in ['hosts']: + info[key] = managed_object[key] + + info['hosts'] = [] + for host_mo in managed_object['hosts']: + info['hosts'].append( + self.get_assisted_install_cluster_host_info( + host_mo + ) + ) + + info['cidr'] = [] + for cluster_network_mo in managed_object['cluster_networks']: + cidr = {} + cidr['type'] = 'Cluster' + cidr['cidr'] = cluster_network_mo['cidr'] + cidr['prefix'] = cluster_network_mo['host_prefix'] + info['cidr'].append(cidr) + + for service_network_mo in managed_object['service_networks']: + cidr = {} + cidr['type'] = 'Service' + cidr['cidr'] = service_network_mo['cidr'] + cidr['prefix'] = None + info['cidr'].append(cidr) + + return info + + def get_assisted_install_clusters_info(self, cache_enabled=True): + if cache_enabled and self.assisted_install_cluster is not None: + return self.assisted_install_cluster + + managed_objects = self.get_assisted_install_cluster_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.assisted_install_cluster = [] + for managed_object in managed_objects: + self.assisted_install_cluster.append( + self.get_assisted_install_cluster_info( + managed_object + ) + ) + + self.log.openshift_mo( + 'assisted_install_cluster.info', + self.assisted_install_cluster + ) + + return self.assisted_install_cluster + + def match_assisted_install_cluster(self, assisted_install_cluster_info, assisted_install_cluster_filter): + if assisted_install_cluster_filter is None or len(assisted_install_cluster_filter) == 0: + return True + + for ap_rule in assisted_install_cluster_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, assisted_install_cluster_info['name']): + return False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, assisted_install_cluster_info['id']): + return False + + if key == 'ids': + key_found = True + if assisted_install_cluster_info['id'] not in value.split(','): + return False + + if not key_found: + self.log.error( + 'match_assisted_install_cluster', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_assisted_install_clusters( + self, + assisted_install_cluster_filter=None, + config_info=False, + credentials_info=False, + infra_info=False, + manifest_info=False, + kubeconfig_info=False, + cache_enabled=True + ): + all_clusters = self.get_assisted_install_clusters_info(cache_enabled=cache_enabled) + if all_clusters is None: + return None + + clusters = [] + + for cluster_info in all_clusters: + if not self.match_assisted_install_cluster(cluster_info, assisted_install_cluster_filter): + continue + + if config_info: + cluster_info['config'] = self.get_assisted_install_cluster_install_config( + cluster_info['id'], + cache_enabled=cache_enabled + ) + + if infra_info: + object_filter = [] + object_filter.append('cluster_id:%s' % (cluster_info['id'])) + cluster_infra_info = self.get_assisted_install_infras( + assisted_install_infra_filter=object_filter, + cache_enabled=cache_enabled + ) + cluster_info['static_network_config'] = None + if cluster_infra_info is not None and len(cluster_infra_info) == 1: + cluster_info['static_network_config'] = cluster_infra_info[0]['static_network_config'] + cluster_info['infra_id'] = cluster_infra_info[0]['id'] + cluster_info['iso_url'] = cluster_infra_info[0]['download_url'] + cluster_info['iso_type'] = cluster_infra_info[0]['type'] + + if credentials_info: + cluster_info['credentials'] = None + if cluster_info['status'] == 'installed': + cluster_info['credentials'] = self.get_assisted_install_cluster_credentials_mo( + cluster_info['id'], + cache_enabled=cache_enabled + ) + + if manifest_info: + cluster_info['manifest'] = self.get_assisted_install_manifest_mo( + cluster_info['id'] + ) + + if kubeconfig_info: + cluster_info['kubeconfig'] = self.get_assisted_install_cluster_kubeconfig_mo( + cluster_info['id'], + cache_enabled=cache_enabled + ) + + clusters.append(cluster_info) + + clusters = sorted( + clusters, + key=lambda i: i['name'].lower() + ) + + self.log.openshift_mo( + 'assisted_install_cluster.full', + clusters + ) + + return clusters + + def get_assisted_install_cluster( + self, + cluster_name=None, + cluster_id=None, + config_info=False, + credentials_info=False, + infra_info=False, + manifest_info=False, + kubeconfig_info=False, + cache_enabled=True + ): + if cluster_name is None and cluster_id is None: + self.log.error( + 'get_assisted_install_cluster', + 'Select cluster by name or id' + ) + return None + + if cluster_name is not None and cluster_id is not None: + self.log.error( + 'get_assisted_install_cluster', + 'Select cluster by name or id' + ) + return None + + object_filter = [] + if cluster_id is not None: + object_filter.append('id:%s' % (cluster_id)) + if cluster_name is not None: + object_filter.append('name:%s' % (cluster_name)) + + clusters = self.get_assisted_install_clusters( + assisted_install_cluster_filter=object_filter, + config_info=config_info, + credentials_info=credentials_info, + infra_info=infra_info, + manifest_info=manifest_info, + kubeconfig_info=kubeconfig_info, + cache_enabled=cache_enabled + ) + if clusters is None or len(clusters) == 0: + return None + + if len(clusters) > 1: + self.log.error( + 'get_assisted_install_cluster', + 'Multiple cluster found [%s] [%s]' % (cluster_id, cluster_name) + ) + return None + + return clusters[0] + + def get_assisted_install_cluster_status(self, cluster_id): + cluster_info = self.get_assisted_install_cluster( + cluster_id=cluster_id, + cache_enabled=False + ) + if cluster_info is not None: + return cluster_info['status'] + + return None + + def get_assisted_install_cluster_host_status(self, cluster_id): + cluster_info = self.get_assisted_install_cluster( + cluster_id=cluster_id, + cache_enabled=False + ) + + hosts = {} + if cluster_info is not None: + if 'hosts' in cluster_info and cluster_info['hosts'] is not None: + for host_info in cluster_info['hosts']: + try: + host_ip = host_info['inventory']['bmc_address'] + hosts[host_ip] = host_info['status'] + except BaseException: + pass + + return hosts + + def get_assisted_install_cluster_progress(self, cluster_id): + cluster_info = self.get_assisted_install_cluster( + cluster_id=cluster_id, + cache_enabled=False + ) + if cluster_info is not None: + if cluster_info['status'] == 'installed': + return 100 + + if 'progress' in cluster_info and cluster_info['progress'] is not None: + if 'total_percentage' not in cluster_info['progress']: + self.log.error( + 'get_assisted_install_cluster_progress', + 'Unexpected cluster info: %s' % (json.dumps(cluster_info, indent=4)) + ) + return None + + return cluster_info['progress']['total_percentage'] + + return None + + def wait_assisted_install_cluster_status(self, cluster_id, status, timeout=7200): + start_time = int(time.time()) + + while True: + cluster_info = self.get_assisted_install_cluster( + cluster_id=cluster_id, + cache_enabled=False + ) + if cluster_info is not None: + if cluster_info['status'] == status: + return True + + time.sleep(5) + + if int(time.time()) - start_time > timeout: + self.log.error( + 'wait_assisted_install_cluster_status', + 'Timeout %s reached' % (timeout) + ) + return False + + def wait_assisted_install_cluster_hosts_discovered(self, cluster_id, bmc_addresses, timeout=3600): + start_time = int(time.time()) + + while True: + cluster_info = self.get_assisted_install_cluster( + cluster_id=cluster_id, + cache_enabled=False + ) + if cluster_info is not None: + if 'hosts' in cluster_info and cluster_info['hosts'] is not None: + discovered_bmc_addresses = [] + for host_info in cluster_info['hosts']: + if 'inventory' in host_info and host_info['inventory'] is not None: + if host_info['inventory']['bmc_address'] in bmc_addresses: + discovered_bmc_addresses.append( + host_info['inventory']['bmc_address'] + ) + + if len(discovered_bmc_addresses) == len(bmc_addresses): + return True + + time.sleep(5) + + if int(time.time()) - start_time > timeout: + self.log.error( + 'wait_assisted_install_cluster_hosts_discovered', + 'Timeout %s reached' % (timeout) + ) + return False + + def update_assisted_install_cluster_hosts_hostname(self, cluster_id, hostname, attempts=3): + attempt = 0 + updated_hosts = {} + while True: + cluster_info = self.get_assisted_install_cluster( + cluster_id=cluster_id, + cache_enabled=False + ) + if cluster_info is not None: + if 'hosts' in cluster_info and cluster_info['hosts'] is not None: + for host_info in cluster_info['hosts']: + if 'inventory' in host_info and host_info['inventory'] is not None: + host_bmc = host_info['inventory']['bmc_address'] + if host_bmc not in updated_hosts: + response = self.update_assisted_install_infra_hostname( + host_info['infra_env_id'], + host_info['id'], + hostname[host_bmc] + ) + if response is not None: + updated_hosts[host_bmc] = True + + if len(hostname) == len(updated_hosts): + return True + + time.sleep(5) + + attempt = attempt + 1 + if attempt > attempts: + self.log.error( + 'update_assisted_install_cluster_hosts_hostname', + 'Max attempts reached' + ) + return False diff --git a/lib/openshift/assistedinstall/cluster/main.py b/lib/openshift/assistedinstall/cluster/main.py new file mode 100644 index 00000000..9a254c9f --- /dev/null +++ b/lib/openshift/assistedinstall/cluster/main.py @@ -0,0 +1,11 @@ +from lib.openshift.assistedinstall.cluster.api import AssistedInstallClusterApi +from lib.openshift.assistedinstall.cluster.info import AssistedInstallClusterInfo + + +class AssistedInstallCluster( + AssistedInstallClusterApi, + AssistedInstallClusterInfo + ): + def __init__(self): + AssistedInstallClusterApi.__init__(self) + AssistedInstallClusterInfo.__init__(self) diff --git a/lib/openshift/assistedinstall/event/__init__.py b/lib/openshift/assistedinstall/event/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/assistedinstall/event/api.py b/lib/openshift/assistedinstall/event/api.py new file mode 100644 index 00000000..b5a3a2de --- /dev/null +++ b/lib/openshift/assistedinstall/event/api.py @@ -0,0 +1,12 @@ +class AssistedInstallEventApi(): + def __init__(self): + self.assisted_install_event_api_version = 'v2' + self.assisted_install_event_url = '%s/events' % ( + self.assisted_install_event_api_version + ) + + def get_assisted_install_event_mo(self): + response = self.get_assisted_install_mo( + self.assisted_install_event_url + ) + return response diff --git a/lib/openshift/assistedinstall/event/info.py b/lib/openshift/assistedinstall/event/info.py new file mode 100644 index 00000000..48dbe7a6 --- /dev/null +++ b/lib/openshift/assistedinstall/event/info.py @@ -0,0 +1,3 @@ +class AssistedInstallEventInfo(): + def __init__(self): + pass diff --git a/lib/openshift/assistedinstall/event/main.py b/lib/openshift/assistedinstall/event/main.py new file mode 100644 index 00000000..c4d2b3f7 --- /dev/null +++ b/lib/openshift/assistedinstall/event/main.py @@ -0,0 +1,11 @@ +from lib.openshift.assistedinstall.event.api import AssistedInstallEventApi +from lib.openshift.assistedinstall.event.info import AssistedInstallEventInfo + + +class AssistedInstallEvent( + AssistedInstallEventApi, + AssistedInstallEventInfo + ): + def __init__(self): + AssistedInstallEventApi.__init__(self) + AssistedInstallEventInfo.__init__(self) diff --git a/lib/openshift/assistedinstall/infra/__init__.py b/lib/openshift/assistedinstall/infra/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/assistedinstall/infra/api.py b/lib/openshift/assistedinstall/infra/api.py new file mode 100644 index 00000000..6c47fd39 --- /dev/null +++ b/lib/openshift/assistedinstall/infra/api.py @@ -0,0 +1,54 @@ +import json + + +class AssistedInstallInfraApi(): + def __init__(self): + self.assisted_install_infra_mo = None + + self.assisted_install_infra_api_version = 'v2' + self.assisted_install_infra_url = '%s/infra-envs' % ( + self.assisted_install_infra_api_version + ) + + def get_assisted_install_infra_mo(self, cache_enabled=True): + if cache_enabled and self.assisted_install_infra_mo is not None: + return self.assisted_install_infra_mo + + self.assisted_install_infra_mo = self.get_assisted_install_mo( + self.assisted_install_infra_url + ) + + self.log.openshift_mo( + 'assisted_install_infra.mo', + self.assisted_install_infra_mo + ) + + return self.assisted_install_infra_mo + + def create_assisted_install_infra(self, data): + response = self.post_assisted_install_mo( + self.assisted_install_infra_url, + data=json.dumps(data) + ) + + if response is None: + return None + + return response['id'] + + def update_assisted_install_infra_hostname(self, infra_id, host_id, hostname): + url = '%s/%s/hosts/%s' % ( + self.assisted_install_infra_url, + infra_id, + host_id + ) + + data = {} + data['host_name'] = hostname + + response = self.patch_assisted_install_mo( + url, + data=json.dumps(data) + ) + + return response diff --git a/lib/openshift/assistedinstall/infra/info.py b/lib/openshift/assistedinstall/infra/info.py new file mode 100644 index 00000000..cf6cfa8c --- /dev/null +++ b/lib/openshift/assistedinstall/infra/info.py @@ -0,0 +1,83 @@ +import json + +from lib import filter_helper + + +class AssistedInstallInfraInfo(): + def __init__(self): + self.assisted_install_infra = None + + def get_assisted_install_infra_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + for key in ['download_url', 'type']: + if key not in info: + info[key] = None + + if 'static_network_config' in info: + info['static_network_config'] = json.loads(info['static_network_config']) + + return info + + def get_assisted_install_infras_info(self, cache_enabled=True): + if cache_enabled and self.assisted_install_infra is not None: + return self.assisted_install_infra + + managed_objects = self.get_assisted_install_infra_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.assisted_install_infra = [] + for managed_object in managed_objects: + self.assisted_install_infra.append( + self.get_assisted_install_infra_info( + managed_object + ) + ) + + self.log.openshift_mo( + 'assisted_install_infra.info', + self.assisted_install_infra + ) + + return self.assisted_install_infra + + def match_assisted_install_infra(self, assisted_install_infra_info, assisted_install_infra_filter): + if assisted_install_infra_filter is None or len(assisted_install_infra_filter) == 0: + return True + + for ap_rule in assisted_install_infra_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'cluster_id': + key_found = True + if not filter_helper.match_string(value, assisted_install_infra_info['cluster_id']): + return False + + if not key_found: + self.log.error( + 'match_assisted_install_infra', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_assisted_install_infras(self, assisted_install_infra_filter=None, cache_enabled=True): + all_infras = self.get_assisted_install_infras_info(cache_enabled=cache_enabled) + if all_infras is None: + return None + + infras = [] + + for infra_info in all_infras: + if not self.match_assisted_install_infra(infra_info, assisted_install_infra_filter): + continue + + infras.append(infra_info) + + return infras diff --git a/lib/openshift/assistedinstall/infra/main.py b/lib/openshift/assistedinstall/infra/main.py new file mode 100644 index 00000000..de480ec4 --- /dev/null +++ b/lib/openshift/assistedinstall/infra/main.py @@ -0,0 +1,11 @@ +from lib.openshift.assistedinstall.infra.api import AssistedInstallInfraApi +from lib.openshift.assistedinstall.infra.info import AssistedInstallInfraInfo + + +class AssistedInstallInfra( + AssistedInstallInfraApi, + AssistedInstallInfraInfo + ): + def __init__(self): + AssistedInstallInfraApi.__init__(self) + AssistedInstallInfraInfo.__init__(self) diff --git a/lib/openshift/assistedinstall/main.py b/lib/openshift/assistedinstall/main.py new file mode 100644 index 00000000..99ba677f --- /dev/null +++ b/lib/openshift/assistedinstall/main.py @@ -0,0 +1,23 @@ +from lib.openshift.assistedinstall.api import AssistedInstallApi +from lib.openshift.assistedinstall.cluster.main import AssistedInstallCluster +from lib.openshift.assistedinstall.event.main import AssistedInstallEvent +from lib.openshift.assistedinstall.infra.main import AssistedInstallInfra +from lib.openshift.assistedinstall.manifest.main import AssistedInstallManifest +from lib.openshift.assistedinstall.version.main import AssistedInstallVersion + + +class AssistedInstall( + AssistedInstallApi, + AssistedInstallCluster, + AssistedInstallEvent, + AssistedInstallInfra, + AssistedInstallManifest, + AssistedInstallVersion + ): + def __init__(self): + AssistedInstallApi.__init__(self) + AssistedInstallCluster.__init__(self) + AssistedInstallEvent.__init__(self) + AssistedInstallInfra.__init__(self) + AssistedInstallManifest.__init__(self) + AssistedInstallVersion.__init__(self) diff --git a/lib/openshift/assistedinstall/manifest/__init__.py b/lib/openshift/assistedinstall/manifest/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/assistedinstall/manifest/api.py b/lib/openshift/assistedinstall/manifest/api.py new file mode 100644 index 00000000..3f190b3d --- /dev/null +++ b/lib/openshift/assistedinstall/manifest/api.py @@ -0,0 +1,41 @@ +import json + +class AssistedInstallManifestApi(): + def __init__(self): + self.assisted_install_manifest_api_version = 'v2' + self.assisted_install_manifest_url = '%s/clusters' % ( + self.assisted_install_manifest_api_version + ) + + def get_assisted_install_manifest_mo(self, cluster_id): + url = '%s/%s/manifests' % ( + self.assisted_install_manifest_url, + cluster_id + ) + + response = self.get_assisted_install_mo( + url + ) + + return response + + def create_assisted_install_manifest(self, cluster_id, filename, content): + url = '%s/%s/manifests' % ( + self.assisted_install_manifest_url, + cluster_id + ) + + data = {} + data['file_name'] = filename + data['folder'] = 'manifests' + data['content'] = content + + response = self.post_assisted_install_mo( + url, + data=json.dumps(data) + ) + + if response is None: + return False + + return True diff --git a/lib/openshift/assistedinstall/manifest/info.py b/lib/openshift/assistedinstall/manifest/info.py new file mode 100644 index 00000000..aa84d7f2 --- /dev/null +++ b/lib/openshift/assistedinstall/manifest/info.py @@ -0,0 +1,3 @@ +class AssistedInstallManifestInfo(): + def __init__(self): + pass diff --git a/lib/openshift/assistedinstall/manifest/main.py b/lib/openshift/assistedinstall/manifest/main.py new file mode 100644 index 00000000..c9ba2cf1 --- /dev/null +++ b/lib/openshift/assistedinstall/manifest/main.py @@ -0,0 +1,11 @@ +from lib.openshift.assistedinstall.manifest.api import AssistedInstallManifestApi +from lib.openshift.assistedinstall.manifest.info import AssistedInstallManifestInfo + + +class AssistedInstallManifest( + AssistedInstallManifestApi, + AssistedInstallManifestInfo + ): + def __init__(self): + AssistedInstallManifestApi.__init__(self) + AssistedInstallManifestInfo.__init__(self) diff --git a/lib/openshift/assistedinstall/output.py b/lib/openshift/assistedinstall/output.py new file mode 100644 index 00000000..81574d6a --- /dev/null +++ b/lib/openshift/assistedinstall/output.py @@ -0,0 +1,536 @@ +import json +from lib import file_helper + + +class AssistedInstallOutput(): + def __init__(self): + pass + + def print_assisted_install_clusters_state(self, info, title=False): + if title: + self.my_output.default( + 'Assisted Installation - Clusters [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'status_info', + 'openshift_version', + 'network_type' + ] + + headers = [ + 'Name', + 'Status', + 'Version', + 'CNI' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_assisted_install_cluster_cidr(self, cluster): + if 'cidr' not in cluster or cluster['cidr'] is None: + self.my_output.default('[WARNING] CIDR information not found') + return + + order = [ + 'type', + 'cidr', + 'prefix' + ] + + headers = [ + 'Type', + 'Subnet', + 'Prefix' + ] + + for cidr in cluster['cidr']: + if cidr['prefix'] is None: + cidr['prefix'] = '--' + + self.my_output.my_table( + cluster['cidr'], + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_assisted_install_cluster_config(self, cluster): + if 'config' not in cluster or cluster['config'] is None: + self.my_output.default('[WARNING] Configuration information not found') + return + + self.my_output.default( + 'Cluster configuration', + underline=True, + after_newline=True, + before_newline=True + ) + + self.my_output.default(json.dumps(cluster['config'], indent=4)) + + def print_assisted_install_cluster_static_network_config(self, cluster): + if 'static_network_config' not in cluster or cluster['static_network_config'] is None: + return + + if len(cluster['static_network_config']) == 0: + return + + index = 1 + for config in cluster['static_network_config']: + self.my_output.default( + 'Static network configuration #%s' % (index), + underline=True, + after_newline=True, + before_newline=True + ) + + self.my_output.default( + config['network_yaml'] + ) + + order = [ + 'logical_nic_name', + 'mac_address' + ] + + headers = [ + 'Logical nic name', + 'MAC address' + ] + + self.my_output.my_table( + config['mac_interface_map'], + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + index = index + 1 + + def print_assisted_install_cluster_hosts(self, cluster): + if 'hosts' not in cluster or cluster['hosts'] is None or len(cluster['hosts']) == 0: + self.my_output.default('[WARNING] No discovered hosts information') + return + + self.my_output.default( + 'Hosts discovery', + underline=True, + before_newline=True + ) + + order = [ + 'hostname', + 'suggested_role', + 'role', + 'inventory.bmc_address', + 'status_info', + 'ntp_ready_tick', + 'is_valid.hardware_tick', + 'is_valid.network_tick', + 'is_valid.operators_tick', + 'updated_at' + ] + + headers = [ + 'Hostname', + 'Suggested Role', + 'Role', + 'IMC', + 'Status', + 'NTP Ready', + 'HW Valid', + 'Network Valid', + 'Operator Valid', + 'Updated' + ] + + self.my_output.my_table( + cluster['hosts'], + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + for host_info in cluster['hosts']: + if 'inventory' not in host_info or host_info['inventory'] is None: + self.my_output.default('[WARNING] No inventory info') + else: + order = [ + 'inventory.bmc_address', + 'inventory.bmc_v6address', + 'inventory.hostname', + 'id', + 'infra_env_id', + 'inventory.system_vendor.manufacturer', + 'inventory.system_vendor.product_name', + 'inventory.system_vendor.serial_number', + 'inventory.boot.command_line', + 'inventory.boot.current_boot_mode', + 'inventory.cpu.architecture', + 'inventory.cpu.count', + 'inventory.cpu.frequency', + 'inventory.cpu.model_name', + 'inventory.memory.physical_bytes', + 'inventory.memory.usable_bytes' + ] + + headers = [ + 'IMC v4', + 'IMC v6', + 'Hostname', + 'Id', + 'Infra Id', + 'Vendor', + 'Product', + 'Serial', + 'Boot cmd', + 'Boot mode', + 'CPU architecture', + 'CPU count', + 'CPU frequency', + 'CPU model', + 'Memory physical bytes', + 'Memory usable bytes' + ] + + self.my_output.dictionary( + host_info, + title='Host %s' % (host_info['inventory']['bmc_address']), + keys=order, + title_keys=headers, + justify=True + ) + + if 'interfaces' not in host_info['inventory'] or host_info['inventory']['interfaces'] is None: + self.my_output.default('[WARNING] No interfaces info') + else: + order = [ + 'name', + 'biosdevname', + 'type', + 'mac_address', + 'mtu', + 'ipv4_addresses', + 'ipv6_addresses', + 'has_carrier', + 'flags' + ] + + headers = [ + 'Inteface Name', + 'Bios name', + 'Type', + 'MAC', + 'MTU', + 'IPv4', + 'IPv6', + 'Carrier', + 'Flags' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + host_info['inventory']['interfaces'], + order, + ['ipv4_addresses', 'ipv6_addresses', 'flags'] + ), + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if 'routes' not in host_info['inventory'] or host_info['inventory']['routes'] is None: + self.my_output.default('[WARNING] No disks info') + else: + order = [ + 'destination', + 'gateway', + 'interface' + ] + + headers = [ + 'Route', + 'Gateway', + 'Interface' + ] + + self.my_output.my_table( + host_info['inventory']['routes'], + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if 'disks' not in host_info['inventory'] or host_info['inventory']['disks'] is None: + self.my_output.default('[WARNING] No disks info') + else: + order = [ + 'name', + 'path', + 'size_bytes', + 'drive_type', + 'bootable', + 'target_tick', + 'vendor', + 'model' + ] + + headers = [ + 'Disk name', + 'Path', + 'Size [B]', + 'Type', + 'Bootable', + 'Target', + 'Vendor', + 'Model' + ] + + disks = [] + for disk_info in host_info['inventory']['disks']: + if disk_info['installation_eligibility']['not_eligible_reasons'] is None: + disks.append( + disk_info + ) + + self.my_output.my_table( + disks, + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if 'ntp_sources' not in host_info or host_info['ntp_sources'] is None: + self.my_output.default('[WARNING] No NTP sources info') + else: + order = [ + 'source_name', + 'reachable_tick' + ] + + headers = [ + 'NTP Source', + 'Reachable' + ] + + self.my_output.my_table( + host_info['ntp_sources'], + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + if 'validations_info' not in host_info or host_info['validations_info'] is None: + self.my_output.default('[WARNING] No validation info') + else: + order = [ + 'type', + 'id', + 'status', + 'message' + ] + + headers = [ + 'Validation type', + 'Id', + 'Status', + 'Message' + ] + + self.my_output.my_table( + host_info['validations_info'], + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_assisted_install_cluster_kubeconfig(self, cluster): + if 'kubeconfig' in cluster and cluster['kubeconfig'] is not None: + content = file_helper.get_file_text( + cluster['kubeconfig'] + ) + self.my_output.default( + 'Kubeconfig', + underline=True, + before_newline=True, + after_newline=True + ) + self.my_output.default(content) + + def print_assisted_install_cluster_credentials(self, cluster): + order = [ + 'credentials.console_url', + 'credentials.username', + 'credentials.password' + ] + + headers = [ + 'URL', + 'Username', + 'Password' + ] + + self.my_output.dictionary( + cluster, + title='Cluster console access', + values=cluster, + keys=order, + title_keys=headers, + justify=True + ) + + def print_assisted_install_cluster(self, cluster): + order = [ + 'name', + 'id', + 'user_name', + 'platform.type', + 'openshift_version', + 'ocp_release_image', + 'network_type', + 'high_availability_mode', + 'status_info', + 'created_at', + 'base_dns_domain', + 'api_vipsT', + 'ingress_vipsT', + 'http_proxy', + 'https_proxy', + 'no_proxy', + 'ssh_public_key', + 'iso_type', + 'iso_url', + 'credentials.console_url', + 'credentials.username', + 'credentials.password' + ] + + headers = [ + 'Name', + 'Id', + 'Owner', + 'Type', + 'Version', + 'Image', + 'CNI', + 'HA Mode', + 'Status', + 'Created at', + 'Base DNS', + 'API VIP', + 'Ingress VIP', + 'HTTP proxy', + 'HTTPS proxy', + 'No proxy', + 'SSH public key', + 'ISO Type', + 'ISO URL', + 'Console URL', + 'Username', + 'Password' + ] + + cluster['api_vipsT'] = '--' + if 'api_vips' in cluster and cluster['api_vips'] is not None: + api_vips = [] + for api_vip in cluster['api_vips']: + api_vips.append( + api_vip['ip'] + ) + + cluster['api_vipsT'] = ', '.join(api_vips) + + cluster['ingress_vipsT'] = '--' + if 'ingress_vips' in cluster and cluster['ingress_vips'] is not None: + ingress_vips = [] + for ingress_vip in cluster['ingress_vips']: + ingress_vips.append( + ingress_vip['ip'] + ) + + cluster['ingress_vipsT'] = ', '.join(ingress_vips) + + self.my_output.dictionary( + cluster, + title='Assisted Installation - Cluster [%s]' % (cluster['name']), + values=cluster, + keys=order, + title_keys=headers, + justify=True + ) + + self.print_assisted_install_cluster_cidr(cluster) + self.print_assisted_install_cluster_config(cluster) + self.print_assisted_install_cluster_static_network_config(cluster) + self.print_assisted_install_cluster_hosts(cluster) + self.print_assisted_install_cluster_kubeconfig(cluster) + + def print_assisted_install_versions(self, info, title=False): + if title: + self.my_output.default( + 'Assisted Installation - OpenShift version [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + order = [ + 'display_name', + 'support_level', + 'cpu_architectures' + ] + + headers = [ + 'Name', + 'Support', + 'CPU' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + row_separator=True, + allow_order_subkeys=True, + underline=True, + table=True + ) diff --git a/lib/openshift/assistedinstall/version/__init__.py b/lib/openshift/assistedinstall/version/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/openshift/assistedinstall/version/api.py b/lib/openshift/assistedinstall/version/api.py new file mode 100644 index 00000000..d26f97f6 --- /dev/null +++ b/lib/openshift/assistedinstall/version/api.py @@ -0,0 +1,30 @@ +class AssistedInstallVersionApi(): + def __init__(self): + self.assisted_install_openshift_version_mo = None + self.assisted_install_component_version_mo = None + + self.assisted_install_version_api_version = 'v2' + self.assisted_install_openshift_version_url = '%s/openshift-versions' % ( + self.assisted_install_version_api_version + ) + self.assisted_install_component_version_url = '%s/component-versions' % ( + self.assisted_install_version_api_version + ) + + def get_assisted_install_openshift_version_mo(self, cache_enabled=True): + if cache_enabled and self.assisted_install_openshift_version_mo is not None: + return self.assisted_install_openshift_version_mo + + self.assisted_install_openshift_version_mo = self.get_assisted_install_mo( + self.assisted_install_openshift_version_url + ) + return self.assisted_install_openshift_version_mo + + def get_assisted_install_component_version_mo(self, cache_enabled=True): + if cache_enabled and self.assisted_install_component_version_mo is not None: + return self.assisted_install_component_version_mo + + self.assisted_install_component_version_mo = self.get_assisted_install_mo( + self.assisted_install_component_version_url + ) + return self.assisted_install_component_version_mo diff --git a/lib/openshift/assistedinstall/version/info.py b/lib/openshift/assistedinstall/version/info.py new file mode 100644 index 00000000..373fae8b --- /dev/null +++ b/lib/openshift/assistedinstall/version/info.py @@ -0,0 +1,112 @@ +class AssistedInstallVersionInfo(): + def __init__(self): + self.assisted_install_openshift_version = None + self.assisted_install_component_version = None + + def get_assisted_install_openshift_version_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + info['major'] = int(info['display_name'].split('.')[0]) + info['minor'] = int(info['display_name'].split('.')[1]) + info['sub'] =int(info['display_name'].split('.')[2].split('-')[0]) + return info + + def get_assisted_install_component_version_info(self, managed_object): + info = {} + info['__Output'] = {} + for key in managed_object: + info[key] = managed_object[key] + + return info + + def get_assisted_install_openshift_versions_info(self, cache_enabled=True): + if cache_enabled and self.assisted_install_openshift_version is not None: + return self.assisted_install_openshift_version + + managed_objects = self.get_assisted_install_openshift_version_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.assisted_install_openshift_version = [] + for key in managed_objects: + self.assisted_install_openshift_version.append( + self.get_assisted_install_openshift_version_info( + managed_objects[key] + ) + ) + + self.log.openshift_mo( + 'assisted_install_openshift_version.info', + self.assisted_install_openshift_version + ) + + self.assisted_install_openshift_version = sorted( + self.assisted_install_openshift_version, + key=lambda i: ( + i['major'], + i['minor'], + i['sub'] + ), + reverse=True + ) + + return self.assisted_install_openshift_version + + def get_assisted_install_component_versions_info(self, cache_enabled=True): + if cache_enabled and self.assisted_install_component_version is not None: + return self.assisted_install_component_version + + managed_objects = self.get_assisted_install_component_version_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.assisted_install_component_version = self.get_assisted_install_component_version_info( + managed_objects['versions'] + ) + self.assisted_install_component_version['release_tag'] = managed_objects['release_tag'] + + self.log.openshift_mo( + 'assisted_install_component_version.info', + self.assisted_install_component_version + ) + + return self.assisted_install_component_version + + def match_assisted_install_openshift_version(self, assisted_install_openshift_version_info, assisted_install_openshift_version_filter): + if assisted_install_openshift_version_filter is None or len(assisted_install_openshift_version_filter) == 0: + return True + + for ap_rule in assisted_install_openshift_version_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if not key_found: + self.log.error( + 'match_assisted_install_openshift_version', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_assisted_install_versions(self, cache_enabled=True): + versions = {} + versions['openshift'] = self.get_assisted_install_openshift_versions_info(cache_enabled=cache_enabled) + versions['component'] = self.get_assisted_install_component_versions_info(cache_enabled=cache_enabled) + return versions + + def get_assisted_install_versions_latest(self, support_level='production', cache_enabled=True): + versions = self.get_assisted_install_openshift_versions_info(cache_enabled=cache_enabled) + if len(versions) == 0: + return None + + if support_level == 'any': + return versions[0] + + for version in versions: + if version['support_level'] == support_level: + return version['display_name'] + + return None diff --git a/lib/openshift/assistedinstall/version/main.py b/lib/openshift/assistedinstall/version/main.py new file mode 100644 index 00000000..52caa152 --- /dev/null +++ b/lib/openshift/assistedinstall/version/main.py @@ -0,0 +1,11 @@ +from lib.openshift.assistedinstall.version.api import AssistedInstallVersionApi +from lib.openshift.assistedinstall.version.info import AssistedInstallVersionInfo + + +class AssistedInstallVersion( + AssistedInstallVersionApi, + AssistedInstallVersionInfo + ): + def __init__(self): + AssistedInstallVersionApi.__init__(self) + AssistedInstallVersionInfo.__init__(self) diff --git a/lib/openshift/console.py b/lib/openshift/console.py new file mode 100644 index 00000000..06cf9f6e --- /dev/null +++ b/lib/openshift/console.py @@ -0,0 +1,27 @@ +from lib import log_helper + +from lib.openshift import api +from lib.openshift import settings + +from lib.openshift.assistedinstall.main import AssistedInstall +from lib.openshift.accountsmgmt.main import AccountsMgmt + + +class Console(AssistedInstall, AccountsMgmt): + def __init__(self, log_id=None): + AssistedInstall.__init__(self) + AccountsMgmt.__init__(self) + + self.log = log_helper.Log(log_id=log_id) + + self.settings_handler = settings.OpenShiftSettings() + + self.api_handler = None + if self.is_ready(): + self.api_handler = api.Api(self.settings_handler.get_api_token(), log_id=log_id) + + def get_pull_secret(self): + return self.settings_handler.get_pull_secret() + + def is_ready(self): + return self.settings_handler.is_configured() diff --git a/lib/openshift/output.py b/lib/openshift/output.py new file mode 100644 index 00000000..325edac0 --- /dev/null +++ b/lib/openshift/output.py @@ -0,0 +1,14 @@ +from lib import output_helper + +from lib.openshift.assistedinstall.output import AssistedInstallOutput + + +class OpenshiftOutput( + AssistedInstallOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) diff --git a/lib/openshift/settings.py b/lib/openshift/settings.py new file mode 100644 index 00000000..e315bb3b --- /dev/null +++ b/lib/openshift/settings.py @@ -0,0 +1,66 @@ +import os + +from lib import log_helper +from lib import file_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class OpenShiftSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log = log_helper.Log() + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.openshift_settings_directory = os.path.join( + self.settings_dir, + 'openshift' + ) + + self.openshift_api_token_filename = os.path.join( + self.openshift_settings_directory, + 'token' + ) + + self.openshift_pull_secret_filename = os.path.join( + self.openshift_settings_directory, + 'pull_secret.txt' + ) + + if not self.initialize_openshift_settings(): + raise ValueError('OpenShift settings initialization failed') + + def initialize_openshift_settings(self): + if not os.path.isdir(self.openshift_settings_directory): + os.makedirs(self.openshift_settings_directory, exist_ok=True) + return True + + def is_configured(self): + if self.get_api_token() is None: + return False + + if self.get_pull_secret() is None: + return False + + return True + + def get_api_token(self): + return file_helper.get_file_text(self.openshift_api_token_filename) + + def set_api_token(self, token): + return file_helper.set_file(self.openshift_api_token_filename, token) + + def get_pull_secret(self): + return file_helper.get_file_text(self.openshift_pull_secret_filename) + + def set_pull_secret(self, filename): + pull_secret = self.get_file_text(filename) + if pull_secret is None: + return False + + return file_helper.set_file(self.openshift_pull_secret_filename, pull_secret) diff --git a/lib/osp/__init__.py b/lib/osp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/api.py b/lib/osp/api.py new file mode 100644 index 00000000..7f9fedc4 --- /dev/null +++ b/lib/osp/api.py @@ -0,0 +1,909 @@ +import traceback + +import keystoneclient.v2_0.client as ksclient +import glanceclient.v2.client as glclient +import novaclient.client as nvclient +from neutronclient.v2_0 import client as neutronclient +from cinderclient.v3 import client as cinderclient + +# Exceptions +from keystoneclient.v2_0.client import exceptions as ksexceptions +from novaclient import exceptions as nexceptions +from cinderclient import exceptions as cinceptions +from neutronclient.v2_0.client import exceptions as neuceptions + +# Keystone v3 support +from keystoneauth1.identity import v3 +from keystoneauth1 import session +from keystoneclient.v3 import client + +from lib import file_helper + + +class OspApi(): + def __init__(self, openrc_filename, cert_filename): + self.api_version = None + self.keystone_session = None + self.api = {} + self.api['keystone'] = None + + self.api_timeout_seconds = 10 + self.connect_timeout_seconds = 10 + self.api_retries = 1 + + self.cert_filename = cert_filename + self.cert = None + if self.cert_filename is not None: + self.cert = file_helper.get_file_text(cert_filename) + if self.cert is None: + raise ValueError('Cert load failed') + + self.openrc = self.load_openrc(openrc_filename) + if self.openrc is None: + raise ValueError('Openstack openrc parse failed') + + def parse_openrc(self, openrc_filename): + content = file_helper.get_file_text(openrc_filename) + if content is None: + self.log.error( + 'parse_openrc', + 'Openrc file read failed: %s' % (openrc_filename) + ) + return None + + openrc_content = {} + + for line in content.split('\n'): + if line.startswith('export '): + if len(line.split('export ')[1].split('=')) == 2: + (key, value) = line.split('export ')[1].split('=') + openrc_content[key.upper()] = value + + return openrc_content + + def load_openrc(self, openrc_filename): + openrc_content = self.parse_openrc(openrc_filename) + if openrc_content is None: + return None + + if 'OS_IDENTITY_API_VERSION' not in openrc_content: + self.log.error( + 'load_openrc', + 'Identity key not found' + ) + return None + + if openrc_content['OS_IDENTITY_API_VERSION'] == '3': + self.api_version = 3 + + if openrc_content['OS_IDENTITY_API_VERSION'] in ['2', '2.0']: + self.api_version = 2 + + if self.api_version is None: + self.log.error( + 'load_openrc', + 'Unsupported version: %s' % openrc_content['OS_IDENTITY_API_VERSION'] + ) + return None + + openrc = {} + for key in openrc_content: + if key.startswith('OS_'): + openrc[key] = openrc_content[key] + + return openrc + + def get_api_keystone_session(self, cache_enabled=True): + if cache_enabled and self.keystone_session is not None: + return self.keystone_session + + self.get_api_keystone(cache_enabled=cache_enabled) + return self.keystone_session + + def get_api_keystone_v2(self): + for key in ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME', 'OS_REGION_NAME']: + if key not in self.openrc: + self.log.error( + 'get_api_keystone_v2', + 'Required key missing: %s' % (key) + ) + return None + + keystone_handler = None + try: + keystone_handler = ksclient.Client( + auth_url=self.openrc['OS_AUTH_URL'], + username=self.openrc['OS_USERNAME'], + password=self.openrc['OS_PASSWORD'], + tenant_name=self.openrc['OS_TENANT_NAME'], + region_name=self.openrc['OS_REGION_NAME'], + timeout=self.api_timeout_seconds + ) + + except ksexceptions.VersionNotAvailable: + self.log.error( + 'get_api_keystone_v2', + 'Suitable Keystone v2 client not found' + ) + self.log.error( + 'get_api_keystone_v2', + traceback.format_exc() + ) + return None + + except ksexceptions.DiscoveryFailure: + self.log.error( + 'get_api_keystone_v2', + 'Keystone v2 server response invalid' + ) + self.log.error( + 'get_api_keystone_v2', + traceback.format_exc() + ) + return None + + except ksexceptions.ClientException: + self.log.error( + 'get_api_keystone_v2', + 'Failed to initiate Keystone v3 clien' + ) + self.log.error( + 'get_api_keystone_v2', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_keystone_v2', + 'Keystone v2 authentication failed' + ) + self.log.error( + 'get_api_keystone_v2', + traceback.format_exc() + ) + return None + + if keystone_handler is None: + self.log.error( + 'get_api_keystone_v2', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_keystone_v2', + 'Keystone v2 authentication successful (%s)' % (self.openrc['OS_AUTH_URL']) + ) + + self.api['keystone'] = keystone_handler + return self.api['keystone'] + + def get_api_keystone_v3(self): + for key in ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_PROJECT_NAME', 'OS_USER_DOMAIN_NAME', 'OS_PROJECT_DOMAIN_NAME']: + if key not in self.openrc: + self.log.error( + 'get_api_keystone_v3', + 'Required key missing: %s' % (key) + ) + return None + + keystone_handler = None + try: + auth = v3.Password( + auth_url=self.openrc['OS_AUTH_URL'], + username=self.openrc['OS_USERNAME'], + password=self.openrc['OS_PASSWORD'], + project_name=self.openrc['OS_PROJECT_NAME'], + user_domain_name=self.openrc['OS_USER_DOMAIN_NAME'], + project_domain_name=self.openrc['OS_PROJECT_DOMAIN_NAME'] + ) + # https://docs.openstack.org/python-keystoneclient/ocata/using-api-v3.html + # Note: The session.Session() method is deprecated + # and may be removed in future versions of Keystone. + if self.cert is None: + self.keystone_session = session.Session( + auth=auth, + verify=False, + timeout=self.api_timeout_seconds + ) + keystone_handler = client.Client( + session=self.keystone_session, + interface='public' + ) + + else: + self.keystone_session = session.Session( + auth=auth, + verify=self.cert_filename, + timeout=self.api_timeout_seconds + ) + + keystone_handler = client.Client( + session=self.keystone_session, + interface='public' + ) + + except ksexceptions.VersionNotAvailable: + self.log.error( + 'get_api_keystone_v3', + 'Suitable Keystone v3 client not found' + ) + self.log.error( + 'get_api_keystone_v3', + traceback.format_exc() + ) + return None + + except ksexceptions.DiscoveryFailure: + self.log.error( + 'get_api_keystone_v3', + 'Keystone v3 server response invalid' + ) + self.log.error( + 'get_api_keystone_v3', + traceback.format_exc() + ) + return None + + except ksexceptions.ClientException: + self.log.error( + 'get_api_keystone_v3', + 'Failed to initiate Keystone v3 client' + ) + self.log.error( + 'get_api_keystone_v3', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_keystone_v3', + 'Keystone v3 authentication failed' + ) + self.log.error( + 'get_api_keystone_v3', + traceback.format_exc() + ) + return None + + if keystone_handler is None: + self.log.error( + 'get_api_keystone_v3', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_keystone_v3', + 'Keystone v3 authentication successful (%s)' % (self.openrc['OS_AUTH_URL']) + ) + + self.api['keystone'] = keystone_handler + return self.api['keystone'] + + def get_api_keystone(self, cache_enabled=True): + if cache_enabled: + if 'keystone' in self.api: + if self.api['keystone'] is not None: + return self.api['keystone'] + + if self.api_version == 2: + return self.get_api_keystone_v2() + + if self.api_version == 3: + return self.get_api_keystone_v3() + + return None + + def get_api_cinder_v2(self): + for key in ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME']: + if key not in self.openrc: + self.log.error( + 'get_api_cinder_v2', + 'Required key missing: %s' % (key) + ) + return None + + cinder_handler = None + try: + cinder_handler = cinderclient.Client( + self.openrc['OS_USERNAME'], + self.openrc['OS_PASSWORD'], + self.openrc['OS_TENANT_NAME'], + self.openrc['OS_AUTH_URL'], + service_type='volume' + ) + + except cinceptions.UnsupportedVersion: + self.log.error( + 'get_api_cinder_v2', + 'Invalid Cinder version' + ) + self.log.error( + 'get_api_cinder_v2', + traceback.format_exc() + ) + return None + + except cinceptions.ClientException: + self.log.error( + 'get_api_cinder_v2', + 'Authentication failed' + ) + self.log.error( + 'get_api_cinder_v2', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_cinder_v2', + 'General failure' + ) + self.log.error( + 'get_api_cinder_v2', + traceback.format_exc() + ) + return None + + if cinder_handler is None: + self.log.error( + 'get_api_cinder_v2', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_cinder_v2', + 'Cinder authentication successful' + ) + + self.api['cinder'] = cinder_handler + return self.api['cinder'] + + def get_api_cinder_v3(self, cache_enabled=True): + cinder_handler = None + keystone_session = self.get_api_keystone_session(cache_enabled=cache_enabled) + if keystone_session is None: + return None + + try: + cinder_handler = cinderclient.Client( + service_type='volumev2', + session=keystone_session + ) + + except cinceptions.UnsupportedVersion: + self.log.error( + 'get_api_cinder_v3', + 'Invalid Cinder version' + ) + self.log.error( + 'get_api_cinder_v3', + traceback.format_exc() + ) + return None + + except cinceptions.ClientException: + self.log.error( + 'get_api_cinder_v3', + 'Authentication failed' + ) + self.log.error( + 'get_api_cinder_v3', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_cinder_v3', + 'General failure' + ) + self.log.error( + 'get_api_cinder_v3', + traceback.format_exc() + ) + return None + + if cinder_handler is None: + self.log.error( + 'get_api_cinder_v3', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_cinder_v3', + 'Cinder authentication successful' + ) + + self.api['cinder'] = cinder_handler + return self.api['cinder'] + + def get_api_cinder(self, cache_enabled=True): + if cache_enabled: + if 'cinder' in self.api: + if self.api['cinder'] is not None: + return self.api['cinder'] + + if 'OS_VOLUME_API_VERSION' in self.openrc: + if self.openrc['OS_VOLUME_API_VERSION'] == '2': + return self.get_api_cinder_v2() + + if self.openrc['OS_VOLUME_API_VERSION'] == '3': + return self.get_api_cinder_v3(cache_enabled=cache_enabled) + + if 'OS_VOLUME_API_VERSION' not in self.openrc: + if self.api_version == 2: + return self.get_api_cinder_v2() + + if self.api_version == 3: + return self.get_api_cinder_v3(cache_enabled=cache_enabled) + + self.log.error( + 'get_api_cinder', + 'Unsupported cinder api version: %s' % (self.api_version) + ) + return None + + def get_api_glance_v2(self, cache_enabled=True): + keystone_handler = self.get_api_keystone() + if keystone_handler is None: + return None + + keystone_session = self.get_api_keystone_session(cache_enabled=cache_enabled) + if keystone_session is None: + return None + + glance_handler = None + try: + glance_handler = glclient.Client( + session=self.keystone_session + ) + except BaseException: + glance_handler = None + + try: + if glance_handler is None: + for service in keystone_handler.services.list(): + if service.name == 'glance': + glance_endpoint = service.links['self'] + glance_id = service.id + + for endpoint in keystone_handler.endpoints.list(): + if endpoint.service_id == glance_id and endpoint.interface == 'public': + glance_endpoint = endpoint.url + + glance_handler = glclient.Client( + endpoint=glance_endpoint, + session=keystone_session + ) + + except ksexceptions.EmptyCatalog: + self.log.error( + 'get_api_glance_v2', + 'Keystone service catalog empty. Cannot fetch Glance endpoint.' + ) + self.log.error( + 'get_api_glance_v2', + traceback.format_exc() + ) + return None + + except RuntimeError: + self.log.error( + 'get_api_glance_v2', + 'Glance authentication failed with runtime error.' + ) + self.log.error( + 'get_api_glance_v2', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_glance_v2', + 'Glance authentication failed.' + ) + self.log.error( + 'get_api_glance_v2', + traceback.format_exc() + ) + return None + + if glance_handler is None: + self.log.error( + 'get_api_glance_v2', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_glance_v2', + 'Glance authentication successful.' + ) + + self.api['glance'] = glance_handler + return self.api['glance'] + + def get_api_glance_v3(self, cache_enabled=True): + keystone_handler = self.get_api_keystone() + if keystone_handler is None: + return None + + keystone_session = self.get_api_keystone_session(cache_enabled=cache_enabled) + if keystone_session is None: + return None + + try: + for service in keystone_handler.services.list(): + if service.name == 'glance': + glance_endpoint = service.links['self'] + glance_id = service.id + + for endpoint in keystone_handler.endpoints.list(): + if endpoint.service_id == glance_id and endpoint.interface == 'public': + glance_endpoint = endpoint.url + + glance_handler = glclient.Client( + endpoint=glance_endpoint, + session=keystone_session + ) + + except ksexceptions.EmptyCatalog: + self.log.error( + 'get_api_glance_v3', + 'Keystone service catalog empty. Cannot fetch Glance endpoint.' + ) + self.log.error( + 'get_api_glance_v3', + traceback.format_exc() + ) + return None + + except RuntimeError: + self.log.error( + 'get_api_glance_v3', + 'Glance authentication failed with runtime error.' + ) + self.log.error( + 'get_api_glance_v3', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_glance_v3', + 'Glance authentication failed.' + ) + self.log.error( + 'get_api_glance_v3', + traceback.format_exc() + ) + return None + + if glance_handler is None: + self.log.error( + 'get_api_glance_v3', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_glance_v3', + 'Glance authentication successful.' + ) + + self.api['glance'] = glance_handler + return self.api['glance'] + + def get_api_glance(self, cache_enabled=True): + if cache_enabled: + if 'glance' in self.api: + if self.api['glance'] is not None: + return self.api['glance'] + + if 'OS_IMAGE_API_VERSION' in self.openrc: + if self.openrc['OS_IMAGE_API_VERSION'] == '2': + return self.get_api_glance_v2(cache_enabled=cache_enabled) + + if self.openrc['OS_IMAGE_API_VERSION'] == '3': + return self.get_api_glance_v3(cache_enabled=cache_enabled) + + if 'OS_IMAGE_API_VERSION' not in self.openrc: + if self.api_version == 2: + return self.get_api_glance_v2(cache_enabled=cache_enabled) + + if self.api_version == 3: + return self.get_api_glance_v3(cache_enabled=cache_enabled) + + self.log.error( + 'get_api_glance', + 'Unsupported glance api version: %s' % (self.api_version) + ) + return None + + def get_api_neutron_v2(self): + neutron_handler = None + try: + neutron_handler = neutronclient.Client( + auth_url=self.openrc['OS_AUTH_URL'], + username=self.openrc['OS_USERNAME'], + password=self.openrc['OS_PASSWORD'], + tenant_name=self.openrc['OS_TENANT_NAME'] + ) + + except neuceptions.NeutronClientException: + self.log.error( + 'get_api_neutron_v2', + 'Neutron authentication failed' + ) + self.log.error( + 'get_api_neutron_v2', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_neutron_v2', + 'Neutron authentication failed' + ) + self.log.error( + 'get_api_neutron_v2', + traceback.format_exc() + ) + return None + + if neutron_handler is None: + self.log.error( + 'get_api_neutron_v2', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_neutron_v2', + 'Neutron authentication successful.' + ) + + self.api['neutron'] = neutron_handler + return self.api['neutron'] + + def get_api_neutron_v3(self, cache_enabled=True): + neutron_handler = None + keystone_session = self.get_api_keystone_session(cache_enabled=cache_enabled) + if keystone_session is None: + return None + + try: + neutron_handler = neutronclient.Client( + session=keystone_session + ) + + except cinceptions.UnsupportedVersion: + self.log.error( + 'get_api_neutron_v3', + 'Invalid Cinder version' + ) + self.log.error( + 'get_api_neutron_v3', + traceback.format_exc() + ) + return None + + except cinceptions.ClientException: + self.log.error( + 'get_api_neutron_v3', + 'Authentication failed' + ) + self.log.error( + 'get_api_neutron_v3', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_neutron_v3', + 'General failure' + ) + self.log.error( + 'get_api_neutron_v3', + traceback.format_exc() + ) + return None + + if neutron_handler is None: + self.log.error( + 'get_api_neutron_v3', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_neutron_v3', + 'Neutron authentication successful.' + ) + + self.api['neutron'] = neutron_handler + return self.api['neutron'] + + def get_api_neutron(self, cache_enabled=True): + if cache_enabled: + if 'neutron' in self.api: + if self.api['neutron'] is not None: + return self.api['neutron'] + + if self.api_version == 2: + return self.get_api_neutron_v2() + + if self.api_version == 3: + return self.get_api_neutron_v3(cache_enabled=cache_enabled) + + self.log.error( + 'get_api_neutron', + 'Unsupported neutron api version: %s' % (self.api_version) + ) + return None + + def get_api_nova_v2(self): + for key in ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME', 'OS_REGION_NAME']: + if key not in self.openrc: + self.log.error( + 'get_api_nova_v2', + 'Required key missing: %s' % (key) + ) + return None + + nova_handler = None + try: + nova_handler = nvclient.Client( + auth_url=self.openrc['OS_AUTH_URL'], + username=self.openrc['OS_USERNAME'], + password=self.openrc['OS_PASSWORD'], + tenant_name=self.openrc['OS_TENANT_NAME'], + region_name=self.openrc['OS_REGION_NAME'], + version=2 + ) + except nexceptions.ClientException: + self.log.error( + 'get_api_nova_v2', + 'Nova authentication failed' + ) + self.log.error( + 'get_api_nova_v3', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_nova_v2', + 'Nova authentication failed' + ) + self.log.error( + 'get_api_nova_v2', + traceback.format_exc() + ) + return None + + if nova_handler is None: + self.log.error( + 'get_api_nova_v2', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_nova_v2', + 'Nova authentication successful.' + ) + + self.api['nova'] = nova_handler + return self.api['nova'] + + def get_api_nova_v3(self): + for key in ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_PROJECT_NAME', 'OS_REGION_NAME', 'OS_USER_DOMAIN_NAME', 'OS_PROJECT_DOMAIN_NAME']: + if key not in self.openrc: + self.log.error( + 'get_api_nova_v2', + 'Required key missing: %s' % (key) + ) + return None + + nova_handler = None + try: + if self.cert_filename is not None: + nova_handler = nvclient.Client( + auth_url=self.openrc['OS_AUTH_URL'], + username=self.openrc['OS_USERNAME'], + password=self.openrc['OS_PASSWORD'], + project_name=self.openrc['OS_PROJECT_NAME'], + region_name=self.openrc['OS_REGION_NAME'], + user_domain_name=self.openrc['OS_USER_DOMAIN_NAME'], + project_domain_name=self.openrc['OS_PROJECT_DOMAIN_NAME'], + cacert=self.cert_filename, + version=2 + ) + else: + nova_handler = nvclient.Client( + auth_url=self.openrc['OS_AUTH_URL'], + username=self.openrc['OS_USERNAME'], + password=self.openrc['OS_PASSWORD'], + project_name=self.openrc['OS_PROJECT_NAME'], + region_name=self.openrc['OS_REGION_NAME'], + user_domain_name=self.openrc['OS_USER_DOMAIN_NAME'], + project_domain_name=self.openrc['OS_PROJECT_DOMAIN_NAME'], + insecure=True, + version=2 + ) + + except nexceptions.ClientException: + self.log.error( + 'get_api_nova_v3', + 'Nova authentication failed' + ) + self.log.error( + 'get_api_nova_v3', + traceback.format_exc() + ) + return None + + except BaseException: + self.log.error( + 'get_api_nova_v3', + 'Nova authentication failed' + ) + self.log.error( + 'get_api_nova_v3', + traceback.format_exc() + ) + return None + + if nova_handler is None: + self.log.error( + 'get_api_nova_v3', + 'Unsuccessful' + ) + return None + + self.log.debug( + 'get_api_nova_v3', + 'Nova authentication successful.' + ) + + self.api['nova'] = nova_handler + return self.api['nova'] + + def get_api_nova(self, cache_enabled=True): + if cache_enabled: + if 'nova' in self.api: + if self.api['nova'] is not None: + return self.api['nova'] + + if 'OS_COMPUTE_API_VERSION' in self.openrc: + if self.openrc['OS_COMPUTE_API_VERSION'].startswith('1'): + return self.get_api_nova_v2() + + if self.openrc['OS_COMPUTE_API_VERSION'].startswith('2'): + return self.get_api_nova_v3() + + if 'OS_COMPUTE_API_VERSION' not in self.openrc: + if self.api_version == 2: + return self.get_api_nova_v2() + + if self.api_version == 3: + return self.get_api_nova_v3() + + self.log.error( + 'get_api_nova', + 'Unsupported nova api version: %s' % (self.api_version) + ) + return None diff --git a/lib/osp/availability_zone/README.md b/lib/osp/availability_zone/README.md new file mode 100644 index 00000000..8762c6a4 --- /dev/null +++ b/lib/osp/availability_zone/README.md @@ -0,0 +1 @@ +create/delete \ No newline at end of file diff --git a/lib/osp/availability_zone/__init__.py b/lib/osp/availability_zone/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/availability_zone/api.py b/lib/osp/availability_zone/api.py new file mode 100644 index 00000000..ba33eca7 --- /dev/null +++ b/lib/osp/availability_zone/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspAvailabilityZoneApi(): + def __init__(self): + self.availability_zone_mo = None + + def get_availability_zone_mo(self, cache_enabled=True): + if cache_enabled: + if self.availability_zone_mo is not None: + return self.availability_zone_mo + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_availability_zone_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.availability_zone_mo = api_handler.availability_zones.list() + self.log.osp( + 'get', + 'availability_zones', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_availability_zone_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'availability_zones', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.availability_zone_mo diff --git a/lib/osp/availability_zone/info.py b/lib/osp/availability_zone/info.py new file mode 100644 index 00000000..a0344f50 --- /dev/null +++ b/lib/osp/availability_zone/info.py @@ -0,0 +1,185 @@ +from lib import filter_helper + + +class OspAvailabilityZoneInfo(): + def __init__(self): + self.availability_zone = None + + def get_availability_zones_properties(self, managed_objects): + properties = [] + for managed_object in managed_objects: + properties.append( + managed_object.to_dict() + ) + return properties + + def get_availability_zone_info(self, availability_zone_mo): + if availability_zone_mo is None: + return None + + properties = availability_zone_mo.to_dict() + + info = {} + info['__Output'] = {} + info['name'] = properties['zoneName'] + info['available'] = properties['zoneState']['available'] + if info['available']: + info['availableTick'] = '\u2713' + info['__Output']['availableTick'] = 'Green' + else: + info['availableTick'] = '\u2717' + info['__Output']['availableTick'] = 'Red' + + info['host'] = [] + for host_name in properties['hosts']: + host_info = {} + host_info['name'] = host_name + host_info['service'] = [] + service_names = [] + service_namesT = [] + for service_name in properties['hosts'][host_name]: + service_info = {} + service_info['__Output'] = {} + service_info['name'] = service_name + service_names.append( + service_name + ) + service_info['available'] = properties['hosts'][host_name][service_name]['available'] + if service_info['available']: + service_info['availableTick'] = '\u2713' + service_info['__Output']['availableTick'] = 'Green' + else: + service_info['availableTick'] = '\u2717' + service_info['__Output']['availableTick'] = 'Red' + + service_info['active'] = properties['hosts'][host_name][service_name]['active'] + if service_info['active']: + service_info['activeTick'] = '\u2713' + service_info['__Output']['activeTick'] = 'Green' + service_namesT.append( + '%s [\u2713]' % (service_name) + ) + else: + service_info['activeTick'] = '\u2717' + service_info['__Output']['activeTick'] = 'Red' + service_namesT.append( + '%s [\u2717]' % (service_name) + ) + + service_info['updated_at'] = properties['hosts'][host_name][service_name]['updated_at'] + service_info['updated_age'] = self.convert_timestamp_to_age( + service_info['updated_at'], + on_error='--' + ) + + host_info['service'].append( + service_info + ) + + host_info['service_names'] = ', '.join(service_names) + host_info['service_namesT'] = ', '.join(service_namesT) + info['host'].append( + host_info + ) + + info['host'] = sorted( + info['host'], + key=lambda i: i['name'] + ) + + return info + + def get_availability_zones_info(self, cache_enabled=True): + if cache_enabled: + if self.availability_zone is not None: + return self.availability_zone + + managed_objects = self.get_availability_zone_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'availability_zones', + self.get_availability_zones_properties(managed_objects) + ) + + self.availability_zone = [] + for managed_object in managed_objects: + availability_zone_info = self.get_availability_zone_info( + managed_object + ) + self.availability_zone.append( + availability_zone_info + ) + + self.log.osp_mo( + 'availability_zones.info', + self.availability_zone + ) + + return self.availability_zone + + def match_availability_zone(self, availability_zone_info, availability_zone_filter): + if availability_zone_filter is None or len(availability_zone_filter) == 0: + return True + + for ap_rule in availability_zone_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, availability_zone_info['name']): + return False + + if key == 'hv': + key_found = True + found = False + for host_info in availability_zone_info['host']: + if filter_helper.match_string(value, host_info['name']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_availability_zone', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_availability_zones(self, object_filter=None, hv_info=False, cache_enabled=True): + all_availability_zones = self.get_availability_zones_info(cache_enabled=cache_enabled) + if all_availability_zones is None: + return None + + availability_zones = [] + + for availability_zone_info in all_availability_zones: + if not self.match_availability_zone(availability_zone_info, object_filter): + continue + + if hv_info: + for host in availability_zone_info['host']: + hypervisor_info = self.get_hypervisor(host['name']) + if hypervisor_info is not None: + host['running_vms'] = hypervisor_info['running_vms'] + host['cpu_summary'] = hypervisor_info['cpu_summary'] + host['memory_summary'] = hypervisor_info['memory_summary'] + host['disk_summary'] = hypervisor_info['disk_summary'] + + availability_zones.append( + availability_zone_info + ) + + availability_zones = sorted( + availability_zones, + key=lambda i: i['name'] + ) + + return availability_zones diff --git a/lib/osp/availability_zone/main.py b/lib/osp/availability_zone/main.py new file mode 100644 index 00000000..e323602e --- /dev/null +++ b/lib/osp/availability_zone/main.py @@ -0,0 +1,11 @@ +from lib.osp.availability_zone.api import OspAvailabilityZoneApi +from lib.osp.availability_zone.info import OspAvailabilityZoneInfo + + +class OspAvailabilityZone( + OspAvailabilityZoneApi, + OspAvailabilityZoneInfo + ): + def __init__(self): + OspAvailabilityZoneApi.__init__(self) + OspAvailabilityZoneInfo.__init__(self) diff --git a/lib/osp/availability_zone/output.py b/lib/osp/availability_zone/output.py new file mode 100644 index 00000000..4bb1a616 --- /dev/null +++ b/lib/osp/availability_zone/output.py @@ -0,0 +1,89 @@ +class OspAvailabilityZoneOutput(): + def __init__(self): + pass + + def print_availability_zones(self, info, title=False): + if title: + self.my_output.default( + 'Availability Zone [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'availableTick', + 'host.name', + 'host.service_namesT' + ] + + headers = [ + 'AZ', + 'Avail', + 'Hypervisor', + 'Service Name [Active]' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['host'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_availability_zones_hv(self, info, title=False): + if title: + self.my_output.default( + 'Availability Zone - Hypervisor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'availableTick', + 'host.name', + 'host.running_vms', + 'host.cpu_summary', + 'host.memory_summary', + 'host.disk_summary' + ] + + headers = [ + 'AZ', + 'Avail', + 'Hypervisor', + 'VMs', + 'CPU', + 'Memory', + 'Disk' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['host'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/osp/common.py b/lib/osp/common.py new file mode 100644 index 00000000..66cd35ba --- /dev/null +++ b/lib/osp/common.py @@ -0,0 +1,81 @@ +import time +import datetime + + +class OspCommon(): + def __init__(self): + pass + + def convert_age(self, seconds): + if seconds > 60 * 60 * 24: + return '%sd' % (int(seconds / (60 * 60 * 24))) + + if seconds > 60 * 60: + hours = 0 + while True: + if seconds < 60 * 60: + break + + hours = hours + 1 + seconds = seconds - 60 * 60 + + return '%sh%sm' % ( + hours, + int(seconds / 60) + ) + + if seconds > 60: + return '%sm' % (int(seconds / 60)) + + return '%ss' % (seconds) + + def convert_timestamp(self, timestamp): + if timestamp is None: + return None + + new_timestamp = None + if isinstance(timestamp, str): + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S%z').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp.rstrip('Z'), '%Y-%m-%dT%H:%M:%S').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f').timetuple())) + except BaseException: + pass + + return new_timestamp + + try: + new_timestamp = int(timestamp.timestamp()) + except BaseException: + pass + + return new_timestamp + + def convert_timestamp_to_age(self, timestamp, on_error=None): + timestamp = self.convert_timestamp(timestamp) + if timestamp is None: + return on_error + + return self.convert_age(int(time.time()) - timestamp) + + def format_value_dotted(self, value): + if isinstance(value, str): + value = int(value) + + return format(value, ",") diff --git a/lib/osp/flavor/README.md b/lib/osp/flavor/README.md new file mode 100644 index 00000000..4b852667 --- /dev/null +++ b/lib/osp/flavor/README.md @@ -0,0 +1,2 @@ +search by key +create/delete flavor incl. keys add/delete \ No newline at end of file diff --git a/lib/osp/flavor/__init__.py b/lib/osp/flavor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/flavor/api.py b/lib/osp/flavor/api.py new file mode 100644 index 00000000..59a8f95e --- /dev/null +++ b/lib/osp/flavor/api.py @@ -0,0 +1,144 @@ +import time +import traceback + + +class OspFlavorApi(): + def __init__(self): + self.flavor_mo = None + self.flavor_keys_mo = None + + def get_flavor_mo(self, cache_enabled=True): + if cache_enabled: + if self.flavor_mo is not None: + return self.flavor_mo + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_flavor_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.flavor_mo = api_handler.flavors.list() + self.log.osp( + 'get', + 'flavors', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_flavor_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'flavors', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.flavor_mo + + def get_flavor_keys_mo(self, cache_enabled=True): + if cache_enabled: + if self.flavor_keys_mo is not None: + return self.flavor_keys_mo + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_flavor_keys_mo', + 'No api handler' + ) + return None + + try: + flavors_mo = self.get_flavor_mo(cache_enabled=cache_enabled) + if flavors_mo is None: + return None + + start_time = int(time.time() * 1000) + + self.flavor_keys_mo = {} + for flavor_mo in flavors_mo: + self.flavor_keys_mo[flavor_mo.id] = flavor_mo.get_keys() + + self.log.osp( + 'get', + 'flavors_keys', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_flavor_keys_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'flavors_keys', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.flavor_keys_mo + + def create_flavor_mo(self, name, ram, vcpus, disk, uuid='auto'): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_flavor', + 'No api handler' + ) + return None + + try: + ret = api_handler.flavors.create( + name, + ram, + vcpus, + disk, + uuid + ) + new_flavor_id = ret.id + except BaseException: + self.log.error( + 'create_flavor', + 'API failed' + ) + self.log.error( + 'create_flavor', + traceback.format_exc() + ) + return None + + return new_flavor_id + + def delete_flavor_mo(self, flavor_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_flavor', + 'No api handler' + ) + return None + + try: + api_handler.flavors.delete( + flavor_id + ) + + except BaseException: + self.log.error( + 'create_flavor', + 'API failed' + ) + self.log.error( + 'create_flavor', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/flavor/info.py b/lib/osp/flavor/info.py new file mode 100644 index 00000000..f8426e19 --- /dev/null +++ b/lib/osp/flavor/info.py @@ -0,0 +1,288 @@ +from lib import filter_helper + + +class OspFlavorInfo(): + def __init__(self): + self.flavor = None + self.flavor_keys = None + + def get_flavors_properties(self, managed_objects): + properties = [] + for managed_object in managed_objects: + properties.append( + managed_object.to_dict() + ) + return properties + + def get_flavor_info(self, flavor_mo): + if flavor_mo is None: + return None + + properties = flavor_mo.to_dict() + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'vcpus', + 'ram', + 'disk', + 'rxtx_factor' + ] + for key in keys: + info[key] = properties[key] + + info['resource'] = 'C:%s M:%s D:%s' % ( + info['vcpus'], + info['ram'], + info['disk'] + ) + + info['public'] = properties['os-flavor-access:is_public'] + if info['public']: + info['publicTick'] = '\u2713' + info['__Output']['publicTick'] = 'Green' + else: + info['publicTick'] = '\u2717' + info['__Output']['publicTick'] = 'Red' + + info['enabled'] = not properties['OS-FLV-DISABLED:disabled'] + if info['enabled']: + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + else: + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + + info['ephemeral'] = properties['OS-FLV-EXT-DATA:ephemeral'] + return info + + def get_flavors_info(self, cache_enabled=True): + if cache_enabled: + if self.flavor is not None: + return self.flavor + + managed_objects = self.get_flavor_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'flavors', + self.get_flavors_properties(managed_objects) + ) + + self.flavor = [] + for managed_object in managed_objects: + flavor_info = self.get_flavor_info( + managed_object + ) + self.flavor.append( + flavor_info + ) + + self.log.osp_mo( + 'flavors.info', + self.flavor + ) + + return self.flavor + + def get_flavor_keys_info(self, flavor_keys_mo): + info = {} + for key in flavor_keys_mo: + info[key] = flavor_keys_mo[key] + return info + + def get_flavors_keys_info(self, cache_enabled=True): + if cache_enabled: + if self.flavor_keys is not None: + return self.flavor_keys + + flavor_keys_mo = self.get_flavor_keys_mo(cache_enabled=cache_enabled) + if flavor_keys_mo is None: + return None + + self.flavor_keys = {} + for flavor_id in flavor_keys_mo: + self.flavor_keys[flavor_id] = self.get_flavor_keys_info(flavor_keys_mo[flavor_id]) + + self.log.osp_mo( + 'flavors_keys.info', + self.flavor_keys + ) + + return self.flavor_keys + + def get_flavor_keys(self, flavor_id, cache_enabled=True): + flavors_keys = self.get_flavors_keys_info(cache_enabled=cache_enabled) + if flavors_keys is None: + return None + + if flavor_id not in flavors_keys: + return None + + return flavors_keys[flavor_id] + + def match_flavor(self, flavor_info, flavor_filter): + if flavor_filter is None or len(flavor_filter) == 0: + return True + + key_filter = None + value_filter = None + for ap_rule in flavor_filter: + key = ap_rule.split(':')[0] + if key == 'key': + key_filter = ':'.join(ap_rule.split(':')[1:]) + if key == 'value': + value_filter = ':'.join(ap_rule.split(':')[1:]) + + for ap_rule in flavor_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, flavor_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, flavor_info['name']): + return False + + if key == 'vm': + key_found = True + if 'vm' in flavor_info: + found = False + for vm_info in flavor_info['vm']: + if filter_helper.match_tenant_name(value, vm_info['tenant_name']): + found = True + break + + if not found: + return False + + if key == 'value': + key_found = True + if key_filter is None and 'keys' in flavor_info: + found = False + for key in flavor_info['keys']: + if filter_helper.match_string(value, flavor_info['keys'][key]): + found = True + break + + if not found: + return False + + if key == 'key': + key_found = True + if 'keys' in flavor_info: + found = False + for key in flavor_info['keys']: + if filter_helper.match_string(value, key): + if value_filter is None: + found = True + break + + if value_filter is not None: + if filter_helper.match_string(value_filter, flavor_info['keys'][key]): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_flavor', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_flavors(self, object_filter=None, keys_info=False, vm_info=False, cache_enabled=True): + all_flavors = self.get_flavors_info(cache_enabled=cache_enabled) + if all_flavors is None: + return None + + flavors = [] + + for flavor_info in all_flavors: + if not self.match_flavor(flavor_info, object_filter): + continue + + if keys_info: + flavor_info['keys'] = self.get_flavor_keys(flavor_info['id'], cache_enabled=cache_enabled) + if not self.match_flavor(flavor_info, object_filter): + continue + + if vm_info: + flavor_info['vm'] = [] + flavor_vms = self.get_virtual_machines( + object_filter=[ + 'flavor_id:%s' % (flavor_info['id']) + ], + tenant_info=True + ) + if flavor_vms is None: + self.log.error( + 'get_flavors', + 'Get vm with flavors failed: %s' % (flavor_info['id']) + ) + else: + for flavor_vm in flavor_vms: + flavor_vm_info = {} + flavor_vm_info['tenant'] = flavor_vm['tenant_name'] + flavor_vm_info['name'] = flavor_vm['name'] + flavor_vm_info['tenant_name'] = '%s/%s' % ( + flavor_vm['tenant_name'], + flavor_vm['name'] + ) + flavor_info['vm'].append( + flavor_vm_info + ) + + if not self.match_flavor(flavor_info, object_filter): + continue + + flavors.append( + flavor_info + ) + + flavors = sorted( + flavors, + key=lambda i: i['name'].lower() + ) + + return flavors + + def get_flavor(self, flavor_id=None, flavor_name=None, keys_info=False, vm_info=False, cache_enabled=True): + object_filter = [] + if flavor_id is not None: + object_filter.append( + 'id:%s' % (flavor_id) + ) + if flavor_name is not None: + object_filter.append( + 'name:%s' % (flavor_name) + ) + + flavors = self.get_flavors( + object_filter=object_filter, + keys_info=keys_info, + vm_info=vm_info, + cache_enabled=cache_enabled + ) + if flavors is None or len(flavors) != 1: + return None + + return flavors[0] + + def is_flavor(self, flavor_id=None, flavor_name=None, cache_enabled=True): + if self.get_flavor(flavor_id=flavor_id, flavor_name=flavor_name) is None: + return False + return True diff --git a/lib/osp/flavor/main.py b/lib/osp/flavor/main.py new file mode 100644 index 00000000..d93e1b2d --- /dev/null +++ b/lib/osp/flavor/main.py @@ -0,0 +1,11 @@ +from lib.osp.flavor.api import OspFlavorApi +from lib.osp.flavor.info import OspFlavorInfo + + +class OspFlavor( + OspFlavorApi, + OspFlavorInfo + ): + def __init__(self): + OspFlavorApi.__init__(self) + OspFlavorInfo.__init__(self) diff --git a/lib/osp/flavor/output.py b/lib/osp/flavor/output.py new file mode 100644 index 00000000..67875c40 --- /dev/null +++ b/lib/osp/flavor/output.py @@ -0,0 +1,201 @@ +import copy + + +class OspFlavorOutput(): + def __init__(self): + pass + + def print_flavors(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Flavor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'name', + 'enabledTick', + 'publicTick', + 'vcpus', + 'ram', + 'disk', + 'ephemeral' + ] + + headers = headers + [ + 'Name', + 'Enabled', + 'Pub', + 'CPU', + 'Mem [MB]', + 'Disk [GB]', + 'Eph [GB]' + ] + + if 'keys' in info[0]: + order.append('keysT') + headers.append('Keys') + + for item in info: + item['keysT'] = [] + for key in item['keys']: + item['keysT'].append( + '%s = %s' % ( + key, + item['keys'][key] + ) + ) + if len(item['keysT']) == 0: + item['keysT'].append('--') + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['keysT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + else: + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_flavors_id(self, info, title=False): + if title: + self.my_output.default( + 'Flavor - Identifiers [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'name' + ] + + headers = [ + 'Id', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_flavors_vm(self, info, title=False): + if title: + self.my_output.default( + 'Flavor - Virtual Machine Usage [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'vcpus', + 'ram', + 'disk', + 'ephemeral', + 'vm.tenant_name' + ] + + headers = [ + 'Name', + 'CPU', + 'Mem [MB]', + 'Disk [GB]', + 'Eph [GB]', + 'VM' + ] + + for item in info: + if len(item['vm']) == 0: + item['vm'].append(dict(tenant_name='--')) + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vm'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def select_flavor(self, info): + self.my_output.default( + 'Select Flavor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No flavor found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_flavors(new_info, title=False, select=True) + + while True: + answer = input("Select flavor using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/floating_ip/README.md b/lib/osp/floating_ip/README.md new file mode 100644 index 00000000..c964a25a --- /dev/null +++ b/lib/osp/floating_ip/README.md @@ -0,0 +1,2 @@ +create/delete +assoc/disassoc \ No newline at end of file diff --git a/lib/osp/floating_ip/__init__.py b/lib/osp/floating_ip/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/floating_ip/api.py b/lib/osp/floating_ip/api.py new file mode 100644 index 00000000..cdddd784 --- /dev/null +++ b/lib/osp/floating_ip/api.py @@ -0,0 +1,112 @@ +import time +import json +import traceback + + +class OspFloatingIpApi(): + def __init__(self): + self.floating_ip_mo = None + + def get_floating_ip_mo(self, cache_enabled=True): + if cache_enabled: + if self.floating_ip_mo is not None: + return self.floating_ip_mo + + api_handler = self.get_api_neutron(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_floating_ip_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.floating_ip_mo = api_handler.list_floatingips()['floatingips'] + self.log.osp( + 'get', + 'floating_ips', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_floating_ip_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'floating_ips', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.floating_ip_mo + + def create_floating_ip_mo(self, tenant_id, port_id, floating_network_id, floating_subnet_id, floating_ip_address=None): + try: + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_floating_ip_mo', + 'No api handler' + ) + return None + + body = {} + body['floatingip'] = {} + body['floatingip']['tenant_id'] = tenant_id + body['floatingip']['port_id'] = port_id + body['floatingip']['floating_network_id'] = floating_network_id + body['floatingip']['subnet_id'] = floating_subnet_id + if floating_ip_address is not None: + body['floatingip']['floating_ip_address'] = floating_ip_address + + self.log.debug( + 'create_floating_ip_mo', + 'Create floating IP: %s' % (json.dumps(body, indent=4)) + ) + ret = api_handler.create_floatingip(body=body) + floating_ip_id = ret['floatingip']['id'] + + except BaseException: + self.log.error( + 'create_floating_ip_mo', + 'Neutron API exception' + ) + self.log.error( + 'create_floating_ip_mo', + traceback.format_exc() + ) + return None + + return floating_ip_id + + def delete_floating_ip_mo(self, floating_ip_id): + try: + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_floating_ip_mo', + 'No api handler' + ) + return False + + self.log.debug( + 'create_floating_ip_mo', + 'Delete floating IP: %s' % (floating_ip_id) + ) + + api_handler.delete_floatingip(floating_ip_id) + + except BaseException: + self.log.error( + 'delete_floating_ip_mo', + 'Neutron API exception' + ) + self.log.error( + 'delete_floating_ip_mo', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/floating_ip/info.py b/lib/osp/floating_ip/info.py new file mode 100644 index 00000000..e3f1c820 --- /dev/null +++ b/lib/osp/floating_ip/info.py @@ -0,0 +1,259 @@ +from lib import filter_helper +from lib import ip_helper + + +class OspFloatingIpInfo(): + def __init__(self): + self.floating_ip = None + + def get_floating_ip_info(self, floating_ip_mo): + if floating_ip_mo is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'tenant_id', + 'floating_ip_address', + 'floating_network_id', + 'router_id', + 'port_id', + 'fixed_ip_address', + 'status', + 'description', + 'port_details', + 'tags', + 'created_at', + 'updated_at', + 'revision_number', + 'project_id' + ] + for key in keys: + info[key] = floating_ip_mo[key] + + if info['status'] == 'ACTIVE': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + return info + + def get_floating_ips_info(self, cache_enabled=True): + if cache_enabled: + if self.floating_ip is not None: + return self.floating_ip + + managed_objects = self.get_floating_ip_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.floating_ip = [] + for managed_object in managed_objects: + floating_ip_info = self.get_floating_ip_info( + managed_object + ) + self.floating_ip.append( + floating_ip_info + ) + + self.log.osp_mo( + 'floating_ips', + self.floating_ip + ) + + return self.floating_ip + + def match_floating_ip(self, floating_ip_info, floating_ip_filter): + if floating_ip_filter is None or len(floating_ip_filter) == 0: + return True + + for ap_rule in floating_ip_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'floating-ip': + key_found = True + if ip_helper.is_valid_ipv4_cidr(value): + if not ip_helper.is_ipv4_in_cidr(floating_ip_info['floating_ip_address'], value): + return False + + if ip_helper.is_valid_ipv4_address(value): + if not filter_helper.match_string(floating_ip_info['floating_ip_address'], value): + return False + + if key == 'fixed-ip': + key_found = True + if ip_helper.is_valid_ipv4_cidr(value): + if not ip_helper.is_ipv4_in_cidr(floating_ip_info['fixed_ip_address'], value): + return False + + if ip_helper.is_valid_ipv4_address(value): + if not filter_helper.match_string(floating_ip_info['fixed_ip_address'], value): + return False + + if key == 'router': + key_found = True + if 'router_name' in floating_ip_info: + if not filter_helper.match_string(value, floating_ip_info['router_name']): + return False + + if key == 'floating-network': + key_found = True + if 'floating_network_name' in floating_ip_info: + if not filter_helper.match_string(value, floating_ip_info['floating_network_name']): + return False + + if key == 'tenant': + key_found = True + if 'tenant_name' in floating_ip_info: + if not filter_helper.match_string(value, floating_ip_info['tenant_name']): + return False + + if key == 'fixed-network': + key_found = True + if 'port_details' in floating_ip_info and floating_ip_info['port_details'] is not None: + if 'network_name' in floating_ip_info['port_details']: + if not filter_helper.match_string(value, floating_ip_info['port_details']['network_name']): + return False + + if key == 'vm': + key_found = True + if 'port_details' in floating_ip_info and floating_ip_info['port_details'] is not None: + if 'vm_name' in floating_ip_info['port_details']: + if not filter_helper.match_tenant_name(value, floating_ip_info['port_details']['vm_name']): + return False + + if key == 'mac': + key_found = True + if 'port_details' in floating_ip_info and floating_ip_info['port_details'] is not None: + if 'mac_address' in floating_ip_info['port_details']: + if not ip_helper.is_mac_match(value, floating_ip_info['port_details']['mac_address']): + return False + + if not key_found: + self.log.error( + 'match_floating_ip', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_floating_ips(self, object_filter=None, tenant_info=False, network_info=False, router_info=False, port_info=False, cache_enabled=True): + all_floating_ips = self.get_floating_ips_info(cache_enabled=cache_enabled) + if all_floating_ips is None: + return None + + floating_ips = [] + + for floating_ip_info in all_floating_ips: + if not self.match_floating_ip(floating_ip_info, object_filter): + continue + + if tenant_info: + floating_ip_info['tenant_name'] = self.get_tenant_name( + floating_ip_info['tenant_id'], + cache_enabled=cache_enabled + ) + if not self.match_floating_ip(floating_ip_info, object_filter): + continue + + if network_info: + floating_ip_info['floating_network_name'] = self.get_network_name( + floating_ip_info['floating_network_id'], + cache_enabled=cache_enabled + ) + if not self.match_floating_ip(floating_ip_info, object_filter): + continue + + if router_info: + floating_ip_info['router_name'] = self.get_router_name( + floating_ip_info['router_id'], + cache_enabled=cache_enabled + ) + if not self.match_floating_ip(floating_ip_info, object_filter): + continue + + if port_info: + if 'port_details' in floating_ip_info and floating_ip_info['port_details'] is not None: + floating_ip_info['port_details']['network_name'] = self.get_network_name( + floating_ip_info['port_details']['network_id'], + cache_enabled=cache_enabled + ) + + floating_ip_info['port_details']['vm_name'] = self.get_virtual_machine_tenant_name( + floating_ip_info['port_details']['device_id'], + cache_enabled=cache_enabled + ) + + if not self.match_floating_ip(floating_ip_info, object_filter): + continue + + floating_ips.append( + floating_ip_info + ) + + floating_ips = sorted( + floating_ips, + key=lambda i: i['floating_ip_address'] + ) + + return floating_ips + + def get_floating_ip(self, floating_id=None, floating_ip=None, fixed_ip=None, tenant_info=False, network_info=False, router_info=False, port_info=False, cache_enabled=True): + object_filter = [] + + if floating_id is not None: + object_filter.append('id:%s' % (floating_id)) + + if floating_ip is not None: + object_filter.append('floating-ip:%s' % (floating_ip)) + + if fixed_ip is not None: + object_filter.append('fixed-ip:%s' % (fixed_ip)) + + floating_ips = self.get_floating_ips( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + router_info=router_info, + port_info=port_info, + cache_enabled=cache_enabled + ) + if floating_ips is None or len(floating_ips) != 1: + return None + + return floating_ips[0] + + def is_floating_ip(self, floating_ip, cache_enabled=True): + if self.get_floating_ip(floating_ip=floating_ip, cache_enabled=cache_enabled) is None: + return False + return True + + def get_floating_ip_port(self, floating_id=None, floating_ip=None, fixed_ip=None, cache_enabled=True): + floating_ip_info = self.get_floating_ip( + floating_id=floating_id, + floating_ip=floating_ip, + fixed_ip=fixed_ip, + port_info=True, + cache_enabled=cache_enabled + ) + if floating_ip_info is None: + return None + + return floating_ip_info['port_details'] + + def get_floating_ip_virtual_machine_name(self, floating_id=None, floating_ip=None, fixed_ip=None, cache_enabled=True): + floating_ip_port_details = self.get_floating_ip_port_details( + floating_id=floating_id, + floating_ip=floating_ip, + fixed_ip=fixed_ip, + cache_enabled=cache_enabled + ) + if floating_ip_port_details is None: + return None + + return floating_ip_port_details['vm_name'] diff --git a/lib/osp/floating_ip/main.py b/lib/osp/floating_ip/main.py new file mode 100644 index 00000000..4496ce76 --- /dev/null +++ b/lib/osp/floating_ip/main.py @@ -0,0 +1,11 @@ +from lib.osp.floating_ip.api import OspFloatingIpApi +from lib.osp.floating_ip.info import OspFloatingIpInfo + + +class OspFloatingIp( + OspFloatingIpApi, + OspFloatingIpInfo + ): + def __init__(self): + OspFloatingIpApi.__init__(self) + OspFloatingIpInfo.__init__(self) diff --git a/lib/osp/floating_ip/output.py b/lib/osp/floating_ip/output.py new file mode 100644 index 00000000..98201254 --- /dev/null +++ b/lib/osp/floating_ip/output.py @@ -0,0 +1,93 @@ +class OspFloatingIpOutput(): + def __init__(self): + pass + + def print_floating_ips(self, info, title=False): + if title: + self.my_output.default( + 'Floating IP [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'status', + 'floating_ip_address', + 'tenant_name', + 'floating_network_name', + 'fixed_ip_address', + 'port_details.mac_address', + 'port_details.network_name', + 'port_details.vm_name', + 'router_name' + ] + + headers = [ + 'Status', + 'Floating', + 'Tenant', + 'Floating Network', + 'Fixed', + 'MAC', + 'Network', + 'VM', + 'Router' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_floating_ips_id(self, info, title=False): + if title: + self.my_output.default( + 'Floating IP - Identifiers[#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'status', + 'floating_ip_address', + 'floating_network_id', + 'fixed_ip_address', + 'port_details.network_id', + 'port_details.device_id', + 'router_id', + 'tenant_id' + ] + + headers = [ + 'Status', + 'Floating', + 'Network', + 'Fixed', + 'Network', + 'VM', + 'Router', + 'Tenant' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/osp/hypervisor/README.md b/lib/osp/hypervisor/README.md new file mode 100644 index 00000000..e8cac0fe --- /dev/null +++ b/lib/osp/hypervisor/README.md @@ -0,0 +1,3 @@ +sr-iov +host settings +add az in list and search \ No newline at end of file diff --git a/lib/osp/hypervisor/__init__.py b/lib/osp/hypervisor/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/hypervisor/api.py b/lib/osp/hypervisor/api.py new file mode 100644 index 00000000..aafa366c --- /dev/null +++ b/lib/osp/hypervisor/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspHypervisorApi(): + def __init__(self): + self.hypervisor_mo = None + + def get_hypervisor_mo(self, cache_enabled=True): + if cache_enabled: + if self.hypervisor_mo is not None: + return self.hypervisor_mo + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_hypervisor_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.hypervisor_mo = api_handler.hypervisors.list() + self.log.osp( + 'get', + 'hypervisors', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_hypervisor_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'hypervisors', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.hypervisor_mo diff --git a/lib/osp/hypervisor/info.py b/lib/osp/hypervisor/info.py new file mode 100644 index 00000000..2ff88d8f --- /dev/null +++ b/lib/osp/hypervisor/info.py @@ -0,0 +1,208 @@ +from lib import ip_helper +from lib import filter_helper + + +class OspHypervisorInfo(): + def __init__(self): + self.hypervisor = None + + def get_hypervisor_info(self, hypervisor_mo): + if hypervisor_mo is None: + return None + + info = hypervisor_mo.to_dict() + info['__Output'] = {} + + if info['state'] == 'up': + info['__Output']['state'] = 'Green' + else: + info['__Output']['state'] = 'Red' + + if info['status'] == 'enabled': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + info['cpu_summary'] = '%s/%s' % ( + info['vcpus_used'], + info['vcpus'] + ) + + memory_usage_pct = int(info['memory_mb_used'] * 100 / info['memory_mb']) + info['memory_summary'] = '%s/%s [MB] (%s%%)' % ( + self.format_value_dotted(info['memory_mb_used']), + self.format_value_dotted(info['memory_mb']), + memory_usage_pct + ) + + disk_usage_pct = int(info['local_gb_used'] * 100 / info['local_gb']) + info['disk_summary'] = '%s/%s [GB] (%s%%)' % ( + self.format_value_dotted(info['local_gb_used']), + self.format_value_dotted(info['local_gb']), + disk_usage_pct + ) + + return info + + def get_hypervisors_info(self, cache_enabled=True): + if cache_enabled: + if self.hypervisor is not None: + return self.hypervisor + + managed_objects = self.get_hypervisor_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.hypervisor = [] + for managed_object in managed_objects: + hypervisor_info = self.get_hypervisor_info( + managed_object + ) + self.hypervisor.append( + hypervisor_info + ) + + self.log.osp_mo( + 'hypervisors', + self.hypervisor + ) + + return self.hypervisor + + def match_hypervisor(self, hypervisor_info, hypervisor_filter): + if hypervisor_filter is None or len(hypervisor_filter) == 0: + return True + + for ap_rule in hypervisor_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, hypervisor_info['hypervisor_hostname']): + return False + + if key == 'address': + key_found = True + if ip_helper.is_valid_ipv4_address(value): + if not filter_helper.match_string(value, hypervisor_info['host_ip']): + return False + + if ip_helper.is_valid_ipv4_cidr(value): + if not ip_helper.is_ipv4_in_cidr(hypervisor_info['host_ip'], value): + return False + + if key == 'vm': + key_found = True + if 'vm_info' in hypervisor_info: + found = False + for vm_info in hypervisor_info['vm_info']: + if filter_helper.match_tenant_name(value, vm_info['tenant_name']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_hypervisor', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_hypervisors(self, object_filter=None, vm_info=False, cache_enabled=True): + all_hypervisors = self.get_hypervisors_info(cache_enabled=cache_enabled) + if all_hypervisors is None: + return None + + hypervisors = [] + + for hypervisor_info in all_hypervisors: + if not self.match_hypervisor(hypervisor_info, object_filter): + continue + + if vm_info: + hypervisor_vms = self.get_virtual_machines( + object_filter=[ + 'hypervisor:%s' % (hypervisor_info['hypervisor_hostname']) + ], + tenant_info=True, + flavor_info=True + ) + hypervisor_info['vm_info'] = [] + if hypervisor_vms is None: + self.log.error( + 'get_hypervisors', + 'Failed to get virtual machine info: %s' % ( + hypervisor_info['name'] + ) + ) + else: + for hypervisor_vm in hypervisor_vms: + hypervisor_vm_info = {} + hypervisor_vm_info['__Output'] = hypervisor_vm['__Output'] + hypervisor_vm_info['tenant'] = hypervisor_vm['tenant_name'] + hypervisor_vm_info['name'] = hypervisor_vm['name'] + hypervisor_vm_info['tenant_name'] = '%s/%s' % ( + hypervisor_vm_info['tenant'], + hypervisor_vm_info['name'] + ) + hypervisor_vm_info['status'] = hypervisor_vm['status'] + hypervisor_vm_info['vcpus'] = hypervisor_vm['flavor_info']['vcpus'] + hypervisor_vm_info['ram'] = hypervisor_vm['flavor_info']['ram'] + hypervisor_vm_info['disk'] = hypervisor_vm['flavor_info']['disk'] + + hypervisor_info['vm_info'].append( + hypervisor_vm_info + ) + + if not self.match_hypervisor(hypervisor_info, object_filter): + continue + + hypervisors.append( + hypervisor_info + ) + + hypervisors = sorted( + hypervisors, + key=lambda i: i['hypervisor_hostname'].lower() + ) + + return hypervisors + + def get_hypervisor(self, name, vm_info=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (name) + ) + hypervisors_info = self.get_hypervisors( + object_filter=object_filter, + vm_info=vm_info, + cache_enabled=cache_enabled + ) + if hypervisors_info is None: + self.log.error( + 'get_hypervisor', + 'Failed to get hypervisors' + ) + return None + + if len(hypervisors_info) == 0: + self.log.error( + 'get_hypervisor', + 'No hypervisors found' + ) + return None + + if len(hypervisors_info) > 1: + self.log.error( + 'get_hypervisor', + 'Multiple hypervisors found: %s' % (name) + ) + return None + + return hypervisors_info[0] diff --git a/lib/osp/hypervisor/main.py b/lib/osp/hypervisor/main.py new file mode 100644 index 00000000..f94264c5 --- /dev/null +++ b/lib/osp/hypervisor/main.py @@ -0,0 +1,11 @@ +from lib.osp.hypervisor.api import OspHypervisorApi +from lib.osp.hypervisor.info import OspHypervisorInfo + + +class OspHypervisor( + OspHypervisorApi, + OspHypervisorInfo + ): + def __init__(self): + OspHypervisorApi.__init__(self) + OspHypervisorInfo.__init__(self) diff --git a/lib/osp/hypervisor/output.py b/lib/osp/hypervisor/output.py new file mode 100644 index 00000000..6853d707 --- /dev/null +++ b/lib/osp/hypervisor/output.py @@ -0,0 +1,97 @@ +class OspHypervisorOutput(): + def __init__(self): + pass + + def print_hypervisors(self, info, title=False): + if title: + self.my_output.default( + 'Hypervisor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'hypervisor_hostname', + 'host_ip', + 'status', + 'state', + 'running_vms', + 'cpu_summary', + 'memory_summary', + 'disk_summary' + ] + + headers = [ + 'Id', + 'Hypervisor', + 'IP', + 'Status', + 'State', + 'VMs', + 'CPU', + 'Memory', + 'Disk' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_hypervisors_vm(self, info, title=False): + if title: + self.my_output.default( + 'Hypervisor - Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'hypervisor_hostname', + 'vm_info.tenant', + 'vm_info.name', + 'vm_info.status', + 'vm_info.vcpus', + 'vm_info.ram', + 'vm_info.disk' + ] + + headers = [ + 'Id', + 'Hypervisor', + 'Tenant', + 'Name', + 'Status', + 'CPU', + 'Memory [MB]', + 'Disk [GB]' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vm_info'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/osp/image/README.md b/lib/osp/image/README.md new file mode 100644 index 00000000..551b61bd --- /dev/null +++ b/lib/osp/image/README.md @@ -0,0 +1 @@ +create/delete image \ No newline at end of file diff --git a/lib/osp/image/__init__.py b/lib/osp/image/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/image/api.py b/lib/osp/image/api.py new file mode 100644 index 00000000..06ca1881 --- /dev/null +++ b/lib/osp/image/api.py @@ -0,0 +1,196 @@ +import time +import traceback + + +class OspImageApi(): + def __init__(self): + self.image_mo = None + + def get_image_id_mo(self, image_id, cache_enabled=True): + if cache_enabled: + if self.image_mo is not None: + for item in self.image_mo: + if item.id == image_id: + return item + + api_handler = self.get_api_glance(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_image_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + image_mo = api_handler.images.get(image_id) + self.log.osp( + 'get', + 'image', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_image_id_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'image', + True, + int(time.time() * 1000) - start_time + ) + return None + + return image_mo + + def get_image_mo(self, cache_enabled=True): + if cache_enabled: + if self.image_mo is not None: + return self.image_mo + + api_handler = self.get_api_glance(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_image_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.image_mo = api_handler.images.list() + + self.log.osp( + 'get', + 'images', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_image_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'images', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.image_mo + + def create_image_mo(self, image_name, source_filename, container_format='bare', disk_format='qcow2'): + api_handler = self.get_api_glance(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_image_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + image_ref = api_handler.images.create( + name=image_name, + container_format=container_format, + disk_format=disk_format + ) + + new_image_id = image_ref.id + api_handler.images.upload( + new_image_id, + open(source_filename, 'rb') + ) + + self.log.osp( + 'create', + 'image', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.create_image_mo', traceback.format_exc()) + self.log.osp( + 'create', + 'image', + True, + int(time.time() * 1000) - start_time + ) + return None + + return new_image_id + + def delete_image_mo(self, image_id): + api_handler = self.get_api_glance(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_image_mo', + 'No api handler' + ) + return False + + try: + start_time = int(time.time() * 1000) + + api_handler.images.delete(image_id) + + self.log.osp( + 'delete', + 'image', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.delete_image_mo', traceback.format_exc()) + self.log.osp( + 'delete', + 'image', + True, + int(time.time() * 1000) - start_time + ) + return False + + return True + + def download_image(self, image_id, destination_filename): + api_handler = self.get_api_glance(cache_enabled=False) + if api_handler is None: + self.log.error( + 'download_image', + 'No api handler' + ) + return False + + try: + image_data = api_handler.images.data(image_id) + + except BaseException: + self.log.error( + 'download_image', + 'API Exception' + ) + self.log.error( + 'download_image', + traceback.format_exc() + ) + return False + + try: + with open(destination_filename, "wb") as file_handler: + for chunk in image_data: + file_handler.write(chunk) + + except BaseException: + self.log.error( + 'download_image', + 'Image download failed' + ) + self.log.error( + 'download_image', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/image/info.py b/lib/osp/image/info.py new file mode 100644 index 00000000..a413603c --- /dev/null +++ b/lib/osp/image/info.py @@ -0,0 +1,183 @@ +from lib import filter_helper + + +class OspImageInfo(): + def __init__(self): + self.image = None + + def get_image_info(self, image_mo): + if image_mo is None: + return None + + info = {} + info['__Output'] = {} + info['name'] = getattr(image_mo, 'name') + info['disk_format'] = getattr(image_mo, 'disk_format') + info['container_format'] = getattr(image_mo, 'container_format') + info['visibility'] = getattr(image_mo, 'visibility') + info['size'] = getattr(image_mo, 'size') + info['sizeT'] = self.format_value_dotted(info['size']) + info['virtual_size'] = getattr(image_mo, 'virtual_size') + info['status'] = getattr(image_mo, 'status') + if info['status'] == 'active': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + info['checksum'] = getattr(image_mo, 'checksum') + info['protected'] = getattr(image_mo, 'protected') + if info['protected']: + info['protectedTick'] = '\u2713' + else: + info['protectedTick'] = '\u2717' + info['min_ram'] = getattr(image_mo, 'min_ram') + info['min_disk'] = getattr(image_mo, 'min_disk') + info['owner'] = getattr(image_mo, 'owner') + info['os_hidden'] = getattr(image_mo, 'os_hidden') + info['os_hash_algo'] = getattr(image_mo, 'os_hash_algo') + info['os_hash_value'] = getattr(image_mo, 'os_hash_value') + info['id'] = getattr(image_mo, 'id') + info['updated_at'] = getattr(image_mo, 'updated_at') + info['created_at'] = getattr(image_mo, 'created_at') + info['locations'] = getattr(image_mo, 'locations') + info['file'] = getattr(image_mo, 'file') + + return info + + def get_images_info(self, cache_enabled=True): + if cache_enabled: + if self.image is not None: + return self.image + + managed_objects = self.get_image_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.image = [] + for managed_object in managed_objects: + image_info = self.get_image_info( + managed_object + ) + self.image.append( + image_info + ) + + self.log.osp_mo( + 'images', + self.image + ) + + return self.image + + def match_image(self, image_info, image_filter): + if image_filter is None or len(image_filter) == 0: + return True + + for ap_rule in image_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, image_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, image_info['name']): + return False + + if key == 'vm': + key_found = True + if 'vm' in image_info: + found = False + for vm_info in image_info['vm']: + if filter_helper.match_tenant_name(value, vm_info['tenant_name']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_image', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_images(self, object_filter=None, vm_info=False, cache_enabled=True): + all_images = self.get_images_info(cache_enabled=cache_enabled) + if all_images is None: + return None + + images = [] + + for image_info in all_images: + if not self.match_image(image_info, object_filter): + continue + + if vm_info: + image_info['vm'] = [] + image_vms = self.get_virtual_machines( + object_filter=[ + 'image_id:%s' % (image_info['id']) + ], + tenant_info=True + ) + if image_vms is None: + self.log.error( + 'get_images', + 'Get vm with image failed: %s' % (image_info['id']) + ) + else: + for image_vm in image_vms: + image_vm_info = {} + image_vm_info['tenant'] = image_vm['tenant_name'] + image_vm_info['name'] = image_vm['name'] + image_vm_info['tenant_name'] = '%s/%s' % ( + image_vm['tenant_name'], + image_vm['name'] + ) + image_info['vm'].append( + image_vm_info + ) + + if not self.match_image(image_info, object_filter): + continue + + + images.append( + image_info + ) + + images = sorted( + images, + key=lambda i: i['name'].lower() + ) + + return images + + def get_image(self, image_id=None, image_name=None, cache_enabled=True): + object_filter = [] + if image_id is not None: + object_filter.append('id:%s' % (image_id)) + if image_name is not None: + object_filter.append('name:%s' % (image_name)) + + images = self.get_images( + object_filter=object_filter, + cache_enabled=cache_enabled + ) + + if images is None or len(images) != 1: + return None + + return images[0] + + def is_image(self, image_id=None, image_name=None, cache_enabled=True): + if self.get_image(image_id=image_id, image_name=image_name, cache_enabled=cache_enabled): + return True + return False diff --git a/lib/osp/image/main.py b/lib/osp/image/main.py new file mode 100644 index 00000000..977d3ea5 --- /dev/null +++ b/lib/osp/image/main.py @@ -0,0 +1,14 @@ +from lib.osp.image.api import OspImageApi +from lib.osp.image.info import OspImageInfo +from lib.osp.image.task import OspImageTask + + +class OspImage( + OspImageApi, + OspImageInfo, + OspImageTask + ): + def __init__(self): + OspImageApi.__init__(self) + OspImageInfo.__init__(self) + OspImageTask.__init__(self) diff --git a/lib/osp/image/output.py b/lib/osp/image/output.py new file mode 100644 index 00000000..c46a1ac4 --- /dev/null +++ b/lib/osp/image/output.py @@ -0,0 +1,169 @@ +import copy + + +class OspImageOutput(): + def __init__(self): + pass + + def print_images(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Image [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'name', + 'disk_format', + 'container_format', + 'sizeT', + 'status', + 'visibility', + 'protectedTick', + 'checksum' + ] + + headers = headers + [ + 'Name', + 'Disk', + 'Container', + 'Size [B]', + 'Status', + 'Visibility', + 'Protected', + 'Checksum' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_images_id(self, info, title=False): + if title: + self.my_output.default( + 'Image - Identifiers [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'name' + ] + + headers = [ + 'Id', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_images_vm(self, info, title=False): + if title: + self.my_output.default( + 'Image - Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'disk_format', + 'container_format', + 'sizeT', + 'status', + 'vm.tenant_name' + ] + + headers = [ + 'Name', + 'Disk', + 'Container', + 'Size [B]', + 'Status', + 'Virtual Machine' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['vm'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def select_image(self, info): + self.my_output.default( + 'Select Image [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No image found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_images(new_info, title=False, select=True) + + while True: + answer = input("Select image using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/image/task.py b/lib/osp/image/task.py new file mode 100644 index 00000000..2eef572a --- /dev/null +++ b/lib/osp/image/task.py @@ -0,0 +1,165 @@ +import os +import time +import traceback + + +class OspImageTask(): + def __init__(self): + pass + + def wait_for_image_status(self, image_id, status_array, reverse=False, timeout=300): + start_time = int(time.time()) + while True: + try: + image_mo = self.get_image_id_mo(image_id, cache_enabled=False) + if image_mo is not None: + current_status = image_mo.status + if image_mo.status.lower() == 'error': + return False + + if not reverse: + if current_status in status_array: + return True + + if reverse: + if current_status not in status_array: + return True + + except BaseException: + self.log.error( + 'wait_for_image_status', + traceback.format_exc() + ) + + time.sleep(5) + if (int(time.time()) - start_time) > timeout: + self.log.error( + 'wait_for_image_status', + 'Timeout reached for image: %s' % (image_id) + ) + return False + + def wait_for_image_active(self, image_id, timeout=300): + return self.wait_for_image_status(image_id, ['active'], timeout=timeout) + + def create_image_from_virtual_machine(self, virtual_machine_id, image_name, wait=False): + # https://github.com/openstack/python-novaclient/blob/master/novaclient/v2/servers.py + api_handler = self.get_api_nova() + if api_handler is None: + self.log.error( + 'create_image_from_virtual_machine', + 'No api handler' + ) + return None + + if self.get_image(image_name=image_name) is not None: + self.log.error( + 'create_image_from_virtual_machine', + 'Image already exists: %s' % (image_name) + ) + return None + + try: + image_id = api_handler.servers.create_image( + virtual_machine_id, + image_name + ) + except BaseException: + self.log.error( + 'create_image_from_virtual_machine', + 'Failed for virtual machine %s and image name %s' % ( + virtual_machine_id, + image_name + ) + ) + self.log.error( + 'create_image_from_virtual_machine', + traceback.format_exc() + ) + return None + + if image_id is None: + self.log.error( + 'create_image_from_virtual_machine', + 'Image id none for for virtual machine %s and image name %s' % ( + virtual_machine_id, + image_name + ) + ) + return None + + return image_id + + def download_image(self, image_id, filename): + api_handler = self.get_api_glance() + if api_handler is None: + self.log.error( + 'download_image', + 'No api handler' + ) + return False + + if os.path.isfile(filename): + self.log.error( + 'Filename already exists: %s' % (filename) + ) + + try: + data_handler = api_handler.images.data(image_id) + + except BaseException: + self.log.error( + 'download_image', + 'Glance API Exception for image: %s' % (image_id) + ) + self.log.error( + 'download_image', + traceback.format_exc() + ) + return False + + try: + with open(filename, 'wb') as file_handler: + for chunk in data_handler: + file_handler.write(chunk) + + except Exception: + self.log.error( + 'download_image', + 'Glance Image download failed: %s => %s' % ( + image_id, + filename + ) + ) + self.log.error( + 'download_image', + traceback.format_exc() + ) + return False + + return True + + def delete_image(self, image_id): + api_handler = self.get_api_glance() + if api_handler is None: + self.log.error( + 'download_image', + 'No api handler' + ) + return None + + try: + api_handler.images.delete(image_id) + + except BaseException: + self.log.error( + 'delete_image', + 'Glance API Exception: %s' % (image_id) + ) + self.log.error( + 'delete_image', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/main.py b/lib/osp/main.py new file mode 100644 index 00000000..f3b0bc7a --- /dev/null +++ b/lib/osp/main.py @@ -0,0 +1,68 @@ +from lib import log_helper + +from lib.osp.api import OspApi +from lib.osp.common import OspCommon + +from lib.osp.availability_zone.main import OspAvailabilityZone +from lib.osp.flavor.main import OspFlavor +from lib.osp.floating_ip.main import OspFloatingIp +from lib.osp.hypervisor.main import OspHypervisor +from lib.osp.image.main import OspImage +from lib.osp.network.main import OspNetwork +from lib.osp.port.main import OspPort +from lib.osp.quota.main import OspQuota +from lib.osp.role.main import OspRole +from lib.osp.router.main import OspRouter +from lib.osp.security_group.main import OspSecurityGroup +from lib.osp.snapshot.main import OspSnapshot +from lib.osp.subnet.main import OspSubnet +from lib.osp.tenant.main import OspTenant +from lib.osp.user.main import OspUser +from lib.osp.virtual_machine.main import OspVirtualMachine +from lib.osp.volume.main import OspVolume + + +class Osp( + OspApi, + OspCommon, + OspAvailabilityZone, + OspFlavor, + OspFloatingIp, + OspHypervisor, + OspImage, + OspNetwork, + OspPort, + OspQuota, + OspRole, + OspRouter, + OspSecurityGroup, + OspSnapshot, + OspSubnet, + OspTenant, + OspUser, + OspVirtualMachine, + OspVolume + ): + def __init__(self, openrc_filename, cert_filename=None, log_id=None): + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + OspApi.__init__(self, openrc_filename, cert_filename) + OspCommon.__init__(self) + OspAvailabilityZone.__init__(self) + OspFlavor.__init__(self) + OspFloatingIp.__init__(self) + OspHypervisor.__init__(self) + OspImage.__init__(self) + OspNetwork.__init__(self) + OspPort.__init__(self) + OspQuota.__init__(self) + OspRole.__init__(self) + OspRouter.__init__(self) + OspSecurityGroup.__init__(self) + OspSnapshot.__init__(self) + OspSubnet.__init__(self) + OspTenant.__init__(self) + OspUser.__init__(self) + OspVirtualMachine.__init__(self) + OspVolume.__init__(self) diff --git a/lib/osp/network/__init__.py b/lib/osp/network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/network/api.py b/lib/osp/network/api.py new file mode 100644 index 00000000..d1a2756e --- /dev/null +++ b/lib/osp/network/api.py @@ -0,0 +1,170 @@ +import time +import json +import traceback + + +class OspNetworkApi(): + def __init__(self): + self.network_mo = None + + def get_network_mo(self, cache_enabled=True): + if cache_enabled: + if self.network_mo is not None: + return self.network_mo + + api_handler = self.get_api_neutron(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_network_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.network_mo = api_handler.list_networks()['networks'] + self.log.osp( + 'get', + 'networks', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_network_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'networks', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.network_mo + + def create_external_network_mo(self, network_name, physical_network='phys_ext'): + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_tenant_network_mo', + 'No api handler' + ) + return None + + body = {} + body['network'] = {} + body['network']['name'] = network_name + body['network']['admin_state_up'] = True + body['network']['provider:physical_network'] = physical_network + body['network']['provider:network_type'] = 'flat' + body['network']['router:external'] = True + + self.log.debug( + 'create_external_network_mo', + json.dumps(body, indent=4) + ) + + try: + network = api_handler.create_network(body=body) + network_id = network['network']['id'] + + except BaseException: + self.log.error( + 'create_provider_network_mo', + traceback.format_exc() + ) + return None + + return network_id + + def create_provider_network_mo(self, tenant_id, network_name, physical_network, provider_network_type, provider_segmentation_id): + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_tenant_network_mo', + 'No api handler' + ) + return None + + body = {} + body['network'] = {} + body['network']['name'] = network_name + body['network']['admin_state_up'] = True + body['network']['provider:physical_network'] = physical_network + body['network']['provider:network_type'] = provider_network_type + body['network']['provider:segmentation_id'] = provider_segmentation_id + if tenant_id is not None: + body['network']['tenant_id'] = tenant_id + + self.log.debug( + 'create_provider_network_mo', + json.dumps(body, indent=4) + ) + + try: + network = api_handler.create_network(body=body) + network_id = network['network']['id'] + + except BaseException: + self.log.error( + 'create_provider_network_mo', + traceback.format_exc() + ) + return None + + return network_id + + def create_tenant_network_mo(self, tenant_id, network_name): + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_tenant_network_mo', + 'No api handler' + ) + return None + + body = {} + body['network'] = {} + body['network']['name'] = network_name + body['network']['admin_state_up'] = True + if tenant_id is not None: + body['network']['tenant_id'] = tenant_id + + self.log.debug( + 'create_tenant_network_mo', + json.dumps(body, indent=4) + ) + + try: + network = api_handler.create_network(body=body) + network_id = network['network']['id'] + + except BaseException: + self.log.error( + 'create_tenant_network_mo', + traceback.format_exc() + ) + return None + + return network_id + + def delete_network_mo(self, network_id): + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_network_mo', + 'No api handler' + ) + return False + + try: + api_handler.delete_network(network_id) + + except BaseException: + self.log.error( + 'delete_network_mo', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/network/info.py b/lib/osp/network/info.py new file mode 100644 index 00000000..04cea22a --- /dev/null +++ b/lib/osp/network/info.py @@ -0,0 +1,341 @@ +from lib import filter_helper +from lib import ip_helper + + +class OspNetworkInfo(): + def __init__(self): + self.network = None + + def get_network_info(self, network_mo): + if network_mo is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'tenant_id', + 'admin_state_up', + 'mtu', + 'status', + 'subnets', + 'shared', + 'availability_zone_hints', + 'availability_zones', + 'ipv4_address_scope', + 'ipv6_address_scope', + 'port_security_enabled', + 'created_at', + 'updated_at' + ] + for key in keys: + info[key] = None + if key in network_mo: + info[key] = network_mo[key] + + info['external'] = network_mo['router:external'] + info['provider_network_type'] = network_mo['provider:network_type'] + info['provider_physical_network'] = network_mo['provider:physical_network'] + info['provider_segmentation_id'] = network_mo['provider:segmentation_id'] + + if info['status'] == 'ACTIVE': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + if info['admin_state_up']: + info['adminTick'] = '\u2713' + info['__Output']['adminTick'] = 'Green' + else: + info['adminTick'] = '\u2717' + info['__Output']['adminTick'] = 'Green' + + if info['external']: + info['externalTick'] = '\u2713' + else: + info['externalTick'] = '\u2717' + + if info['shared']: + info['sharedTick'] = '\u2713' + else: + info['sharedTick'] = '\u2717' + + if info['port_security_enabled']: + info['securityTick'] = '\u2713' + else: + info['securityTick'] = '\u2717' + + info['created_age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + info['updated_age'] = self.convert_timestamp_to_age( + info['updated_at'], + on_error='--' + ) + + return info + + def get_networks_info(self, cache_enabled=True): + if cache_enabled: + if self.network is not None: + return self.network + + managed_objects = self.get_network_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'networks', + managed_objects + ) + + self.network = [] + for managed_object in managed_objects: + network_info = self.get_network_info( + managed_object + ) + self.network.append( + network_info + ) + + self.log.osp_mo( + 'networks.info', + self.network + ) + + return self.network + + def match_network(self, network_info, network_filter): + if network_filter is None or len(network_filter) == 0: + return True + + for ap_rule in network_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, network_info['id']): + return False + + if key == 'name': + key_found = True + if len(value.split('/')) == 1: + if not filter_helper.match_string(value, network_info['name']): + return False + if len(value.split('/')) == 2: + if not filter_helper.match_string(value.split('/')[1], network_info['name']): + return False + + if 'tenant_name' in network_info: + if not filter_helper.match_string(value.split('/', maxsplit=1)[0], network_info['tenant_name']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, network_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in network_info: + if not filter_helper.match_string(value, network_info['tenant_name']): + return False + + if key == 'external': + key_found = True + if value not in ['true', 'false']: + self.log.error( + 'match_network', + 'Unsupported external value: %s' % (value) + ) + return False + + if value == 'true' and not network_info['external']: + return False + + if value == 'false' and network_info['external']: + return False + + if key == 'mac': + key_found = True + if 'port_info' in network_info: + found = False + for port_info in network_info['port_info']: + if ip_helper.is_mac_match(value, port_info['mac_address']): + found = True + break + + if not found: + return False + + if key == 'address': + key_found = True + if 'subnet_info' in network_info: + found = False + for subnet_info in network_info['subnet_info']: + if ip_helper.is_ipv4_in_cidr(value, subnet_info['cidr']): + found = True + break + + if not found: + return False + + if key == 'vm_name': + key_found = True + if 'port_info' in network_info: + found = False + for port_info in network_info['port_info']: + if filter_helper.match_tenant_name(value, port_info['vm_tenant_name']): + found = True + break + + if not found: + return False + + if key == 'hv': + key_found = True + if 'port_info' in network_info: + found = False + for port_info in network_info['port_info']: + if port_info['binding_host_id'] is not None: + if filter_helper.match_string(value, port_info['binding_host_id']): + found = True + break + + if not found: + return False + + if key == 'vlan': + key_found = True + if network_info['provider_segmentation_id'] is None: + return False + + if not filter_helper.match_string(value, str(network_info['provider_segmentation_id'])): + return False + + if not key_found: + self.log.error( + 'match_network', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_networks(self, object_filter=None, tenant_info=False, subnet_info=False, port_info=False, router_info=False, cache_enabled=True): + all_networks = self.get_networks_info(cache_enabled=cache_enabled) + if all_networks is None: + return None + + networks = [] + + for network_info in all_networks: + if not self.match_network(network_info, object_filter): + continue + + if tenant_info: + network_info['tenant_name'] = self.get_tenant_name( + network_info['tenant_id'], + cache_enabled=cache_enabled + ) + if not self.match_network(network_info, object_filter): + continue + + if subnet_info: + network_info['subnet_info'] = [] + for subnet_id in network_info['subnets']: + network_subnet_info = self.get_subnet(subnet_id=subnet_id) + if network_subnet_info is None: + self.log.error( + 'get_networks', + 'Subnet info failed: %s' % (subnet_id) + ) + continue + + network_info['subnet_info'].append( + network_subnet_info + ) + + if not self.match_network(network_info, object_filter): + continue + + if port_info or router_info: + network_port_filter = [] + network_port_filter.append( + 'network_id:%s' % (network_info['id']) + ) + network_info['port_info'] = self.get_ports( + object_filter=network_port_filter, + vm_info=True + ) + + if not self.match_network(network_info, object_filter): + continue + + network_info['router_id'] = None + network_info['router_tenant_name'] = None + network_info['router_name'] = None + + routers = self.get_routers(tenant_info=True) + if routers is not None: + for router in routers: + for port_info in network_info['port_info']: + if port_info['device_id'] == router['id']: + network_info['router_id'] = router['id'] + network_info['router_tenant_name'] = router['tenant_name'] + network_info['router_name'] = router['name'] + + networks.append( + network_info + ) + + networks = sorted( + networks, + key=lambda i: i['name'].lower() + ) + + return networks + + def get_network(self, network_id=None, network_name=None, tenant_info=False, subnet_info=False, port_info=False, cache_enabled=True): + object_filter = [] + if network_id is not None: + object_filter.append( + 'id:%s' % (network_id) + ) + if network_name is not None: + object_filter.append( + 'name:%s' % (network_name) + ) + + networks = self.get_networks( + object_filter=object_filter, + tenant_info=tenant_info, + subnet_info=subnet_info, + port_info=port_info, + cache_enabled=cache_enabled + ) + if networks is None or len(networks) != 1: + return None + + return networks[0] + + def get_network_name(self, network_id, cache_enabled=True): + network_info = self.get_network( + network_id=network_id, + cache_enabled=cache_enabled + ) + if network_info is None: + return None + return network_info['name'] + + def is_network_name(self, network_name, cache_enabled=True): + network = self.get_network(network_name=network_name, cache_enabled=cache_enabled) + if network is None: + return False + return True diff --git a/lib/osp/network/main.py b/lib/osp/network/main.py new file mode 100644 index 00000000..b8b99fd9 --- /dev/null +++ b/lib/osp/network/main.py @@ -0,0 +1,11 @@ +from lib.osp.network.api import OspNetworkApi +from lib.osp.network.info import OspNetworkInfo + + +class OspNetwork( + OspNetworkApi, + OspNetworkInfo + ): + def __init__(self): + OspNetworkApi.__init__(self) + OspNetworkInfo.__init__(self) diff --git a/lib/osp/network/output.py b/lib/osp/network/output.py new file mode 100644 index 00000000..5487743b --- /dev/null +++ b/lib/osp/network/output.py @@ -0,0 +1,297 @@ +import copy + + +class OspNetworkOutput(): + def __init__(self): + pass + + def print_networks(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Network [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None: + item['tenant_name'] = '--' + + item['router'] = '--' + if item['router_name'] is not None: + item['router'] = '%s/%s' % ( + item['router_tenant_name'], + item['router_name'] + ) + + if len(item['subnet_info']) == 0: + empty_subnet = {} + empty_subnet['name'] = '--' + empty_subnet['cidr'] = '--' + item['subnet_info'].append(empty_subnet) + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'name', + 'tenant_name', + 'adminTick', + 'status', + 'sharedTick', + 'externalTick', + 'securityTick', + 'mtu', + 'subnet_info.name', + 'subnet_info.cidr', + 'router', + 'created_age' + ] + + headers = headers + [ + 'Name', + 'Tenant', + 'Admin', + 'Status', + 'Shared', + 'Ext', + 'Sec', + 'MTU', + 'Subnet', + 'CIDR', + 'Router', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['subnet_info'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_networks_port(self, info, title=False): + if title: + self.my_output.default( + 'Network - Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None: + item['extended_name'] = item['name'] + else: + item['extended_name'] = '%s/%s' % ( + item['tenant_name'], + item['name'] + ) + + if len(item['subnet_info']) == 0: + item['subnet_info'].append( + dict( + name='--', + cidr='--' + ) + ) + + if len(item['port_info']) == 0: + item['port_info'].append( + dict( + mac_address='--', + ips='--', + type='--', + vm_tenant_name='--' + ) + ) + + for port in item['port_info']: + if port['vm_tenant_name'] is None: + port['vm_tenant_name'] = '--' + + if 'binding_host_id' not in port or port['binding_host_id'] is None: + port['binding_host_id'] = '--' + + order = [ + 'extended_name', + 'subnet_info.cidr', + 'port_info.mac_address', + 'port_info.ips', + 'port_info.type', + 'port_info.vm_tenant_name', + 'port_info.binding_host_id' + ] + + headers = [ + 'Name', + 'CIDR', + 'MAC', + 'IP', + 'Type', + 'VM', + 'HV' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['subnet_info', 'port_info'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_networks_phy(self, info, title=False): + if title: + self.my_output.default( + 'Network - Phy [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None: + item['extended_name'] = item['name'] + else: + item['extended_name'] = '%s/%s' % ( + item['tenant_name'], + item['name'] + ) + + if item['provider_segmentation_id'] is None: + item['provider_segmentation_id'] = '--' + + order = [ + 'extended_name', + 'adminTick', + 'status', + 'provider_network_type', + 'provider_physical_network', + 'provider_segmentation_id' + ] + + headers = [ + 'Name', + 'Admin', + 'Status', + 'Network Type', + 'Physical Network', + 'Segmentation ID' + ] + + self.my_output.my_table( + new_info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_networks_id(self, info, title=False): + if title: + self.my_output.default( + 'Network - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'name', + 'tenant_id', + 'subnets' + ] + + headers = [ + 'Id', + 'Name', + 'Tenant', + 'Subnet' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['subnets'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def select_network(self, info): + self.my_output.default( + 'Select Network [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No network found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_networks(new_info, title=False, select=True) + + while True: + answer = input("Select network using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/output.py b/lib/osp/output.py new file mode 100644 index 00000000..ce36e802 --- /dev/null +++ b/lib/osp/output.py @@ -0,0 +1,63 @@ +from lib import output_helper +from lib.osp.availability_zone.output import OspAvailabilityZoneOutput +from lib.osp.flavor.output import OspFlavorOutput +from lib.osp.floating_ip.output import OspFloatingIpOutput +from lib.osp.hypervisor.output import OspHypervisorOutput +from lib.osp.image.output import OspImageOutput +from lib.osp.network.output import OspNetworkOutput +from lib.osp.port.output import OspPortOutput +from lib.osp.quota.output import OspQuotaOutput +from lib.osp.role.output import OspRoleOutput +from lib.osp.router.output import OspRouterOutput +from lib.osp.security_group.output import OspSecurityGroupOutput +from lib.osp.snapshot.output import OspSnapshotOutput +from lib.osp.subnet.output import OspSubnetOutput +from lib.osp.tenant.output import OspTenantOutput +from lib.osp.user.output import OspUserOutput +from lib.osp.virtual_machine.output import OspVirtualMachineOutput +from lib.osp.volume.output import OspVolumeOutput + + +class OspOutput( + OspAvailabilityZoneOutput, + OspFlavorOutput, + OspFloatingIpOutput, + OspHypervisorOutput, + OspImageOutput, + OspNetworkOutput, + OspPortOutput, + OspQuotaOutput, + OspRoleOutput, + OspRouterOutput, + OspSecurityGroupOutput, + OspSnapshotOutput, + OspSubnetOutput, + OspTenantOutput, + OspUserOutput, + OspVirtualMachineOutput, + OspVolumeOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + OspAvailabilityZoneOutput.__init__(self) + OspFlavorOutput.__init__(self) + OspFloatingIpOutput.__init__(self) + OspHypervisorOutput.__init__(self) + OspImageOutput.__init__(self) + OspNetworkOutput.__init__(self) + OspPortOutput.__init__(self) + OspQuotaOutput.__init__(self) + OspRoleOutput.__init__(self) + OspRouterOutput.__init__(self) + OspSecurityGroupOutput.__init__(self) + OspSnapshotOutput.__init__(self) + OspSubnetOutput.__init__(self) + OspTenantOutput.__init__(self) + OspUserOutput.__init__(self) + OspVirtualMachineOutput.__init__(self) + OspVolumeOutput.__init__(self) diff --git a/lib/osp/port/README.md b/lib/osp/port/README.md new file mode 100644 index 00000000..7783bfd1 --- /dev/null +++ b/lib/osp/port/README.md @@ -0,0 +1 @@ +create/delete port incl. sriov \ No newline at end of file diff --git a/lib/osp/port/__init__.py b/lib/osp/port/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/port/api.py b/lib/osp/port/api.py new file mode 100644 index 00000000..fcfec65f --- /dev/null +++ b/lib/osp/port/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspPortApi(): + def __init__(self): + self.port_mo = None + + def get_port_mo(self, cache_enabled=True): + if cache_enabled: + if self.port_mo is not None: + return self.port_mo + + api_handler = self.get_api_neutron(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_port_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.port_mo = api_handler.list_ports()['ports'] + self.log.osp( + 'get', + 'ports', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_port_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'ports', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.port_mo diff --git a/lib/osp/port/info.py b/lib/osp/port/info.py new file mode 100644 index 00000000..96758bde --- /dev/null +++ b/lib/osp/port/info.py @@ -0,0 +1,383 @@ +from lib import filter_helper +from lib import ip_helper + + +class OspPortInfo(): + def __init__(self): + self.port = None + + def get_port_info(self, port_mo): + if port_mo is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'network_id', + 'tenant_id', + 'mac_address', + 'admin_state_up', + 'status', + 'device_id', + 'device_owner', + 'fixed_ips', + 'allowed_address_pairs', + 'extra_dhcp_opts', + 'security_groups', + 'port_security_enabled', + 'propagate_uplink_status', + 'tags', + 'created_at', + 'updated_at', + ] + for key in keys: + info[key] = None + if key in port_mo: + info[key] = port_mo[key] + + ips = [] + for fixed_ip in info['fixed_ips']: + ips.append( + fixed_ip['ip_address'] + ) + info['ips'] = ','.join(ips) + + keys = [ + 'binding:vnic_type', + 'binding:profile', + 'binding:host_id', + 'binding:vif_type', + 'binding:vif_details' + ] + for key in keys: + new_key_name = key.replace(':', '_') + info[new_key_name] = None + if key in port_mo: + info[new_key_name] = port_mo[key] + + if info['admin_state_up']: + info['adminTick'] = '\u2713' + info['__Output']['adminTick'] = 'Green' + else: + info['adminTick'] = '\u2717' + info['__Output']['adminTick'] = 'Red' + + info['port_security_enabledTick'] = '' + if info['port_security_enabled']: + info['port_security_enabledTick'] = '\u2713' + + info['statusT'] = info['status'] + if info['status'] == 'N/A': + info['statusT'] = '--' + else: + if info['statusT'] == 'ACTIVE': + info['__Output']['statusT'] = 'Green' + else: + info['__Output']['statusT'] = 'Red' + + info['type'] = None + if info['device_owner'] == 'compute:ALL': + info['type'] = 'Compute' + if info['device_owner'] == 'network:dhcp': + info['type'] = 'DHCP' + if info['device_owner'] == 'network:floatingip': + info['type'] = 'Floating' + if info['device_owner'] == 'network:router_gateway': + info['type'] = 'Gateway' + if info['device_owner'] == 'network:router_ha_interface': + info['type'] = 'HA' + if info['device_owner'] == 'network:ha_router_replicated_interface': + info['type'] = 'HA' + + if info['type'] is None: + if len(info['device_owner']) > 0: + self.log.error( + 'get_port_info', + 'Unsupported device owner: %s' % (info['id']) + ) + + info['age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + return info + + def get_ports_info(self, cache_enabled=True): + if cache_enabled: + if self.port is not None: + return self.port + + managed_objects = self.get_port_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'ports', + managed_objects + ) + + self.port = [] + for managed_object in managed_objects: + port_info = self.get_port_info( + managed_object + ) + self.port.append( + port_info + ) + + self.log.osp_mo( + 'ports.info', + self.port + ) + + return self.port + + def match_port(self, port_info, port_filter): + if port_filter is None or len(port_filter) == 0: + return True + + for ap_rule in port_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, port_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, port_info['name']): + return False + + if key == 'state': + key_found = True + if not filter_helper.match_string(value, port_info['status']): + return False + + if key == 'type': + key_found = True + if not filter_helper.match_string(value, port_info['type']): + return False + + if key == 'mac': + key_found = True + if not ip_helper.is_mac_match(value, port_info['mac_address']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, port_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in port_info: + if not filter_helper.match_string(value, port_info['tenant_name']): + return False + + if key == 'network_id': + key_found = True + if not filter_helper.match_string(value, port_info['network_id']): + return False + + if key == 'network_name': + key_found = True + if 'network_name' in port_info: + if not filter_helper.match_string(value, port_info['network_name']): + return False + + if key == 'subnet_id': + key_found = True + found = False + for fixed_ip in port_info['fixed_ips']: + if filter_helper.match_string(value, fixed_ip['subnet_id']): + found = True + break + + if not found: + return False + + if key == 'subnet_name': + key_found = True + found = False + subnet_ready = True + for fixed_ip in port_info['fixed_ips']: + if 'subnet_name' not in fixed_ip: + subnet_ready = False + break + + if filter_helper.match_string(value, fixed_ip['subnet_name']): + found = True + break + + if subnet_ready and not found: + return False + + if key == 'vm_id': + key_found = True + if port_info['device_owner'] != 'compute:ALL': + return False + if not filter_helper.match_string(value, port_info['device_id']): + return False + + if key == 'vm_name': + key_found = True + if 'vm_tenant_name' in port_info: + if not filter_helper.match_tenant_name(value, port_info['vm_tenant_name']): + return False + + if key == 'address': + key_found = True + if ip_helper.is_valid_ipv4_address(value): + found = False + for fixed_ip in port_info['fixed_ips']: + if filter_helper.match_string(value, fixed_ip['ip_address']): + found = True + break + + if not found: + return False + + if ip_helper.is_valid_ipv4_cidr(value): + found = False + for fixed_ip in port_info['fixed_ips']: + if ip_helper.is_ipv4_in_cidr(fixed_ip['ip_address'], value): + found = True + break + + if not found: + return False + + if key == 'hv': + key_found = True + if not filter_helper.match_string(value, port_info['binding_host_id']): + return False + + if key == 'sg': + key_found = True + if 'security_group_names' in port_info: + found = False + for security_group_name in port_info['security_group_names']: + if filter_helper.match_tenant_name(value, security_group_name): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_port', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_ports(self, object_filter=None, tenant_info=False, network_info=False, subnet_info=False, security_info=False, vm_info=False, fip_info=False, cache_enabled=True): + all_ports = self.get_ports_info(cache_enabled=cache_enabled) + if all_ports is None: + return None + + ports = [] + + for port_info in all_ports: + if not self.match_port(port_info, object_filter): + continue + + if tenant_info: + port_info['tenant_name'] = None + if len(port_info['tenant_id']) > 0: + port_info['tenant_name'] = self.get_tenant_name( + port_info['tenant_id'] + ) + + if not self.match_port(port_info, object_filter): + continue + + if network_info: + port_info['network_name'] = self.get_network_name( + port_info['network_id'] + ) + + if not self.match_port(port_info, object_filter): + continue + + if subnet_info: + for fixed_ip_mo in port_info['fixed_ips']: + fixed_ip_mo['subnet_name'] = self.get_subnet_name( + fixed_ip_mo['subnet_id'] + ) + + if not self.match_port(port_info, object_filter): + continue + + if security_info: + port_info['security_group_names'] = [] + for security_group_id in port_info['security_groups']: + security_group_name = self.get_security_group_tenant_name( + security_group_id, + cache_enabled=cache_enabled + ) + if security_group_id is None: + self.log.error( + 'get_ports', + 'Failed to get security group details: %s' % (security_group_id) + ) + else: + port_info['security_group_names'].append( + security_group_name + ) + + port_info['security_group_names_value'] = ','.join( + port_info['security_group_names'] + ) + + if vm_info: + port_info['vm_tenant_name'] = None + if port_info['device_owner'] == 'compute:ALL': + port_info['vm_tenant_name'] = self.get_virtual_machine_tenant_name( + port_info['device_id'] + ) + + if not self.match_port(port_info, object_filter): + continue + + if fip_info: + port_info['floating_ip'] = None + floating_filter = [] + floating_filter.append('mac:%s' % (port_info['mac_address'])) + port_floating_ips = self.get_floating_ips( + object_filter=floating_filter + ) + if port_floating_ips is not None and len(port_floating_ips) > 0: + if len(port_floating_ips) > 1: + self.log.error( + 'get_ports', + 'Unexpected fip count for port id: %s' % (port_info['id']) + ) + else: + port_info['floating_ip'] = port_floating_ips[0] + + for fixed_ip_mo in port_info['fixed_ips']: + fixed_ip_mo['floating_ip'] = None + if port_info['floating_ip'] is not None: + if port_info['floating_ip']['fixed_ip_address'] == fixed_ip_mo['ip_address']: + fixed_ip_mo['floating_ip'] = port_info['floating_ip']['floating_ip_address'] + + ports.append( + port_info + ) + + ports = sorted( + ports, + key=lambda i: i['ips'] + ) + + return ports diff --git a/lib/osp/port/main.py b/lib/osp/port/main.py new file mode 100644 index 00000000..29f8bd22 --- /dev/null +++ b/lib/osp/port/main.py @@ -0,0 +1,11 @@ +from lib.osp.port.api import OspPortApi +from lib.osp.port.info import OspPortInfo + + +class OspPort( + OspPortApi, + OspPortInfo + ): + def __init__(self): + OspPortApi.__init__(self) + OspPortInfo.__init__(self) diff --git a/lib/osp/port/output.py b/lib/osp/port/output.py new file mode 100644 index 00000000..17315887 --- /dev/null +++ b/lib/osp/port/output.py @@ -0,0 +1,331 @@ +import copy +import json + + +class OspPortOutput(): + def __init__(self): + pass + + def print_ports(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['name'] is None or len(item['name']) == 0: + item['name'] = '--' + + if item['type'] is None: + item['type'] = '--' + + if item['tenant_name'] is None: + item['tenant_name'] = '--' + + if item['network_name'] is None: + item['network_name'] = '--' + + for fip in item['fixed_ips']: + if fip['subnet_name'] is None: + fip['subnet_name'] = '--' + + if 'floating_ip' not in fip or fip['floating_ip'] is None: + fip['floating_ip'] = '--' + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'mac_address', + 'adminTick', + 'statusT', + 'type', + 'name', + 'fixed_ips.ip_address', + 'fixed_ips.floating_ip', + 'fixed_ips.subnet_name', + 'network_name', + 'tenant_name', + 'age' + ] + + headers = headers + [ + 'MAC', + 'Admin', + 'Status', + 'Type', + 'Name', + 'IP', + 'Floating IP', + 'Subnet', + 'Network', + 'Tenant', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['fixed_ips'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_ports_security(self, info, title=False): + if title: + self.my_output.default( + 'Port - Security [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['type'] is None: + item['type'] = '--' + + if item['vm_tenant_name'] is None: + item['vm_tenant_name'] = '--' + + if len(item['allowed_address_pairs']) == 0: + item['aap'] = [] + else: + item['aap'] = json.dumps( + item['allowed_address_pairs'], + indent=2 + ).split('\n') + + if len(item['security_group_names']) == 0: + item['security_group_names'].append('--') + + order = [ + 'mac_address', + 'adminTick', + 'statusT', + 'type', + 'fixed_ips.ip_address', + 'vm_tenant_name', + 'aap', + 'port_security_enabledTick', + 'security_group_names' + ] + + headers = [ + 'MAC', + 'Admin', + 'Status', + 'Type', + 'IP', + 'VM', + 'Allowed Access Pairs', + 'Port Security', + 'Security Group' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['fixed_ips', 'aap', 'security_group_names'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_ports_hv(self, info, title=False): + if title: + self.my_output.default( + 'Port - Hypervisor [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['type'] is None: + item['type'] = '--' + + if item['vm_tenant_name'] is None: + item['vm_tenant_name'] = '--' + + if item['binding_host_id'] is None or len(item['binding_host_id']) == 0: + item['binding_host_id'] = '--' + + if len(item['binding_profile']) == 0: + item['binding_profileT'] = ['--'] + else: + item['binding_profileT'] = json.dumps( + item['binding_profile'], + indent=2 + ).split('\n') + + if len(item['binding_vif_details']) == 0: + item['binding_vif_detailsT'] = ['--'] + else: + item['binding_vif_detailsT'] = json.dumps( + item['binding_vif_details'], + indent=2 + ).split('\n') + + order = [ + 'mac_address', + 'adminTick', + 'statusT', + 'type', + 'fixed_ips.ip_address', + 'vm_tenant_name', + 'binding_vnic_type', + 'binding_profileT', + 'binding_host_id', + 'binding_vif_type', + 'binding_vif_detailsT' + ] + + headers = [ + 'MAC', + 'Admin', + 'Status', + 'Type', + 'IP', + 'VM', + 'VNIC', + 'Profile', + 'Host', + 'Type', + 'Details' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['fixed_ips', 'binding_profileT', 'binding_vif_detailsT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_ports_id(self, info, title=False): + if title: + self.my_output.default( + 'Port - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + item['itnd'] = [] + item['itnd'].append( + 'MAC: %s' % (item['mac_address']) + ) + item['itnd'].append( + 'ID: %s' % (item['id']) + ) + item['itnd'].append( + 'Tenant: %s' % (item['tenant_id']) + ) + item['itnd'].append( + 'Network: %s' % (item['network_id']) + ) + item['itnd'].append( + 'Device: %s' % (item['device_id']) + ) + order = [ + 'itnd', + 'fixed_ips.subnet_id', + 'security_groups' + ] + + headers = [ + 'Base', + 'Subnet', + 'Security Group' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['fixed_ips', 'itnd', 'security_groups'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def select_port(self, info): + self.my_output.default( + 'Select Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No port found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_ports(new_info, title=False, select=True) + + while True: + answer = input("Select port using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/quota/README.md b/lib/osp/quota/README.md new file mode 100644 index 00000000..fa74caf9 --- /dev/null +++ b/lib/osp/quota/README.md @@ -0,0 +1,2 @@ +create/delete quota +quota usage \ No newline at end of file diff --git a/lib/osp/quota/__init__.py b/lib/osp/quota/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/quota/api.py b/lib/osp/quota/api.py new file mode 100644 index 00000000..804bb306 --- /dev/null +++ b/lib/osp/quota/api.py @@ -0,0 +1,55 @@ +import time +import traceback + + +class OspQuotaApi(): + def __init__(self): + self.quota_mo = {} + + def get_quota_mo(self, tenant_ids, cache_enabled=True): + if cache_enabled: + cache_ready = True + for tenant_id in tenant_ids: + if tenant_id not in self.quota_mo or self.quota_mo[tenant_id] is None: + cache_ready = False + break + + if cache_ready: + return self.quota_mo + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_quota_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + for tenant_id in tenant_ids: + perform_api = True + if cache_enabled and tenant_id in self.quota_mo and self.quota_mo[tenant_id] is not None: + perform_api = False + + if perform_api: + self.quota_mo[tenant_id] = api_handler.quotas.get(tenant_id) + + self.log.osp( + 'get', + 'quotas', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_quota_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'quotas', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.quota_mo diff --git a/lib/osp/quota/info.py b/lib/osp/quota/info.py new file mode 100644 index 00000000..32938f96 --- /dev/null +++ b/lib/osp/quota/info.py @@ -0,0 +1,118 @@ +from lib import filter_helper + + +class OspQuotaInfo(): + def __init__(self): + self.quota = {} + + def get_quota_info(self, quota_mo): + if quota_mo is None: + return None + + info = quota_mo.to_dict() + info['__Output'] = {} + + return info + + def serialize_quota(self): + quota = [] + for tenant_id in self.quota: + item = self.quota[tenant_id] + item['tenant_id'] = tenant_id + quota.append( + item + ) + + return quota + + def get_quotas_info(self, tenant_ids, cache_enabled=True): + if cache_enabled: + cache_ready = True + for tenant_id in tenant_ids: + if tenant_id not in self.quota or self.quota[tenant_id] is None: + cache_ready = False + break + + if cache_ready: + return self.serialize_quota() + + managed_objects = self.get_quota_mo(tenant_ids, cache_enabled=cache_enabled) + if managed_objects is None: + return None + + for tenant_id in managed_objects: + self.quota[tenant_id] = self.get_quota_info( + managed_objects[tenant_id] + ) + + self.log.osp_mo( + 'quotas', + self.serialize_quota() + ) + + return self.serialize_quota() + + def match_quota(self, quota_info, quota_filter): + if quota_filter is None or len(quota_filter) == 0: + return True + + for ap_rule in quota_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, quota_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in quota_info: + if not filter_helper.match_string(value, quota_info['tenant_name']): + return False + + if not key_found: + self.log.error( + 'match_quota', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_quotas(self, object_filter=None, tenant_info=False, cache_enabled=True): + tenant_ids = self.get_tenant_ids() + if tenant_ids is None: + return None + + all_quotas = self.get_quotas_info(tenant_ids, cache_enabled=cache_enabled) + if all_quotas is None: + return None + + quotas = [] + + for quota_info in all_quotas: + if not self.match_quota(quota_info, object_filter): + continue + + if tenant_info: + quota_info['tenant_name'] = self.get_tenant_name( + quota_info['tenant_id'], + cache_enabled=cache_enabled + ) + + if not self.match_quota(quota_info, object_filter): + continue + + quotas.append( + quota_info + ) + + if tenant_info: + quotas = sorted( + quotas, + key=lambda i: i['tenant_name'] + ) + + return quotas diff --git a/lib/osp/quota/main.py b/lib/osp/quota/main.py new file mode 100644 index 00000000..70e849c7 --- /dev/null +++ b/lib/osp/quota/main.py @@ -0,0 +1,11 @@ +from lib.osp.quota.api import OspQuotaApi +from lib.osp.quota.info import OspQuotaInfo + + +class OspQuota( + OspQuotaApi, + OspQuotaInfo + ): + def __init__(self): + OspQuotaApi.__init__(self) + OspQuotaInfo.__init__(self) diff --git a/lib/osp/quota/output.py b/lib/osp/quota/output.py new file mode 100644 index 00000000..476d8141 --- /dev/null +++ b/lib/osp/quota/output.py @@ -0,0 +1,61 @@ +class OspQuotaOutput(): + def __init__(self): + pass + + def print_quotas(self, info, title=False): + if title: + self.my_output.default( + 'Quota [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenant_name', + 'instances', + 'cores', + 'ram', + 'fixed_ips', + 'floating_ips', + 'key_pairs', + 'metadata_items', + 'security_groups', + 'security_group_rules', + 'server_groups', + 'server_group_members', + 'injected_files', + 'injected_file_path_bytes', + 'injected_file_content_bytes' + ] + + headers = [ + 'Tenant', + 'Instance', + 'Core', + 'Memory', + 'Fixed IP', + 'Floating IP', + 'Key Pair', + 'Metadata', + 'SecGroups', + 'Rules', + 'ServerGroups', + 'Members', + 'Files', + 'PathBytes', + 'ContentBytes' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/osp/role/__init__.py b/lib/osp/role/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/role/api.py b/lib/osp/role/api.py new file mode 100644 index 00000000..cd34a7d4 --- /dev/null +++ b/lib/osp/role/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspRoleApi(): + def __init__(self): + self.role_mo = None + + def get_role_mo(self, cache_enabled=True): + if cache_enabled: + if self.role_mo is not None: + return self.role_mo + + api_handler = self.get_api_keystone(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_role_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.role_mo = api_handler.roles.list() + self.log.osp( + 'get', + 'roles', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_role_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'roles', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.role_mo diff --git a/lib/osp/role/info.py b/lib/osp/role/info.py new file mode 100644 index 00000000..5cd9d04e --- /dev/null +++ b/lib/osp/role/info.py @@ -0,0 +1,75 @@ +from lib import filter_helper + + +class OspRoleInfo(): + def __init__(self): + self.role = None + + def get_role_info(self, role_mo): + if role_mo is None: + return None + + info = role_mo.to_dict() + info['__Output'] = {} + + return info + + def get_roles_info(self, cache_enabled=True): + if cache_enabled: + if self.role is not None: + return self.role + + managed_objects = self.get_role_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.role = [] + for managed_object in managed_objects: + role_info = self.get_role_info( + managed_object + ) + self.role.append( + role_info + ) + + self.log.osp_mo( + 'roles', + self.role + ) + + return self.role + + def match_role(self, role_info, role_filter): + if role_filter is None or len(role_filter) == 0: + return True + + for ap_rule in role_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if not key_found: + self.log.error( + 'match_role', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_roles(self, object_filter=None, cache_enabled=True): + all_roles = self.get_roles_info(cache_enabled=cache_enabled) + if all_roles is None: + return None + + roles = [] + + for role_info in all_roles: + if not self.match_role(role_info, object_filter): + continue + + roles.append( + role_info + ) + + return roles diff --git a/lib/osp/role/main.py b/lib/osp/role/main.py new file mode 100644 index 00000000..fe555d20 --- /dev/null +++ b/lib/osp/role/main.py @@ -0,0 +1,11 @@ +from lib.osp.role.api import OspRoleApi +from lib.osp.role.info import OspRoleInfo + + +class OspRole( + OspRoleApi, + OspRoleInfo + ): + def __init__(self): + OspRoleApi.__init__(self) + OspRoleInfo.__init__(self) diff --git a/lib/osp/role/output.py b/lib/osp/role/output.py new file mode 100644 index 00000000..63c34610 --- /dev/null +++ b/lib/osp/role/output.py @@ -0,0 +1,35 @@ +class OspRoleOutput(): + def __init__(self): + pass + + def print_roles(self, info, title=False): + if title: + self.my_output.default( + 'Role [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'name' + ] + + headers = [ + 'Id', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/osp/router/README.md b/lib/osp/router/README.md new file mode 100644 index 00000000..8762c6a4 --- /dev/null +++ b/lib/osp/router/README.md @@ -0,0 +1 @@ +create/delete \ No newline at end of file diff --git a/lib/osp/router/__init__.py b/lib/osp/router/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/router/api.py b/lib/osp/router/api.py new file mode 100644 index 00000000..a293eb4e --- /dev/null +++ b/lib/osp/router/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspRouterApi(): + def __init__(self): + self.router_mo = None + + def get_router_mo(self, cache_enabled=True): + if cache_enabled: + if self.router_mo is not None: + return self.router_mo + + api_handler = self.get_api_neutron(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_router_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.router_mo = api_handler.list_routers()['routers'] + self.log.osp( + 'get', + 'routers', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_router_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'routers', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.router_mo diff --git a/lib/osp/router/info.py b/lib/osp/router/info.py new file mode 100644 index 00000000..9f98b56f --- /dev/null +++ b/lib/osp/router/info.py @@ -0,0 +1,268 @@ +from lib import filter_helper + + +class OspRouterInfo(): + def __init__(self): + self.router = None + + def get_router_info(self, router_mo): + if router_mo is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'tenant_id', + 'admin_state_up', + 'status', + 'availability_zones', + 'ha', + 'routes', + 'created_at', + 'updated_at' + ] + for key in keys: + info[key] = None + if key in router_mo: + info[key] = router_mo[key] + + info['network_id'] = router_mo['external_gateway_info']['network_id'] + info['fixed_ips'] = router_mo['external_gateway_info']['external_fixed_ips'] + info['snat'] = router_mo['external_gateway_info']['enable_snat'] + + if info['status'] == 'ACTIVE': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + if info['admin_state_up']: + info['adminTick'] = '\u2713' + info['__Output']['adminTick'] = 'Green' + else: + info['adminTick'] = '\u2717' + info['__Output']['adminTick'] = 'Green' + + if info['ha']: + info['haTick'] = '\u2713' + else: + info['haTick'] = '\u2717' + + if info['snat']: + info['snatTick'] = '\u2713' + else: + info['snatTick'] = '\u2717' + + info['created_age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + info['updated_age'] = self.convert_timestamp_to_age( + info['updated_at'], + on_error='--' + ) + + return info + + def get_routers_info(self, cache_enabled=True): + if cache_enabled: + if self.router is not None: + return self.router + + managed_objects = self.get_router_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'routers', + managed_objects + ) + + self.router = [] + for managed_object in managed_objects: + router_info = self.get_router_info( + managed_object + ) + self.router.append( + router_info + ) + + self.log.osp_mo( + 'routers.info', + self.router + ) + + return self.router + + def match_router(self, router_info, router_filter): + if router_filter is None or len(router_filter) == 0: + return True + + for ap_rule in router_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, router_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, router_info['name']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, router_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in router_info: + if not filter_helper.match_string(value, router_info['tenant_name']): + return False + + if key == 'network_id': + key_found = True + if not filter_helper.match_string(value, router_info['network_id']): + return False + + if key == 'network_name': + key_found = True + if 'network_name' in router_info: + if not filter_helper.match_string(value, router_info['network_name']): + return False + + if not key_found: + self.log.error( + 'match_router', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_routers(self, object_filter=None, tenant_info=False, network_info=False, subnet_info=False, port_info=False, cache_enabled=True): + all_routers = self.get_routers_info(cache_enabled=cache_enabled) + if all_routers is None: + return None + + routers = [] + + for router_info in all_routers: + if not self.match_router(router_info, object_filter): + continue + + if tenant_info: + router_info['tenant_name'] = self.get_tenant_name( + router_info['tenant_id'], + cache_enabled=cache_enabled + ) + + if not self.match_router(router_info, object_filter): + continue + + if network_info: + router_info['network_name'] = self.get_network_name( + router_info['network_id'], + cache_enabled=cache_enabled + ) + + if not self.match_router(router_info, object_filter): + continue + + if subnet_info: + for fixed_ip in router_info['fixed_ips']: + router_subnet_info = self.get_subnet( + fixed_ip['subnet_id'] + ) + if router_subnet_info is None: + self.log.error( + 'get_routers', + 'Failed to find subnet: %s' % (fixed_ip['subnet_id']) + ) + else: + fixed_ip['subnet_name'] = router_subnet_info['name'] + fixed_ip['gateway_ip'] = router_subnet_info['gateway_ip'] + fixed_ip['cidr'] = router_subnet_info['cidr'] + + if not self.match_router(router_info, object_filter): + continue + + if port_info: + router_info['port_info'] = [] + for fixed_ip in router_info['fixed_ips']: + router_port_filter = [] + router_port_filter.append( + 'subnet_id:%s' % (fixed_ip['subnet_id']) + ) + router_port_info = self.get_ports( + object_filter=router_port_filter, + vm_info=True + ) + if router_port_info is None: + self.log.error( + 'get_routers', + 'Failed to get subnet ports: %s' % (fixed_ip['subnet_id']) + ) + else: + for rpi in router_port_info: + if rpi['type'] == 'Floating' and rpi['vm_tenant_name'] is None: + port_details = self.get_floating_ip_port( + floating_ip=rpi['ips'] + ) + if port_details is not None: + rpi['vm_tenant_name'] = port_details['vm_name'] + + router_info['port_info'] = router_info['port_info'] + router_port_info + + if not self.match_router(router_info, object_filter): + continue + + routers.append( + router_info + ) + + routers = sorted( + routers, + key=lambda i: i['name'].lower() + ) + + return routers + + def get_router(self, router_id=None, router_name=None, tenant_info=False, network_info=False, port_info=False, cache_enabled=True): + object_filter = [] + if router_id is not None: + object_filter.append( + 'id:%s' % (router_id) + ) + if router_name is not None: + object_filter.append( + 'name:%s' % (router_name) + ) + + routers = self.get_routers( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + port_info=port_info, + cache_enabled=cache_enabled + ) + if routers is None or len(routers) != 1: + return None + + return routers[0] + + def get_router_name(self, router_id, cache_enabled=True): + router_info = self.get_router( + router_id=router_id, + cache_enabled=cache_enabled + ) + if router_info is None: + return None + return router_info['name'] diff --git a/lib/osp/router/main.py b/lib/osp/router/main.py new file mode 100644 index 00000000..bd703c39 --- /dev/null +++ b/lib/osp/router/main.py @@ -0,0 +1,11 @@ +from lib.osp.router.api import OspRouterApi +from lib.osp.router.info import OspRouterInfo + + +class OspRouter( + OspRouterApi, + OspRouterInfo + ): + def __init__(self): + OspRouterApi.__init__(self) + OspRouterInfo.__init__(self) diff --git a/lib/osp/router/output.py b/lib/osp/router/output.py new file mode 100644 index 00000000..7f320ab9 --- /dev/null +++ b/lib/osp/router/output.py @@ -0,0 +1,212 @@ +import copy + + +class OspRouterOutput(): + def __init__(self): + pass + + def print_routers(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Router [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'name', + 'tenant_name', + 'adminTick', + 'status', + 'haTick', + 'snatTick', + 'network_name', + 'fixed_ips.subnet_name', + 'fixed_ips.cidr', + 'fixed_ips.gateway_ip', + 'fixed_ips.ip_address', + 'created_age' + ] + + headers = headers + [ + 'Name', + 'Tenant', + 'Admin', + 'Status', + 'HA', + 'SNAT', + 'Network', + 'Subnet', + 'CIDR', + 'Gateway', + 'IP', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fixed_ips'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_routers_port(self, info, title=False): + if title: + self.my_output.default( + 'Router - Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + if item['tenant_name'] is None: + item['extended_name'] = item['name'] + else: + item['extended_name'] = '%s/%s' % ( + item['tenant_name'], + item['name'] + ) + + if len(item['port_info']) == 0: + item['port_info'].append( + dict( + mac_address='--', + ips='--', + type='--', + vm_tenant_name='--' + ) + ) + + for port in item['port_info']: + if port['vm_tenant_name'] is None: + port['vm_tenant_name'] = '--' + + order = [ + 'extended_name', + 'port_info.mac_address', + 'port_info.ips', + 'port_info.type', + 'port_info.vm_tenant_name' + ] + + headers = [ + 'Name', + 'MAC', + 'IP', + 'Type', + 'VM' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['port_info'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_routers_id(self, info, title=False): + if title: + self.my_output.default( + 'Router - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'id', + 'tenant_id', + 'network_id', + 'fixed_ips.subnet_id' + ] + + headers = [ + 'Name', + 'Id', + 'Tenant', + 'Network', + 'Subnet' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['fixed_ips'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def select_router(self, info): + self.my_output.default( + 'Select Router [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No router found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_routers(new_info, title=False, select=True) + + while True: + answer = input("Select router using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/security_group/README.md b/lib/osp/security_group/README.md new file mode 100644 index 00000000..bb05faea --- /dev/null +++ b/lib/osp/security_group/README.md @@ -0,0 +1 @@ +create/delete sg \ No newline at end of file diff --git a/lib/osp/security_group/__init__.py b/lib/osp/security_group/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/security_group/api.py b/lib/osp/security_group/api.py new file mode 100644 index 00000000..cca75d8e --- /dev/null +++ b/lib/osp/security_group/api.py @@ -0,0 +1,123 @@ +import time +import json +import traceback + + +class OspSecurityGroupApi(): + def __init__(self): + self.security_group_mo = None + + def get_security_group_mo(self, cache_enabled=True): + if cache_enabled: + if self.security_group_mo is not None: + return self.security_group_mo + + api_handler = self.get_api_neutron(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_security_group_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.security_group_mo = api_handler.list_security_groups()['security_groups'] + self.log.osp( + 'get', + 'security_groups', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_security_group_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'security_groups', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.security_group_mo + + def create_security_group_rule_mo( + self, + security_group_id, + ethertype, + protocol, + direction, + port_range_min = None, + port_range_max = None, + remote_ip_prefix = '0.0.0.0/0', + description = None + ): + try: + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_security_group_rule_mo', + 'No api handler' + ) + return None + + # https://docs.openstack.org/tempest/latest/_modules/network/test_security_groups.html + body = {} + body['security_group_rule'] = {} + body['security_group_rule']['security_group_id'] = security_group_id + body['security_group_rule']['ethertype'] = ethertype + body['security_group_rule']['protocol'] = protocol + body['security_group_rule']['direction'] = direction + body['security_group_rule']['remote_ip_prefix'] = remote_ip_prefix + if description is not None: + body['security_group_rule']['description'] = description + if port_range_min is not None: + body['security_group_rule']['port_range_min'] = port_range_min + if port_range_max is not None: + body['security_group_rule']['port_range_max'] = port_range_max + + self.log.debug( + 'create_security_group_rule_mo', + 'Create security group rule: %s' % (json.dumps(body, indent=4)) + ) + ret = api_handler.create_security_group_rule(body=body) + rule_id = ret['security_group_rule']['id'] + + except BaseException: + self.log.error( + 'create_security_group_rule_mo', + 'Neutron API exception' + ) + self.log.error( + 'create_security_group_rule_mo', + traceback.format_exc() + ) + return None + + return rule_id + + def delete_security_group_rule_mo(self, security_group_rule_id): + try: + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_security_group_rule_mo', + 'No api handler' + ) + return False + + api_handler.delete_security_group_rule(security_group_rule_id) + + except BaseException: + self.log.error( + 'delete_security_group_rule_mo', + 'Neutron API exception' + ) + self.log.error( + 'delete_security_group_rule_mo', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/security_group/info.py b/lib/osp/security_group/info.py new file mode 100644 index 00000000..f766a08b --- /dev/null +++ b/lib/osp/security_group/info.py @@ -0,0 +1,373 @@ +from lib import filter_helper + + +class OspSecurityGroupInfo(): + def __init__(self): + self.security_group = None + + def get_security_group_info(self, security_group_mo): + if security_group_mo is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'tenant_id', + 'description', + 'created_at', + 'updated_at' + ] + + for key in keys: + info[key] = None + if key in security_group_mo: + info[key] = security_group_mo[key] + + info['rule'] = [] + for rule_mo in security_group_mo['security_group_rules']: + rule_info = {} + rule_info['__Output'] = {} + + keys = [ + 'id', + 'ethertype', + 'direction', + 'protocol', + 'port_range_min', + 'port_range_max', + 'remote_ip_prefix', + 'remote_group_id', + 'created_at', + 'updated_at' + ] + for key in keys: + rule_info[key] = None + if key in rule_mo: + rule_info[key] = rule_mo[key] + + rule_info['port_range'] = None + if rule_info['port_range_min'] is not None and rule_info['port_range_max'] is not None: + rule_info['port_range'] = '%s-%s' % ( + rule_info['port_range_min'], + rule_info['port_range_max'] + ) + + rule_info['create_age'] = self.convert_timestamp_to_age( + rule_info['created_at'], + on_error='--' + ) + + rule_info['update_age'] = self.convert_timestamp_to_age( + rule_info['updated_at'], + on_error='--' + ) + + info['rule'].append( + rule_info + ) + + info['rule'] = sorted( + info['rule'], + key=lambda i:( + i['ethertype'], + i['direction'] + ) + ) + + info['rule_count'] = len( + info['rule'] + ) + + info['create_age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + info['update_age'] = self.convert_timestamp_to_age( + info['updated_at'], + on_error='--' + ) + + return info + + def get_security_groups_info(self, cache_enabled=True): + if cache_enabled: + if self.security_group is not None: + return self.security_group + + managed_objects = self.get_security_group_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.security_group = [] + for managed_object in managed_objects: + security_group_info = self.get_security_group_info( + managed_object + ) + self.security_group.append( + security_group_info + ) + + self.log.osp_mo( + 'security_groups', + self.security_group + ) + + return self.security_group + + def match_security_group(self, security_group_info, security_group_filter): + if security_group_filter is None or len(security_group_filter) == 0: + return True + + for ap_rule in security_group_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, security_group_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, security_group_info['name']): + return False + + if key == 'names': + key_found = True + found = False + for item in value.split(','): + (tenant_name, name) = item.split('/') + if 'tenant_name' in security_group_info and 'name' in security_group_info: + if filter_helper.match_string(tenant_name, security_group_info['tenant_name']): + if filter_helper.match_string(name, security_group_info['name']): + found = True + break + + if not found: + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, security_group_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in security_group_info: + if not filter_helper.match_string(value, security_group_info['tenant_name']): + return False + + if key == 'vm_name': + key_found = True + if 'port' in security_group_info: + found = False + for port_info in security_group_info['port']: + if filter_helper.match_string(value, port_info['vm_tenant_name']): + found = True + break + + if not found: + return False + + if key == 'mac': + key_found = True + if 'port' in security_group_info: + found = False + for port_info in security_group_info['port']: + if filter_helper.match_mac(value, port_info['mac_address']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_security_group', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_security_groups(self, object_filter=None, tenant_info=False, rule_info=False, port_info=False, cache_enabled=True): + all_security_groups = self.get_security_groups_info(cache_enabled=cache_enabled) + if all_security_groups is None: + return None + + security_groups = [] + + for security_group_info in all_security_groups: + if not self.match_security_group(security_group_info, object_filter): + continue + + if tenant_info: + security_group_info['tenant_name'] = '' + if len(security_group_info['tenant_id']) > 0: + security_group_info['tenant_name'] = self.get_tenant_name( + security_group_info['tenant_id'] + ) + + if not self.match_security_group(security_group_info, object_filter): + continue + + if rule_info: + for rule in security_group_info['rule']: + rule['remote_group_name'] = None + if rule['remote_group_id'] is not None: + for sg_info in all_security_groups: + if sg_info['id'] == rule['remote_group_id']: + remote_group_tenant = self.get_tenant_name( + sg_info['tenant_id'] + ) + if remote_group_tenant is None: + remote_group_tenant = '--' + + rule['remote_group_name'] = '%s/%s' % ( + remote_group_tenant, + sg_info['name'] + ) + + if not self.match_security_group(security_group_info, object_filter): + continue + + if port_info: + port_object_filter = [] + if len(security_group_info['tenant_name']) == 0: + port_object_filter.append( + 'sg:%s' % (security_group_info['name']) + ) + else: + port_object_filter.append( + 'sg:%s/%s' % ( + security_group_info['tenant_name'], + security_group_info['name'] + ) + ) + + security_group_info['port'] = self.get_ports( + object_filter=port_object_filter, + security_info=True, + vm_info=True + ) + + if not self.match_security_group(security_group_info, object_filter): + continue + + security_groups.append( + security_group_info + ) + + if tenant_info: + security_groups = sorted( + security_groups, + key=lambda i: ( + i['tenant_name'], + i['name'] + ) + ) + else: + security_groups = sorted( + security_groups, + key=lambda i: i['name'] + ) + + return security_groups + + def get_security_group_tenant_name(self, security_group_id, cache_enabled=True): + object_filter = [] + object_filter.append( + 'id:%s' % (security_group_id) + ) + security_groups_info = self.get_security_groups( + object_filter=object_filter, + tenant_info=True, + cache_enabled=cache_enabled + ) + if security_groups_info is None or len(security_groups_info) != 1: + return None + + tenant_name = security_groups_info[0]['tenant_name'] + if tenant_name is None or len(tenant_name) == 0: + return '--/%s' % (security_groups_info[0]['name']) + + return '%s/%s' % (tenant_name, security_groups_info[0]['name']) + + def get_security_group(self, security_group_id=None, security_group_name=None, tenant_id=None, tenant_name=None, tenant_info=False, rule_info=False, port_info=False, cache_enabled=True): + if security_group_id is None and security_group_name is None: + self.log.error( + 'get_security_group', + 'security group id or name expected' + ) + return None + + if security_group_name is not None: + if tenant_id is None and tenant_name is None: + self.log.error( + 'get_security_group', + 'tenant id or name expected' + ) + return None + + object_filter = [] + if security_group_id is not None: + object_filter.append( + 'id:%s' % (security_group_id) + ) + + if security_group_name is not None: + object_filter.append( + 'name:%s' % (security_group_name) + ) + + if tenant_id is not None: + object_filter.append( + 'tenant_id:%s' % (tenant_id) + ) + + if tenant_name is not None: + object_filter.append( + 'tenant_name:%s' % (tenant_name) + ) + + security_groups = self.get_security_groups( + object_filter=object_filter, + tenant_info=tenant_info, + rule_info=rule_info, + port_info=port_info, + cache_enabled=cache_enabled + ) + if security_groups is None or len(security_groups) != 1: + return None + + return security_groups[0] + + def get_security_group_rule(self, security_group_rule_id, security_group_id = None): + if security_group_id is None: + security_groups = self.get_security_groups( + rule_info=True + ) + else: + security_group_info = self.get_security_group( + security_group_id=security_group_id + ) + if security_group_info is None: + return None + security_groups = [security_group_info] + + for security_group in security_groups: + for rule in security_group['rule']: + if rule['id'] == security_group_rule_id: + return rule + + return None + + def is_security_group_rule(self, security_group_rule_id, security_group_id = None): + if self.get_security_group_rule(security_group_rule_id, security_group_id=security_group_id) is None: + return False + return True diff --git a/lib/osp/security_group/main.py b/lib/osp/security_group/main.py new file mode 100644 index 00000000..c9ab401a --- /dev/null +++ b/lib/osp/security_group/main.py @@ -0,0 +1,11 @@ +from lib.osp.security_group.api import OspSecurityGroupApi +from lib.osp.security_group.info import OspSecurityGroupInfo + + +class OspSecurityGroup( + OspSecurityGroupApi, + OspSecurityGroupInfo + ): + def __init__(self): + OspSecurityGroupApi.__init__(self) + OspSecurityGroupInfo.__init__(self) diff --git a/lib/osp/security_group/output.py b/lib/osp/security_group/output.py new file mode 100644 index 00000000..138d1d76 --- /dev/null +++ b/lib/osp/security_group/output.py @@ -0,0 +1,321 @@ +import copy + + +class OspSecurityGroupOutput(): + def __init__(self): + pass + + def print_security_groups(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Security Group [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None or len(item['tenant_name']) == 0: + item['tenant_name'] = '--' + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'tenant_name', + 'name', + 'rule_count', + 'create_age', + 'update_age' + ] + + headers = headers + [ + 'Tenant', + 'Name', + 'Rule Count', + 'Create', + 'Update' + ] + + self.my_output.my_table( + new_info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_security_groups_rule(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Security Group - Rule [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None or len(item['tenant_name']) == 0: + item['tenant_name'] = '--' + + for rule in item['rule']: + if rule['protocol'] is None: + rule['protocol'] = '--' + + if rule['port_range'] is None: + rule['port_range'] = '--' + + if rule['remote_ip_prefix'] is None: + rule['remote_ip_prefix'] = '--' + + if rule['remote_group_name'] is None: + rule['remote_group_name'] = '--' + + order = [ + 'tenant_name', + 'name' + ] + headers = [ + 'Tenant', + 'Name' + ] + if select: + order.append('rule.__id') + headers.append('Index') + + order = order + [ + 'rule.ethertype', + 'rule.direction', + 'rule.protocol', + 'rule.port_range', + 'rule.remote_ip_prefix', + 'rule.remote_group_name', + 'rule.create_age', + 'rule.update_age' + ] + + headers = headers + [ + 'EtherType', + 'Direction', + 'Protocol', + 'Port Range', + 'Remote Prefix', + 'Remote Group', + 'Create', + 'Update' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['rule'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_security_groups_port(self, info, title=False): + if title: + self.my_output.default( + 'Security Group - Port and Rule [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None or len(item['tenant_name']) == 0: + item['tenant_name'] = '--' + + for rule in item['rule']: + if rule['protocol'] is None: + rule['protocol'] = '--' + + if rule['port_range'] is None: + rule['port_range'] = '--' + + if rule['remote_ip_prefix'] is None: + rule['remote_ip_prefix'] = '--' + + if rule['remote_group_name'] is None: + rule['remote_group_name'] = '--' + + for port in item['port']: + if port['vm_tenant_name'] is None: + port['vm_tenant_name'] = '--' + + order = [ + 'tenant_name', + 'name', + 'port.mac_address', + 'port.vm_tenant_name', + 'rule.ethertype', + 'rule.direction', + 'rule.protocol', + 'rule.port_range', + 'rule.remote_ip_prefix', + 'rule.remote_group_name' + ] + + headers = [ + 'Tenant', + 'Name', + 'MAC', + 'VM', + 'EtherType', + 'Direction', + 'Protocol', + 'Port Range', + 'Remote Prefix', + 'Remote Group' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['port', 'rule'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_security_groups_id(self, info, title=False): + if title: + self.my_output.default( + 'Security Group - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'tenant_id', + 'rule.id' + ] + + headers = [ + 'Name', + 'Tenant', + 'Rule' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['rule'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def select_security_group(self, info): + self.my_output.default( + 'Select Security Group [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No security group found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_security_groups(new_info, title=False, select=True) + + while True: + answer = input("Select security group using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item + + def select_security_group_rule(self, info): + self.my_output.default( + 'Select Security Group Rule [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No security group found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + for rule in item['rule']: + rule['__id'] = index + index = index + 1 + + self.print_security_groups_rule(new_info, title=False, select=True) + + while True: + answer = input("Select security group rule using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + for rule in item['rule']: + if rule['__id'] == int(answer): + return rule diff --git a/lib/osp/settings.py b/lib/osp/settings.py new file mode 100644 index 00000000..12826726 --- /dev/null +++ b/lib/osp/settings.py @@ -0,0 +1,359 @@ +import os +import json +import shutil +import traceback + +from lib import filter_helper +from lib import file_helper +from lib import log_helper +from lib.settings_helper import Settings +from lib.cvim import settings as cvim_settings + + +class OspSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.openstack_settings_filename = os.path.join( + self.settings_dir, + 'osp' + ) + + self.openstack_clusters_directory = os.path.join( + self.settings_dir, + 'osp-clusters' + ) + + if not self.initialize_openstack_settings(): + raise ValueError('Openstack settings initialization failed') + + def get_openstack_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Defaults'] = {} + settings['Defaults']['Cluster'] = None + settings['Clusters'] = [] + return settings + + def initialize_openstack_settings(self): + if not os.path.isfile(self.openstack_settings_filename): + settings = self.get_openstack_default_settings() + if not self.set_openstack_settings(settings): + return False + + if not os.path.isdir(self.openstack_clusters_directory): + os.makedirs( + self.openstack_clusters_directory, + exist_ok=True + ) + + if not self.import_cvim_settings(): + return False + + return True + + def delete_cvim_clusters(self): + clusters = self.get_openstack_clusters() + if clusters is not None: + for cluster in clusters: + if cluster['source'] == 'import': + if not self.delete_openstack_cluster(cluster['name']): + self.log.error( + 'delete_cvim_clusters', + 'Cluster delete failed: %s' % (cluster['name']) + ) + return False + + return True + + def import_cvim_settings(self): + default_cluster_name = self.get_default_cluster() + + if not self.delete_cvim_clusters(): + return False + + cvim_settings_handler = cvim_settings.CvimSettings( + log_id=self.log_id + ) + cvim_clusters = cvim_settings_handler.get_cvim_clusters() + for cvim_cluster in cvim_clusters: + if not self.set_openstack_cluster('%s' % (cvim_cluster['name']), cvim_cluster['openrc'], cluster_source='import'): + self.log.error( + 'import_cvim_settings', + 'Failed to add cvim cluster: %s' % (cvim_cluster['name']) + ) + return False + + if self.get_openstack_cluster(default_cluster_name) is not None: + self.set_default_cluster(default_cluster_name) + + return True + + def get_openstack_settings(self): + if not os.path.isfile(self.openstack_settings_filename): + return None + + try: + with open(self.openstack_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_openstack_settings', traceback.format_exc()) + return None + + return settings + + def set_openstack_settings(self, settings): + try: + with open(self.openstack_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_openstack_settings', traceback.format_exc()) + return False + + return True + + def get_default_cluster(self): + settings = self.get_openstack_settings() + if settings is None: + return None + + try: + default_cluster_name = settings['Defaults']['Cluster'] + except BaseException: + default_cluster_name = None + + return default_cluster_name + + def set_default_cluster(self, name): + settings = self.get_openstack_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Cluster'] = name + return self.set_openstack_settings(settings) + + def get_openstack_cluster_names(self): + clusters = self.get_openstack_clusters() + if clusters is None: + return None + + names = [] + for cluster in clusters: + names.append( + cluster['name'] + ) + + return names + + def match_cluster(self, cluster_settings, cluster_filter): + if cluster_filter is None or len(cluster_filter) == 0: + return True + + for ap_rule in cluster_filter: + (key, value) = ap_rule.split(':') + + key_found = False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, cluster_settings['name']): + return False + + if not key_found: + self.log.error( + 'match_cluster', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_openstack_clusters(self, cluster_filter=None): + settings = self.get_openstack_settings() + if settings is None: + return None + + all_clusters = settings['Clusters'] + clusters = [] + for cluster in all_clusters: + if not self.match_cluster(cluster, cluster_filter): + continue + + clusters.append( + cluster + ) + + clusters = sorted( + clusters, + key=lambda i: i['name'] + ) + + return clusters + + def get_openstack_cluster(self, openstack_name, strict_match=True): + clusters = self.get_openstack_clusters() + if clusters is None: + return None + + candidates = [] + for cluster in clusters: + if cluster['name'] == openstack_name: + return cluster + + if not strict_match: + if openstack_name.lower() in cluster['name'].lower(): + candidates.append(cluster) + + if not strict_match and len(candidates) == 1: + return candidates[0] + + return None + + def set_openstack_clusters(self, clusters): + settings = self.get_openstack_settings() + if settings is None: + return False + + settings['Clusters'] = clusters + return self.set_openstack_settings(settings) + + def get_openstack_cluster_directory(self, openstack_name): + cluster_directory = os.path.join( + self.openstack_clusters_directory, + openstack_name + ) + return cluster_directory + + def parse_openrc(self, openrc_filename): + content = file_helper.get_file_text(openrc_filename) + if content is None: + self.log.error( + 'parse_openrc', + 'Openrc file read failed: %s' % (openrc_filename) + ) + return None + + openrc_content = {} + + for line in content.split('\n'): + if line.startswith('export '): + (key, value) = line.split('export ')[1].split('=') + openrc_content[key.upper()] = value + + return openrc_content + + def set_openstack_cluster(self, openstack_name, openrc_filename, cluster_type='standard', cert_filename=None, cluster_source='user'): + if not os.path.isfile(openrc_filename): + self.log.error( + 'set_openstack_cluster', + 'Openrc file not found: %s' % (openrc_filename) + ) + return False + + openrc_content = self.parse_openrc( + openrc_filename + ) + if openrc_content is None: + return False + + if cert_filename is not None: + if not os.path.isfile(cert_filename): + self.log.error( + 'set_openstack_cluster', + 'Cert file not found: %s' % (openrc_filename) + ) + return False + + clusters = self.get_openstack_clusters() + if clusters is None: + return False + + new_clusters = [] + for cluster in clusters: + if cluster['name'] != openstack_name: + new_clusters.append(cluster) + + cluster_directory = self.get_openstack_cluster_directory(openstack_name) + if not os.path.isdir(cluster_directory): + os.makedirs( + cluster_directory, + exist_ok=True + ) + + target_openrc_filename = os.path.join( + cluster_directory, + 'openrc' + ) + + shutil.copy( + openrc_filename, + target_openrc_filename + ) + if not os.path.isfile(target_openrc_filename): + self.log.error( + 'set_openstack_cluster', + 'Kubeconfig file copy failed: %s => %s' % (openrc_filename, target_openrc_filename) + ) + return False + + target_cert_filename = None + if cert_filename is not None: + target_cert_filename = os.path.join( + cluster_directory, + 'cert' + ) + + shutil.copy( + cert_filename, + target_cert_filename + ) + if not os.path.isfile(target_cert_filename): + self.log.error( + 'set_openstack_cluster', + 'Cert file copy failed: %s => %s' % (cert_filename, target_cert_filename) + ) + return False + + openrc_content['OS_CACERT'] = target_cert_filename + + new_cluster = {} + new_cluster['name'] = openstack_name + new_cluster['export'] = openrc_content + new_cluster['openrc'] = target_openrc_filename + new_cluster['cert'] = target_cert_filename + new_cluster['type'] = cluster_type + new_cluster['source'] = cluster_source + + new_clusters.append(new_cluster) + + return self.set_openstack_clusters(new_clusters) + + def delete_openstack_cluster(self, openstack_name): + clusters = self.get_openstack_clusters() + if clusters is None: + return False + + default_cluster = self.get_default_cluster() + if default_cluster is not None and default_cluster == openstack_name: + self.set_default_cluster(None) + + new_clusters = [] + for cluster in clusters: + if cluster['name'] != openstack_name: + new_clusters.append(cluster) + + cluster_directory = os.path.join( + self.openstack_clusters_directory, + openstack_name + ) + if os.path.isdir(cluster_directory): + shutil.rmtree(cluster_directory) + + return self.set_openstack_clusters(new_clusters) diff --git a/lib/osp/snapshot/__init__.py b/lib/osp/snapshot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/snapshot/api.py b/lib/osp/snapshot/api.py new file mode 100644 index 00000000..5645a3a7 --- /dev/null +++ b/lib/osp/snapshot/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspSnapshotApi(): + def __init__(self): + self.snapshot_mo = None + + def get_snapshot_mo(self, cache_enabled=True): + if cache_enabled: + if self.snapshot_mo is not None: + return self.snapshot_mo + + api_handler = self.get_api_cinder(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_snapshot_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.snapshot_mo = api_handler.volume_snapshots.list() + self.log.osp( + 'get', + 'snapshots', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_snapshot_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'snapshots', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.snapshot_mo diff --git a/lib/osp/snapshot/info.py b/lib/osp/snapshot/info.py new file mode 100644 index 00000000..fc315d85 --- /dev/null +++ b/lib/osp/snapshot/info.py @@ -0,0 +1,179 @@ +from lib import filter_helper + + +class OspSnapshotInfo(): + def __init__(self): + self.snapshot = None + + def get_snapshots_properties(self, managed_objects): + properties = [] + for managed_object in managed_objects: + properties.append( + managed_object.to_dict() + ) + return properties + + def get_snapshot_info(self, snapshot_mo): + if snapshot_mo is None: + return None + + properties = snapshot_mo.to_dict() + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'description', + 'volume_id', + 'status', + 'size', + 'metadata', + 'created_at', + 'updated_at' + ] + for key in keys: + info[key] = None + if key in properties: + info[key] = properties[key] + + info['tenant_id'] = None + if 'os-extended-snapshot-attributes:project_id' in properties: + info['tenant_id'] = properties['os-extended-snapshot-attributes:project_id'] + + info['progress'] = None + if 'os-extended-snapshot-attributes:progress' in properties: + info['progress'] = properties['os-extended-snapshot-attributes:progress'] + + if info['status'] == 'available': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + info['created_age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + info['updated_age'] = self.convert_timestamp_to_age( + info['updated_at'], + on_error='--' + ) + + return info + + def get_snapshots_info(self, cache_enabled=True): + if cache_enabled: + if self.snapshot is not None: + return self.snapshot + + managed_objects = self.get_snapshot_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'snapshots', + self.get_snapshots_properties(managed_objects) + ) + + self.snapshot = [] + for managed_object in managed_objects: + snapshot_info = self.get_snapshot_info( + managed_object + ) + self.snapshot.append( + snapshot_info + ) + + self.log.osp_mo( + 'snapshots.info', + self.snapshot + ) + + return self.snapshot + + def match_snapshot(self, snapshot_info, snapshot_filter): + if snapshot_filter is None or len(snapshot_filter) == 0: + return True + + for ap_rule in snapshot_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'name': + key_found = True + if len(value.split('/')) == 1: + if not filter_helper.match_string(value, snapshot_info['name']): + return False + if len(value.split('/')) == 2: + if not filter_helper.match_string(value.split('/')[1], snapshot_info['name']): + return False + + if 'tenant_name' in snapshot_info: + if not filter_helper.match_string(value.split('/')[0], snapshot_info['tenant_name']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, snapshot_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in snapshot_info: + if not filter_helper.match_string(value, snapshot_info['tenant_name']): + return False + + if key == 'volume_id': + key_found = True + if not filter_helper.match_string(value, snapshot_info['volume_id']): + return False + + if key == 'volume_name': + key_found = True + if 'volume_name' in snapshot_info: + if not filter_helper.match_string(value, snapshot_info['volume_name']): + return False + + if not key_found: + self.log.error( + 'match_snapshot', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_snapshots(self, object_filter=None, tenant_info=False, volume_info=False, cache_enabled=True): + all_snapshots = self.get_snapshots_info(cache_enabled=cache_enabled) + if all_snapshots is None: + return None + + snapshots = [] + + for snapshot_info in all_snapshots: + if not self.match_snapshot(snapshot_info, object_filter): + continue + + if tenant_info: + snapshot_info['tenant_name'] = self.get_tenant_name( + snapshot_info['tenant_id'], + cache_enabled=cache_enabled + ) + if not self.match_snapshot(snapshot_info, object_filter): + continue + + if volume_info: + snapshot_info['volume_name'] = self.get_volume_name( + snapshot_info['volume_id'], + cache_enabled=cache_enabled + ) + if not self.match_snapshot(snapshot_info, object_filter): + continue + + snapshots.append( + snapshot_info + ) + + return snapshots diff --git a/lib/osp/snapshot/main.py b/lib/osp/snapshot/main.py new file mode 100644 index 00000000..f95744c2 --- /dev/null +++ b/lib/osp/snapshot/main.py @@ -0,0 +1,11 @@ +from lib.osp.snapshot.api import OspSnapshotApi +from lib.osp.snapshot.info import OspSnapshotInfo + + +class OspSnapshot( + OspSnapshotApi, + OspSnapshotInfo + ): + def __init__(self): + OspSnapshotApi.__init__(self) + OspSnapshotInfo.__init__(self) diff --git a/lib/osp/snapshot/output.py b/lib/osp/snapshot/output.py new file mode 100644 index 00000000..7f68a77d --- /dev/null +++ b/lib/osp/snapshot/output.py @@ -0,0 +1,77 @@ +class OspSnapshotOutput(): + def __init__(self): + pass + + def print_snapshots(self, info, title=False): + if title: + self.my_output.default( + 'Volume Snapshot [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'tenant_name', + 'volume_name', + 'size', + 'status', + 'progress', + 'created_age' + ] + + headers = [ + 'Name', + 'Tenant', + 'Volume', + 'Size', + 'Status', + 'Progress', + 'Age' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_snapshots_id(self, info, title=False): + if title: + self.my_output.default( + 'Volume Snapshot - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'name' + ] + + headers = [ + 'Id', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/osp/subnet/README.md b/lib/osp/subnet/README.md new file mode 100644 index 00000000..8762c6a4 --- /dev/null +++ b/lib/osp/subnet/README.md @@ -0,0 +1 @@ +create/delete \ No newline at end of file diff --git a/lib/osp/subnet/__init__.py b/lib/osp/subnet/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/subnet/api.py b/lib/osp/subnet/api.py new file mode 100644 index 00000000..8796717d --- /dev/null +++ b/lib/osp/subnet/api.py @@ -0,0 +1,130 @@ +import time +import json +import traceback + +from lib import ip_helper + + +class OspSubnetApi(): + def __init__(self): + self.subnet_mo = None + + def get_subnet_mo(self, cache_enabled=True): + if cache_enabled: + if self.subnet_mo is not None: + return self.subnet_mo + + api_handler = self.get_api_neutron(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_subnet_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.subnet_mo = api_handler.list_subnets()['subnets'] + self.log.osp( + 'get', + 'subnets', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_subnet_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'subnets', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.subnet_mo + + def create_subnet_mo(self, network_id, cidr, tenant_id=None, subnet_name=None, gateway=None, dns=None, dhcp=True, start_ip=None, end_ip=None): + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_subnet_ipv4_mo', + 'No api handler' + ) + return None + + if not ip_helper.is_valid_ipv4_cidr(cidr): + self.log.error( + 'create_subnet_mo', + 'IPv4 subnet supported only' + ) + return None + + subnet_mo = {} + subnet_mo['cidr'] = cidr + subnet_mo['ip_version'] = 4 + subnet_mo['network_id'] = network_id + subnet_mo['enable_dhcp'] = dhcp + + if subnet_name is not None: + subnet_mo['name'] = subnet_name + + if gateway is not None: + subnet_mo['gateway_ip'] = gateway + + if dns is not None: + if isinstance(dns, list): + subnet_mo['dns_nameservers'] = dns + if isinstance(dns, str): + subnet_mo['dns_nameservers'] = [dns] + + if tenant_id is not None: + subnet_mo['tenant_id'] = tenant_id + + if dhcp: + if start_ip is not None and end_ip is not None: + allocation_pool = {} + allocation_pool['start'] = start_ip + allocation_pool['end'] = end_ip + subnet_mo['allocation_pools'] = [allocation_pool] + + body = {} + body['subnets'] = [subnet_mo] + + self.log.debug( + 'create_subnet_mo', + json.dumps(body, indent=4) + ) + + try: + # https://wiki.openstack.org/wiki/Neutron/APIv2-specification + new_subnets = api_handler.create_subnet(body=body) + new_subnet = new_subnets['subnets'][0] + except BaseException: + self.log.error( + 'create_subnet_mo', + traceback.format_exc() + ) + return None + + return new_subnet + + def delete_subnet_mo(self, subnet_id): + api_handler = self.get_api_neutron(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_subnet_mo', + 'No api handler' + ) + return False + + try: + api_handler.delete_subnet(subnet_id) + except BaseException: + self.log.error( + 'delete_subnet_mo', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/subnet/info.py b/lib/osp/subnet/info.py new file mode 100644 index 00000000..84663f30 --- /dev/null +++ b/lib/osp/subnet/info.py @@ -0,0 +1,272 @@ +from lib import filter_helper +from lib import ip_helper + + +class OspSubnetInfo(): + def __init__(self): + self.subnet = None + + def get_subnet_info(self, subnet_mo): + if subnet_mo is None: + return None + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'tenant_id', + 'network_id', + 'ip_version', + 'subnetpool_id', + 'enable_dhcp', + 'ipv6_ra_mode', + 'ipv6_address_mode', + 'gateway_ip', + 'cidr', + 'allocation_pools', + 'host_routes', + 'dns_nameservers', + 'created_at', + 'updated_at' + ] + for key in keys: + info[key] = None + if key in subnet_mo: + info[key] = subnet_mo[key] + + if info['enable_dhcp']: + info['dhcpTick'] = '\u2713' + else: + info['dhcpTick'] = '\u2717' + + info['created_age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + info['updated_age'] = self.convert_timestamp_to_age( + info['updated_at'], + on_error='--' + ) + + return info + + def get_subnets_info(self, cache_enabled=True): + if cache_enabled: + if self.subnet is not None: + return self.subnet + + managed_objects = self.get_subnet_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'subnets', + managed_objects + ) + + self.subnet = [] + for managed_object in managed_objects: + subnet_info = self.get_subnet_info( + managed_object + ) + self.subnet.append( + subnet_info + ) + + self.log.osp_mo( + 'subnets.info', + self.subnet + ) + + return self.subnet + + def match_subnet(self, subnet_info, subnet_filter): + if subnet_filter is None or len(subnet_filter) == 0: + return True + + for ap_rule in subnet_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, subnet_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, subnet_info['name']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, subnet_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in subnet_info: + if not filter_helper.match_string(value, subnet_info['tenant_name']): + return False + + if key == 'network_id': + key_found = True + if not filter_helper.match_string(value, subnet_info['network_id']): + return False + + if key == 'network_name': + key_found = True + if 'network_name' in subnet_info: + if not filter_helper.match_string(value, subnet_info['network_name']): + return False + + if key == 'address': + key_found = True + if not ip_helper.is_ipv4_in_cidr(value, subnet_info['cidr']): + return False + + if key == 'mac': + key_found = True + if 'port_info' in subnet_info: + found = False + for port_info in subnet_info['port_info']: + if ip_helper.is_mac_match(value, port_info['mac_address']): + found = True + break + + if not found: + return False + + if key == 'vm_name': + key_found = True + if 'port_info' in subnet_info: + found = False + for port_info in subnet_info['port_info']: + if filter_helper.match_tenant_name(value, port_info['vm_tenant_name']): + found = True + break + + if not found: + return False + + if key == 'hv': + key_found = True + if 'port_info' in subnet_info: + found = False + for port_info in subnet_info['port_info']: + if port_info['binding_host_id'] is not None: + if filter_helper.match_string(value, port_info['binding_host_id']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_subnet', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_subnets(self, object_filter=None, tenant_info=False, network_info=False, port_info=False, cache_enabled=True): + all_subnets = self.get_subnets_info(cache_enabled=cache_enabled) + if all_subnets is None: + return None + + subnets = [] + + for subnet_info in all_subnets: + if not self.match_subnet(subnet_info, object_filter): + continue + + if tenant_info: + subnet_info['tenant_name'] = self.get_tenant_name( + subnet_info['tenant_id'], + cache_enabled=cache_enabled + ) + if not self.match_subnet(subnet_info, object_filter): + continue + + if network_info: + subnet_info['network_name'] = self.get_network_name( + subnet_info['network_id'], + cache_enabled=cache_enabled + ) + if not self.match_subnet(subnet_info, object_filter): + continue + + if port_info: + network_port_filter = [] + network_port_filter.append( + 'subnet_id:%s' % (subnet_info['id']) + ) + subnet_info['port_info'] = self.get_ports( + object_filter=network_port_filter, + vm_info=True + ) + + if not self.match_subnet(subnet_info, object_filter): + continue + + subnets.append( + subnet_info + ) + + return subnets + + def get_subnet(self, subnet_id=None, subnet_name=None, network_info=False, tenant_info=False, port_info=False, cache_enabled=True): + object_filter = [] + if subnet_id is not None: + object_filter.append( + 'id:%s' % (subnet_id) + ) + if subnet_name is not None: + object_filter.append( + 'name:%s' % (subnet_name) + ) + + subnets = self.get_subnets( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + port_info=port_info + ) + if subnets is None or len(subnets) != 1: + return None + + return subnets[0] + + def get_subnet_name(self, subnet_id, cache_enabled=True): + subnet_info = self.get_subnet( + subnet_id=subnet_id, + cache_enabled=cache_enabled + ) + if subnet_info is None: + return None + return subnet_info['name'] + + def get_subnet_network_name(self, subnet_id, cache_enabled=True): + subnet_info = self.get_subnet( + subnet_id=subnet_id, + network_info=True, + cache_enabled=cache_enabled + ) + if subnet_info is None: + return None + return subnet_info['network_name'] + + def is_subnet_name(self, subnet_name, cache_enabled=True): + subnet_info = self.get_subnet( + subnet_name=subnet_name, + cache_enabled=cache_enabled + ) + if subnet_info is None: + return False + return True diff --git a/lib/osp/subnet/main.py b/lib/osp/subnet/main.py new file mode 100644 index 00000000..840f640b --- /dev/null +++ b/lib/osp/subnet/main.py @@ -0,0 +1,11 @@ +from lib.osp.subnet.api import OspSubnetApi +from lib.osp.subnet.info import OspSubnetInfo + + +class OspSubnet( + OspSubnetApi, + OspSubnetInfo + ): + def __init__(self): + OspSubnetApi.__init__(self) + OspSubnetInfo.__init__(self) diff --git a/lib/osp/subnet/output.py b/lib/osp/subnet/output.py new file mode 100644 index 00000000..bfeb1593 --- /dev/null +++ b/lib/osp/subnet/output.py @@ -0,0 +1,236 @@ +import copy +import json + + +class OspSubnetOutput(): + def __init__(self): + pass + + def print_subnets(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Subnet [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + item['extended_name'] = [] + item['extended_name'].append( + item['name'] + ) + if item['tenant_name'] is None: + item['extended_name'].append( + 'Tenant: --' + ) + else: + item['extended_name'].append( + 'Tenant: %s' % (item['tenant_name']) + ) + + item['extended_name'].append( + 'Network: %s' % (item['network_name']) + ) + + if len(item['dns_nameservers']) == 0: + item['dns_nameservers'] = ['--'] + + if item['gateway_ip'] is None: + item['gateway_ip'] = '--' + + if len(item['allocation_pools']) == 0: + item['pool'] = ['--'] + else: + item['pool'] = json.dumps( + item['allocation_pools'], + indent=2 + ).split('\n') + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'extended_name', + 'cidr', + 'gateway_ip', + 'dhcpTick', + 'pool', + 'dns_nameservers', + 'created_age' + ] + + headers = headers + [ + 'Subnet', + 'CIDR', + 'Gateway', + 'DHCP', + 'Pool', + 'DNS', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['extended_name', 'pool', 'dns_nameservers'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_subnets_port(self, info, title=False): + if title: + self.my_output.default( + 'Subnet - Port [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['tenant_name'] is None: + item['extended_name'] = item['name'] + else: + item['extended_name'] = '%s/%s' % ( + item['tenant_name'], + item['name'] + ) + + if len(item['port_info']) == 0: + item['port_info'].append( + dict( + mac_address='--', + ips='--', + type='--', + vm_tenant_name='--' + ) + ) + + for port in item['port_info']: + if port['vm_tenant_name'] is None: + port['vm_tenant_name'] = '--' + + if 'binding_host_id' not in port or port['binding_host_id'] is None: + port['binding_host_id'] = '--' + + order = [ + 'extended_name', + 'cidr', + 'port_info.mac_address', + 'port_info.ips', + 'port_info.type', + 'port_info.vm_tenant_name', + 'port_info.binding_host_id' + ] + + headers = [ + 'Name', + 'CIDR', + 'MAC', + 'IP', + 'Type', + 'VM', + 'HV' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['port_info'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_subnets_id(self, info, title=False): + if title: + self.my_output.default( + 'Subnet - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'id', + 'name', + 'tenant_id' + ] + + headers = [ + 'Id', + 'Name', + 'Tenant' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def select_subnet(self, info): + self.my_output.default( + 'Select subnet [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No subnet found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_subnets(new_info, title=False, select=True) + + while True: + answer = input("Select subnet using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/tenant/__init__.py b/lib/osp/tenant/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/tenant/api.py b/lib/osp/tenant/api.py new file mode 100644 index 00000000..05f1116c --- /dev/null +++ b/lib/osp/tenant/api.py @@ -0,0 +1,46 @@ +import time +import traceback + + +class OspTenantApi(): + def __init__(self): + self.tenant_mo = None + + def get_tenant_mo(self, cache_enabled=True): + if cache_enabled: + if self.tenant_mo is not None: + return self.tenant_mo + + api_handler = self.get_api_keystone(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_tenant_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + if self.api_version == 2: + self.tenant_mo = api_handler.tenants.list() + if self.api_version == 3: + self.tenant_mo = api_handler.projects.list() + + self.log.osp( + 'get', + 'tenants', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_tenant_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'tenants', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.tenant_mo diff --git a/lib/osp/tenant/info.py b/lib/osp/tenant/info.py new file mode 100644 index 00000000..70e93d7a --- /dev/null +++ b/lib/osp/tenant/info.py @@ -0,0 +1,127 @@ +from lib import filter_helper + + +class OspTenantInfo(): + def __init__(self): + self.tenant = None + + def get_tenant_info(self, tenant_mo): + if tenant_mo is None: + return None + + info = tenant_mo.to_dict() + info['__Output'] = {} + + return info + + def get_tenants_info(self, cache_enabled=True): + if cache_enabled: + if self.tenant is not None: + return self.tenant + + managed_objects = self.get_tenant_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.tenant = [] + for managed_object in managed_objects: + tenant_info = self.get_tenant_info( + managed_object + ) + self.tenant.append( + tenant_info + ) + + self.log.osp_mo( + 'tenants', + self.tenant + ) + + return self.tenant + + def match_tenant(self, tenant_info, tenant_filter): + if tenant_filter is None or len(tenant_filter) == 0: + return True + + for ap_rule in tenant_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, tenant_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, tenant_info['name']): + return False + + if not key_found: + self.log.error( + 'match_tenant', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_tenants(self, object_filter=None, cache_enabled=True): + all_tenants = self.get_tenants_info(cache_enabled=cache_enabled) + if all_tenants is None: + return None + + tenants = [] + + for tenant_info in all_tenants: + if not self.match_tenant(tenant_info, object_filter): + continue + + tenants.append( + tenant_info + ) + + return tenants + + def get_tenant_ids(self, cache_enabled=True): + tenants = self.get_tenants(cache_enabled=cache_enabled) + if tenants is None: + return None + + ids = [] + for tenant in tenants: + ids.append( + tenant['id'] + ) + + return ids + + def get_tenant(self, tenant_id=None, tenant_name=None, cache_enabled=True): + object_filter = [] + if tenant_id is not None: + object_filter.append( + 'id:%s' % (tenant_id) + ) + if tenant_name is not None: + object_filter.append( + 'name:%s' % (tenant_name) + ) + + tenants = self.get_tenants( + object_filter=object_filter, + cache_enabled=cache_enabled + ) + if tenants is None or len(tenants) != 1: + return None + + return tenants[0] + + def get_tenant_name(self, tenant_id, cache_enabled=True): + tenant_info = self.get_tenant( + tenant_id=tenant_id, + cache_enabled=cache_enabled + ) + if tenant_info is None: + return None + return tenant_info['name'] diff --git a/lib/osp/tenant/main.py b/lib/osp/tenant/main.py new file mode 100644 index 00000000..05c23374 --- /dev/null +++ b/lib/osp/tenant/main.py @@ -0,0 +1,11 @@ +from lib.osp.tenant.api import OspTenantApi +from lib.osp.tenant.info import OspTenantInfo + + +class OspTenant( + OspTenantApi, + OspTenantInfo + ): + def __init__(self): + OspTenantApi.__init__(self) + OspTenantInfo.__init__(self) diff --git a/lib/osp/tenant/output.py b/lib/osp/tenant/output.py new file mode 100644 index 00000000..f75cd618 --- /dev/null +++ b/lib/osp/tenant/output.py @@ -0,0 +1,81 @@ +import copy + + +class OspTenantOutput(): + def __init__(self): + pass + + def print_tenants(self, info, title=False, select=False): + if title: + self.my_output.default( + 'Tenant [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [] + headers = [] + if select: + order.append('__id') + headers.append('Index') + + order = order + [ + 'id', + 'name' + ] + + headers = headers + [ + 'Id', + 'Name' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def select_tenant(self, info): + self.my_output.default( + 'Select tenant [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No tenant found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + + self.print_tenants(new_info, title=False, select=True) + + while True: + answer = input("Select tenant using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/user/__init__.py b/lib/osp/user/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/user/api.py b/lib/osp/user/api.py new file mode 100644 index 00000000..5bc19502 --- /dev/null +++ b/lib/osp/user/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspUserApi(): + def __init__(self): + self.user_mo = None + + def get_user_mo(self, cache_enabled=True): + if cache_enabled: + if self.user_mo is not None: + return self.user_mo + + api_handler = self.get_api_keystone(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_user_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.user_mo = api_handler.users.list() + self.log.osp( + 'get', + 'users', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_user_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'users', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.user_mo diff --git a/lib/osp/user/info.py b/lib/osp/user/info.py new file mode 100644 index 00000000..0653e5dd --- /dev/null +++ b/lib/osp/user/info.py @@ -0,0 +1,137 @@ +from lib import filter_helper + + +class OspUserInfo(): + def __init__(self): + self.user = None + + def get_user_info(self, user_mo): + if user_mo is None: + return None + + properties = user_mo.to_dict() + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'name', + 'domain_id', + 'enabled', + 'password_expires_at', + 'default_project_id' + ] + + for key in keys: + info[key] = None + if key in properties: + info[key] = properties[key] + + for key in properties['options']: + info[key] = properties['options'][key] + + if info['enabled']: + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + else: + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + + if info['password_expires_at'] is not None: + info['expiresTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Red' + else: + info['expiresTick'] = '--' + + return info + + def get_users_info(self, cache_enabled=True): + if cache_enabled: + if self.user is not None: + return self.user + + managed_objects = self.get_user_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.user = [] + for managed_object in managed_objects: + user_info = self.get_user_info( + managed_object + ) + self.user.append( + user_info + ) + + self.log.osp_mo( + 'users', + self.user + ) + + return self.user + + def match_user(self, user_info, user_filter): + if user_filter is None or len(user_filter) == 0: + return True + + for ap_rule in user_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, user_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, user_info['name']): + return False + + if not key_found: + self.log.error( + 'match_user', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_users(self, object_filter=None, tenant_info=False, role_info=False, cache_enabled=True): + all_users = self.get_users_info(cache_enabled=cache_enabled) + if all_users is None: + return None + + users = [] + + for user_info in all_users: + if not self.match_user(user_info, object_filter): + continue + + if tenant_info: + user_info['default_project_name'] = None + if user_info['default_project_id'] is not None: + user_info['default_project_name'] = self.get_tenant_name( + user_info['default_project_id'], + cache_enabled=cache_enabled + + ) + + if not self.match_subnet(user_info, object_filter): + continue + + if role_info: + pass + + users.append( + user_info + ) + + users = sorted( + users, + key=lambda i: i['name'] + ) + + return users diff --git a/lib/osp/user/main.py b/lib/osp/user/main.py new file mode 100644 index 00000000..85ff190a --- /dev/null +++ b/lib/osp/user/main.py @@ -0,0 +1,11 @@ +from lib.osp.user.api import OspUserApi +from lib.osp.user.info import OspUserInfo + + +class OspUser( + OspUserApi, + OspUserInfo + ): + def __init__(self): + OspUserApi.__init__(self) + OspUserInfo.__init__(self) diff --git a/lib/osp/user/output.py b/lib/osp/user/output.py new file mode 100644 index 00000000..5b6672fa --- /dev/null +++ b/lib/osp/user/output.py @@ -0,0 +1,51 @@ +import copy + + +class OspUserOutput(): + def __init__(self): + pass + + def print_users(self, info, title=False): + if title: + self.my_output.default( + 'User [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['default_project_name'] is None: + item['default_project_name'] = '--' + + order = [ + 'id', + 'name', + 'enabledTick', + 'expiresTick', + 'domain_id', + 'default_project_name' + ] + + headers = [ + 'Id', + 'Name', + 'Enabled', + 'Expiry', + 'Domain', + 'Default Project' + ] + + self.my_output.my_table( + new_info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/osp/virtual_machine/README.md b/lib/osp/virtual_machine/README.md new file mode 100644 index 00000000..b679c4e1 --- /dev/null +++ b/lib/osp/virtual_machine/README.md @@ -0,0 +1,5 @@ +sriov +vnc console +age +az +sg \ No newline at end of file diff --git a/lib/osp/virtual_machine/__init__.py b/lib/osp/virtual_machine/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/virtual_machine/api.py b/lib/osp/virtual_machine/api.py new file mode 100644 index 00000000..bececd6d --- /dev/null +++ b/lib/osp/virtual_machine/api.py @@ -0,0 +1,279 @@ +import time +import traceback + + +class OspVirtualMachineApi(): + def __init__(self): + self.virtual_machine_mo = None + + def get_virtual_machine_id_mo(self, virtual_machine_id, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_mo is not None: + for item in self.virtual_machine_mo: + if item.id == virtual_machine_id: + return item + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_virtual_machine_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + virtual_machine_mo = api_handler.servers.get(virtual_machine_id) + self.log.osp( + 'get', + 'virtual_machine', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_virtual_machine_id_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'virtual_machines', + True, + int(time.time() * 1000) - start_time + ) + return None + + return virtual_machine_mo + + def get_virtual_machine_mo(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine_mo is not None: + return self.virtual_machine_mo + + api_handler = self.get_api_nova(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_virtual_machine_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.virtual_machine_mo = api_handler.servers.list(search_opts={'all_tenants': 1}) + self.log.osp( + 'get', + 'virtual_machines', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_virtual_machine_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'virtual_machines', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.virtual_machine_mo + + def get_virtual_machine_console(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'get_virtual_machine_console', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + virtual_machine_console = api_handler.servers.get_vnc_console(virtual_machine_id, "novnc")['console']['url'] + self.log.osp( + 'get', + 'get_vnc_console', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_virtual_machine_console', traceback.format_exc()) + self.log.osp( + 'get', + 'get_vnc_console', + True, + int(time.time() * 1000) - start_time + ) + return None + + return virtual_machine_console + + def get_virtual_machine_logs(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'get_virtual_machine_logs', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + virtual_machine_logs = api_handler.servers.get_console_output(virtual_machine_id) + self.log.osp( + 'get', + 'get_console_output', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_virtual_machine_console', traceback.format_exc()) + self.log.osp( + 'get', + 'get_console_output', + True, + int(time.time() * 1000) - start_time + ) + return None + + return virtual_machine_logs + + def create_virtual_machine_mo(self, vm_name, image_id, flavor_id, az=None, config_drive=None, nics=[], files=[], userdata=None): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'create_virtual_machine_mo', + 'No api handler' + ) + return None + + try: + # C:\Users\\AppData\Local\Programs\Python\Python39\Lib\site-packages\novaclient\v2\servers.py + server_obj = api_handler.servers.create( + name=vm_name, + image=image_id, + flavor=flavor_id, + nics=nics, + config_drive=config_drive, + files=files, + availability_zone=az, + userdata=userdata + ) + + self.log.debug( + 'create_virtual_machine_mo', + str(server_obj) + ) + + new_virtual_machine_id = server_obj.id + + except BaseException: + self.log.error( + 'create_virtual_machine_mo', + traceback.format_exc() + ) + return None + + return new_virtual_machine_id + + def start_virtual_machine_mo(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'start_virtual_machine_mo', + 'No api handler' + ) + return False + + try: + api_handler.servers.start(virtual_machine_id) + except BaseException: + self.log.error( + 'start_virtual_machine', + traceback.format_exc() + ) + return False + + return True + + def stop_virtual_machine_mo(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'stop_virtual_machine_mo', + 'No api handler' + ) + return False + + try: + api_handler.servers.stop(virtual_machine_id) + except BaseException: + self.log.error( + 'stop_virtual_machine_mo', + traceback.format_exc() + ) + return False + + return True + + def migrate_virtual_machine_mo(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'migrate_virtual_machine_mo', + 'No api handler' + ) + return False + + try: + api_handler.servers.migrate(virtual_machine_id) + except BaseException: + self.log.error( + 'migrate_virtual_machine_mo', + traceback.format_exc() + ) + return False + + return True + + def resize_virtual_machine_mo(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'resize_virtual_machine_mo', + 'No api handler' + ) + return False + + try: + api_handler.servers.confirm_resize(virtual_machine_id) + except BaseException: + self.log.error( + 'resize_virtual_machine_mo', + traceback.format_exc() + ) + return False + + return True + + def delete_virtual_machine_mo(self, virtual_machine_id): + api_handler = self.get_api_nova(cache_enabled=False) + if api_handler is None: + self.log.error( + 'delete_virtual_machine_mo', + 'No api handler' + ) + return False + + try: + api_handler.servers.delete(virtual_machine_id) + except BaseException: + self.log.error( + 'delete_virtual_machine_mo', + traceback.format_exc() + ) + return False + + return True diff --git a/lib/osp/virtual_machine/info.py b/lib/osp/virtual_machine/info.py new file mode 100644 index 00000000..c4ca2b81 --- /dev/null +++ b/lib/osp/virtual_machine/info.py @@ -0,0 +1,495 @@ +from lib import filter_helper +from lib import ip_helper + + +class OspVirtualMachineInfo(): + def __init__(self): + self.virtual_machine = None + + def get_virtual_machines_properties(self, managed_objects): + properties = [] + for managed_object in managed_objects: + properties.append( + managed_object.to_dict() + ) + return properties + + def get_virtual_machine_info(self, virtual_machine_mo): + if virtual_machine_mo is None: + return None + + info = virtual_machine_mo.to_dict() + info['__Output'] = {} + + if info['status'] == 'ACTIVE': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + if isinstance(info['image'], str): + info['bootFrom'] = 'Volume' + else: + info['bootFrom'] = 'Image' + + info['power_state'] = None + if info['OS-EXT-STS:power_state'] == 0: + info['power_state'] = 'powered-down' + if info['OS-EXT-STS:power_state'] == 1: + info['power_state'] = 'powered-up' + if info['OS-EXT-STS:power_state'] == 4: + info['power_state'] = 'shutdown' + + info['task_state'] = info['OS-EXT-STS:task_state'] + + info['hypervisor'] = info['OS-EXT-SRV-ATTR:hypervisor_hostname'] + + info['interface'] = [] + if info['addresses'] is not None: + for network_name in info['addresses']: + for ip_network_info in info['addresses'][network_name]: + interface_info = {} + interface_info['network'] = network_name + interface_info['ip'] = ip_network_info['addr'] + interface_info['type'] = ip_network_info['OS-EXT-IPS:type'] + interface_info['ip_type'] = '%s (%s)' % ( + interface_info['ip'], + interface_info['type'] + ) + interface_info['mac'] = ip_network_info['OS-EXT-IPS-MAC:mac_addr'] + interface_info['network_ip'] = '%s=%s' % ( + interface_info['network'], + interface_info['ip'] + ) + info['interface'].append(interface_info) + + info['age'] = self.convert_timestamp_to_age( + info['created'], + on_error='--' + ) + + return info + + def get_virtual_machines_info(self, cache_enabled=True): + if cache_enabled: + if self.virtual_machine is not None: + return self.virtual_machine + + managed_objects = self.get_virtual_machine_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'virtual_machines', + self.get_virtual_machines_properties(managed_objects) + ) + + self.virtual_machine = [] + for managed_object in managed_objects: + virtual_machine_info = self.get_virtual_machine_info( + managed_object + ) + self.virtual_machine.append( + virtual_machine_info + ) + + self.log.osp_mo( + 'virtual_machines.info', + self.virtual_machine + ) + + return self.virtual_machine + + def match_virtual_machine(self, virtual_machine_info, virtual_machine_filter): + if virtual_machine_filter is None or len(virtual_machine_filter) == 0: + return True + + for ap_rule in virtual_machine_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['name']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in virtual_machine_info: + if not filter_helper.match_string(value, virtual_machine_info['tenant_name']): + return False + + if key == 'image_id': + key_found = True + if not isinstance(virtual_machine_info['image'], dict): + return False + + if not filter_helper.match_string(value, virtual_machine_info['image']['id']): + return False + + if key == 'image_name': + key_found = True + if 'image_info' in virtual_machine_info: + if virtual_machine_info['image_info'] is None: + return False + + if not filter_helper.match_string(value, virtual_machine_info['image_info']['name']): + return False + + if key == 'flavor_id': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['flavor']['id']): + return False + + if key == 'flavor_name': + key_found = True + if 'flavor_info' in virtual_machine_info: + if not filter_helper.match_string(value, virtual_machine_info['flavor_info']['name']): + return False + + if key == 'network_id': + key_found = True + found = False + for interface_info in virtual_machine_info['interface']: + if filter_helper.match_string(value, interface_info['id']): + found = True + break + + if not found: + return False + + if key == 'network_name': + key_found = True + found = False + for interface_info in virtual_machine_info['interface']: + if filter_helper.match_string(value, interface_info['network']): + found = True + break + + if not found: + return False + + if key == 'address': + key_found = True + found = False + for interface_info in virtual_machine_info['interface']: + if ip_helper.is_valid_ipv4_address(value): + if filter_helper.match_string(value, interface_info['ip']): + found = True + break + + if ip_helper.is_valid_ipv4_cidr(value): + if ip_helper.is_ipv4_in_cidr(interface_info['ip'], value): + found = True + break + + if not found: + return False + + if key == 'mac': + key_found = True + found = False + for interface_info in virtual_machine_info['interface']: + if ip_helper.is_mac_match(value, interface_info['mac']): + found = True + break + + if not found: + return False + + if key == 'hypervisor': + key_found = True + if not filter_helper.match_string(value, virtual_machine_info['hypervisor']): + return False + + if key == 'port_id': + key_found = True + found = False + port_ready = True + for interface_info in virtual_machine_info['interface']: + if 'port_info' not in interface_info: + port_ready = False + break + + if interface_info['port_info'] is not None: + if filter_helper.match_string(value, interface_info['port_info']['id']): + found = True + break + + if port_ready and not found: + return False + + if not key_found: + self.log.error( + 'match_virtual_machine', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_virtual_machines( + self, + object_filter=None, + flavor_info=False, + tenant_info=False, + image_info=False, + volume_info=False, + network_info=False, + subnet_info=False, + port_info=False, + security_info=False, + console_info=False, + logs_info=False, + cache_enabled=True + ): + all_virtual_machines = self.get_virtual_machines_info(cache_enabled=cache_enabled) + if all_virtual_machines is None: + return None + + virtual_machines = [] + + for virtual_machine_info in all_virtual_machines: + if not self.match_virtual_machine(virtual_machine_info, object_filter): + continue + + if tenant_info: + virtual_machine_info['tenant_name'] = None + tenant_info = self.get_tenant( + tenant_id=virtual_machine_info['tenant_id'] + ) + if tenant_info is not None: + virtual_machine_info['tenant_name'] = tenant_info['name'] + + if not self.match_virtual_machine(virtual_machine_info, object_filter): + continue + + if flavor_info: + virtual_machine_info['flavor_info'] = self.get_flavor( + flavor_id=virtual_machine_info['flavor']['id'] + ) + if virtual_machine_info['flavor_info'] is None: + self.log.error( + 'get_virtual_machines', + 'Flavor info not found: %s' % (virtual_machine_info['id']) + ) + + if not self.match_virtual_machine(virtual_machine_info, object_filter): + continue + + if volume_info: + virtual_machine_info['volumes'] = [] + if 'os-extended-volumes:volumes_attached' in virtual_machine_info: + for volume_ref in virtual_machine_info['os-extended-volumes:volumes_attached']: + volume_info = self.get_volume(volume_id=volume_ref['id']) + if volume_info is None: + self.log.error( + 'get_virtual_machines', + 'VM %s volume %s info failed' % ( + virtual_machine_info['id'], + volume_ref['id'] + ) + ) + else: + virtual_machine_info['volumes'].append( + volume_info + ) + + if image_info: + virtual_machine_info['image_info'] = None + if virtual_machine_info['bootFrom'] == 'Image': + virtual_machine_info['image_info'] = self.get_image( + image_id=virtual_machine_info['image']['id'] + ) + virtual_machine_info['bootSource'] = None + if virtual_machine_info['image_info'] is not None: + virtual_machine_info['bootSource'] = virtual_machine_info['image_info']['name'] + virtual_machine_info['bootSourceT'] = '(img) %s' % (virtual_machine_info['bootSource']) + + if virtual_machine_info['bootFrom'] == 'Volume': + virtual_machine_info['bootSource'] = None + if volume_info: + if len(virtual_machine_info['volumes']) > 0: + virtual_machine_info['bootSource'] = virtual_machine_info['volumes'][0]['name'] + virtual_machine_info['bootSourceT'] = '(vol) %s' % (virtual_machine_info['bootSource']) + + if not self.match_virtual_machine(virtual_machine_info, object_filter): + continue + + if network_info: + for interface_info in virtual_machine_info['interface']: + interface_info['network_info'] = self.get_network( + network_name=interface_info['network'], + subnet_info=subnet_info + ) + if subnet_info: + if interface_info['network_info'] is not None: + for interface_subnet_info in interface_info['network_info']['subnet_info']: + if ip_helper.is_ipv4_in_cidr(interface_info['ip'], interface_subnet_info['cidr']): + interface_info['subnet'] = interface_subnet_info['cidr'] + + if port_info: + for interface_info in virtual_machine_info['interface']: + interface_info['port_info'] = None + + port_object_filter = [] + port_object_filter.append( + 'mac:%s' % (interface_info['mac']) + ) + port_object_filter.append( + 'vm_id:%s' % (virtual_machine_info['id']) + ) + port_infos = self.get_ports( + object_filter=port_object_filter, + security_info=security_info + ) + if port_infos is None or len(port_infos) == 0: + self.log.error( + 'get_virtual_machines', + 'Failed to find port by mac %s for virtual machine %s' % (interface_info['mac'], virtual_machine_info['id']) + ) + + if port_infos is not None and len(port_infos) > 1: + self.log.error( + 'get_virtual_machines', + 'Multiple ports found for mac %s and virtual machine %s' % (interface_info['mac'], virtual_machine_info['id']) + ) + + if port_infos is not None and len(port_infos) == 1: + interface_info['port_info'] = port_infos[0] + + if not self.match_virtual_machine(virtual_machine_info, object_filter): + continue + + if console_info: + virtual_machine_info['console'] = self.get_virtual_machine_console( + virtual_machine_info['id'] + ) + + if logs_info: + virtual_machine_info['logs'] = str( + self.get_virtual_machine_logs( + virtual_machine_info['id'] + ) + ) + + virtual_machines.append( + virtual_machine_info + ) + + if tenant_info: + virtual_machines = sorted( + virtual_machines, + key=lambda i: ( + i['tenant_name'].lower(), + i['name'].lower() + ) + ) + else: + virtual_machines = sorted( + virtual_machines, + key=lambda i: i['name'].lower() + ) + + self.log.osp_mo( + 'virtual_machines.extended', + virtual_machines + ) + + return virtual_machines + + def get_virtual_machine(self, virtual_machine_id, flavor_info=False, tenant_info=False, image_info=False, volume_info=False, network_info=False, subnet_info=False, cache_enabled=True): + virtual_machines = self.get_virtual_machines( + object_filter=[ + 'id:%s' % (virtual_machine_id) + ], + tenant_info=tenant_info, + flavor_info=flavor_info, + image_info=image_info, + volume_info=volume_info, + network_info=network_info, + subnet_info=subnet_info, + cache_enabled=cache_enabled + ) + if virtual_machines is None or len(virtual_machines) != 1: + return None + return virtual_machines[0] + + def get_virtual_machine_tenant_name(self, virtual_machine_id, cache_enabled=True): + vm_info = self.get_virtual_machine( + virtual_machine_id=virtual_machine_id, + tenant_info=True, + cache_enabled=cache_enabled + ) + if vm_info is None: + return None + + tenant_name = '%s/%s' % ( + vm_info['tenant_name'], + vm_info['name'] + ) + return tenant_name + + def is_virtual_machine_up(self, virtual_machine_id, cache_enabled=True): + virtual_machine_info = self.get_virtual_machine(virtual_machine_id, cache_enabled=cache_enabled) + if virtual_machine_info is None: + self.log.error( + 'is_virtual_machine_up', + 'Virtual machine not found: %s' % (virtual_machine_id) + ) + return False + + if virtual_machine_info['status'] == 'SHUTOFF': + return False + + return True + + def is_virtual_machine(self, virtual_machine_id, cache_enabled=True): + virtual_machine_info = self.get_virtual_machine(virtual_machine_id, cache_enabled=cache_enabled) + if virtual_machine_info is None: + return False + return True + + def get_virtual_machine_by_name(self, virtual_machine_name, tenant_id=None, tenant_name=None, flavor_info=False, tenant_info=False, image_info=False, volume_info=False, network_info=False, subnet_info=False, cache_enabled=True): + object_filter = [] + object_filter.append( + 'name:%s' % (virtual_machine_name) + ) + if tenant_id is not None: + object_filter.append( + 'tenant_id:%s' % (tenant_id) + ) + if tenant_name is not None: + object_filter.append( + 'tenant_name:%s' % (tenant_name) + ) + + virtual_machines = self.get_virtual_machines( + object_filter=object_filter, + tenant_info=tenant_info, + flavor_info=flavor_info, + image_info=image_info, + volume_info=volume_info, + network_info=network_info, + subnet_info=subnet_info, + cache_enabled=cache_enabled + ) + if virtual_machines is None or len(virtual_machines) != 1: + return None + + return virtual_machines[0] + + def is_virtual_machine_by_name(self, virtual_machine_name, tenant_id=None, tenant_name=None, cache_enabled=True): + if self.get_virtual_machine_by_name(virtual_machine_name, tenant_id=tenant_id, tenant_name=tenant_name, cache_enabled=cache_enabled) is None: + return False + return True diff --git a/lib/osp/virtual_machine/main.py b/lib/osp/virtual_machine/main.py new file mode 100644 index 00000000..8b657e15 --- /dev/null +++ b/lib/osp/virtual_machine/main.py @@ -0,0 +1,14 @@ +from lib.osp.virtual_machine.api import OspVirtualMachineApi +from lib.osp.virtual_machine.info import OspVirtualMachineInfo +from lib.osp.virtual_machine.task import OspVirtualMachineTask + + +class OspVirtualMachine( + OspVirtualMachineApi, + OspVirtualMachineInfo, + OspVirtualMachineTask + ): + def __init__(self): + OspVirtualMachineApi.__init__(self) + OspVirtualMachineInfo.__init__(self) + OspVirtualMachineTask.__init__(self) diff --git a/lib/osp/virtual_machine/output.py b/lib/osp/virtual_machine/output.py new file mode 100644 index 00000000..3d77fbd2 --- /dev/null +++ b/lib/osp/virtual_machine/output.py @@ -0,0 +1,327 @@ +import copy + + +class OspVirtualMachineOutput(): + def __init__(self): + pass + + def print_virtual_machines(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + item['task_stateT'] = item['task_state'] + if item['task_state'] is None: + item['task_stateT'] = '--' + + order = [ + 'tenant_name', + 'name', + 'hypervisor', + 'status', + 'power_state', + 'task_stateT', + 'bootSourceT', + 'flavor_info.name', + 'flavor_info.resource', + 'age' + ] + + headers = [ + 'Tenant', + 'VM', + 'Hypervisor', + 'Status', + 'Power', + 'Task', + 'Boot Source', + 'Flavor', + 'Resource', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machines_console(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine Console [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenant_name', + 'name', + 'console' + ] + + headers = [ + 'Tenant', + 'VM', + 'Console' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machines_logs(self, info): + for item in info: + self.my_output.default( + 'Virtual Machine Logs: %s/%s ' % ( + item['tenant_name'], + item['name'] + ), + underline=True, + before_newline=True, + after_newline=True + ) + + self.my_output.default(item['logs']) + + def print_virtual_machines_id(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine - Identifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenant_name', + 'name', + 'id', + 'image.id', + 'flavor.id' + ] + + headers = [ + 'Tenant', + 'VM', + 'Id', + 'Image', + 'Flavor' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machines_net(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine - Networking [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenant_name', + 'name', + 'interface.network', + 'interface.mac', + 'interface.ip_type', + 'interface.subnet' + ] + + headers = [ + 'Tenant', + 'VM', + 'Network', + 'MAC', + 'IP', + 'Subnet' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_virtual_machines_sec(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine - Security [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'tenant_name', + 'name', + 'interface.network', + 'interface.mac', + 'interface.ip_type', + 'interface.subnet', + 'interface.port_info.port_security_enabledTick', + 'interface.port_info.security_group_names_value' + ] + + headers = [ + 'Tenant', + 'VM', + 'Network', + 'MAC', + 'IP', + 'Subnet', + 'Port Security', + 'Security Group' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def select_virtual_machine(self, info): + self.my_output.default( + 'Select Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('No virtual machine found') + return None + + new_info = copy.deepcopy(info) + + index = 1 + for item in new_info: + item['__id'] = index + index = index + 1 + if item['bootSource'] is None: + item['bootSource'] = '--' + + order = [ + '__id', + 'tenant_name', + 'name', + 'status', + 'bootFrom', + 'bootSource', + 'flavor_info.name', + 'flavor_info.resource', + 'interface.network', + 'interface.mac', + 'interface.ip_type', + 'interface.subnet' + ] + + headers = [ + 'Index', + 'Tenant', + 'VM', + 'Status', + 'Boot From', + 'Boot Source', + 'Flavor', + 'Resource', + 'Network', + 'MAC', + 'IP', + 'Subnet' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['interface'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + while True: + answer = input("Select virtual machine using index value (0 to break): ") + if answer is None: + continue + + try: + selected_id = int(answer) + except BaseException: + selected_id = 0 + + if selected_id == 0: + return None + + for item in new_info: + if item['__id'] == int(answer): + return item diff --git a/lib/osp/virtual_machine/task.py b/lib/osp/virtual_machine/task.py new file mode 100644 index 00000000..2706771e --- /dev/null +++ b/lib/osp/virtual_machine/task.py @@ -0,0 +1,153 @@ +import time +import traceback + + +class OspVirtualMachineTask(): + def __init__(self): + pass + + def wait_for_virtual_machine_status(self, virtual_machine_id, status_array, reverse=False, timeout=300): + start_time = int(time.time()) + while True: + virtual_machine_mo = self.get_virtual_machine_id_mo(virtual_machine_id, cache_enabled=False) + if virtual_machine_mo is not None: + current_status = virtual_machine_mo.status + if virtual_machine_mo.status.lower() == 'error': + return False + + if not reverse: + if current_status in status_array: + return True + + if reverse: + if current_status not in status_array: + return True + + time.sleep(5) + if (int(time.time()) - start_time) > timeout: + self.log.error( + 'wait_for_virtual_machine_status', + 'Timeout reached for virtual machine: %s' % (virtual_machine_id) + ) + return False + + def wait_for_virtual_machine_power_state(self, virtual_machine_id, status_array, reverse=False, timeout=300): + start_time = int(time.time()) + while True: + virtual_machine_mo = self.get_virtual_machine_id_mo(virtual_machine_id, cache_enabled=False) + if virtual_machine_mo is not None: + current_status = getattr(virtual_machine_mo, 'OS-EXT-STS:power_state') + if not reverse: + if current_status in status_array: + return True + + if reverse: + if current_status not in status_array: + return True + + time.sleep(5) + if (int(time.time()) - start_time) > timeout: + self.log.error( + 'wait_for_virtual_machine_power_state', + 'Timeout reached for virtual machine: %s' % (virtual_machine_id) + ) + return False + + def start_virtual_machine(self, virtual_machine_id, wait=False): + api_handler = self.get_api_nova() + if api_handler is None: + self.log.error( + 'start_virtual_machine', + 'No api handler' + ) + return False + + try: + api_handler.servers.start(virtual_machine_id) + + except BaseException: + self.log.error( + 'start_virtual_machine', + 'API failed' + ) + self.log.error( + 'start_virtual_machine', + traceback.format_exc() + ) + return False + + if wait: + return self.wait_for_virtual_machine_status(virtual_machine_id, ['ACTIVE']) + + return True + + def stop_virtual_machine(self, virtual_machine_id, wait=False): + api_handler = self.get_api_nova() + if api_handler is None: + self.log.error( + 'stop_virtual_machine', + 'No api handler' + ) + return False + + try: + api_handler.servers.stop(virtual_machine_id) + + except BaseException: + self.log.error( + 'stop_virtual_machine', + 'API failed' + ) + self.log.error( + 'stop_virtual_machine', + traceback.format_exc() + ) + return False + + if wait: + if not self.wait_for_virtual_machine_status(virtual_machine_id, ['SHUTOFF']): + return False + + if not self.wait_for_virtual_machine_power_state(virtual_machine_id, [4]): + return False + + return True + + def delete_virtual_machine(self, virtual_machine_id, wait=False, timeout=300): + api_handler = self.get_api_nova() + if api_handler is None: + self.log.error( + 'delete_virtual_machine', + 'No api handler' + ) + return False + + try: + api_handler.servers.delete(virtual_machine_id) + + except BaseException: + self.log.error( + 'delete_virtual_machine', + 'API failed' + ) + self.log.error( + 'delete_virtual_machine', + traceback.format_exc() + ) + return False + + if wait: + start_time = int(time.time()) + while True: + if not self.is_virtal_machine(virtual_machine_id, cache_enabled=False): + return True + + time.sleep(5) + if (int(time.time()) - start_time) > timeout: + self.log.error( + 'delete_virtual_machine', + 'Timeout reached for virtual machine: %s' % (virtual_machine_id) + ) + return False + + return True diff --git a/lib/osp/volume/__init__.py b/lib/osp/volume/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/osp/volume/api.py b/lib/osp/volume/api.py new file mode 100644 index 00000000..03194d6d --- /dev/null +++ b/lib/osp/volume/api.py @@ -0,0 +1,42 @@ +import time +import traceback + + +class OspVolumeApi(): + def __init__(self): + self.volume_mo = None + + def get_volume_mo(self, cache_enabled=True): + if cache_enabled: + if self.volume_mo is not None: + return self.volume_mo + + api_handler = self.get_api_cinder(cache_enabled=cache_enabled) + if api_handler is None: + self.log.error( + 'get_volume_mo', + 'No api handler' + ) + return None + + try: + start_time = int(time.time() * 1000) + self.volume_mo = api_handler.volumes.list() + self.log.osp( + 'get', + 'volumes.list', + True, + int(time.time() * 1000) - start_time + ) + + except BaseException: + self.log.error('osp.get_volume_mo', traceback.format_exc()) + self.log.osp( + 'get', + 'volumes.list', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.volume_mo diff --git a/lib/osp/volume/info.py b/lib/osp/volume/info.py new file mode 100644 index 00000000..7d2c8545 --- /dev/null +++ b/lib/osp/volume/info.py @@ -0,0 +1,269 @@ +from lib import filter_helper + + +class OspVolumeInfo(): + def __init__(self): + self.volume = None + + def get_volumes_properties(self, managed_objects): + properties = [] + for managed_object in managed_objects: + properties.append( + managed_object.to_dict() + ) + return properties + + def get_volume_info(self, volume_mo): + if volume_mo is None: + return None + + properties = volume_mo.to_dict() + + info = {} + info['__Output'] = {} + + keys = [ + 'id', + 'status', + 'size', + 'availability_zone', + 'created_at', + 'updated_at', + 'name', + 'description', + 'volume_type', + 'snapshot_id', + 'bootable', + 'encrypted', + 'multiattach', + 'volume_image_metadata' + ] + for key in keys: + info[key] = None + if key in properties: + info[key] = properties[key] + + info['tenant_id'] = properties['os-vol-tenant-attr:tenant_id'] + + keys = [ + 'attachment_id', + 'server_id', + 'host_name', + 'device', + 'attached_at' + ] + info['attachment'] = [] + for attachment_mo in properties['attachments']: + attachment_info = {} + for key in keys: + attachment_info[key] = None + if key in attachment_mo: + attachment_info[key] = attachment_mo[key] + info['attachment'].append( + attachment_info + ) + + if info['status'] == 'available': + info['__Output']['status'] = 'Green' + else: + info['__Output']['status'] = 'Red' + + if info['bootable'] == 'true': + info['bootableTick'] = '\u2713' + else: + info['bootableTick'] = '\u2717' + + if info['encrypted']: + info['encryptedTick'] = '\u2713' + else: + info['encryptedTick'] = '\u2717' + + if info['multiattach']: + info['multiattachTick'] = '\u2713' + else: + info['multiattachTick'] = '\u2717' + + if info['snapshot_id'] is not None: + info['snapshotTick'] = '\u2713' + else: + info['snapshotTick'] = '\u2717' + + info['created_age'] = self.convert_timestamp_to_age( + info['created_at'], + on_error='--' + ) + + info['updated_age'] = self.convert_timestamp_to_age( + info['updated_at'], + on_error='--' + ) + + return info + + def get_volumes_info(self, cache_enabled=True): + if cache_enabled: + if self.volume is not None: + return self.volume + + managed_objects = self.get_volume_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.log.osp_mo( + 'volumes', + self.get_volumes_properties(managed_objects) + ) + + self.volume = [] + for managed_object in managed_objects: + volume_info = self.get_volume_info( + managed_object + ) + self.volume.append( + volume_info + ) + + self.log.osp_mo( + 'volumes.info', + self.volume + ) + + return self.volume + + def match_volume(self, volume_info, volume_filter): + if volume_filter is None or len(volume_filter) == 0: + return True + + for ap_rule in volume_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'id': + key_found = True + if not filter_helper.match_string(value, volume_info['id']): + return False + + if key == 'name': + key_found = True + if not filter_helper.match_string(value, volume_info['name']): + return False + + if key == 'tenant_id': + key_found = True + if not filter_helper.match_string(value, volume_info['tenant_id']): + return False + + if key == 'tenant_name': + key_found = True + if 'tenant_name' in volume_info: + if not filter_helper.match_string(value, volume_info['tenant_name']): + return False + + if key == 'vm_id': + key_found = True + found = False + for attachment_info in volume_info['attachment']: + if filter_helper.match_string(value, attachment_info['server_id']): + found = True + break + + if not found: + return False + + if key == 'vm_name': + key_found = True + vm_name_ready = True + found = False + for attachment_info in volume_info['attachment']: + if 'vm_tenant_name' not in attachment_info: + vm_name_ready = False + break + + if filter_helper.match_string(value, attachment_info['vm_tenant_name']): + found = True + break + + if vm_name_ready and not found: + return False + + if key == 'hv': + key_found = True + found = False + for attachment_info in volume_info['attachment']: + if filter_helper.match_string(value, attachment_info['host_name']): + found = True + break + + if not found: + return False + + if not key_found: + self.log.error( + 'match_volume', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_volumes(self, object_filter=None, tenant_info=False, vm_info=False, cache_enabled=True): + all_volumes = self.get_volumes_info(cache_enabled=cache_enabled) + if all_volumes is None: + return None + + volumes = [] + + for volume_info in all_volumes: + if not self.match_volume(volume_info, object_filter): + continue + + if tenant_info: + volume_info['tenant_name'] = self.get_tenant_name( + volume_info['tenant_id'], + cache_enabled=cache_enabled + ) + + if not self.match_volume(volume_info, object_filter): + continue + + if vm_info: + for attachment_info in volume_info['attachment']: + attachment_info['vm_tenant_name'] = self.get_virtual_machine_tenant_name( + attachment_info['server_id'], + cache_enabled=cache_enabled + ) + + volumes.append( + volume_info + ) + + volumes = sorted( + volumes, + key=lambda i: i['name'] + ) + + return volumes + + def get_volume(self, volume_id=None, volume_name=None, cache_enabled=True): + object_filter = [] + if volume_id is not None: + object_filter.append( + 'id:%s' % (volume_id) + ) + if volume_name is not None: + object_filter.append( + 'name:%s' % (volume_name) + ) + + volumes = self.get_volumes(object_filter=object_filter) + if volumes is None or len(volumes) != 1: + return None + + return volumes[0] + + def get_volume_name(self, volume_id, cache_enabled=True): + volume_info = self.get_volume(volume_id=volume_id, cache_enabled=cache_enabled) + if volume_info is None: + return None + return volume_info['name'] diff --git a/lib/osp/volume/main.py b/lib/osp/volume/main.py new file mode 100644 index 00000000..4b3e7461 --- /dev/null +++ b/lib/osp/volume/main.py @@ -0,0 +1,11 @@ +from lib.osp.volume.api import OspVolumeApi +from lib.osp.volume.info import OspVolumeInfo + + +class OspVolume( + OspVolumeApi, + OspVolumeInfo + ): + def __init__(self): + OspVolumeApi.__init__(self) + OspVolumeInfo.__init__(self) diff --git a/lib/osp/volume/output.py b/lib/osp/volume/output.py new file mode 100644 index 00000000..fa917197 --- /dev/null +++ b/lib/osp/volume/output.py @@ -0,0 +1,131 @@ +import copy + +class OspVolumeOutput(): + def __init__(self): + pass + + def print_volumes(self, info, title=False): + if title: + self.my_output.default( + 'Volume [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if len(item['attachment']) == 0: + item['attachment'].append( + dict( + vm_tenant_name='--', + device='--', + host_name='--' + ) + ) + + order = [ + 'name', + 'tenant_name', + 'status', + 'snapshotTick', + 'bootableTick', + 'encryptedTick', + 'multiattachTick', + 'size', + 'volume_type', + 'attachment.vm_tenant_name', + 'attachment.device', + 'attachment.host_name', + 'created_age' + ] + + headers = [ + 'Name', + 'Tenant', + 'Status', + 'Snap', + 'Boot', + 'Encr', + 'Multi', + 'Size', + 'Type', + 'VM', + 'Device', + 'HV', + 'Age' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['attachment'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + def print_volumes_id(self, info, title=False): + if title: + self.my_output.default( + 'Volume - Indentifier [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + new_info = copy.deepcopy(info) + for item in new_info: + if item['snapshot_id'] is None: + item['snapshot_id'] = '--' + + if len(item['attachment']) == 0: + item['attachment'].append( + dict( + attachment_id='--', + server_id='--' + ) + ) + + order = [ + 'name', + 'tenant_name', + 'id', + 'snapshot_id', + 'attachment.attachment_id', + 'attachment.server_id' + ] + + headers = [ + 'Name', + 'Tenant', + 'Id', + 'Snapshot', + 'Attachment', + 'VM' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + new_info, + order, + ['attachment'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) diff --git a/lib/output_helper.py b/lib/output_helper.py new file mode 100644 index 00000000..68bfb040 --- /dev/null +++ b/lib/output_helper.py @@ -0,0 +1,1405 @@ +import json +import os +import re +import copy +import traceback + +from inputimeout import inputimeout, TimeoutOccurred +import colorama + +from lib import filter_helper +from lib import ip_helper + + +class OutputHelper(): + def __init__(self, silent=False, verbose=False, debug=False, log_id=None): + self.flags = {} + self.flags['silent'] = silent + self.flags['verbose'] = verbose + self.flags['debug'] = debug + self.output = '' + self.stream = None + self.set_stream() + + self.logs_directory = '/tmp/iserver' + self.bot_logs_directory = '/tmp/iserver.bot' + + self.output_directory = '/tmp/iserver/' + self.log_id = None + if log_id is not None: + if log_id.startswith('bot.'): + self.output_directory = '/tmp/iserver.bot/' + self.output_directory = os.path.join(self.output_directory, log_id[4:]) + self.log_id = log_id[4:] + else: + self.output_directory = os.path.join(self.output_directory, log_id) + self.log_id = log_id + + self.default_filename = os.path.join(self.output_directory, 'iserver.output.default') + self.verbose_filename = os.path.join(self.output_directory, 'iserver.output.verbose') + self.debug_filename = os.path.join(self.output_directory, 'iserver.output.debug') + self.json_filename = os.path.join(self.output_directory, 'iserver.output.json') + self.devel_filename = os.path.join(self.output_directory, 'devel.debug') + self.duration_filename = os.path.join(self.output_directory, 'duration.debug') + + self.html_table_height_limit = False + + colorama.init() + + def initialize(self, max_dirs=1000): + try: + if not os.path.isdir(self.output_directory): + os.makedirs(self.output_directory, exist_ok=True) + + except BaseException: + print(traceback.format_exc()) + + def is_output(self): + for filename in [self.default_filename, self.verbose_filename, self.debug_filename]: + if os.path.isfile(filename): + return True + return False + + def json_output(self, output): + try: + self.append(self.json_filename, json.dumps(output, indent=4)) + except BaseException: + pass + + def clean(self): + try: + for filename in [self.default_filename, self.verbose_filename, self.debug_filename]: + if os.path.isfile(filename): + os.remove(filename) + except BaseException: + pass + + def clear_output(self): + self.output = '' + + def get_output(self): + return self.output + + def my_print(self, output, underline=False, before_newline=False, after_newline=False): + if output is not None: + if not self.flags['silent']: + if underline: + output = '%s\n%s' % (output, "".join(('-',) * len(output))) + + if before_newline: + output = '\n%s' % (output) + + if after_newline: + output = '%s\n' % (output) + + self.output = '%s\n%s' % ( + self.output, + self.escape_ansi( + self.escape_ticks( + output, + alternative=True + ) + ) + ) + + def print_stream(self, output, stream): + if stream == 'output': + self.my_print(output) + + if stream == 'debug': + self.debug(output) + + if stream == 'info': + self.info(output) + + if stream == 'default': + self.default(output) + self.my_print(output) + + def set_stream(self): + if self.flags['silent']: + self.stream = None + return + + if self.flags['verbose']: + self.stream = 'info' + return + + if self.flags['debug']: + self.stream = 'debug' + return + + self.stream = 'default' + + def set_debug(self): + self.flags['debug'] = True + self.set_stream() + + def set_flags(self, silent, verbose, debug): + self.flags['silent'] = silent + self.flags['verbose'] = verbose + self.flags['debug'] = debug + self.set_stream() + + def escape_ansi(self, line): + ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]') + return ansi_escape.sub('', line) + + def escape_ticks(self, line, alternative=False): + if alternative: + line = line.replace('\u2713', 'V') + line = line.replace('\u2717', 'X') + else: + line = line.replace('\u2713', '+') + line = line.replace('\u2717', '-') + + return line + + def append(self, filename, output): + try: + output = self.escape_ansi(output) + with open(filename, 'a', encoding='utf-8') as file_handler: + file_handler.write('%s\n' % (output)) + except BaseException: + pass + + def traceback(self, output): + ''' Always print ''' + output = '%s %s' % ( + self.add_color('[ERROR]', 'Red'), + output + ) + print(output) + self.append(self.default_filename, output) + self.append(self.verbose_filename, output) + self.append(self.debug_filename, output) + + def error(self, output): + ''' Always print ''' + output = '%s %s' % ( + self.add_color('[ERROR]', 'Red'), + output + ) + print(output) + self.append(self.default_filename, output) + self.append(self.verbose_filename, output) + self.append(self.debug_filename, output) + + def files_only(self, output): + self.append(self.default_filename, output) + self.append(self.verbose_filename, output) + self.append(self.debug_filename, output) + + def default(self, output, underline=False, color=None, before_newline=False, after_newline=False): + ''' Unless silent is set ''' + if underline: + output = '%s\n%s' % (output, "".join(('-',) * len(output))) + + if color is not None: + output = self.add_color( + output, + color + ) + + if before_newline: + output = '\n%s' % (output) + + if after_newline: + output = '%s\n' % (output) + + if not self.flags['silent']: + try: + print(output) + except BaseException: + print( + self.escape_ticks(output) + ) + + self.append(self.default_filename, output) + self.append(self.verbose_filename, output) + self.append(self.debug_filename, output) + + def debug(self, output, underline=False, color=None, before_newline=False, after_newline=False): + ''' When debug flag set ''' + if underline: + output = '%s\n%s' % (output, "".join(('-',) * len(output))) + + if color is not None: + output = self.add_color( + output, + color + ) + + if before_newline: + output = '\n%s' % (output) + + if after_newline: + output = '%s\n' % (output) + + if not self.flags['silent']: + if self.flags['debug']: + print(output) + + self.append(self.debug_filename, output) + + def duration(self, output): + self.append(self.duration_filename, output) + + def devel(self, output): + self.append(self.devel_filename, output) + + def info(self, output, underline=False, color=None, before_newline=False, after_newline=False): + ''' When verbose flag set ''' + if underline: + output = '%s\n%s' % (output, "".join(('-',) * len(output))) + + if color is not None: + output = self.add_color( + output, + color + ) + + if before_newline: + output = '\n%s' % (output) + + if after_newline: + output = '%s\n' % (output) + + if not self.flags['silent']: + if self.flags['verbose']: + print(output) + + self.append(self.verbose_filename, output) + self.append(self.debug_filename, output) + + def get_subkey(self, value, key, cast_none=False, allow_order_subkeys=True): + if value is not None: + if allow_order_subkeys and '.' in key: + subkey = key.split('.')[0] + if subkey not in value: + return '' + + new_key = '.'.join(key.split('.')[1:]) + return self.get_subkey(value[subkey], new_key, cast_none=cast_none) + + if key in value: + if value[key] is None and cast_none: + return '' + return value[key] + + return '' + + def replace_subkey(self, value, key, new_value): + if '.' in key: + subkey = key.split('.')[0] + if subkey not in value: + return value + + if value[subkey] is not None: + if isinstance(value[subkey], dict): + value[subkey][key.split('.')[1]] = new_value + + return value + + value[key] = new_value + return value + + def merge_output(self, values): + if isinstance(values, dict): + if '__Output' not in values: + values['__Output'] = {} + + for key in values: + if isinstance(values[key], dict): + if '__Output' in values[key]: + for okey in values[key]['__Output']: + values['__Output']['%s.%s' % (key, okey)] = values[key]['__Output'][okey] + + if isinstance(values, list): + for value in values: + if '__Output' not in value: + value['__Output'] = {} + + for key in value: + if isinstance(value[key], dict): + if '__Output' in value[key]: + for okey in value[key]['__Output']: + value['__Output']['%s.%s' % (key, okey)] = value[key]['__Output'][okey] + + return values + + def add_color(self, value, color): + if color == 'Red': + return colorama.Fore.RED + value + colorama.Fore.RESET + + if color == 'Green': + return colorama.Fore.GREEN + value + colorama.Fore.RESET + + if color == 'Yellow': + return colorama.Fore.YELLOW + value + colorama.Fore.RESET + + if color == 'Magenta': + return colorama.Fore.MAGENTA + value + colorama.Fore.RESET + + if color == 'Blue': + return colorama.Fore.BLUE + value + colorama.Fore.RESET + + return value + + def add_key_color(self, key, value, value_definition): + if value_definition is None: + return value + + if '__Output' not in value_definition: + return value + + if key not in value_definition['__Output']: + return value + + color = value_definition['__Output'][key] + + if color is None: + return value + + if color == 'Red': + return colorama.Fore.RED + str(value) + colorama.Fore.RESET + + if color == 'Green': + return colorama.Fore.GREEN + str(value) + colorama.Fore.RESET + + if color == 'Yellow': + return colorama.Fore.YELLOW + str(value) + colorama.Fore.RESET + + if color == 'Magenta': + return colorama.Fore.MAGENTA + str(value) + colorama.Fore.RESET + + if color == 'Blue': + return colorama.Fore.BLUE + str(value) + colorama.Fore.RESET + + if color.startswith(':'): + letters = color.lstrip(':') + colored_output = '' + for index, letter in enumerate(value): + if index >= len(letters): + colored_output = colored_output + letter + continue + + if letters[index] == 'R': + colored_output = colored_output + colorama.Fore.RED + letter + colorama.Fore.RESET + continue + + if letters[index] == 'M': + colored_output = colored_output + colorama.Fore.MAGENTA + letter + colorama.Fore.RESET + continue + + if letters[index] == 'G': + colored_output = colored_output + colorama.Fore.GREEN + letter + colorama.Fore.RESET + continue + + if letters[index] == 'Y': + colored_output = colored_output + colorama.Fore.YELLOW + letter + colorama.Fore.RESET + continue + + if letters[index] == 'B': + colored_output = colored_output + colorama.Fore.BLUE + letter + colorama.Fore.RESET + continue + + colored_output = colored_output + letter + + return colored_output + + return value + + def remove_empty_columns(self, headers, order, values, allow_order_subkeys=False): + if headers is None or order is None: + return headers, order + + remove_keys = [] + for key in order: + show_key = False + for value in values: + if allow_order_subkeys and '.' in key: + if isinstance(self.get_subkey(value, key), str): + if len(self.get_subkey(value, key)) > 0: + show_key = True + else: + show_key = True + + else: + if key in value: + if isinstance(value[key], str): + if len(value[key]) > 0: + show_key = True + else: + show_key = True + + if not show_key: + remove_keys.append(key) + + for key in remove_keys: + index = order.index(key) + headers.remove( + headers[index] + ) + order.remove( + key + ) + + return headers, order + + def prepare_list(self, values_ref, empty=[], empty_char='--', chunk={}, separator={}, collapse={}): + values = [] + for value_ref in values_ref: + item = {} + for value_key in value_ref: + if value_key in empty: + if isinstance(value_ref[value_key], list): + if len(value_ref[value_key]) == 0: + item[value_key] = [empty_char] + continue + + if value_ref[value_key] is None: + item[value_key] = empty_char + continue + + item[value_key] = value_ref[value_key] + continue + + if value_key in chunk: + key_separator = ' ' + if value_key in separator: + key_separator = separator[value_key] + + item['%sT' % (value_key)] = filter_helper.get_string_chunks( + value_ref[value_key], + chunk[value_key], + separator=key_separator + ) + item[value_key] = value_ref[value_key] + continue + + item[value_key] = value_ref[value_key] + + for key in collapse: + item[key] = [] + for skey in collapse[key]: + item[key].append( + value_ref[skey] + ) + + values.append(item) + + return values + + def auto_expand_lists(self, values_ref, order): + # this optimizes the expand_lists by using only relevant keys + ip_keys = [] + for order_key in order: + if ip_helper.is_valid_ipv4_address(order_key): + ip_keys.append( + order_key + ) + + values = [] + for value_ref in values_ref: + item = {} + for order_key in order: + if order_key in ip_keys: + key = order_key + else: + key = order_key.split('.')[0] + + if key not in item: + if key in value_ref: + item[key] = value_ref[key] + else: + item[key] = '' + + if '__Output' in value_ref: + item['__Output'] = value_ref['__Output'] + + values.append(item) + + new_values = [] + for value in values: + max_key_length = 0 + keys = [] + for key in order: + if key in value and value[key] is not None: + if isinstance(value[key], list): + keys.append( + key + ) + max_key_length = max( + max_key_length, + len(value[key]) + ) + + if max_key_length == 0: + for key in keys: + value[key] = '' + value['__Last'] = True + new_values.append(value) + + if max_key_length == 1: + for key in keys: + if key not in value or value[key] is None or len(value[key]) == 0: + value[key] = '' + else: + if isinstance(value[key][0], dict): + if '__Output' in value[key][0]: + if '__Output' not in value: + value['__Output'] = {} + + for output_key in value[key][0]['__Output']: + value['__Output']['%s.%s' % (key, output_key)] = value[key][0]['__Output'][output_key] + + value[key] = value[key][0] + + value['__Last'] = True + new_values.append(value) + + if max_key_length > 1: + for index in range(0, max_key_length): + if index == 0: + new_value = copy.deepcopy(value) + if '__Output' not in new_value: + new_value['__Output'] = {} + value['__Last'] = False + + for key in keys: + if key not in value: + new_value[key] = '' + continue + + if value[key] is None or len(value[key]) == 0: + new_value[key] = '' + else: + new_value[key] = copy.deepcopy(value[key][0]) + if isinstance(value[key][0], dict): + if '__Output' in value[key][0]: + for output_key in value[key][0]['__Output']: + new_value['__Output']['%s.%s' % (key, output_key)] = value[key][0]['__Output'][output_key] + + new_values.append(new_value) + + if index > 0: + new_value = copy.deepcopy(value) + if '__Output' not in new_value: + new_value['__Output'] = {} + + for key in keys: + if key not in value: + new_value[key] = '' + continue + + if value[key] is None or len(value[key]) == 0: + new_value[key] = '' + else: + new_value[key] = copy.deepcopy(value[key][0]) + + for displayed_field in order: + new_value = self.replace_subkey( + new_value, + displayed_field, + '' + ) + + new_value['__Last'] = False + for key in keys: + if key not in value: + continue + + if value[key] is not None: + if len(value[key]) > index: + new_value[key] = copy.deepcopy(value[key][index]) + if isinstance(value[key][index], dict): + if '__Output' in value[key][index]: + for output_key in value[key][index]['__Output']: + new_value['__Output']['%s.%s' % (key, output_key)] = value[key][index]['__Output'][output_key] + + if index == max_key_length - 1: + new_value['__Last'] = True + + new_values.append(new_value) + + return new_values + + def expand_lists(self, values_ref, order, keys, filtering_rules=None): + # this optimizes the expand_lists by using only relevant keys + values = [] + for value_ref in values_ref: + item = {} + for order_key in order: + key = order_key.split('.')[0] + if key not in item: + if key in value_ref: + item[key] = value_ref[key] + else: + item[key] = '' + + if '__Output' in value_ref: + item['__Output'] = value_ref['__Output'] + + values.append(item) + + new_values = [] + for value in values: + max_key_length = 0 + for key in keys: + if key in value and value[key] is not None: + if filtering_rules is not None: + value[key] = self.filter_values(value[key], filtering_rules) + + max_key_length = max( + max_key_length, + len(value[key]) + ) + + if max_key_length == 0: + for key in keys: + value[key] = '' + value['__Last'] = True + new_values.append(value) + + if max_key_length == 1: + for key in keys: + if key not in value or value[key] is None or len(value[key]) == 0: + value[key] = '' + else: + if isinstance(value[key][0], dict): + if '__Output' in value[key][0]: + if '__Output' not in value: + value['__Output'] = {} + + for output_key in value[key][0]['__Output']: + value['__Output']['%s.%s' % (key, output_key)] = value[key][0]['__Output'][output_key] + + value[key] = value[key][0] + + value['__Last'] = True + new_values.append(value) + + if max_key_length > 1: + for index in range(0, max_key_length): + if index == 0: + new_value = copy.deepcopy(value) + if '__Output' not in new_value: + new_value['__Output'] = {} + value['__Last'] = False + + for key in keys: + if key not in value: + new_value[key] = '' + continue + + if value[key] is None or len(value[key]) == 0: + new_value[key] = '' + else: + new_value[key] = copy.deepcopy(value[key][0]) + if isinstance(value[key][0], dict): + if '__Output' in value[key][0]: + for output_key in value[key][0]['__Output']: + new_value['__Output']['%s.%s' % (key, output_key)] = value[key][0]['__Output'][output_key] + + new_values.append(new_value) + + if index > 0: + new_value = copy.deepcopy(value) + if '__Output' not in new_value: + new_value['__Output'] = {} + + for key in keys: + if key not in value: + new_value[key] = '' + continue + + if value[key] is None or len(value[key]) == 0: + new_value[key] = '' + else: + new_value[key] = copy.deepcopy(value[key][0]) + + for displayed_field in order: + new_value = self.replace_subkey( + new_value, + displayed_field, + '' + ) + + new_value['__Last'] = False + for key in keys: + if key not in value: + continue + + if value[key] is not None: + if len(value[key]) > index: + new_value[key] = copy.deepcopy(value[key][index]) + if isinstance(value[key][index], dict): + if '__Output' in value[key][index]: + for output_key in value[key][index]['__Output']: + new_value['__Output']['%s.%s' % (key, output_key)] = value[key][index]['__Output'][output_key] + + if index == max_key_length - 1: + new_value['__Last'] = True + + new_values.append(new_value) + + return new_values + + def add_last_tag(self, values): + new_values = [] + is_last = False + for value in values: + if '__Last' in value: + is_last = True + new_values.append(value) + + if not is_last: + for value in new_values: + value['__Last'] = True + + return new_values + + def match_value(self, value, value_filter): + if value_filter is None or len(value_filter) == 0: + return True + + for filtering_rule in value_filter: + (key, value_type, ref_value) = filtering_rule.split(':') + + key_value = self.get_subkey( + value, + key + ) + + if value_type == 'bool': + if isinstance(key_value, bool): + if ref_value == 'true': + if key_value: + return False + + if ref_value == 'false': + if not key_value: + return False + + return True + + def filter_values(self, values, filtering_rules): + new_values = [] + for value in values: + if not self.match_value(value, filtering_rules): + continue + new_values.append(value) + return new_values + + def my_table( + self, + values_ref, + spacing=3, + underline=False, + order=None, + filtering_rules=None, + allow_order_subkeys=False, + headers=None, + headers_upper=False, + table=False, + row_separator=False, + remove_empty_columns=False, + cast_none=False, + stream='default', + merge=False + ): + values = copy.deepcopy( + values_ref + ) + + if merge: + values = self.merge_output( + values + ) + + if remove_empty_columns: + headers, order = self.remove_empty_columns(headers, order, values, allow_order_subkeys=allow_order_subkeys) + + if filtering_rules is not None: + values = self.filter_values(values, filtering_rules) + + if table and row_separator: + values = self.add_last_tag(values) + + if values is None: + values = [] + + if len(values) == 0: + if not table: + return + + # Params fixup + if table: + spacing = 1 + underline = False + + if order is None: + item = values[0] + display = item.keys() + else: + display = order + + # keys holds the column length + + keys = {} + if headers is None: + for key in display: + keys[key] = len(key) + else: + for index, value in enumerate(display): + keys[value] = len(headers[index]) + + for value in values: + for key in keys: + try: + if allow_order_subkeys and '.' in key: + value[key] = str( + self.get_subkey(value, key, cast_none=cast_none) + ) + else: + value[key] = str(value[key]) + except BaseException: + value[key] = '' + + keys[key] = max(keys[key], len(value[key])) + + if headers is not None: + index = 0 + for key in keys: + keys[key] = max(keys[key], len(headers[index])) + index = index + 1 + + for key in keys: + keys[key] = keys[key] + spacing + + # print header + + if headers is None: + header = '' + for key in keys: + header = '%s%s' % (header, key.capitalize().ljust(keys[key])) + else: + header = '' + if table: + header = '| ' + table_top = '+-' + + index = 0 + for key in keys: + + column_title = headers[index] + if headers_upper: + column_title = column_title.upper() + + if table: + table_top = '%s%s+-' % (table_top, ''.ljust(keys[key], '-')) + header = '%s%s| ' % (header, column_title.ljust(keys[key])) + else: + header = '%s%s' % (header, column_title.ljust(keys[key])) + + index = index + 1 + + if table: + header = header.rstrip(' ') + table_top = table_top.rstrip('-') + + if table: + header = '%s\n%s\n%s' % ( + table_top, + header, + table_top + ) + + self.print_stream('\n%s' % (header), stream) + + if underline: + line = '' + index = 0 + for key in keys: + if table: + line = '%s%s%s | ' % ( + line, + ''.ljust(keys[key] - spacing, '-'), + ''.ljust(spacing) + ) + + else: + line = '%s%s%s' % ( + line, + ''.ljust(keys[key] - spacing, '-'), + ''.ljust(spacing) + ) + index = index + 1 + + self.print_stream(line, stream) + + for value in values: + line = '' + if table: + line = '| ' + + index = 0 + for key in keys: + if table: + line = '%s%s| ' % ( + line, + self.add_key_color( + key, + value[key].ljust(keys[key]), + value + ) + ) + else: + line = '%s%s' % (line, value[key].ljust(keys[key])) + + index = index + 1 + + self.print_stream(line, stream) + if table and row_separator: + if '__Last' in value and value['__Last']: + self.print_stream(table_top, stream) + + if table: + if not row_separator: + self.print_stream(table_top, stream) + + def my_table_html(self, values, order, headers, stream='output', title=None): + if self.html_table_height_limit: + if len(values) < 2: + height = 200 + + if 2 <= len(values) < 5: + height = 300 + + if len(values) >= 5: + height = 500 + + self.print_stream( + '' % (height), + stream + ) + + if not self.html_table_height_limit: + self.print_stream( + '
', + stream + ) + + self.print_stream( + '', + stream + ) + if title is not None: + self.print_stream( + '' % ( + len(order), + title, + len(values) + ), + stream + ) + + self.print_stream( + '', + stream + ) + + for header in headers: + self.print_stream('' % (header, header), stream) + self.print_stream( + '', + stream + ) + + self.print_stream('', stream) + for value in values: + self.print_stream('', stream) + for key in order: + if '.' in key: + if isinstance(value[key.split('.')[0]], dict): + self.print_stream('' % (str(self.get_subkey(value, key))), stream) + if isinstance(value[key.split('.')[0]], list): + expanded_value = '' % (expanded_value) + self.print_stream(expanded_value, stream) + else: + if isinstance(value[key], list): + expanded_value = '' % (expanded_value) + self.print_stream(expanded_value, stream) + else: + self.print_stream('' % (value[key]), stream) + + self.print_stream('', stream) + + self.print_stream('', stream) + self.print_stream('
%s [#%s]
%s
%s' + for item in value[key.split('.')[0]]: + expanded_value = '%s%s
' % ( + expanded_value, + str(self.get_subkey(item, '.'.join(key.split('.')[1:]))) + ) + expanded_value = '%s
' + for item in value[key]: + expanded_value = '%s%s
' % ( + expanded_value, + str(item) + ) + expanded_value = '%s
%s
', stream) + + def get_dictionary_value(self, dictionary, key, allow_order_subkeys=True): + my_dictionary = dictionary + dictionary_value = None + + if ':' not in key: + if '.' in key and allow_order_subkeys: + dictionary_value = '' + if isinstance(dictionary[key.split('.')[0]], dict): + dictionary_value = self.get_subkey(dictionary, key) + + if isinstance(dictionary[key.split('.')[0]], list): + values = [] + for item in dictionary[key.split('.')[0]]: + values.append( + self.get_subkey(item, key.split('.')[1]) + ) + dictionary_value = ', '.join(values) + else: + dictionary_value = self.get_subkey(dictionary, key, allow_order_subkeys=allow_order_subkeys) + + if ':' in key: + keys = key.split(':') + for index, iter_key in enumerate(keys): + if iter_key not in my_dictionary: + break + + if index < len(keys) - 1: + my_dictionary = my_dictionary[iter_key] + continue + + dictionary_value = my_dictionary[iter_key] + + return dictionary_value + + def dictionary( + self, + items, + exclude=[], + title=None, + underline=True, + prefix=None, + keys=None, + values=None, + title_keys=None, + justify=False, + allow_order_subkeys=True, + newline=[], + stream='default', + start='\n' + ): + header = '' + if title is not None: + header = '%s%s' % (start, title) + if underline: + header = '%s\n%s' % (header, "".join(('-',) * len(title))) + + body = '' + + # Get longest key + # note that keys may have : syntax + if justify: + longest = 0 + if title_keys is None: + if keys is None: + for i in items: + if i not in exclude: + longest = max(longest, len(i)) + if keys is not None: + for key in keys: + longest = max(longest, len(key.split(':')[-1])) + + if title_keys is not None: + for title_key in title_keys: + longest = max(longest, len(title_key)) + + longest = longest + 1 + + # Print all items + if keys is None: + for item in items: + if item not in exclude: + ikey = item + if justify: + ikey = ikey.ljust(longest) + + if isinstance(items[item], list): + if prefix is not None: + body = '%s%s%s:\n' % (body, prefix, ikey) + else: + body = '%s%s:\n' % (body, ikey) + + for list_item in items[item]: + body = '%s\t%s\n' % (body, list_item) + + else: + + if prefix is not None: + body = '%s%s%s: %s\n' % (body, prefix, ikey, items[item]) + else: + body = '%s%s: %s\n' % (body, ikey, items[item]) + + # Print selected keys with optional title + if keys is not None: + index = 0 + for key in keys: + if key is not None: + ikey = key.split(':')[-1] + ivalue = self.add_key_color( + key, + self.get_dictionary_value(items, key, allow_order_subkeys=allow_order_subkeys), + items + ) + if key is None: + ikey = None + ivalue = values[index] + + if ivalue is not None: + if title_keys is not None: + ikey = title_keys[index] + + if justify: + ikey = ikey.ljust(longest) + + if isinstance(ivalue, list): + if prefix is not None: + body = '%s%s%s:\n' % (body, prefix, ikey) + else: + body = '%s%s:\n' % (body, ikey) + + for list_item in ivalue: + if isinstance(list_item, dict): + list_item_index = 1 + for list_item_key in list_item: + if list_item_key.startswith('__'): + continue + + if list_item_index == 1: + body = '%s\t- %s: %s\n' % (body, list_item_key, list_item[list_item_key]) + list_item_index = list_item_index + 1 + else: + body = '%s\t %s: %s\n' % (body, list_item_key, list_item[list_item_key]) + else: + body = '%s\t%s\n' % (body, list_item) + + if isinstance(ivalue, str): + if '\n' in ivalue: + ivalue = ivalue.replace('\n', '\n\t') + if prefix is not None: + body = '%s%s%s:\n\t%s\n' % (body, prefix, ikey, ivalue) + else: + body = '%s%s:\n\t%s\n' % (body, ikey, ivalue) + else: + if prefix is not None: + body = '%s%s%s: %s\n' % (body, prefix, ikey, ivalue) + else: + body = '%s%s: %s\n' % (body, ikey, ivalue) + + if not isinstance(ivalue, str) and not isinstance(ivalue, list): + if prefix is not None: + body = '%s%s%s: %s\n' % (body, prefix, ikey, ivalue) + else: + body = '%s%s: %s\n' % (body, ikey, ivalue) + + if key in newline: + body = '%s\n' % (body) + + index = index + 1 + + if stream is not None: + if len(header) > 0: + self.print_stream(header, stream) + + if len(body) > 0: + self.print_stream(body, stream) + + output = '%s\n%s' % (header, body) + return output + + def columns(self, data, spacing=2, stream='default', max_length=80): + column_width = [] + column_height = [] + for col in data: + column_height.append(len(col)) + col_width = 0 + for item in col: + col_width = max(col_width, len(item)) + column_width.append(col_width) + + rows = [] + row_length = 0 + row = [] + for col_index in list(range(len(data))): + if row_length > 0: + if row_length + column_width[col_index] > max_length: + rows.append(row) + row = [] + row_length = 0 + else: + row.append( + dict( + data=data[col_index], + width=column_width[col_index], + height=column_height[col_index] + ) + ) + row_length = row_length + column_width[col_index] + continue + + if row_length == 0: + row.append( + dict( + data=data[col_index], + width=column_width[col_index], + height=column_height[col_index] + ) + ) + row_length = column_width[col_index] + + rows.append(row) + + # Fixup column width per row + + for row in rows: + avg_column_width = int(max_length / len(row)) + for col in row: + if col['width'] < avg_column_width: + col['width'] = avg_column_width - spacing - 1 + + # Print out of rows + + for row in rows: + row_lines = 0 + for col in row: + row_lines = max(row_lines, col['height']) + + for line_index in list(range(row_lines)): + line = '' + for col in row: + try: + line = '%s%s%s' % ( + line, + col['data'][line_index].ljust(col['width']), + ''.ljust(spacing) + ) + except BaseException: + line = '%s%s%s' % ( + line, + ''.ljust(col['width']), + ''.ljust(spacing) + ) + self.print_stream(line, stream) + + self.print_stream('', stream) + + def kubernetes_versions(self, versions, verbose, output): + if output == 'json': + self.my_print(json.dumps(versions, indent=4)) + return + self.my_table(versions) + + def clusters_name(self, names, prefix=None): + try: + if names is None or len(names) == 0: + self.my_print('[INFO] No cluster found') + return + + for name in names: + if prefix is None: + self.my_print(name) + else: + self.my_print('%s%s' % (prefix, name)) + except BaseException: + self.my_print('[ERROR] Exception') + + def my_logs(self, logs, stream='devel'): + for log_entry in logs: + if logs[log_entry] is not None: + output = '\nLog: %s' % (log_entry) + output = '%s\n%s\n' % (output, "".join(('-',) * len(output))) + + if stream == 'devel': + if log_entry != 'debug': + self.devel(output) + self.devel(logs[log_entry]) + + if stream == 'default': + self.default(output) + self.default(logs[log_entry]) + + def get_input(self, message, timeout=None): + if timeout is None: + return input(message) + + try: + user_input = inputimeout(prompt=message, timeout=timeout) + except TimeoutOccurred: + user_input = None + + return user_input + + def wrap_bot_html_output(self, html_output, command=None, view={}, exclude_view=[]): + output = '' + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\niserver.bot' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n
' % (output) + output = '%s\n' % (output) + + if len(view) > 0: + view_output = '
    View:' + for key in view: + if key in exclude_view: + view_output = '%s %s' % (view_output, key) + else: + view_output = '%s %s' % (view_output, key, key) + view_output = '%s

' % (view_output) + output = '%s\n%s\n' % (output, view_output) + + output = '%s\n%s' % (output, html_output) + output = '%s\n
' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + output = '%s\n' % (output) + return output + + def sanitize_bot_output(self, output, output_html, url, execution_time=None): + if len(output) > 7000: + output = '%s\n\n... output too long' % (output[:7000]) + + if output_html is None or len(output_html) == 0: + output = '```\n%s\n```' % (output) + else: + if self.log_id is not None and url is not None: + output = '```\n%s\n```\n\nFull output' % (url, output, self.log_id) + + if execution_time is not None: + output = '%s
Execution time: %s ms' % (output, execution_time) + + return output diff --git a/lib/psirt/__init__.py b/lib/psirt/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/psirt/advisory/__init__.py b/lib/psirt/advisory/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/psirt/advisory/api.py b/lib/psirt/advisory/api.py new file mode 100644 index 00000000..d1dba7d7 --- /dev/null +++ b/lib/psirt/advisory/api.py @@ -0,0 +1,76 @@ +import time +import requests +import traceback + + +class PsirtAdvisoryApi(): + def __init__(self): + self.advisory_mo = None + + def get_advisory_mo(self, cache_enabled=True): + if cache_enabled: + if self.advisory_mo is not None: + return self.advisory_mo + + self.advisory_mo = self.get_psirt_cache_entry('advisory') + if self.advisory_mo is not None: + return self.advisory_mo + + api_handler = self.get_api_token() + if api_handler is None: + self.log.error( + 'api.get_advisory_mo', + 'No api token available' + ) + return None + + try: + start_time = int(time.time() * 1000) + + headers = {} + headers['Authorization'] = 'Bearer %s' % (self.api_token) + + response = requests.get( + 'https://apix.cisco.com/security/advisories/v2/all', + headers=headers + ) + + self.log.psirt( + 'get', + 'advisory', + True, + int(time.time() * 1000) - start_time + ) + + if response.status_code > 299: + self.log.error( + 'get_advisory_mo', + 'Failed to get psirt advisory: %s' % ( + headers + ) + ) + self.log.error( + 'get_advisory_mo', + 'Code [%s] Content [%s]' % ( + response.status_code, + response.content + ) + ) + return None + + self.set_psirt_cache_entry( + 'advisory', + response.json()['advisories'] + ) + + except BaseException: + self.log.error('psirt.get_advisory_mo', traceback.format_exc()) + self.log.psirt( + 'get', + 'advisory', + True, + int(time.time() * 1000) - start_time + ) + return None + + return self.advisory_mo diff --git a/lib/psirt/advisory/info.py b/lib/psirt/advisory/info.py new file mode 100644 index 00000000..5ec5d3af --- /dev/null +++ b/lib/psirt/advisory/info.py @@ -0,0 +1,306 @@ +from lib import filter_helper + + +class PsirtAdvisoryInfo(): + def __init__(self): + self.advisory = None + + def get_advisory_info(self, advisory_mo): + if advisory_mo is None: + return None + + info = {} + info['__Output'] = {} + + for key in advisory_mo: + if key in ['bugIDs']: + continue + info[key] = advisory_mo[key] + + info['bugIDs'] = [] + for bug_mo in advisory_mo['bugIDs']: + if bug_mo != 'NA': + info['bugIDs'].append( + bug_mo + ) + + info['productVersion'] = {} + products_with_version = [ + 'Cisco Wireless LAN Controller (WLC)', + 'Cisco Firepower Threat Defense Software', + 'Cisco Adaptive Security Appliance (ASA) Software', + 'Cisco Firepower Extensible Operating System (FXOS)', + 'Cisco Firepower Management Center', + 'Cisco NX-OS Software', + 'Cisco NX-OS System Software in ACI Mode', + 'Cisco IOS XE Software', + 'Cisco IOS' + ] + + for product_mo in advisory_mo['productNames']: + if product_mo in info['productVersion']: + # base product name already defined, there is no version here anyway in product_mo + continue + + is_product_mo_with_version = False + for product_with_version in products_with_version: + if product_mo == product_with_version: + # it must have been already added to 'productName' + continue + + if product_mo.startswith(product_with_version): + if len(product_mo.split(' ')) == len(product_with_version.split(' ')) + 1: + # product_mo = Cisco IOS 12.2 + # product_with_version = Cisco IOS + is_product_mo_with_version = True + if product_with_version not in info['productVersion']: + info['productVersion'][product_with_version] = [] + + if len(product_mo.split(' ')[-1]) > 0: + info['productVersion'][product_with_version].append( + product_mo.split(' ')[-1] + ) + + if not is_product_mo_with_version: + info['productVersion'][product_mo] = [] + + if info['sir'] == 'Critical': + info['__Output']['sir'] = 'Red' + + if info['sir'] == 'High': + info['__Output']['sir'] = 'Magenta' + + if info['sir'] == 'Medium': + info['__Output']['sir'] = 'Yellow' + + if info['sir'] == 'Low': + info['__Output']['sir'] = 'Green' + + if info['sir'] == 'Informational': + info['__Output']['sir'] = 'Blue' + + if info['sir'] not in ['Critical', 'High', 'Medium', 'NA', 'Low', 'Informational']: + print(info['sir']) + + if info['status'] == 'Final': + info['finalTick'] = '\u2713' + else: + info['finalTick'] = '\u2717' + + info['add_age'] = self.convert_timestamp_to_age( + info['firstPublished'], + on_error='--' + ) + + info['add_days'] = self.convert_timestamp_to_days( + info['firstPublished'] + ) + + info['update_age'] = self.convert_timestamp_to_age( + info['lastUpdated'], + on_error='--' + ) + + info['update_days'] = self.convert_timestamp_to_days( + info['lastUpdated'], + on_error=None + ) + return info + + def get_advisories_info(self, cache_enabled=True): + if cache_enabled: + if self.advisory is not None: + return self.advisory + + managed_objects = self.get_advisory_mo(cache_enabled=cache_enabled) + if managed_objects is None: + return None + + self.advisory = [] + for managed_object in managed_objects: + advisory_info = self.get_advisory_info( + managed_object + ) + self.advisory.append( + advisory_info + ) + + self.log.psirt_mo( + 'advisory', + self.advisory + ) + + return self.advisory + + def match_advisory(self, advisory_info, advisory_filter): + if advisory_filter is None or len(advisory_filter) == 0: + return True + + for ap_rule in advisory_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + key_found = False + + if key == 'bug': + key_found = True + found = False + for bug in advisory_info['bugIDs']: + if filter_helper.match_string(value, bug): + found = True + break + + if not found: + return False + + if key == 'cve': + key_found = True + found = False + for cve in advisory_info['cves']: + if filter_helper.match_string(value, cve): + found = True + break + + if not found: + return False + + if key == 'cwe': + key_found = True + found = False + for cwe in advisory_info['cwe']: + if filter_helper.match_string(value, cwe): + found = True + break + + if not found: + return False + + if key == 'product': + key_found = True + found = False + for product_name in advisory_info['productVersion']: + if filter_helper.match_string(value, product_name): + found = True + break + + if not found: + return False + + if key == 'version': + key_found = True + found = False + for product_name in advisory_info['productVersion']: + for product_version in advisory_info['productVersion'][product_name]: + if filter_helper.match_string(value, product_version): + found = True + break + + if not found: + return False + + if key == 'severity': + key_found = True + + if value not in ['crit', 'high', 'med', 'low', 'info']: + self.log.error( + 'match_advisory', + 'Unsupported severity value: %s' % (value) + ) + + if value == 'crit': + if advisory_info['sir'] not in ['Critical']: + return False + + if value == 'high': + if advisory_info['sir'] not in ['Critical', 'High']: + return False + + if value == 'med': + if advisory_info['sir'] not in ['Critical', 'High', 'Medium']: + return False + + if value == 'low': + if advisory_info['sir'] not in ['Critical', 'High', 'Medium', 'Low']: + return False + + if value == 'info': + if advisory_info['sir'] not in ['Critical', 'High', 'Medium', 'Low', 'Informational']: + return False + + if key == 'added': + key_found = True + if advisory_info['add_days'] is None: + return False + + if advisory_info['add_days'] > int(value): + return False + + if key == 'updated': + key_found = True + if advisory_info['update_days'] is None: + return False + + if advisory_info['update_days'] > int(value): + return False + + if not key_found: + self.log.error( + 'match_advisory', + 'Unsupported key: %s' % (key) + ) + + return True + + def get_advisory_product_versions(self, product_versions, advisory_filter): + selected_product_versions = {} + + product_filter = None + version_filter = None + for ap_rule in advisory_filter: + key = ap_rule.split(':')[0] + value = ':'.join(ap_rule.split(':')[1:]) + + if key == 'product': + product_filter = value + + if key == 'version': + version_filter = value + + for product_name in product_versions: + if product_filter is not None: + if not filter_helper.match_string(product_filter, product_name): + continue + + selected_product_versions[product_name] = [] + for product_version in product_versions[product_name]: + if version_filter is not None: + if not filter_helper.match_string(version_filter, product_version): + continue + + selected_product_versions[product_name].append( + product_version + ) + + return selected_product_versions + + def get_advisories(self, object_filter=None, cache_enabled=True): + all_advisories = self.get_advisories_info(cache_enabled=cache_enabled) + if all_advisories is None: + return None + + advisories = [] + + for advisory_info in all_advisories: + if not self.match_advisory(advisory_info, object_filter): + continue + + advisory_info['productVersion'] = self.get_advisory_product_versions( + advisory_info['productVersion'], + object_filter + ) + + advisories.append( + advisory_info + ) + + return advisories diff --git a/lib/psirt/advisory/main.py b/lib/psirt/advisory/main.py new file mode 100644 index 00000000..395e40d4 --- /dev/null +++ b/lib/psirt/advisory/main.py @@ -0,0 +1,11 @@ +from lib.psirt.advisory.api import PsirtAdvisoryApi +from lib.psirt.advisory.info import PsirtAdvisoryInfo + + +class PsirtAdvisory( + PsirtAdvisoryApi, + PsirtAdvisoryInfo + ): + def __init__(self): + PsirtAdvisoryApi.__init__(self) + PsirtAdvisoryInfo.__init__(self) diff --git a/lib/psirt/advisory/output.py b/lib/psirt/advisory/output.py new file mode 100644 index 00000000..c9b46b13 --- /dev/null +++ b/lib/psirt/advisory/output.py @@ -0,0 +1,345 @@ +from lib import filter_helper + + +class PsirtAdvisoryOutput(): + def __init__(self): + pass + + def print_advisory(self, info, title=False): + if title: + self.my_output.default( + 'Advisory [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['advisoryTitleT'] = filter_helper.get_string_chunks( + item['advisoryTitle'], + length=40 + ) + item['products'] = [] + for product_name in item['productVersion']: + item['products'].append( + product_name + ) + + order = [ + 'sir', + 'finalTick', + 'advisoryTitleT', + 'bugIDs', + 'cves', + 'cwe', + 'products', + 'add_age', + 'update_age' + ] + + headers = [ + 'Sev', + 'Final', + 'Title', + 'Bug', + 'CVE', + 'CWE', + 'Product', + 'Add', + 'Update' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['advisoryTitleT', 'bugIDs', 'cves', 'cwe', 'products'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_advisory_url(self, info, title=False): + if title: + self.my_output.default( + 'Advisory - URL [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['advisoryTitleT'] = filter_helper.get_string_chunks( + item['advisoryTitle'], + length=40 + ) + item['url'] = [] + item['url'].append( + 'cvrf: %s' % (item['cvrfUrl']) + ) + item['url'].append( + 'csaf: %s' % (item['csafUrl']) + ) + item['url'].append( + 'pub: %s' % (item['publicationUrl']) + ) + + order = [ + 'sir', + 'finalTick', + 'advisoryTitleT', + 'url' + ] + + headers = [ + 'Sev', + 'Final', + 'Title', + 'URL' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['advisoryTitleT', 'url'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_advisory_summary(self, info, title=False): + if title: + self.my_output.default( + 'Advisory - Summary [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['advisoryTitleT'] = filter_helper.get_string_chunks( + item['advisoryTitle'], + length=40 + ) + + item['summaryT'] = filter_helper.get_string_chunks( + item['summary'].replace('\r\n', '').replace('

', '').replace('

', ''), + length=100 + ) + + order = [ + 'sir', + 'finalTick', + 'advisoryTitleT', + 'summaryT' + ] + + headers = [ + 'Sev', + 'Final', + 'Title', + 'Summary' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['advisoryTitleT', 'summaryT'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_advisory_version(self, info, title=False): + if title: + self.my_output.default( + 'Advisory - Product Version [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + for item in info: + item['advisoryTitleT'] = filter_helper.get_string_chunks( + item['advisoryTitle'], + length=40 + ) + item['productNameVersion'] = [] + for product_name in item['productVersion']: + if len(item['productVersion'][product_name]) == 0: + item['productNameVersion'].append( + product_name + ) + else: + for product_version in item['productVersion'][product_name]: + item['productNameVersion'].append( + '%s %s' % ( + product_name, + product_version + ) + ) + + order = [ + 'sir', + 'finalTick', + 'advisoryTitleT', + 'bugIDs', + 'cves', + 'cwe', + 'productNameVersion', + 'add_age', + 'update_age' + ] + + headers = [ + 'Sev', + 'Final', + 'Title', + 'Bug', + 'CVE', + 'CWE', + 'Product', + 'Add', + 'Update' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['advisoryTitleT', 'bugIDs', 'cves', 'cwe', 'productNameVersion'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_advisory_product(self, info, title=False, product_filter=None): + severities = ['Critical', 'High', 'Medium', 'NA', 'Low', 'Informational'] + products = {} + for item in info: + for product_name in item['productVersion']: + if product_filter is not None and not filter_helper.match_string(product_filter, product_name): + continue + + if product_name not in products: + product_info = {} + product_info['ver'] = [] + product_info['bug'] = [] + product_info['cve'] = [] + product_info['cwe'] = [] + for sev in severities: + product_info[sev] = 0 + products[product_name] = product_info + + for ver in item['productVersion'][product_name]: + if ver not in products[product_name]['ver']: + products[product_name]['ver'].append(ver) + + for bug in item['bugIDs']: + if bug not in products[product_name]['bug']: + products[product_name]['bug'].append(bug) + + for cve in item['cves']: + if cve not in products[product_name]['cve']: + products[product_name]['cve'].append(cve) + + for cwe in item['cwe']: + if cwe not in products[product_name]['cwe']: + products[product_name]['cwe'].append(cwe) + + if item['sir'] in severities: + products[product_name][item['sir']] = products[product_name][item['sir']] + 1 + + items = [] + for product_name in products: + item = products[product_name] + item['name'] = product_name + items.append( + item + ) + + items = sorted( + items, + key=lambda i: i['name'].lower() + ) + + if title: + self.my_output.default( + 'Advisory - Product Pivot View [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'name', + 'ver', + 'Critical', + 'High', + 'Medium', + 'Low', + 'Informational', + 'bug', + 'cve', + 'cwe' + ] + + headers = [ + 'Product', + 'Version', + 'Crit', + 'High', + 'Med', + 'Low', + 'Info', + 'Bug', + 'CVE', + 'CWE' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + items, + order, + ['ver', 'bug', 'cve', 'cwe'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/psirt/api.py b/lib/psirt/api.py new file mode 100644 index 00000000..ec92e6a2 --- /dev/null +++ b/lib/psirt/api.py @@ -0,0 +1,64 @@ +import os +import time +import json +import traceback +import yaml +import requests + + +class PsirtApi(): + def __init__(self, key, secret): + self.api_key = key + self.api_secret = secret + self.api_token = None + self.api_timeout_seconds = 3 + self.api_retries = 1 + self.ssl_verify = False + + def get_api_token(self): + if self.api_token is not None: + return self.api_token + + try: + # curl -s -k -H "Content-Type: application/x-www-form-urlencoded" -X POST -d "client_id=deadbabebeef" -d "client_secret=deadbabebeef" -d "grant_type=client_credentials" https://id.cisco.com/oauth2/default/v1/token + + url = 'https://id.cisco.com/oauth2/default/v1/token' + + data = {} + data['client_id'] = self.api_key + data['client_secret'] = self.api_secret + data['grant_type'] = 'client_credentials' + + response = requests.post( + url, + headers={'Content-Type': 'application/x-www-form-urlencoded'}, + data=data, + verify=self.ssl_verify + ) + + if response.status_code > 299: + self.log.error( + 'api.get_api_token', + 'Failed to get api token: key [%s] secret [%s] code [%s]' % ( + self.api_key, + self.api_secret, + response.status_code + ) + ) + self.log.error( + 'api.get_api_token', + response.content + ) + return None + + self.api_token = response.json()['access_token'] + + except BaseException: + self.log.error( + 'api.get_api_token', + 'Failed to get api token' + ) + self.log.error('api.get_api_token', traceback.format_exc()) + return None + + return self.api_token diff --git a/lib/psirt/cache.py b/lib/psirt/cache.py new file mode 100644 index 00000000..d9063a91 --- /dev/null +++ b/lib/psirt/cache.py @@ -0,0 +1,66 @@ +import os +import time +import json +import traceback + +from lib.psirt import settings + + +class PsirtCache(): + def __init__(self): + self.settings_handler = settings.PsirtSettings(log_id=self.log_id) + psirt_settings = self.settings_handler.get_psirt_settings() + + self.psirt_cache_enabled = psirt_settings['cache'] + self.psirt_cache_directory = psirt_settings['directory'] + self.psirt_cache_ttl = psirt_settings['ttl'] + + def get_psirt_cache_file(self, name): + filename = os.path.join( + self.psirt_cache_directory, + name + ) + if not os.path.isfile(filename): + self.log.debug('get_psirt_cache_file', 'cache not found: %s' % (filename)) + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_psirt_cache_file', traceback.format_exc()) + return None + + if int(time.time()) - content['timestamp'] > self.psirt_cache_ttl: + self.log.debug('get_psirt_cache_file', 'cache miss: %s' % (name)) + return None + + return content['content'] + + def set_psirt_cache_file(self, name, content): + filename = os.path.join( + self.psirt_cache_directory, + name + ) + + try: + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(content, indent=4)) + + except BaseException: + self.log.error('set_psirt_cache_file', traceback.format_exc()) + return False + + return True + + def get_psirt_cache_entry(self, cache_entry_name): + if not self.psirt_cache_enabled: + return None + return self.get_psirt_cache_file(cache_entry_name) + + def set_psirt_cache_entry(self, cache_entry_name, entry_content): + content = {} + content['content'] = entry_content + content['timestamp'] = int(time.time()) + return self.set_psirt_cache_file(cache_entry_name, content) diff --git a/lib/psirt/common.py b/lib/psirt/common.py new file mode 100644 index 00000000..d7ebb2bc --- /dev/null +++ b/lib/psirt/common.py @@ -0,0 +1,94 @@ +import time +import datetime + + +class PsirtCommon(): + def __init__(self): + pass + + def convert_age(self, seconds): + if seconds > 365 * 60 * 60 * 24: + years = int(seconds / (365 * 60 * 60 * 24)) + remaining = seconds - years * 365 * 60 * 60 * 24 + days = int(remaining / (60 * 60 * 24)) + return '%sy%sd' % (years, days) + + if seconds > 60 * 60 * 24: + return '%sd' % (int(seconds / (60 * 60 * 24))) + + if seconds > 60 * 60: + hours = 0 + while True: + if seconds < 60 * 60: + break + + hours = hours + 1 + seconds = seconds - 60 * 60 + + return '%sh%sm' % ( + hours, + int(seconds / 60) + ) + + if seconds > 60: + return '%sm' % (int(seconds / 60)) + + return '%ss' % (seconds) + + def convert_days(self, seconds): + if seconds > 60 * 60 * 24: + return int(seconds / (60 * 60 * 24)) + + return 1 + + def convert_timestamp(self, timestamp): + if timestamp is None: + return None + + new_timestamp = None + if isinstance(timestamp, str): + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S%z').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp.rstrip('Z'), '%Y-%m-%dT%H:%M:%S').timetuple())) + except BaseException: + pass + + if new_timestamp is None: + try: + new_timestamp = int(time.mktime(datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f').timetuple())) + except BaseException: + pass + + return new_timestamp + + try: + new_timestamp = int(timestamp.timestamp()) + except BaseException: + pass + + return new_timestamp + + def convert_timestamp_to_age(self, timestamp, on_error=None): + timestamp = self.convert_timestamp(timestamp) + if timestamp is None: + return on_error + + return self.convert_age(int(time.time()) - timestamp) + + def convert_timestamp_to_days(self, timestamp, on_error=None): + timestamp = self.convert_timestamp(timestamp) + if timestamp is None: + return on_error + + return self.convert_days(int(time.time()) - timestamp) diff --git a/lib/psirt/main.py b/lib/psirt/main.py new file mode 100644 index 00000000..1e40d36c --- /dev/null +++ b/lib/psirt/main.py @@ -0,0 +1,25 @@ +from lib import log_helper + +from lib.psirt.api import PsirtApi +from lib.psirt.cache import PsirtCache +from lib.psirt.common import PsirtCommon + +from lib.psirt.advisory.main import PsirtAdvisory + + +class Psirt( + PsirtApi, + PsirtCache, + PsirtCommon, + PsirtAdvisory + ): + def __init__(self, key, secret, verbose=False, debug=False, log_id=None): + self.verbose = verbose + self.debug = debug + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + PsirtApi.__init__(self, key, secret) + PsirtCache.__init__(self) + PsirtCommon.__init__(self) + PsirtAdvisory.__init__(self) diff --git a/lib/psirt/output.py b/lib/psirt/output.py new file mode 100644 index 00000000..9ebd7018 --- /dev/null +++ b/lib/psirt/output.py @@ -0,0 +1,45 @@ +from lib import output_helper + +from lib.psirt.advisory.output import PsirtAdvisoryOutput + + +class PsirtOutput( + PsirtAdvisoryOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + PsirtAdvisoryOutput.__init__(self) + + def print_psirt_settings(self, psirt_settings, show_password=False): + if not show_password: + psirt_settings['key'] = '***' + psirt_settings['secret'] = '***' + + order = [ + 'enabled', + 'key', + 'secret', + 'cache', + 'directory', + 'ttl' + ] + + headers = [ + 'Enabled', + 'Key', + 'Secret', + 'Cache', + 'Directory', + 'TTL' + ] + self.my_output.dictionary( + psirt_settings, + keys=order, + title_keys=headers, + title='Psirt API settings' + ) diff --git a/lib/psirt/settings.py b/lib/psirt/settings.py new file mode 100644 index 00000000..613ead81 --- /dev/null +++ b/lib/psirt/settings.py @@ -0,0 +1,101 @@ +import os +import json +import traceback + +from lib import log_helper +from lib.settings_helper import Settings + + +class PsirtSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.psirt_settings_filename = os.path.join( + self.settings_dir, + 'psirt' + ) + + self.psirt_cache_directory = os.path.join( + self.settings_dir, + 'psirt-cache' + ) + + if not self.initialize_psirt_settings(): + raise ValueError('Psirt settings initialization failed') + + def get_psirt_default_settings(self): + settings = {} + settings['enabled'] = False + settings['key'] = None + settings['secret'] = None + settings['cache'] = True + settings['directory'] = self.psirt_cache_directory + settings['ttl'] = 60 * 60 * 24 + return settings + + def initialize_psirt_settings(self): + if not os.path.isfile(self.psirt_settings_filename): + settings = self.get_psirt_default_settings() + if not self.set_psirt_settings(settings): + return False + + if not os.path.isdir(self.psirt_cache_directory): + os.makedirs(self.psirt_cache_directory, exist_ok=True) + + return True + + def get_psirt_settings(self): + if not os.path.isfile(self.psirt_settings_filename): + return None + + try: + with open(self.psirt_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_psirt_settings', traceback.format_exc()) + return None + + return settings + + def set_psirt_settings(self, settings): + try: + with open(self.psirt_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_psirt_settings', traceback.format_exc()) + return False + + return True + + def get_psirt_credentials(self): + settings = self.get_psirt_settings() + if not settings['enabled']: + return None, None + return settings['key'], settings['secret'] + + def set_psirt_credentials(self, key, secret, enabled=True): + settings = self.get_psirt_settings() + settings['enabled'] = enabled + settings['key'] = key + settings['secret'] = secret + return self.set_psirt_settings(settings) + + def set_cache_on(self): + settings = self.get_psirt_settings() + settings['cache'] = True + return self.set_psirt_settings(settings) + + def set_cache_off(self): + settings = self.get_psirt_settings() + settings['cache'] = False + return self.set_psirt_settings(settings) + + def set_cache_ttl(self, ttl): + settings = self.get_psirt_settings() + settings['ttl'] = ttl + return self.set_psirt_settings(settings) diff --git a/lib/redfish/__init__.py b/lib/redfish/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/__pycache__/__init__.cpython-310.pyc b/lib/redfish/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..55ae70cc Binary files /dev/null and b/lib/redfish/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/cache.cpython-310.pyc b/lib/redfish/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..fcfc7ebd Binary files /dev/null and b/lib/redfish/__pycache__/cache.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/common.cpython-310.pyc b/lib/redfish/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..615e8221 Binary files /dev/null and b/lib/redfish/__pycache__/common.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/dell.cpython-310.pyc b/lib/redfish/__pycache__/dell.cpython-310.pyc new file mode 100644 index 00000000..df3183e3 Binary files /dev/null and b/lib/redfish/__pycache__/dell.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/endpoint.cpython-310.pyc b/lib/redfish/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..c277b3f5 Binary files /dev/null and b/lib/redfish/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/endpoint_settings.cpython-310.pyc b/lib/redfish/__pycache__/endpoint_settings.cpython-310.pyc new file mode 100644 index 00000000..c7dd230d Binary files /dev/null and b/lib/redfish/__pycache__/endpoint_settings.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/fi.cpython-310.pyc b/lib/redfish/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..c1319f2d Binary files /dev/null and b/lib/redfish/__pycache__/fi.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/fi_inventory.cpython-310.pyc b/lib/redfish/__pycache__/fi_inventory.cpython-310.pyc new file mode 100644 index 00000000..6342e5cc Binary files /dev/null and b/lib/redfish/__pycache__/fi_inventory.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/generic.cpython-310.pyc b/lib/redfish/__pycache__/generic.cpython-310.pyc new file mode 100644 index 00000000..1ecd7379 Binary files /dev/null and b/lib/redfish/__pycache__/generic.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/hp.cpython-310.pyc b/lib/redfish/__pycache__/hp.cpython-310.pyc new file mode 100644 index 00000000..26e70670 Binary files /dev/null and b/lib/redfish/__pycache__/hp.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/settings.cpython-310.pyc b/lib/redfish/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..7f00dde4 Binary files /dev/null and b/lib/redfish/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/tree.cpython-310.pyc b/lib/redfish/__pycache__/tree.cpython-310.pyc new file mode 100644 index 00000000..b203ebd3 Binary files /dev/null and b/lib/redfish/__pycache__/tree.cpython-310.pyc differ diff --git a/lib/redfish/__pycache__/ucs_rack.cpython-310.pyc b/lib/redfish/__pycache__/ucs_rack.cpython-310.pyc new file mode 100644 index 00000000..cbb0e2d5 Binary files /dev/null and b/lib/redfish/__pycache__/ucs_rack.cpython-310.pyc differ diff --git a/lib/redfish/cache.py b/lib/redfish/cache.py new file mode 100644 index 00000000..ade254eb --- /dev/null +++ b/lib/redfish/cache.py @@ -0,0 +1,171 @@ +import os +import json +import traceback + +from lib import log_helper +from lib.redfish.settings import RedfishSettings + + +class RedfishCache(RedfishSettings): + def __init__(self, log_id=None): + RedfishSettings.__init__(self, log_id=log_id) + self.log = log_helper.Log(log_id=log_id) + + self.redfish_settings = self.get_redfish_settings() + if self.redfish_settings is None: + raise ValueError('Redfish settings read failed') + + if self.is_cache_enabled(): + self.redfish_cache_directory = self.redfish_settings['CacheDirectory'] + self.redfish_cache_filename = os.path.join( + self.redfish_cache_directory, + 'cache' + ) + + if not self.initialize_redfish_cache(): + raise ValueError('Redfish cache initialization failed') + + def get_cache_resources_filename(self, cache_entry_name): + cache_entry = self.get_redfish_cache_entry(cache_entry_name) + if cache_entry is None: + return None + + redfish_cache_resources_filename = os.path.join( + self.redfish_cache_directory, + cache_entry['CacheFileName'] + ) + + return redfish_cache_resources_filename + + def is_cache_enabled(self): + if 'CacheEnabled' in self.redfish_settings: + return self.redfish_settings['CacheEnabled'] + return False + + def is_redfish_cache_name(self, cache_entry_name): + if self.get_redfish_cache_entry(cache_entry_name) is None: + return False + + return True + + def get_redfish_cache_entry(self, cache_entry_name): + cache_list = self.get_redfish_cache_list() + if cache_list is None: + return None + + for cache_entry in cache_list: + if cache_entry['CacheName'] == cache_entry_name: + return cache_entry + + return None + + def add_redfish_cache_entry(self, cache_entry_name, identity): + if self.is_redfish_cache_name(cache_entry_name): + return True + + cache_list = self.get_redfish_cache_list() + if cache_list is None: + cache_list = [] + + cache_list_entry = identity + cache_list_entry['CacheName'] = cache_entry_name + cache_list.append(cache_list_entry) + + return self.set_redfish_cache_list(cache_list) + + def delete_redfish_cache_entry(self, cache_entry_name): + cache_list = self.get_redfish_cache_list() + if cache_list is None: + return True + + new_cache_list = [] + + for cache_list_entry in cache_list: + if cache_list_entry['CacheName'] != cache_entry_name: + new_cache_list.append(cache_list_entry) + + if cache_list_entry['CacheName'] == cache_entry_name: + redfish_cache_resources_filename = os.path.join( + self.redfish_cache_directory, + cache_list_entry['CacheFileName'] + ) + if os.path.isfile(redfish_cache_resources_filename): + os.remove(redfish_cache_resources_filename) + + return self.set_redfish_cache_list(new_cache_list) + + def delete_redfish_cache_entries(self): + cache_list = self.get_redfish_cache_list() + if cache_list is None: + return True + + for cache_list_entry in cache_list: + if not self.delete_redfish_cache_entry(cache_list_entry['CacheName']): + return False + + return True + + def get_redfish_cache_list(self): + if not os.path.isfile(self.redfish_cache_filename): + return None + + try: + with open(self.redfish_cache_filename, 'r', encoding='utf-8') as file_handler: + cache_list = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_redfish_cache_list', traceback.format_exc()) + return None + + cache_list = sorted(cache_list, key=lambda i: i['Product']) + return cache_list + + def set_redfish_cache_list(self, cache_list): + try: + with open(self.redfish_cache_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(cache_list, indent=4)) + + except BaseException: + self.log.error('set_redfish_cache_list', traceback.format_exc()) + return False + + return True + + def set_redfish_cache_endpoint(self, identity, resources, extra_resources=None, custom_cache_name=None): + cache_name = identity['DefaultCacheName'] + if custom_cache_name is not None and len(custom_cache_name) > 0: + cache_name = custom_cache_name + + if not self.add_redfish_cache_entry(cache_name, identity): + self.log.error( + 'set_redfish_cache_endpoint', + 'Failed to set redfish cache: %s' % (cache_name) + ) + return None + + try: + entry = {} + entry['identity'] = identity + entry['resources'] = resources + entry['extra'] = extra_resources + + redfish_cache_resources_filename = os.path.join( + self.redfish_cache_directory, + identity['CacheFileName'] + ) + with open(redfish_cache_resources_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps(entry, indent=4) + ) + + except BaseException: + self.log.error('set_redfish_cache_endpoint', traceback.format_exc()) + return None + + return cache_name + + def initialize_redfish_cache(self): + if not os.path.isfile(self.redfish_cache_filename): + if not self.set_redfish_cache_list([]): + return False + return True diff --git a/lib/redfish/common.py b/lib/redfish/common.py new file mode 100644 index 00000000..b1926e16 --- /dev/null +++ b/lib/redfish/common.py @@ -0,0 +1,601 @@ +import os +import json +import time +import traceback +import requests + +from lib import info_helper +from lib import log_helper + +# mypy: ignore-errors +requests.packages.urllib3.disable_warnings() + + +class RedfishEndpointCommon(): + def __init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=None, + cache_filename=None, + auto_connect=True, + get_timeout=10, + ssl_verify=False, + deep_search_exlusions=True, + log_id=None + ): + self.log = log_helper.Log(log_id=log_id) + self.endpoint_handler = endpoint_handler + self.endpoint_ip = endpoint_ip + self.endpoint_port = endpoint_port + self.redfish_username = redfish_username + self.redfish_password = redfish_password + self.ssl_verify = ssl_verify + self.auto_connect = auto_connect + + self.system_id = system_id + self.get_timeout = get_timeout + + self.session_handler = None + self.session_id = None + self.session_token = None + + self.cache_filename = cache_filename + self.cache = None + if self.cache_filename is not None: + if os.path.isfile(self.cache_filename): + try: + with open(self.cache_filename, 'r', encoding='utf-8') as file_handler: + self.cache = json.loads(file_handler.read()) + + except BaseException: + pass + + if self.cache is None: + raise ValueError( + 'Redfish cache file initialization failed: %s' % (self.cache_filename) + ) + + self.deep_search_exclusions = deep_search_exlusions + + self.info_handler = info_helper.InfoHelper() + + def get_endpoint_configuration(self): + configuration = {} + configuration['type'] = self.endpoint_type + configuration['ip'] = self.endpoint_ip + configuration['port'] = self.endpoint_port + configuration['username'] = self.redfish_username + configuration['password'] = self.redfish_password + configuration['inventory_type'] = '' + configuration['inventory_id'] = '' + if self.endpoint_type == 'fi': + configuration['inventory_type'] = self.inventory_type + configuration['inventory_id'] = self.inventory_id + + return configuration + + def is_cache_enabled(self): + if self.cache_filename is not None: + return True + return False + + def get_excluded_tree_uri(self): + if not self.deep_search_exclusions: + return [] + + uri = [ + ] + return uri + + def is_connected(self): + if self.is_cache_enabled(): + return True + + if not self.auto_connect: + self.connect() + + if self.session_id is not None and self.session_token is not None: + return True + + return False + + def path_fixup(self, path): + if not path.startswith('/redfish/v1/'): + path = '/redfish/v1/%s' % ( + path.lstrip('/') + ) + + if 'SYSTEM_ID' in path: + system_id = self.get_system_id() + if system_id is None: + self.log.error('get_properties', 'System ID not found') + return None + + path = path.replace( + 'SYSTEM_ID', + system_id + ) + + return path + + def get_property_keys(self, key): + if '\'' in key: + keys = [] + key_name = '' + for item in key.split('.'): + if item.startswith('"') and item.endswith('\''): + keys.append(item.strip('\'')) + continue + + if item.startswith('\''): + key_name = item.lstrip('\'') + continue + + if item.endswith('\''): + key_name = '%s.%s' % (key_name, item.rstrip('\'')) + keys.append(key_name) + key_name = '' + continue + + if key_name == '': + keys.append(item) + continue + + key_name = '%s.%s' % (key_name, item) + + return keys + + return key.split('.') + + def select_properties(self, data, properties): + selected_properties = {} + + for property_value in properties: + search_properties = data + keys = self.get_property_keys(property_value) + index = 0 + result = None + + for key in keys: + index = index + 1 + if isinstance(search_properties, dict): + if key in search_properties: + search_properties = search_properties[key] + if index == len(keys): + result = search_properties + break + + if result is not None: + selected_properties[property_value] = result + + return selected_properties + + def get_properties_cache(self, path, properties=[]): + if path not in self.cache['resources']: + return None + return self.cache['resources'][path] + + def get_properties(self, path, properties=[], retry=3): + if not self.is_connected(): + return None + + path = self.path_fixup(path) + + start_time = int(time.time() * 1000) + if self.is_cache_enabled(): + all_properties = self.get_properties_cache(path, properties=properties) + else: + try: + url = 'https://%s:%s%s' % ( + self.endpoint_ip, + self.endpoint_port, + path + ) + + headers = {} + headers['X-Auth-Token'] = self.session_token + + response = self.session_handler.get( + url, + headers=headers, + verify=self.ssl_verify, + timeout=self.get_timeout + ) + + except requests.exceptions.ConnectionError: + self.log.error( + 'get_properties', + 'Redfish get object connection error: %s %s' % (self.endpoint_ip, path) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + False, + duration_ms + ) + + if retry > 0: + time.sleep(.1) + return self.get_properties(path, properties=properties, retry=retry - 1) + + self.log.error( + 'get_properties', + 'Redfish get failed after retries: %s %s' % (self.endpoint_ip, path) + ) + + return None + + except requests.exceptions.Timeout: + self.log.error( + 'get_properties', + 'Redfish get object timeout: %s %s' % (self.endpoint_ip, path) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + False, + duration_ms + ) + + if retry > 0: + time.sleep(.1) + return self.get_properties(path, properties=properties, retry=retry - 1) + + self.log.error( + 'get_properties', + 'Redfish get failed after retries: %s %s' % (self.endpoint_ip, path) + ) + + return None + + except BaseException: + self.log.error( + 'get_properties', + 'Redfish get object exception: %s %s' % (self.endpoint_ip, path) + ) + + self.log.error( + 'get_properties', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + False, + duration_ms + ) + + if retry > 0: + time.sleep(.1) + return self.get_properties(path, properties=properties, retry=retry - 1) + + self.log.error( + 'get_properties', + 'Redfish get failed after retries: %s %s' % (self.endpoint_ip, path) + ) + + return None + + if response.status_code > 299: + self.log.error( + 'get_properties', + 'Redfish get object failed: %s %s %s %s' % ( + self.endpoint_ip, + path, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + False, + duration_ms + ) + + return None + + try: + all_properties = response.json() + except BaseException: + self.log.error( + 'get_properties', + 'Redfish get object json exception: %s %s' % (self.endpoint_ip, path) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + True, + duration_ms + ) + + if properties is None or len(properties) == 0: + self.log.debug( + 'get_properties', + 'Redfish get %s in %s ms' % (path, duration_ms) + ) + self.log.odata( + path, + all_properties + ) + return all_properties + + selected_properties = self.select_properties( + all_properties, + properties + ) + self.log.debug( + 'get_properties', + 'Redfish get %s in %s ms' % (path, duration_ms) + ) + self.log.odata( + path, + selected_properties + ) + + return selected_properties + + def match_rule(self, rule, value): + if rule.startswith('EQ('): + if not isinstance(value, str): + return False + + if value == rule.lstrip('EQ(').rstrip(')'): + return True + + return False + + if rule.startswith('eq('): + if isinstance(value, str): + if value.lower() == rule.lstrip('eq(').rstrip(')').lower(): + return True + + if isinstance(value, int): + try: + if value == int(rule.lstrip('eq(').rstrip(')')): + return True + except BaseException: + pass + + return False + + if rule.startswith('IN('): + if not isinstance(value, str): + return False + + if rule.lstrip('IN(').rstrip(')') in value: + return True + + return False + + if rule.startswith('in('): + if not isinstance(value, str): + return False + + if rule.lstrip('in(').rstrip(')').lower() in value.lower(): + return True + + return False + + if rule.startswith('gt('): + if not isinstance(value, int): + try: + value = int(value) + except BaseException: + return False + + try: + if value > int(rule.lstrip('gt(').rstrip(')')): + return True + except BaseException: + pass + + return False + + if rule.startswith('ge('): + if not isinstance(value, int): + try: + value = int(value) + except BaseException: + return False + + try: + if value >= int(rule.lstrip('ge(').rstrip(')')): + return True + except BaseException: + pass + + return False + + if rule.startswith('lt('): + if not isinstance(value, int): + try: + value = int(value) + except BaseException: + return False + + try: + if value < int(rule.lstrip('lt(').rstrip(')')): + return True + except BaseException: + pass + + return False + + if rule.startswith('le('): + if not isinstance(value, int): + try: + value = int(value) + except BaseException: + return False + + try: + if value <= int(rule.lstrip('le(').rstrip(')')): + return True + except BaseException: + pass + + return False + + if rule.startswith('ne('): + if isinstance(value, str): + try: + if value.lower() != rule.lstrip('eq(').rstrip(')').lower(): + return True + except BaseException: + pass + + if isinstance(value, int): + try: + if value != int(rule.lstrip('eq(').rstrip(')')): + return True + except BaseException: + pass + + return False + + if rule.startswith('NE('): + if isinstance(value, str): + try: + if value != rule.lstrip('eq(').rstrip(')'): + return True + except BaseException: + pass + + return False + + # implicit eq() + if isinstance(value, str): + if value.lower() == rule.lstrip('eq(').rstrip(')').lower(): + return True + + if isinstance(value, int): + try: + if value == int(rule.lstrip('eq(').rstrip(')')): + return True + except BaseException: + pass + + return False + + def match_rules(self, rules, value): + # Match any + for rule in rules: + if self.match_rule(rule, value): + return True + + return False + + def filter_key(self, data, rules): + if not isinstance(data, dict): + return data + + filtered = {} + for key in data: + if self.match_rules(rules, key): + filtered[key] = data[key] + continue + + if isinstance(data[key], dict): + branch = self.filter_key(data[key], rules) + if len(branch) > 0: + filtered[key] = branch + + return filtered + + def filter_value(self, data, rules): + if not isinstance(data, dict): + return data + + filtered = {} + for key in data: + if isinstance(data[key], dict): + branch = self.filter_value(data[key], rules) + if len(branch) > 0: + filtered[key] = branch + continue + + if isinstance(data[key], list): + continue + + if self.match_rules(rules, data[key]): + filtered[key] = data[key] + + return filtered + + def clear_system_id(self): + self.system_id = None + + def set_system_id(self, system_id): + self.system_id = system_id + + def get_system_id(self): + if self.system_id is not None: + return self.system_id + + value = self.get_properties('Systems') + if value is None: + self.log.error( + 'get_system_id', + 'Failed to get Systems' + ) + return None + + try: + system_id = value['Members'][0]['@odata.id'].split('/')[-1] + self.system_id = system_id + except BaseException: + self.log.error( + 'get_system_id', + json.dumps(value, indent=4) + ) + return None + + return self.system_id + + def _get_property_value(self, value, key): + if value is None: + return '__ERROR' + + if ':' in key: + subkey = key.split(':')[0] + if subkey not in value: + return '__ERROR' + + new_key = ':'.join(key.split(':')[1:]) + return self._get_property_value(value[subkey], new_key) + + if key in value: + return value[key] + + return '__ERROR' + + def get_property_value(self, managed_object, key, on_error=None, on_none=None): + if managed_object is None: + return on_error + + if not isinstance(managed_object, dict): + return on_error + + value = self._get_property_value(managed_object, key) + if value == '__ERROR': + return on_error + + if value is None: + return on_none + + return value diff --git a/lib/redfish/dell/__init__.py b/lib/redfish/dell/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/dell/__pycache__/__init__.cpython-310.pyc b/lib/redfish/dell/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..1490c3d1 Binary files /dev/null and b/lib/redfish/dell/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/redfish/dell/__pycache__/endpoint.cpython-310.pyc b/lib/redfish/dell/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..e8389007 Binary files /dev/null and b/lib/redfish/dell/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/redfish/dell/__pycache__/identity.cpython-310.pyc b/lib/redfish/dell/__pycache__/identity.cpython-310.pyc new file mode 100644 index 00000000..36111244 Binary files /dev/null and b/lib/redfish/dell/__pycache__/identity.cpython-310.pyc differ diff --git a/lib/redfish/dell/__pycache__/power.cpython-310.pyc b/lib/redfish/dell/__pycache__/power.cpython-310.pyc new file mode 100644 index 00000000..27e529ea Binary files /dev/null and b/lib/redfish/dell/__pycache__/power.cpython-310.pyc differ diff --git a/lib/redfish/dell/__pycache__/template.cpython-310.pyc b/lib/redfish/dell/__pycache__/template.cpython-310.pyc new file mode 100644 index 00000000..7288b23f Binary files /dev/null and b/lib/redfish/dell/__pycache__/template.cpython-310.pyc differ diff --git a/lib/redfish/dell/__pycache__/thermal.cpython-310.pyc b/lib/redfish/dell/__pycache__/thermal.cpython-310.pyc new file mode 100644 index 00000000..9643fd68 Binary files /dev/null and b/lib/redfish/dell/__pycache__/thermal.cpython-310.pyc differ diff --git a/lib/redfish/dell/endpoint.py b/lib/redfish/dell/endpoint.py new file mode 100644 index 00000000..3cd17f49 --- /dev/null +++ b/lib/redfish/dell/endpoint.py @@ -0,0 +1,59 @@ +from lib.redfish.standard.endpoint import RedfishEndpointStandard +from lib.redfish.dell.template import RedfishEndpointDellTemplate + + +class RedfishEndpointDell(RedfishEndpointStandard, RedfishEndpointDellTemplate): + def __init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=None, + auto_connect=True, + get_timeout=10, + ssl_verify=False, + deep_search_exlusions=True, + log_id=None + ): + RedfishEndpointStandard.__init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + RedfishEndpointDellTemplate.__init__( + self + ) + + self.endpoint_type = 'dell' + + def get_excluded_tree_uri(self): + if not self.deep_search_exclusions: + return [] + + uri = [ + '/redfish/v1/Managers/iDRAC.Embedded.1/PrivilegeRegistry', + '/redfish/v1/Systems/System.Embedded.1/SecureBoot/Oem/Dell/Certificates', + '/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs', + '/redfish/v1/JobService/Jobs', + '/redfish/v1/Managers/iDRAC.Embedded.1/LogServices', + '/redfish/v1/AccountService', + '/redfish/v1/TelemetryService', + '/redfish/v1/JsonSchemas', + '/redfish/v1/UpdateService/FirmwareInventory', + '/redfish/v1/UpdateService/SoftwareInventory', + '/redfish/v1/Systems/System.Embedded.1/SecureBoot/SecureBootDatabases', + '/redfish/v1/SessionService' + ] + + return uri diff --git a/lib/redfish/dell/identity.py b/lib/redfish/dell/identity.py new file mode 100644 index 00000000..f8c2f9a5 --- /dev/null +++ b/lib/redfish/dell/identity.py @@ -0,0 +1,54 @@ +import uuid + + +class RedfishEndpointDellTemplateIdentity(): + def __init__(self): + self.identity_main_url = '/' + self.chassis_url = '/Chassis/System.Embedded.1' + self.system_url = '/Systems/System.Embedded.1' + self.idrac_url = '/Managers/iDRAC.Embedded.1' + + def get_identity_default_cache_name(self, properties): + firmware = properties['Firmware'] + if len(firmware) > 0: + firmware = firmware.replace('(', '.').replace(')', '') + + product = properties['Product'].replace(' ', '-') + + name = 'dell-%s-%s-%s-%s' % ( + product.lower(), + properties['SerialNumber'].lower(), + firmware.lower(), + properties['PowerState'].lower() + ) + return name + + def get_template_identity_properties(self): + main = self.get_properties(self.identity_main_url) + chassis = self.get_properties(self.chassis_url) + system = self.get_properties(self.system_url) + idrac = self.get_properties(self.idrac_url) + + if main is None or chassis is None or system is None or idrac is None: + return None + + properties = {} + properties['Product'] = chassis['Model'] + properties['Model'] = chassis['Model'] + properties['Vendor'] = main['Vendor'] + properties['RedfishVersion'] = main['RedfishVersion'] + properties['UUID'] = chassis['UUID'] + properties['Firmware'] = idrac['FirmwareVersion'] + properties['HostName'] = system['HostName'] + properties['Name'] = system['Name'] + properties['SerialNumber'] = system['SerialNumber'] + properties['PowerState'] = system['PowerState'] + properties['BiosVersion'] = system['BiosVersion'] + + properties['DefaultCacheName'] = self.get_identity_default_cache_name(properties) + if properties['UUID'] == '': + properties['CacheFileName'] = str(uuid.uuid4()).lower() + else: + properties['CacheFileName'] = properties['UUID'].lower() + + return properties diff --git a/lib/redfish/dell/output.py b/lib/redfish/dell/output.py new file mode 100644 index 00000000..3f1bbfd7 --- /dev/null +++ b/lib/redfish/dell/output.py @@ -0,0 +1,229 @@ +class RedfishEndpointDellOutput( + ): + def __init__(self): + pass + + def print_dell_properties(self, template_name, properties): + if template_name.lower() == 'identity': + self.print_dell_identity_properties(properties) + + if template_name.lower() == 'power': + self.print_dell_power_properties(properties) + + if template_name.lower() == 'thermal': + self.print_dell_thermal_properties(properties) + + def print_dell_identity_properties(self, properties): + keys = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'HostName', + 'SerialNumber', + 'UUID', + 'BiosVersion', + 'Firmware', + 'PowerState', + 'RedfishVersion' + ] + + headers = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'Hostname', + 'Serial Number', + 'UUID', + 'Bios Version', + 'Firmware', + 'Power State', + 'Redfish Version' + ] + + self.my_output.dictionary( + properties, + title='Dell Redfish Endpoint', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_dell_power_consumption_properties(self, properties): + keys = [ + 'PowerConsumedWatts', + 'MinConsumedWatts', + 'AverageConsumedWatts', + 'MaxConsumedWatts', + 'LimitException' + ] + + headers = [ + 'Current', + 'Min', + 'Average', + 'Max', + 'Limit action' + ] + + self.my_output.dictionary( + properties['Data']['PowerControl'], + title='Power Consumption (Watt)', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_dell_power_voltage_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'ReadingVolts', + 'UpperThresholdCritical' + ] + + headers = [ + 'Voltage Sensor', + 'State', + 'Health', + 'Volts', + 'Upper Threshold' + ] + + self.my_output.my_table( + properties['Data']['Voltage'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_dell_power_supply_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'SerialNumber', + 'FirmwareVersion', + 'PowerOutputWatts', + 'PowerInputWatts', + 'MaximumVoltage', + 'MinimumVoltage', + 'MaximumFrequencyHz', + 'MinimumFrequencyHz' + ] + + headers = [ + 'PSU Name', + 'State', + 'Health', + 'Serial', + 'Firmware', + 'Output (Watt)', + 'Input (Watt)', + 'Max (V)', + 'Min (V)', + 'Max (Hz)', + 'Min (Hz)' + ] + + self.my_output.my_table( + properties['Data']['PowerSupply'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_dell_power_properties(self, properties): + self.print_dell_power_consumption_properties(properties) + self.print_dell_power_voltage_properties(properties) + self.print_dell_power_supply_properties(properties) + + def print_dell_thermal_summary_properties(self, properties): + keys = [ + 'SensorHealth', + 'HighestTemperature', + 'SmallestGap', + 'OverThreshold', + 'FanHealth' + ] + + headers = [ + 'Sensors Health', + 'Highest (C)', + 'Smallest Gap (C)', + 'Over Threshold', + 'Fans Health' + ] + + self.my_output.dictionary( + properties['Summary'], + title='Thermal Summary', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_dell_thermal_temperature_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + + headers = [ + 'Sensor Name', + 'State', + 'Health', + 'Location', + 'Value (Celcius)', + 'Upper Threshold (Celcius)' + ] + + self.my_output.my_table( + properties['Data']['Temperature'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_dell_thermal_fan_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'Value' + ] + + headers = [ + 'Fan Name', + 'State', + 'Health', + 'Value' + ] + + self.my_output.my_table( + properties['Data']['Fan'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_dell_thermal_properties(self, properties): + self.print_dell_thermal_summary_properties(properties) + self.print_dell_thermal_temperature_properties(properties) + self.print_dell_thermal_fan_properties(properties) diff --git a/lib/redfish/dell/power.py b/lib/redfish/dell/power.py new file mode 100644 index 00000000..56f3376d --- /dev/null +++ b/lib/redfish/dell/power.py @@ -0,0 +1,119 @@ +class RedfishEndpointDellTemplatePower(): + def __init__(self): + pass + + def get_template_power_properties(self): + uri = '/redfish/v1/Chassis/System.Embedded.1/Power' + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Data']['PowerControl'] = {} + + # { + # "PhysicalContext": "PowerSupply", + # "PowerMetrics": { + # "MinConsumedWatts": 186, + # "AverageConsumedWatts": 349, + # "MaxConsumedWatts": 495 + # }, + # "MemberId": "1", + # "PowerLimit": { + # "LimitException": "NoAction" + # }, + # "PowerConsumedWatts": 360, + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerControl/1" + # } + power_control_data = data['PowerControl'][0] + properties['Data']['PowerControl']['PowerConsumedWatts'] = power_control_data['PowerConsumedWatts'] + properties['Data']['PowerControl']['LimitException'] = power_control_data['PowerLimit']['LimitException'] + for key in power_control_data['PowerMetrics']: + properties['Data']['PowerControl'][key] = power_control_data['PowerMetrics'][key] + + # { + # "PhysicalContext": "PowerSupply", + # "SensorNumber": 48, + # "MemberId": "1", + # "@odata.id": "/redfish/v1/Chassis/1/Power#/Voltages/PSU1_VOUT", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # }, + # "UpperThresholdCritical": 14, + # "Name": "PSU1_VOUT", + # "ReadingVolts": 12.2 + # }, + properties['Data']['Voltage'] = [] + for voltage in data['Voltages']: + voltage_info = {} + voltage_info['Name'] = voltage['Name'] + voltage_info['ReadingVolts'] = voltage['ReadingVolts'] + voltage_info['UpperThresholdCritical'] = voltage['UpperThresholdCritical'] + voltage_info['PhysicalContext'] = voltage['PhysicalContext'] + voltage_info['State'] = voltage['Status']['State'] + voltage_info['Health'] = voltage['Status']['Health'] + properties['Data']['Voltage'].append(voltage_info) + + # { + # "SerialNumber": "LIT241244RQ", + # "InputRanges": [ + # { + # "InputType": "AC", + # "OutputWattage": 1050, + # "MaximumFrequencyHz": 63, + # "MaximumVoltage": 264, + # "MinimumVoltage": 90, + # "MinimumFrequencyHz": 47 + # } + # ], + # "FirmwareVersion": "10062019", + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerSupplies/PSU1", + # "PowerOutputWatts": 171, + # "LineInputVoltage": 229, + # "Name": "PSU1", + # "PowerInputWatts": 186, + # "Manufacturer": "Cisco Systems Inc", + # "LastPowerOutputWatts": 171, + # "MemberId": "1", + # "PartNumber": "341-0638-03", + # "PowerSupplyType": "AC", + # "Model": "PS-2112-9S-LF", + # "SparePartNumber": "341-0638-03", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + properties['Data']['PowerSupply'] = [] + for power_supply in data['PowerSupplies']: + power_supply_info = {} + power_supply_info['Name'] = power_supply['Name'] + power_supply_info['Model'] = power_supply['Model'] + power_supply_info['SerialNumber'] = power_supply['SerialNumber'] + power_supply_info['PartNumber'] = power_supply['PartNumber'] + power_supply_info['SparePartNumber'] = power_supply['SparePartNumber'] + power_supply_info['Manufacturer'] = power_supply['Manufacturer'] + power_supply_info['FirmwareVersion'] = power_supply['FirmwareVersion'] + power_supply_info['State'] = power_supply['Status']['State'] + power_supply_info['Health'] = power_supply['Status']['Health'] + power_supply_info['PowerSupplyType'] = power_supply['PowerSupplyType'] + power_supply_info['PowerOutputWatts'] = power_supply['PowerOutputWatts'] + power_supply_info['LastPowerOutputWatts'] = power_supply['LastPowerOutputWatts'] + power_supply_info['PowerInputWatts'] = power_supply['PowerInputWatts'] + for input_range in power_supply['InputRanges']: + for key in input_range: + if key != 'InputType': + power_supply_info[key] = input_range[key] + + properties['Data']['PowerSupply'].append(power_supply_info) + + properties['Summary'] = {} + properties['Summary']['Source'] = 'Redfish' + properties['Summary']['PowerNow'] = properties['Data']['PowerControl']['PowerConsumedWatts'] + properties['Summary']['PowerMin'] = properties['Data']['PowerControl']['MinConsumedWatts'] + properties['Summary']['PowerAvg'] = properties['Data']['PowerControl']['AverageConsumedWatts'] + properties['Summary']['PowerMax'] = properties['Data']['PowerControl']['MaxConsumedWatts'] + + return properties diff --git a/lib/redfish/dell/template.py b/lib/redfish/dell/template.py new file mode 100644 index 00000000..b8c8257b --- /dev/null +++ b/lib/redfish/dell/template.py @@ -0,0 +1,58 @@ +import time + +from lib.redfish.dell.identity import RedfishEndpointDellTemplateIdentity +from lib.redfish.dell.power import RedfishEndpointDellTemplatePower +from lib.redfish.dell.thermal import RedfishEndpointDellTemplateThermal + + +class RedfishEndpointDellTemplate(RedfishEndpointDellTemplateIdentity, RedfishEndpointDellTemplatePower, RedfishEndpointDellTemplateThermal): + def __init__(self): + RedfishEndpointDellTemplateIdentity.__init__( + self + ) + RedfishEndpointDellTemplatePower.__init__( + self + ) + RedfishEndpointDellTemplateThermal.__init__( + self + ) + + def get_template_properties(self, template_name, cache_enabled=True, cache_key=None, cache_ttl=0): + if cache_enabled and cache_key is not None: + self.set_system_id( + cache_key + ) + properties = self.endpoint_handler.endpoint_settings_handler.get_endpoint_settings( + cache_key, + filename=template_name + ) + if properties is not None: + if cache_ttl == 0: + return properties['data'] + if int(time.time()) - properties['timestamp'] < cache_ttl: + return properties['data'] + + properties = None + + if template_name == 'identity': + properties = self.get_template_identity_properties() + + if template_name == 'power': + properties = self.get_template_power_properties() + + if template_name == 'thermal': + properties = self.get_template_thermal_properties() + + if properties is not None: + if cache_enabled and cache_key is not None: + cache_entry = {} + cache_entry['timestamp'] = int(time.time()) + cache_entry['data'] = properties + + self.endpoint_handler.endpoint_settings_handler.set_endpoint_settings( + cache_key, + cache_entry, + filename=template_name + ) + + return properties diff --git a/lib/redfish/dell/thermal.py b/lib/redfish/dell/thermal.py new file mode 100644 index 00000000..707a0ee7 --- /dev/null +++ b/lib/redfish/dell/thermal.py @@ -0,0 +1,129 @@ +class RedfishEndpointDellTemplateThermal(): + def __init__(self): + pass + + def get_template_thermal_properties(self): + uri = '/redfish/v1/Chassis/System.Embedded.1/Thermal' + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Summary'] = {} + properties['Summary']['FanHealth'] = True + properties['Summary']['SensorHealth'] = True + properties['Summary']['HighestTemperature'] = None + properties['Summary']['SmallestGap'] = None + properties['Summary']['OverThreshold'] = 0 + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Temperatures/MLOM_TEMP", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # }, + # "SensorNumber": 60, + # "Name": "MLOM_TEMP", + # "PhysicalContext": "NetworkingDevice", + # "MemberId": "1", + # "UpperThresholdCritical": 90, + # "ReadingCelsius": 55 + # }, + properties['Data']['Temperature'] = [] + for sensor in data['Temperatures']: + sensor_info = {} + sensor_info['State'] = sensor['Status']['State'] + sensor_info['Health'] = '' + if 'Health' in sensor['Status']: + sensor_info['Health'] = sensor['Status']['Health'] + if sensor_info['State'] == 'Enabled': + if sensor_info['Health'].lower() != 'ok': + properties['Summary']['SensorHealth'] = False + + sensor_info['SensorNumber'] = sensor['SensorNumber'] + sensor_info['Name'] = sensor['Name'] + sensor_info['PhysicalContext'] = sensor['PhysicalContext'] + sensor_info['ReadingCelsius'] = sensor['ReadingCelsius'] + sensor_info['UpperThresholdCritical'] = sensor['UpperThresholdCritical'] + + properties['Data']['Temperature'].append(sensor_info) + + try: + value = int(sensor_info['ReadingCelsius']) + if properties['Summary']['HighestTemperature'] is None: + properties['Summary']['HighestTemperature'] = value + else: + properties['Summary']['HighestTemperature'] = max( + properties['Summary']['HighestTemperature'], + value + ) + except BaseException: + pass + + try: + value = int(sensor_info['UpperThresholdCritical']) - int(sensor_info['ReadingCelsius']) + if value < 0: + properties['Summary']['OverThreshold'] = properties['Summary']['OverThreshold'] + 1 + else: + if properties['Summary']['SmallestGap'] is None: + properties['Summary']['SmallestGap'] = value + else: + properties['Summary']['SmallestGap'] = min( + properties['Summary']['SmallestGap'], + value + ) + except BaseException: + pass + + properties['Data']['Temperature'] = sorted(properties['Data']['Temperature'], key=lambda i: i['Name']) + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Fans/MOD1_FAN1", + # "ReadingUnits": "RPM", + # "Reading": 7070, + # "PhysicalContext": "Fan", + # "MemberId": "1", + # "Name": "MOD1_FAN1_SPEED", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + properties['Data']['Fan'] = [] + for fan in data['Fans']: + fan_info = {} + fan_info['Name'] = fan['Name'] + fan_info['State'] = fan['Status']['State'] + fan_info['Health'] = '' + if 'Health' in fan['Status']: + fan_info['Health'] = fan['Status']['Health'] + if fan_info['State'] == 'Enabled': + if fan_info['Health'].lower() != 'ok': + properties['Summary']['FanHealth'] = False + + fan_info['PhysicalContext'] = '' + if 'PhysicalContext' in fan: + fan_info['PhysicalContext'] = fan['PhysicalContext'] + fan_info['ReadingUnits'] = '' + if 'ReadingUnits' in fan: + fan_info['ReadingUnits'] = fan['ReadingUnits'] + fan_info['Reading'] = '' + if 'Reading' in fan: + fan_info['Reading'] = fan['Reading'] + fan_info['Value'] = '%s %s' % (fan_info['Reading'], fan_info['ReadingUnits']) + properties['Data']['Fan'].append(fan_info) + + properties['Data']['Fan'] = sorted(properties['Data']['Fan'], key=lambda i: i['Name']) + + return properties diff --git a/lib/redfish/endpoint.py b/lib/redfish/endpoint.py new file mode 100644 index 00000000..3cddfcb4 --- /dev/null +++ b/lib/redfish/endpoint.py @@ -0,0 +1,350 @@ +import json + +from lib.redfish.cache import RedfishCache +from lib.redfish import endpoint_settings +from lib.redfish.ucs_rack import endpoint as ucs_rack_endpoint +from lib.redfish.standard import endpoint as standard_endpoint +from lib.redfish.fi import endpoint as fi_endpoint +from lib.redfish.dell import endpoint as dell_endpoint +from lib.redfish.hpe import endpoint as hpe_endpoint +from lib.redfish import tree + + +class RedfishEndpoint(RedfishCache): + def __init__( + self, + endpoint_type, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=None, + cache_name=None, + get_timeout=10, + auto_connect=True, + ssl_verify=False, + deep_search_exlusions=True, + tree_max_execution_time=0, + log_id=None + ): + + RedfishCache.__init__(self, log_id=log_id) + + self.endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings(log_id=log_id) + + self.tree_max_execution_time = tree_max_execution_time + self.endpoint_handler = None + + endpoint_cache_filename = None + endpoint_cache_entry = None + if endpoint_type == 'cache': + endpoint_cache_entry = self.get_redfish_cache_entry(cache_name) + if endpoint_cache_entry is None: + raise ValueError('Unknown cache entry: %s' % (cache_name)) + + endpoint_cache_filename = self.get_cache_resources_filename(cache_name) + if endpoint_cache_filename is None or len(endpoint_cache_filename) == 0: + raise ValueError('Unknown cache filename: %s' % (cache_name)) + + endpoint_type = endpoint_cache_entry['EndpointType'] + endpoint_ip = endpoint_cache_entry['EndpointType'] + redfish_username = None + redfish_password = None + + if endpoint_type == 'standard': + self.endpoint_handler = standard_endpoint.RedfishEndpointStandard( + self, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=endpoint_cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + + if endpoint_type == 'ucsc': + self.endpoint_handler = ucs_rack_endpoint.RedfishEndpointUcsRack( + self, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=system_id, + cache_filename=endpoint_cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + + if endpoint_type == 'fi': + self.endpoint_handler = fi_endpoint.RedfishEndpointFabricInterconnect( + self, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=endpoint_cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + + if endpoint_cache_entry is not None: + self.endpoint_handler.set_inventory( + endpoint_cache_entry['EndpointInventoryType'], + endpoint_cache_entry['EndpointInventoryId'] + ) + + if endpoint_type == 'dell': + self.endpoint_handler = dell_endpoint.RedfishEndpointDell( + self, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=endpoint_cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + + if endpoint_type == 'hpe': + self.endpoint_handler = hpe_endpoint.RedfishEndpointHpe( + self, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=endpoint_cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + + if self.endpoint_handler is None: + raise ValueError('Unsupported endpoint type: %s' % (endpoint_type)) + + self.tree_handler = tree.RedfishTree(self.endpoint_handler) + + def __del__(self): + if self.endpoint_handler is not None: + del self.endpoint_handler + + def connect(self): + return self.endpoint_handler.connect() + + def is_connected(self): + return self.endpoint_handler.is_connected() + + def get_properties(self, path, properties=[]): + return self.endpoint_handler.get_properties(path, properties=properties) + + def get_tree(self, path): + self.tree_handler.initialize_tree( + path, + True, + self.tree_max_execution_time + ) + success = self.tree_handler.get_tree() + if not success: + self.log.error( + 'get_tree', + 'Max path walk time reached: %s seconds' % (self.tree_max_execution_time) + ) + return None + + my_tree = json.loads( + json.dumps( + self.tree_handler.tree, + sort_keys=True + ) + ) + + return my_tree + + def filter_key(self, rules, path=None, data=None): + if path is None and data is None: + return None + + if data is None: + data = self.get_properties( + path, + properties=[] + ) + if data is None: + return None + + filtered_data = self.endpoint_handler.filter_key(data, rules) + return filtered_data + + def get_keys(self, path, deep, key_filter): + keys = {} + + if deep: + data = self.get_tree( + path + ) + if data is None: + return None + + for uri in data: + if data[uri] is None: + continue + + properties = self.filter_key( + key_filter, + data=data[uri] + ) + + if len(properties) > 0: + keys[uri] = properties + + if not deep: + path = self.endpoint_handler.path_fixup(path) + properties = self.filter_key( + key_filter, + path=path + ) + + if properties is not None and len(properties) > 0: + keys[path] = properties + + return keys + + def filter_value(self, rules, path=None, data=None): + if path is None and data is None: + return None + + if data is None: + data = self.get_properties( + path, + properties=[] + ) + if data is None: + return None + + filtered_data = self.endpoint_handler.filter_value(data, rules) + return filtered_data + + def get_values(self, path, deep, value_filter): + values = {} + + if deep: + data = self.get_tree( + path + ) + if data is None: + return None + + for uri in data: + if data[uri] is None: + continue + + properties = self.filter_value( + value_filter, + data=data[uri] + ) + + if len(properties) > 0: + values[uri] = properties + + if not deep: + path = self.endpoint_handler.path_fixup(path) + properties = self.filter_value( + value_filter, + path=path + ) + + if len(properties) > 0: + values[path] = properties + + return values + + def get_odata_ids(self, path): + properties = self.get_properties(path) + if properties is None: + return None + + return self.tree_handler.find_odata_id(properties) + + def get_children(self, path, deep): + self.tree_handler.initialize_tree( + path, + deep, + self.tree_max_execution_time + ) + success = self.tree_handler.get_tree() + if not success: + self.log.error( + 'get_children', + 'Max path walk time reached: %s' % (self.tree_max_execution_time) + ) + return None + + return sorted(self.tree_handler.tree.keys()) + + def get_descriptions(self, path, deep): + redfish_properties = [ + '@odata.id', + '@odata.type', + '@odata.context', + 'Id', + 'Name', + 'Description' + ] + + descriptions = {} + + if deep: + data = self.get_tree( + path + ) + if data is None: + return None + + for uri in data: + if data[uri] is not None: + uri_description = {} + for key in redfish_properties: + if key in data[uri]: + uri_description[key] = data[uri][key] + descriptions[uri] = uri_description + + if not deep: + path = self.endpoint_handler.path_fixup(path) + properties = self.get_properties( + path, + redfish_properties + ) + if properties is None: + return None + + descriptions[path] = properties + + return descriptions + + def get_action(self, path, deep): + key_filter = [ + 'eq(Actions)' + ] + + return self.get_keys(path, deep, key_filter) + + def get_oem(self, path, deep): + key_filter = [ + 'eq(Oem)' + ] + + return self.get_keys(path, deep, key_filter) diff --git a/lib/redfish/endpoint_settings.py b/lib/redfish/endpoint_settings.py new file mode 100644 index 00000000..046f7cb4 --- /dev/null +++ b/lib/redfish/endpoint_settings.py @@ -0,0 +1,357 @@ +import os +import time +import json + +from progress.bar import Bar + +from lib import ip_helper +from lib import log_helper + +from lib.settings_helper import Settings +from lib.redfish import endpoint + + +class RedfishEndpointSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self) + + self.log_id = log_id + self.log = log_helper.Log(log_id=log_id) + + self.redfish_settings_filename = os.path.join( + self.settings_dir, + 'redfish' + ) + + self.endpoint_directory = os.path.join( + self.settings_dir, + 'endpoint' + ) + + if not self.initialize_endpoint_directory(): + raise ValueError('Endpoints initialization failed') + + def initialize_endpoint_directory(self): + try: + if not os.path.isdir(self.endpoint_directory): + os.makedirs(self.endpoint_directory) + + for filename in os.listdir(self.endpoint_directory): + filename_path = os.path.join( + self.endpoint_directory, + filename + ) + if os.path.isdir(filename_path): + continue + + try: + with open(filename_path, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error( + 'initialize_endpoint_directory', + 'File read failed: %s' % (filename_path) + ) + continue + + os.remove(filename_path) + os.makedirs(filename_path, exist_ok=True) + + settings_filename = os.path.join( + filename_path, + 'settings' + ) + + try: + with open(settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + settings, + indent=4 + ) + ) + + except BaseException: + self.log.error( + 'initialize_endpoint_directory', + 'File write failed: %s' % (settings_filename) + ) + + except BaseException: + return False + return True + + def get_endpoint_ids(self): + return os.listdir(self.endpoint_directory) + + def get_endpoint_settings(self, endpoint_id, filename='settings'): + endpoint_directory = os.path.join( + self.endpoint_directory, + endpoint_id + ) + endpoint_filename = os.path.join( + endpoint_directory, + filename + ) + if not os.path.isfile(endpoint_filename): + return None + + try: + with open(endpoint_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error( + 'get_endpoint_settings', + 'File read failed: %s' % (endpoint_filename) + ) + return None + + return settings + + def set_endpoint_settings(self, endpoint_id, settings, filename='settings'): + endpoint_directory = os.path.join( + self.endpoint_directory, + endpoint_id + ) + if not os.path.isdir(endpoint_directory): + os.makedirs(endpoint_directory, exist_ok=True) + + endpoint_filename = os.path.join( + endpoint_directory, + filename + ) + + try: + with open(endpoint_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write( + json.dumps( + settings, + indent=4 + ) + ) + + except BaseException: + self.log.error( + 'set_endpoint_settings', + 'File write failed: %s' % (endpoint_filename) + ) + return False + + return True + + def get_redfish_endpoint_id(self, identity): + if 'SerialNumber' not in identity: + self.log.error( + 'get_redfish_endpoint_id', + 'No serial in endpoint identity: %s' % (identity) + ) + return None + + return identity['SerialNumber'] + + def is_redfish_endpoint(self, endpoint_id): + if self.get_redfish_endpoint_settings(endpoint_id) is None: + return False + return True + + def get_redfish_endpoint_settings(self, endpoint_id): + endpoint_settings = self.get_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return None + + if 'redfish' in endpoint_settings: + return endpoint_settings['redfish'] + + return None + + def set_redfish_endpoint_access(self, access, endpoint_id): + endpoint_settings = {} + endpoint_settings['endpoint_id'] = endpoint_id + endpoint_settings['redfish'] = {} + endpoint_settings['redfish']['endpoint_id'] = endpoint_id + endpoint_settings['redfish']['endpoint'] = access + + if not self.set_endpoint_settings(endpoint_id, endpoint_settings): + self.log.error( + 'set_redfish_endpoint_access', + 'Failed: %s' % (endpoint_id) + ) + return False + + return True + + def set_redfish_endpoint_settings(self, redfish_endpoint_configuration, redfish_endpoint_identity): + endpoint_id = self.get_redfish_endpoint_id( + redfish_endpoint_identity + ) + + if endpoint_id is None: + self.log.error( + 'set_redfish_endpoint_settings', + 'Failed on no endpoint id: %s' % (redfish_endpoint_identity) + ) + return False + + endpoint_settings = {} + endpoint_settings['endpoint_id'] = endpoint_id + endpoint_settings['redfish'] = {} + endpoint_settings['redfish']['endpoint_id'] = endpoint_id + endpoint_settings['redfish']['endpoint'] = redfish_endpoint_configuration + + if not self.set_endpoint_settings(endpoint_id, endpoint_settings): + self.log.error( + 'set_redfish_endpoint_settings', + 'Failed: %s' % (endpoint_id) + ) + return False + + data = {} + data['timestamp'] = int(time.time()) + data['data'] = redfish_endpoint_identity + if not self.set_endpoint_settings(endpoint_id, data, filename='identity'): + self.log.error( + 'set_redfish_endpoint_settings', + 'Identity failed: %s' % (endpoint_id) + ) + return False + + return True + + def match_redfish_endpoint(self, redfish_endpoint, endpoint_type, endpoint_ip, serial_number): + if endpoint_type is not None and len(endpoint_type) > 0 and endpoint_type != 'any': + if redfish_endpoint['endpoint']['type'] != endpoint_type: + return False + + if endpoint_ip is not None and len(endpoint_ip) > 0: + if ip_helper.is_valid_ipv4_address(endpoint_ip): + if redfish_endpoint['endpoint']['ip'] != endpoint_ip: + return False + + if ip_helper.is_valid_ipv4_cidr(endpoint_ip): + if not ip_helper.is_ipv4_in_cidr(redfish_endpoint['endpoint']['ip'], endpoint_ip): + return False + + if serial_number is not None and len(serial_number) > 0: + if redfish_endpoint['identity']['SerialNumber'] != serial_number: + return False + + return True + + def get_redfish_endpoints_settings(self, endpoint_type=None, endpoint_ip=None, serial_number=None, include=[]): + endpoint_ids = self.get_endpoint_ids() + + endpoints = [] + for endpoint_id in endpoint_ids: + redfish_endpoint = self.get_redfish_endpoint_settings(endpoint_id) + if redfish_endpoint is None: + continue + + match = self.match_redfish_endpoint( + redfish_endpoint, + endpoint_type, + endpoint_ip, + serial_number + ) + + if not match: + continue + + for key in include: + data = self.get_endpoint_settings( + endpoint_id, + filename=key + ) + if data is not None: + redfish_endpoint[key] = data['data'] + + endpoints.append( + redfish_endpoint + ) + + endpoints = sorted( + endpoints, + key=lambda i: i['identity']['HostName'].lower() + ) + + return endpoints + + def get_endpoint_id_with_ip(self, endpoint_ip): + endpoint_ids = self.get_endpoint_ids() + + for endpoint_id in endpoint_ids: + redfish_settings = self.get_redfish_endpoint_settings(endpoint_id) + if redfish_settings is None: + continue + + if redfish_settings['endpoint']['ip'] == endpoint_ip: + return endpoint_id + + return None + + def get_servers_redfish_settings(self, servers_mo, verify=False, bar_enabled=False): + redfish_endpoints_settings = self.get_redfish_endpoints_settings() + if redfish_endpoints_settings is None: + return None + + for server_mo in servers_mo: + server_mo['redfish_capable'] = True + if server_mo['ManagementMode'] == 'UCSM': + server_mo['redfish_capable'] = False + server_mo['redfish_enabled'] = False + server_mo['redfish_endpoint'] = None + server_mo['redfish_verified'] = '' + + if server_mo['redfish_capable']: + for redfish_endpoint in redfish_endpoints_settings: + if server_mo['Serial'] == redfish_endpoint['identity']['SerialNumber']: + server_mo['redfish_enabled'] = True + server_mo['redfish_verified'] = False + server_mo['redfish_endpoint_id'] = redfish_endpoint['endpoint_id'] + for key in redfish_endpoint['endpoint']: + server_mo['redfish_endpoint_%s' % (key)] = redfish_endpoint['endpoint'][key] + + if verify: + if bar_enabled: + bar_handler = Bar('Progress', max=len(servers_mo)) + bar_handler.goto(0) + + for server_mo in servers_mo: + if server_mo['redfish_enabled']: + server_mo['redfish_verified'] = self.verify_redfish_endpoint_authentication( + server_mo['redfish_endpoint_id'] + ) + if bar_enabled: + bar_handler.next() + + if bar_enabled: + bar_handler.finish() + + return servers_mo + + def delete_redfish_endpoint_settings(self, endpoint_id): + endpoint_settings = self.get_endpoint_settings(endpoint_id) + if 'redfish' in endpoint_settings: + del endpoint_settings['redfish'] + + return self.set_endpoint_settings(endpoint_id, endpoint_settings) + + def verify_redfish_endpoint_authentication(self, endpoint_id): + endpoint_settings = self.get_redfish_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return False + + redfish_handler = endpoint.RedfishEndpoint( + endpoint_settings['endpoint']['type'], + endpoint_settings['endpoint']['ip'], + endpoint_settings['endpoint']['port'], + endpoint_settings['endpoint']['username'], + endpoint_settings['endpoint']['password'], + log_id=self.log_id + ) + + if not redfish_handler.is_connected(): + return False + + return True diff --git a/lib/redfish/fi/__init__.py b/lib/redfish/fi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/fi/__pycache__/__init__.cpython-310.pyc b/lib/redfish/fi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a9e63ee9 Binary files /dev/null and b/lib/redfish/fi/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/endpoint.cpython-310.pyc b/lib/redfish/fi/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..85503b61 Binary files /dev/null and b/lib/redfish/fi/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/identity_chassis.cpython-310.pyc b/lib/redfish/fi/__pycache__/identity_chassis.cpython-310.pyc new file mode 100644 index 00000000..d17bc795 Binary files /dev/null and b/lib/redfish/fi/__pycache__/identity_chassis.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/identity_server.cpython-310.pyc b/lib/redfish/fi/__pycache__/identity_server.cpython-310.pyc new file mode 100644 index 00000000..4b7e273e Binary files /dev/null and b/lib/redfish/fi/__pycache__/identity_server.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/inventory.cpython-310.pyc b/lib/redfish/fi/__pycache__/inventory.cpython-310.pyc new file mode 100644 index 00000000..c26a0182 Binary files /dev/null and b/lib/redfish/fi/__pycache__/inventory.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/main.cpython-310.pyc b/lib/redfish/fi/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8cde717f Binary files /dev/null and b/lib/redfish/fi/__pycache__/main.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/power.cpython-310.pyc b/lib/redfish/fi/__pycache__/power.cpython-310.pyc new file mode 100644 index 00000000..00d8a527 Binary files /dev/null and b/lib/redfish/fi/__pycache__/power.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/power_chassis.cpython-310.pyc b/lib/redfish/fi/__pycache__/power_chassis.cpython-310.pyc new file mode 100644 index 00000000..385d1817 Binary files /dev/null and b/lib/redfish/fi/__pycache__/power_chassis.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/power_server.cpython-310.pyc b/lib/redfish/fi/__pycache__/power_server.cpython-310.pyc new file mode 100644 index 00000000..00616f94 Binary files /dev/null and b/lib/redfish/fi/__pycache__/power_server.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/templates.cpython-310.pyc b/lib/redfish/fi/__pycache__/templates.cpython-310.pyc new file mode 100644 index 00000000..bbbe2533 Binary files /dev/null and b/lib/redfish/fi/__pycache__/templates.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/thermal.cpython-310.pyc b/lib/redfish/fi/__pycache__/thermal.cpython-310.pyc new file mode 100644 index 00000000..4d031846 Binary files /dev/null and b/lib/redfish/fi/__pycache__/thermal.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/thermal_chassis.cpython-310.pyc b/lib/redfish/fi/__pycache__/thermal_chassis.cpython-310.pyc new file mode 100644 index 00000000..a4f13d00 Binary files /dev/null and b/lib/redfish/fi/__pycache__/thermal_chassis.cpython-310.pyc differ diff --git a/lib/redfish/fi/__pycache__/thermal_server.cpython-310.pyc b/lib/redfish/fi/__pycache__/thermal_server.cpython-310.pyc new file mode 100644 index 00000000..1215d779 Binary files /dev/null and b/lib/redfish/fi/__pycache__/thermal_server.cpython-310.pyc differ diff --git a/lib/redfish/fi/endpoint.py b/lib/redfish/fi/endpoint.py new file mode 100644 index 00000000..0c310755 --- /dev/null +++ b/lib/redfish/fi/endpoint.py @@ -0,0 +1,390 @@ +import json +import time +import traceback +import requests + +from lib.redfish.common import RedfishEndpointCommon +from lib.redfish.fi.inventory import RedfishEndpointFabricInterconnectInventory +from lib.redfish.fi.templates import RedfishEndpointFabricInterconnectTemplates + +# mypy: ignore-errors +requests.packages.urllib3.disable_warnings() + + +class RedfishEndpointFabricInterconnect(RedfishEndpointCommon, RedfishEndpointFabricInterconnectInventory, RedfishEndpointFabricInterconnectTemplates): + def __init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=None, + auto_connect=True, + get_timeout=10, + ssl_verify=False, + deep_search_exlusions=True, + log_id=None + ): + self.session_connected = False + + RedfishEndpointCommon.__init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + RedfishEndpointFabricInterconnectInventory.__init__( + self + ) + RedfishEndpointFabricInterconnectTemplates.__init__( + self + ) + + self.endpoint_type = 'fi' + if auto_connect: + self.connect() + + def __del__(self): + self.disconnect() + + def get_excluded_tree_uri(self): + if not self.deep_search_exclusions: + return [] + + uri = [ + '/api-explorer/resources/redfish/v1/JsonSchemas', + '/api-explorer/resources/redfish/v1/TaskService' + ] + + return uri + + def path_fixup(self, path): + if path.startswith('/redfish/v1/'): + path = path.lstrip('/redfish/v1/') + + if not path.startswith('/api-explorer/resources/redfish/v1'): + path = '/api-explorer/resources/redfish/v1/%s' % ( + path.lstrip('/') + ) + + if 'SYSTEM_ID' in path: + system_id = self.get_system_id() + if system_id is None: + self.log.error('get_properties', 'System ID not found') + return None + + path = path.replace( + 'SYSTEM_ID', + system_id + ) + + return path + + def get_properties(self, path, properties=[], fixup=True, inventory_type=None, inventory_id=None): + if not self.is_connected(): + return None + + if fixup: + path = self.path_fixup(path) + + start_time = int(time.time() * 1000) + if self.is_cache_enabled(): + all_properties = self.get_properties_cache(path, properties=properties) + else: + try: + url = 'https://%s/%s' % ( + self.endpoint_ip, + path + ) + + headers = {} + if len(self.inventory_type) > 0 and len(self.inventory_id) > 0: + headers['Inventory-Type'] = self.inventory_type + headers['Inventory-Id'] = self.inventory_id + + if inventory_type is not None: + headers['Inventory-Type'] = inventory_type + + if inventory_id is not None: + headers['Inventory-Id'] = inventory_id + + response = self.session_handler.get( + url, + headers=headers, + verify=self.ssl_verify, + timeout=self.get_timeout + ) + + except BaseException: + self.log.error( + 'get_properties', + 'Redfish get object exception: %s %s' % (self.endpoint_ip, path) + ) + + self.log.error( + 'get_properties', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + False, + duration_ms + ) + + return None + + if response.status_code > 299: + self.log.error( + 'get_properties', + 'Redfish get object failed: %s %s %s %s' % ( + self.endpoint_ip, + path, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + False, + duration_ms + ) + + return None + + try: + all_properties = response.json() + except BaseException: + self.log.error( + 'get_properties', + 'Redfish get object json exception: %s %s' % (self.endpoint_ip, path) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + '%s:%s' % (self.endpoint_ip, path), + True, + duration_ms + ) + + if properties is None or len(properties) == 0: + self.log.debug( + 'get_properties', + 'Redfish get %s in %s ms' % (path, duration_ms) + ) + self.log.odata( + path, + all_properties + ) + return all_properties + + selected_properties = {} + for key in properties: + if key in all_properties: + selected_properties[key] = all_properties[key] + + self.log.debug( + 'get_properties', + 'Redfish get %s in %s ms' % (path, duration_ms) + ) + self.log.odata( + path, + selected_properties + ) + + return selected_properties + + def is_connected(self): + if self.is_cache_enabled(): + return True + + return self.session_connected + + def connect(self): + if self.is_cache_enabled(): + return True + + if self.session_handler is not None: + return True + + start_time = int(time.time() * 1000) + self.session_handler = requests.Session() + + url = 'https://%s/Login' % (self.endpoint_ip) + data = {} + data['User'] = self.redfish_username + data['Password'] = self.redfish_password + + try: + response = self.session_handler.post( + url, + data=json.dumps(data), + verify=self.ssl_verify + ) + + except BaseException: + self.log.error( + 'connect', + 'Redfish authentication exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'connect', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'connect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + if response.status_code >= 300: + self.log.error( + 'connect', + 'Redfish authentication failed: %s %s %s' % ( + self.endpoint_ip, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'connect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + self.session_connected = True + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.debug( + 'get_properties', + 'Redfish connected to %s in %s ms' % (self.endpoint_ip, duration_ms) + ) + self.log.redfish( + 'connect %s' % (self.endpoint_ip), + True, + duration_ms + ) + + return True + + def disconnect(self): + if self.is_cache_enabled(): + return True + + if self.session_handler is None: + return True + + start_time = int(time.time() * 1000) + url = 'https://%s/Logout' % ( + self.endpoint_ip + ) + + success = True + try: + response = self.session_handler.post( + url, + verify=self.ssl_verify + ) + except BaseException: + self.log.error( + 'disconnect', + 'Redfish session close exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'disconnect', + traceback.format_exc() + ) + success = False + + if not success: + self.session_handler = requests.Session() + try: + response = self.session_handler.post( + url, + verify=self.ssl_verify + ) + except BaseException: + self.log.error( + 'disconnect', + 'Redfish session close exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'disconnect', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'disconnect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + if response.status_code >= 300: + self.log.error( + 'disconnect', + 'Redfish session close failed: %s %s %s' % ( + self.endpoint_ip, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'disconnect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + self.session_connected = False + self.session_handler = None + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.debug( + 'get_properties', + 'Redfish disconnected from %s in %s ms' % (self.endpoint_ip, duration_ms) + ) + self.log.redfish( + 'disconnect %s' % (self.endpoint_ip), + True, + duration_ms + ) + + return True diff --git a/lib/redfish/fi/identity_chassis.py b/lib/redfish/fi/identity_chassis.py new file mode 100644 index 00000000..dfef0c6f --- /dev/null +++ b/lib/redfish/fi/identity_chassis.py @@ -0,0 +1,89 @@ +import uuid + +from lib import ip_helper + + +class RedfishEndpointFabricInterconnectTemplateIdentityChassis(): + def __init__(self): + self.identity_main_url = '/' + self.default_chassis_uri = '/redfish/v1/Chassis/1' + + def get_chassis_uri(self): + uri = '/redfish/v1/Chassis' + children = self.endpoint_handler.get_odata_ids(uri) + if children is None: + self.log.error( + 'get_chassis_uri', + 'Failed to discover Chassis: %s' % (uri) + ) + return self.default_chassis_uri + + chassis_uri = None + for child in children: + if child == uri: + continue + + leaf = child.split('/')[-1] + + if leaf == 'Chassis': + continue + + if leaf == 'CMC': + continue + + if leaf == 'PeerCMC': + continue + + if leaf.startswith('FEM'): + continue + + if leaf.startswith('Blade'): + continue + + chassis_uri = 'Chassis/%s' % (leaf) + break + + if chassis_uri is None: + self.log.error( + 'get_chassis_uri', + 'Failed to find Chassis: %s' % (uri) + ) + return self.default_chassis_uri + + return chassis_uri + + def get_identity_chassis_default_cache_name(self, properties): + name = 'chassis-%s-%s' % ( + properties['Product'], + properties['SerialNumber'].lower() + ) + return name + + def get_template_identity_chassis_properties(self): + main = self.get_properties(self.identity_main_url) + if main is None: + return None + + chassis = self.get_properties(self.get_chassis_uri()) + if chassis is None: + return None + + properties = {} + properties['Product'] = chassis['Model'] + properties['Model'] = chassis['Model'] + properties['Vendor'] = chassis['Manufacturer'] + properties['RedfishVersion'] = main['RedfishVersion'] + properties['SerialNumber'] = chassis['SerialNumber'] + properties['PowerState'] = 'Off' + if self.is_chassis_power_on(): + properties['PowerState'] = 'On' + properties['HostName'] = None + properties['UUID'] = ip_helper.generate_uuid( + properties['SerialNumber'] + ) + properties['Name'] = None + + properties['DefaultCacheName'] = self.get_identity_chassis_default_cache_name(properties) + properties['CacheFileName'] = properties['UUID'].lower() + + return properties diff --git a/lib/redfish/fi/identity_server.py b/lib/redfish/fi/identity_server.py new file mode 100644 index 00000000..20c0e0d5 --- /dev/null +++ b/lib/redfish/fi/identity_server.py @@ -0,0 +1,69 @@ +import uuid + + +class RedfishEndpointFabricInterconnectTemplateIdentityServer(): + def __init__(self): + self.identity_main_url = '/' + self.identity_system_url = '/Systems/SYSTEM_ID' + self.identity_firmware_url = '/UpdateService/FirmwareInventory/CIMC' + + def get_identity_server_default_cache_name(self, properties): + firmware = properties['Firmware'] + if len(firmware) > 0: + firmware = firmware.replace('(', '.').replace(')', '') + + product = properties['Product'].replace('UCSC-', '').replace('UCSS-', '') + + name = 'ucsc-%s-%s-%s-%s' % ( + product.lower(), + properties['SerialNumber'].lower(), + firmware.lower(), + properties['PowerState'].lower() + ) + return name + + def get_template_identity_server_properties(self): + main = self.get_properties(self.identity_main_url) + if main is None: + return None + + system = self.get_properties(self.identity_system_url) + if system is None: + return None + + firmware = self.get_properties(self.identity_firmware_url) + if firmware is None: + return None + + properties = {} + properties['UUID'] = main['UUID'] + properties['RedfishVersion'] = main['RedfishVersion'] + properties['Product'] = system['Model'] + properties['Vendor'] = system['Manufacturer'] + + if system is not None: + keys = [ + 'SerialNumber', + 'PowerState', + 'Name', + 'BiosVersion', + 'Model' + ] + for key in keys: + properties[key] = '' + if key in system: + properties[key] = system[key] + + properties['HostName'] = properties['Name'] + properties['Firmware'] = '' + if firmware is not None: + if 'Version' in firmware: + properties['Firmware'] = firmware['Version'] + + properties['DefaultCacheName'] = self.get_identity_server_default_cache_name(properties) + if properties['UUID'] == '': + properties['CacheFileName'] = str(uuid.uuid4()).lower() + else: + properties['CacheFileName'] = properties['UUID'].lower() + + return properties diff --git a/lib/redfish/fi/inventory.py b/lib/redfish/fi/inventory.py new file mode 100644 index 00000000..c9e04280 --- /dev/null +++ b/lib/redfish/fi/inventory.py @@ -0,0 +1,212 @@ +import json + + +class RedfishEndpointFabricInterconnectInventory(): + def __init__(self): + self.inventory_type = '' + self.inventory_id = '' + self.inventory = None + + def get_inventory_type(self): + return self.inventory_type + + def get_inventory_id(self): + return self.inventory_id + + def set_inventory(self, inventory_type, inventory_id): + self.inventory_type = inventory_type + self.inventory_id = inventory_id + self.clear_system_id() + + def get_chassis(self): + chassis = self.get_properties( + 'Chassis', + fixup=False + ) + return chassis + + def get_servers(self): + chassis = self.get_properties( + 'Servers', + fixup=False + ) + return chassis + + def get_chassis_info(self): + data = self.get_chassis() + chassiz_info = [] + + for chassis in data['Results']: + chassis_info = {} + chassis_info['InventoryType'] = 'Chassis' + chassis_info['Iom1'] = chassis['Ioms'][0]['Name'] + chassis_info['Iom2'] = chassis['Ioms'][1]['Name'] + chassis_info['Name'] = chassis['chassis']['Name'] + chassis_info['Model'] = chassis['chassis']['Model'] + chassis_info['Serial'] = chassis['chassis']['Serial'] + chassis_info['Identifier'] = chassis['chassis']['Identifier'] + + if chassis['chassis']['AlarmSummary']['Warning'] == 0 and chassis['chassis']['AlarmSummary']['Critical'] == 0: + chassis_info['Health'] = 'Healthy' + chassis_info['HealthSummary'] = 'Healthy' + if chassis['chassis']['AlarmSummary']['Warning'] > 0 and chassis['chassis']['AlarmSummary']['Critical'] == 0: + chassis_info['Health'] = 'Warnings' + chassis_info['HealthSummary'] = 'Warnings (%s)' % (chassis['chassis']['AlarmSummary']['Warning']) + if chassis['chassis']['AlarmSummary']['Critical'] > 0: + chassis_info['Health'] = 'Critical' + chassis_info['HealthSummary'] = 'Critical (%s)' % (chassis['chassis']['AlarmSummary']['Critical']) + + chassiz_info.append(chassis_info) + + return chassiz_info + + def get_servers_info(self): + data = self.get_servers() + servers_info = [] + + for server in data['Results']: + server_info = {} + server_info['InventoryType'] = 'Server' + server_info['Name'] = server['Name'] + server_info['Model'] = server['Model'] + server_info['Serial'] = server['Serial'] + server_info['ConnectionStatus'] = server['ConnectionStatus'] + server_info['Identifier'] = server['Identifier'] + server_info['ChassisIdentifier'] = server['Identifier'].split('/')[0] + + server_info['OperPowerState'] = server['OperPowerState'] + server_info['Power'] = False + if server_info['OperPowerState'] == 'on': + server_info['Power'] = True + server_info['ServerProfile'] = server['ServerProfile'] + + server_info['IP_Inband'] = None + server_info['IP_Outband'] = None + for kvm in server['KvmIpAddresses']: + if kvm['Name'] == 'Inband': + server_info['IP_Inband'] = kvm['Address'] + if kvm['Name'] == 'Outband': + server_info['IP_Outband'] = kvm['Address'] + + if server['AlarmSummary']['Warning'] == 0 and server['AlarmSummary']['Critical'] == 0: + server_info['Health'] = 'Healthy' + server_info['HealthSummary'] = 'Healthy' + if server['AlarmSummary']['Warning'] > 0 and server['AlarmSummary']['Critical'] == 0: + server_info['Health'] = 'Warnings' + server_info['HealthSummary'] = 'Warnings (%s)' % (server['AlarmSummary']['Warning']) + if server['AlarmSummary']['Critical'] > 0: + server_info['Health'] = 'Critical' + server_info['HealthSummary'] = 'Critical (%s)' % (server['AlarmSummary']['Critical']) + + servers_info.append(server_info) + + return servers_info + + def get_server_to_chassis_info(self): + for server in self.inventory['servers']: + for chassis in self.inventory['chassis']: + if server['ChassisIdentifier'] == chassis['Identifier']: + server['Chassis'] = chassis + + def get_server_inventory(self, server_system_id): + inventory = self.get_inventory() + + for server in inventory['servers']: + if server['Serial'] == server_system_id: + return server + + return None + + def get_blades_id(self): + blades = [] + + for chassis in self.inventory['chassis']: + chassis_properties = self.get_properties( + 'Chassis', + fixup=True, + inventory_type=chassis['InventoryType'], + inventory_id=chassis['Iom1'] + ) + + if chassis_properties is None: + self.log.error( + 'get_blades_id', + 'Chassis properties not found: %s %s' % ( + chassis['InventoryType'], + chassis['Iom1'] + ) + ) + continue + + self.log.debug( + 'get_blades_id', + '%s %s properties: %s' % ( + chassis['InventoryType'], + chassis['Iom1'], + json.dumps(chassis_properties, indent=4) + ) + ) + + for member in chassis_properties['Members']: + if member['@odata.id'].startswith('/redfish/v1/Chassis/Blade'): + blade = self.get_properties( + member['@odata.id'], + fixup=True, + inventory_type=chassis['InventoryType'], + inventory_id=chassis['Iom1'] + ) + if blade is not None: + if 'SerialNumber' in blade: + blade_info = {} + blade_info['ChassisId'] = chassis['Identifier'] + blade_info['BladeId'] = blade['Id'] + blade_info['SerialNumber'] = blade['SerialNumber'] + blades.append(blade_info) + + self.log.debug( + 'get_blades_id', + 'Blades %s %s properties: %s' % ( + chassis['InventoryType'], + chassis['Iom1'], + json.dumps(blades, indent=4) + ) + ) + + return blades + + def get_server_to_blade_info(self): + for server in self.inventory['servers']: + server['BladeId'] = None + + blades = self.get_blades_id() + if blades is None: + self.log.error('get_server_to_blade_info', 'Blade IDs discovery failed') + return + + self.log.debug( + 'get_server_to_blade_info', + 'Blade IDs: %s' % (json.dumps(blades, indent=4)) + ) + + for server in self.inventory['servers']: + for blade in blades: + if server['Serial'] == blade['SerialNumber']: + server['BladeId'] = blade['BladeId'] + + def get_inventory(self): + if self.inventory is not None: + return self.inventory + + if self.is_cache_enabled(): + return self.cache['extra']['Inventory'] + + self.inventory = {} + self.inventory['chassis'] = self.get_chassis_info() + self.inventory['servers'] = self.get_servers_info() + self.log.debug('get_inventory', 'Base info: %s' % (json.dumps(self.inventory, indent=4))) + + self.get_server_to_chassis_info() + self.get_server_to_blade_info() + self.log.debug('get_inventory', 'Extended info: %s' % (json.dumps(self.inventory, indent=4))) + + return self.inventory diff --git a/lib/redfish/fi/output.py b/lib/redfish/fi/output.py new file mode 100644 index 00000000..31fd33a7 --- /dev/null +++ b/lib/redfish/fi/output.py @@ -0,0 +1,387 @@ +import json + + +class RedfishEndpointFabricInterconnectOutput( + ): + def __init__(self): + pass + + def print_template_identity_chassis_properties(self, properties): + keys = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'HostName', + 'SerialNumber', + 'UUID', + 'BiosVersion', + 'Firmware', + 'PowerState', + 'RedfishVersion' + ] + + headers = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'Hostname', + 'Serial Number', + 'UUID', + 'Bios Version', + 'Firmware', + 'Power State', + 'Redfish Version' + ] + + self.my_output.dictionary( + properties, + title='UCS Rack Redfish Endpoint', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_template_identity_server_properties(self, properties): + keys = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'HostName', + 'SerialNumber', + 'UUID', + 'BiosVersion', + 'Firmware', + 'PowerState', + 'RedfishVersion' + ] + + headers = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'Hostname', + 'Serial Number', + 'UUID', + 'Bios Version', + 'Firmware', + 'Power State', + 'Redfish Version' + ] + + self.my_output.dictionary( + properties, + title='UCS FI-Attached Server Redfish Endpoint', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_inventory_chassis(self, chassis): + order = [ + 'InventoryType', + 'Identifier', + 'Iom1', + 'Iom2', + 'Name', + 'Model', + 'Serial' + ] + + headers = [ + 'Inventory Type', + 'Chassis Id', + 'Inventory Id (IOM1)', + 'Inventory Id (IOM2)', + 'Chassis Name', + 'Chassis Model', + 'Chassis Serial', + ] + + self.my_output.my_table( + chassis, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_inventory_servers(self, servers): + order = [ + 'InventoryType', + 'Name', + 'ChassisIdentifier', + 'Model', + 'Serial' + ] + + headers = [ + 'Inventory Type', + 'Inventory Id', + 'Chassis Id', + 'Server Model', + 'Server Serial' + ] + + self.my_output.my_table( + servers, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_inventory(self, inventory, output='default'): + if output == 'json': + self.my_output.default( + json.dumps( + inventory, + indent=4 + ) + ) + return + + self.print_inventory_chassis(inventory['chassis']) + self.print_inventory_servers(inventory['servers']) + + def print_template_power_chassis_control_properties(self, properties): + keys = [ + 'CurrentConsumedWatts' + ] + headers = [ + 'CurrentConsumedWatts' + ] + + self.my_output.dictionary( + properties['Data']['PowerControl'], + title='Power Control', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_template_power_chassis_blade_properties(self, properties): + order = [ + 'MemberId', + 'State', + 'Health', + 'AverageConsumedWatts', + 'CurrentConsumedWatts', + 'MaxConsumedWatts', + 'MinConsumedWatts', + 'MaxPowerWatts', + 'MinPowerWatts' + ] + + headers = [ + 'Blade Name', + 'State', + 'Health', + 'AverageConsumedWatts', + 'CurrentConsumedWatts', + 'MaxConsumedWatts', + 'MinConsumedWatts', + 'MaxPowerWatts', + 'MinPowerWatts' + ] + + self.my_output.my_table( + properties['Data']['Blade'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_template_power_chassis_supply_properties(self, properties): + order = [ + 'Name', + 'State', + 'Manufacturer', + 'Model', + 'SerialNumber' + ] + + headers = [ + 'PSU Name', + 'State', + 'Manufacturer', + 'Model', + 'SerialNumber' + ] + + self.my_output.my_table( + properties['Data']['PowerSupply'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_template_power_chassis_properties(self, properties): + self.print_template_power_chassis_control_properties(properties) + self.print_template_power_chassis_blade_properties(properties) + self.print_template_power_chassis_supply_properties(properties) + + def print_template_power_server_consumption_properties(self, properties): + keys = [ + 'CurrentConsumedWatts', + 'AverageConsumedWatts', + 'MaxConsumedWatts', + 'MinConsumedWatts' + ] + + headers = [ + 'Current', + 'Average', + 'Max', + 'Min' + ] + + self.my_output.dictionary( + properties['Data']['PowerControl'], + title='Power Consumption (Watt)', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_template_power_server_voltage_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'ReadingVolts', + 'UpperThresholdCritical' + ] + + headers = [ + 'Voltage Sensor', + 'State', + 'Health', + 'Volts', + 'Upper Threshold' + ] + + self.my_output.my_table( + properties['Data']['Voltage'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_template_power_server_properties(self, properties): + self.print_template_power_server_consumption_properties(properties) + self.print_template_power_server_voltage_properties(properties) + + def print_template_thermal_chassis_temperature_properties(self, properties): + order = [ + 'Name', + 'State', + 'ReadingCelsius' + ] + + headers = [ + 'Sensor Name', + 'State', + 'Value (Celcius)' + ] + + self.my_output.my_table( + properties['Temperature'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_template_thermal_chassis_fan_properties(self, properties): + order = [ + 'Name', + 'State', + 'Model', + 'SerialNumber' + ] + + headers = [ + 'Fan Name', + 'State', + 'Model', + 'SerialNumber' + ] + + self.my_output.my_table( + properties['Fan'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_template_thermal_chassis_properties(self, properties): + self.print_template_thermal_chassis_temperature_properties(properties) + self.print_template_thermal_chassis_fan_properties(properties) + + def print_template_thermal_server_summary_properties(self, properties): + keys = [ + 'State', + 'Health' + ] + + headers = [ + 'State', + 'Health' + ] + + self.my_output.dictionary( + properties, + title='Thermal Summary', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_template_thermal_server_temperature_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + + headers = [ + 'Sensor Name', + 'State', + 'Health', + 'Location', + 'Value (Celcius)', + 'Upper Threshold (Celcius)' + ] + + self.my_output.my_table( + properties['Temperature'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_template_thermal_server_properties(self, properties): + self.print_template_thermal_server_summary_properties(properties) + self.print_template_thermal_server_temperature_properties(properties) diff --git a/lib/redfish/fi/power_chassis.py b/lib/redfish/fi/power_chassis.py new file mode 100644 index 00000000..4b09641c --- /dev/null +++ b/lib/redfish/fi/power_chassis.py @@ -0,0 +1,136 @@ +class RedfishEndpointFabricInterconnectTemplatePowerChassis(): + def __init__(self): + pass + + def is_chassis_power_on(self, inventory_type=None, inventory_id=None): + power_properties = self.get_template_power_chassis_properties( + inventory_type=inventory_type, + inventory_id=inventory_id + ) + if power_properties is None: + return False + + chassis_power_on = False + for power_supply in power_properties['Data']['PowerSupply']: + chassis_power_on = chassis_power_on or power_supply['On'] + + return chassis_power_on + + def get_template_power_chassis_properties(self, inventory_type=None, inventory_id=None): + uri = '%s/Power' % (self.get_chassis_uri()) + data = self.get_properties( + uri, + inventory_type=inventory_type, + inventory_id=inventory_id + ) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Data']['PowerControl'] = {} + properties['Data']['PowerControl']['CurrentConsumedWatts'] = 0 + properties['Data']['Blade'] = [] + properties['Data']['PowerSupply'] = [] + + for item in data['PowerControl']: + if item['MemberId'] == 'Chassis': + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerControl/Chassis", + # "MemberId": "Chassis", + # "Name": "Chassis Power Control", + # "Oem": { + # "Cisco": { + # "@odata.type": "#CiscoUCSExtensions.v1_0_0.CiscoUCSExtensions", + # "PowerExtendedEnabled": false, + # "PowerGridMaxWatts": 3044, + # "PowerN+1MaxWatts": 3044, + # "PowerN+2MaxWatts": 3044, + # "PowerNotRedundantMaxWatts": 6087, + # "PowerProfileMaxWatts": 8027, + # "PowerProfileMinWatts": 4060, + # "PowerRebalanceEnabled": true, + # "PowerSaveEnabled": false + # } + # }, + # "PowerLimit": { + # "LimitInWatts": null + # }, + # "Status": { + # "Health": "OK", + # "State": "Enabled" + # } + for key in item['Oem']['Cisco']: + if key != '@odata.type': + properties['Data']['PowerControl'][key] = item['Oem']['Cisco'][key] + + if item['MemberId'].startswith('Blade'): + # { + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerControl/Blade8", + # "MemberId": "Blade8", + # "Name": "Blade 8 Power Control", + # "Oem": { + # "Cisco": { + # "@odata.type": "#CiscoUCSExtensions.v1_0_0.CiscoUCSExtensions", + # "InitialPowerLimit": { + # "LimitInWatts": 0 + # }, + # "PowerAllocationPriority": 3, + # "PowerCharacteristics": { + # "MaxPowerWatts": 0, + # "MinPowerWatts": 0, + # "PowerProfileMaxWatts": 0, + # "PowerProfileMinWatts": 0 + # }, + # "PowerMetrics": { + # "AverageConsumedWatts": 0, + # "CurrentConsumedWatts": 0, + # "IntervalInMsec": 1000, + # "MaxConsumedWatts": 0, + # "MinConsumedWatts": 0 + # } + # } + # }, + # "PowerLimit": { + # "LimitInWatts": 0 + # }, + # "Status": { + # "Health": "OK", + # "State": "Absent" + # } + # }, + blade_info = {} + blade_info['MemberId'] = item['MemberId'] + blade_info['State'] = item['Status']['State'] + blade_info['Health'] = item['Status']['Health'] + blade_info['PowerLimitInWatts'] = item['PowerLimit']['LimitInWatts'] + for key in item['Oem']['Cisco']['PowerMetrics']: + blade_info[key] = item['Oem']['Cisco']['PowerMetrics'][key] + for key in item['Oem']['Cisco']['PowerCharacteristics']: + blade_info[key] = item['Oem']['Cisco']['PowerCharacteristics'][key] + properties['Data']['Blade'].append(blade_info) + + properties['Data']['PowerControl']['CurrentConsumedWatts'] = properties['Data']['PowerControl']['CurrentConsumedWatts'] + item['Oem']['Cisco']['PowerMetrics']['CurrentConsumedWatts'] + + for item in data['PowerSupplies']: + power_supply_info = {} + power_supply_info['MemberId'] = item['MemberId'] + power_supply_info['Name'] = item['Name'] + power_supply_info['State'] = item['Status']['State'] + if power_supply_info['State'] == 'Enabled': + power_supply_info['On'] = True + power_supply_info['Manufacturer'] = item['Manufacturer'] + power_supply_info['Model'] = item['Model'] + power_supply_info['SerialNumber'] = item['SerialNumber'] + else: + power_supply_info['On'] = False + power_supply_info['Manufacturer'] = '' + power_supply_info['Model'] = '' + power_supply_info['SerialNumber'] = '' + + properties['Data']['PowerSupply'].append(power_supply_info) + + properties['Summary'] = {} + properties['Summary']['Source'] = 'Redfish' + properties['Summary']['PowerNow'] = properties['Data']['PowerControl']['CurrentConsumedWatts'] + + return properties diff --git a/lib/redfish/fi/power_server.py b/lib/redfish/fi/power_server.py new file mode 100644 index 00000000..eb2f0086 --- /dev/null +++ b/lib/redfish/fi/power_server.py @@ -0,0 +1,163 @@ +class RedfishEndpointFabricInterconnectTemplatePowerServer(): + def __init__(self): + pass + + def get_server_chassis_properties(self): + if self.is_cache_enabled(): + return self.cache['extra']['Power'] + + server_inventory = self.get_server_inventory(self.get_system_id()) + if server_inventory is None: + return None + + chassis_power = self.get_template_power_chassis_properties( + inventory_type='Chassis', + inventory_id=server_inventory['Chassis']['Iom1'] + ) + + return chassis_power + + def get_server_power_utilization(self): + server_inventory = self.get_server_inventory(self.get_system_id()) + if server_inventory is None: + return None + + chassis_power = self.get_server_chassis_properties() + if chassis_power is None: + return None + + info = {} + for blade in chassis_power['Blade']: + if blade['MemberId'] == server_inventory['BladeId']: + keys = [ + 'MaxPowerWatts', + 'MinPowerWatts', + 'PowerProfileMaxWatts', + 'PowerProfileMinWatts', + 'PowerMetrics', + 'AverageConsumedWatts', + 'CurrentConsumedWatts', + 'IntervalInMsec', + 'MaxConsumedWatts', + 'MinConsumedWatts' + ] + for key in keys: + if key in blade: + info[key] = blade[key] + + return info + + def get_template_power_server_properties(self): + uri = 'Chassis/SYSTEM_ID/Power' + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Data']['PowerControl'] = {} + + # "PowerControl": [ + # { + # "@odata.id": "/redfish/v1/Chassis/FCH25337EHM/Power#/PowerControl/0", + # "MemberId": "0", + # "Name": "POWER_USAGE", + # "PowerConsumedWatts": 253 + # } + # ], + power_control_data = data['PowerControl'][0] + properties['Data']['PowerControl']['PowerConsumedWatts'] = power_control_data['PowerConsumedWatts'] + + server_power_utilization = self.get_server_power_utilization() + if server_power_utilization is not None: + for key in server_power_utilization: + properties['Data']['PowerControl'][key] = server_power_utilization[key] + + # "Voltages": [ + # { + # "@odata.id": "/redfish/v1/Chassis/FCH25337EHM/Power#/Voltages/0", + # "LowerThresholdFatal": 10.79699993133545, + # "MemberId": "0", + # "Name": "P12V", + # "PhysicalContext": "PowerSupply", + # "ReadingVolts": 12.095000267028809, + # "Status": { + # "Health": "OK", + # "State": "Enabled" + # }, + # "UpperThresholdCritical": 12.6850004196167, + # "UpperThresholdFatal": 13.156999588012695 + # } + # ], + properties['Data']['Voltage'] = [] + for voltage in data['Voltages']: + voltage_info = {} + voltage_info['Name'] = voltage['Name'] + voltage_info['ReadingVolts'] = voltage['ReadingVolts'] + voltage_info['UpperThresholdCritical'] = voltage['UpperThresholdCritical'] + voltage_info['PhysicalContext'] = voltage['PhysicalContext'] + voltage_info['State'] = voltage['Status']['State'] + voltage_info['Health'] = voltage['Status']['Health'] + properties['Data']['Voltage'].append(voltage_info) + + # { + # "SerialNumber": "LIT241244RQ", + # "InputRanges": [ + # { + # "InputType": "AC", + # "OutputWattage": 1050, + # "MaximumFrequencyHz": 63, + # "MaximumVoltage": 264, + # "MinimumVoltage": 90, + # "MinimumFrequencyHz": 47 + # } + # ], + # "FirmwareVersion": "10062019", + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerSupplies/PSU1", + # "PowerOutputWatts": 171, + # "LineInputVoltage": 229, + # "Name": "PSU1", + # "PowerInputWatts": 186, + # "Manufacturer": "Cisco Systems Inc", + # "LastPowerOutputWatts": 171, + # "MemberId": "1", + # "PartNumber": "341-0638-03", + # "PowerSupplyType": "AC", + # "Model": "PS-2112-9S-LF", + # "SparePartNumber": "341-0638-03", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + # properties['PowerSupply'] = [] + # for power_supply in data['PowerSupplies']: + # power_supply_info = {} + # power_supply_info['Name'] = power_supply['Name'] + # power_supply_info['Model'] = power_supply['Model'] + # power_supply_info['SerialNumber'] = power_supply['SerialNumber'] + # power_supply_info['PartNumber'] = power_supply['PartNumber'] + # power_supply_info['SparePartNumber'] = power_supply['SparePartNumber'] + # power_supply_info['Manufacturer'] = power_supply['Manufacturer'] + # power_supply_info['FirmwareVersion'] = power_supply['FirmwareVersion'] + # power_supply_info['State'] = power_supply['Status']['State'] + # power_supply_info['Health'] = power_supply['Status']['Health'] + # power_supply_info['PowerSupplyType'] = power_supply['PowerSupplyType'] + # power_supply_info['PowerOutputWatts'] = power_supply['PowerOutputWatts'] + # power_supply_info['LastPowerOutputWatts'] = power_supply['LastPowerOutputWatts'] + # power_supply_info['PowerInputWatts'] = power_supply['PowerInputWatts'] + # for input_range in power_supply['InputRanges']: + # for key in input_range: + # if key != 'InputType': + # power_supply_info[key] = input_range[key] + + # properties['PowerSupply'].append(power_supply_info) + + properties['Summary'] = {} + properties['Summary']['Source'] = 'Redfish' + properties['Summary']['PowerNow'] = properties['Data']['PowerControl']['PowerConsumedWatts'] + properties['Summary']['PowerMin'] = properties['Data']['PowerControl']['MinConsumedWatts'] + properties['Summary']['PowerAvg'] = properties['Data']['PowerControl']['AverageConsumedWatts'] + properties['Summary']['PowerMax'] = properties['Data']['PowerControl']['MaxConsumedWatts'] + + return properties diff --git a/lib/redfish/fi/templates.py b/lib/redfish/fi/templates.py new file mode 100644 index 00000000..3342622e --- /dev/null +++ b/lib/redfish/fi/templates.py @@ -0,0 +1,95 @@ +from lib.redfish.fi.identity_chassis import RedfishEndpointFabricInterconnectTemplateIdentityChassis +from lib.redfish.fi.identity_server import RedfishEndpointFabricInterconnectTemplateIdentityServer +from lib.redfish.fi.power_chassis import RedfishEndpointFabricInterconnectTemplatePowerChassis +from lib.redfish.fi.power_server import RedfishEndpointFabricInterconnectTemplatePowerServer +from lib.redfish.fi.thermal_chassis import RedfishEndpointFabricInterconnectTemplateThermalChassis +from lib.redfish.fi.thermal_server import RedfishEndpointFabricInterconnectTemplateThermalServer + + +class RedfishEndpointFabricInterconnectTemplates( + RedfishEndpointFabricInterconnectTemplateIdentityChassis, + RedfishEndpointFabricInterconnectTemplateIdentityServer, + RedfishEndpointFabricInterconnectTemplatePowerChassis, + RedfishEndpointFabricInterconnectTemplatePowerServer, + RedfishEndpointFabricInterconnectTemplateThermalChassis, + RedfishEndpointFabricInterconnectTemplateThermalServer + ): + def __init__(self): + RedfishEndpointFabricInterconnectTemplateIdentityChassis.__init__( + self + ) + RedfishEndpointFabricInterconnectTemplateIdentityServer.__init__( + self + ) + RedfishEndpointFabricInterconnectTemplatePowerChassis.__init__( + self + ) + RedfishEndpointFabricInterconnectTemplatePowerServer.__init__( + self + ) + RedfishEndpointFabricInterconnectTemplateThermalChassis.__init__( + self + ) + RedfishEndpointFabricInterconnectTemplateThermalServer.__init__( + self + ) + + def get_template_identity_properties(self): + if self.inventory_type == 'Chassis': + return self.get_template_identity_chassis_properties() + + if self.inventory_type == 'Server': + return self.get_template_identity_server_properties() + + return None + + def get_template_properties(self, template_name): + if template_name == 'identity': + if self.inventory_type == 'Chassis': + return self.get_template_identity_chassis_properties() + + if self.inventory_type == 'Server': + return self.get_template_identity_server_properties() + + if template_name == 'power': + if self.inventory_type == 'Chassis': + return self.get_template_power_chassis_properties() + + if self.inventory_type == 'Server': + return self.get_template_power_server_properties() + + if template_name == 'thermal': + if self.inventory_type == 'Chassis': + return self.get_template_thermal_chassis_properties() + + if self.inventory_type == 'Server': + return self.get_template_thermal_server_properties() + + self.log.error( + 'get_template_properties', + 'Unsupported template: %s for inventory type %s' % (template_name, self.inventory_type) + ) + + return None + + def print_template_properties(self, template_name, properties): + if template_name.lower() == 'identity': + if self.inventory_type == 'Chassis': + self.print_template_identity_chassis_properties(properties) + + if self.inventory_type == 'Server': + self.print_template_identity_server_properties(properties) + + if template_name.lower() == 'power': + if self.inventory_type == 'Chassis': + self.print_template_power_chassis_properties(properties) + + if self.inventory_type == 'Server': + self.print_template_power_server_properties(properties) + + if template_name.lower() == 'thermal': + if self.inventory_type == 'Chassis': + self.print_template_thermal_chassis_properties(properties) + + if self.inventory_type == 'Server': + self.print_template_thermal_server_properties(properties) diff --git a/lib/redfish/fi/thermal_chassis.py b/lib/redfish/fi/thermal_chassis.py new file mode 100644 index 00000000..2bc18323 --- /dev/null +++ b/lib/redfish/fi/thermal_chassis.py @@ -0,0 +1,78 @@ +class RedfishEndpointFabricInterconnectTemplateThermalChassis(): + def __init__(self): + pass + + def get_template_thermal_chassis_properties(self): + uri = '%s/Thermal' % (self.get_chassis_uri()) + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + + properties['Temperature'] = [] + for sensor in data['Temperatures']: + # { + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Temperatures/1", + # "MemberId": "1", + # "Name": "ASIC_TEMP_A", + # "ReadingCelsius": 54, + # "Status": { + # "Health": "OK", + # "State": "Enabled" + # } + # }, + sensor_info = {} + sensor_info['State'] = sensor['Status']['State'] + sensor_info['Name'] = sensor['Name'] + if sensor_info['State'] == 'Enabled': + sensor_info['ReadingCelsius'] = sensor['ReadingCelsius'] + else: + sensor_info['ReadingCelsius'] = '' + properties['Temperature'].append(sensor_info) + + properties['Temperature'] = sorted(properties['Temperature'], key=lambda i: i['Name']) + + properties['Fan'] = [] + for fan in data['Fans']: + # { + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Fans/1", + # "Assembly": { + # "@odata.id": "/redfish/v1/Chassis/1/Thermal/Fans/1/Assembly" + # }, + # "HotPluggable": true, + # "Location": { + # "PartLocation": { + # "LocationOrdinalValue": 1, + # "LocationType": "Slot" + # } + # }, + # "Manufacturer": "Cisco Systems Inc", + # "MemberId": "1", + # "Model": "UCSX-9508-FAN", + # "Name": "Fan Module 1 Fan 1", + # "PartNumber": "73-19422-04 ", + # "SerialNumber": "FCH2517709V", + # "Status": { + # "State": "Enabled" + # } + # }, + fan_info = {} + fan_info['Name'] = fan['Name'] + fan_info['State'] = fan['Status']['State'] + if fan_info['State'] == 'Enabled': + fan_info['PartNumber'] = fan['PartNumber'] + fan_info['SerialNumber'] = fan['SerialNumber'] + fan_info['Model'] = fan['Model'] + fan_info['Manufacturer'] = fan['Manufacturer'] + else: + fan_info['PartNumber'] = '' + fan_info['SerialNumber'] = '' + fan_info['Model'] = '' + fan_info['Manufacturer'] = '' + + properties['Fan'].append(fan_info) + + properties['Fan'] = sorted(properties['Fan'], key=lambda i: i['Name']) + + return properties diff --git a/lib/redfish/fi/thermal_server.py b/lib/redfish/fi/thermal_server.py new file mode 100644 index 00000000..edc1d46c --- /dev/null +++ b/lib/redfish/fi/thermal_server.py @@ -0,0 +1,83 @@ +class RedfishEndpointFabricInterconnectTemplateThermalServer(): + def __init__(self): + pass + + def get_template_thermal_server_properties(self): + uri = 'Chassis/SYSTEM_ID/Thermal' + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['State'] = data['Status']['State'] + properties['Health'] = data['Status']['Health'] + + # "@odata.id": "/redfish/v1/Chassis/FCH25337EHM/Thermal#/Temperatures/0", + # "MemberId": "0", + # "Name": "TEMP_FRONT", + # "PhysicalContext": "SystemBoard", + # "ReadingCelsius": 16, + # "Status": { + # "Health": "OK", + # "State": "Enabled" + # }, + # "UpperThresholdCritical": 45, + # "UpperThresholdFatal": 50 + properties['Temperature'] = [] + for sensor in data['Temperatures']: + sensor_info = {} + sensor_info['State'] = sensor['Status']['State'] + sensor_info['Health'] = sensor['Status']['Health'] + sensor_info['Name'] = sensor['Name'] + sensor_info['PhysicalContext'] = sensor['PhysicalContext'] + sensor_info['ReadingCelsius'] = sensor['ReadingCelsius'] + sensor_info['UpperThresholdCritical'] = '' + if 'UpperThresholdCritical' in sensor: + sensor_info['UpperThresholdCritical'] = sensor['UpperThresholdCritical'] + sensor_info['UpperThresholdFatal'] = '' + if 'UpperThresholdFatal' in sensor: + sensor_info['UpperThresholdFatal'] = sensor['UpperThresholdFatal'] + properties['Temperature'].append(sensor_info) + + properties['Temperature'] = sorted(properties['Temperature'], key=lambda i: i['Name']) + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Fans/MOD1_FAN1", + # "ReadingUnits": "RPM", + # "Reading": 7070, + # "PhysicalContext": "Fan", + # "MemberId": "1", + # "Name": "MOD1_FAN1_SPEED", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + # properties['Fan'] = [] + # for fan in data['Fans']: + # fan_info = {} + # fan_info['Name'] = fan['Name'] + # fan_info['State'] = fan['Status']['State'] + # fan_info['Health'] = '' + # if 'Health' in fan['Status']: + # fan_info['Health'] = fan['Status']['Health'] + # fan_info['PhysicalContext'] = '' + # if 'PhysicalContext' in fan: + # fan_info['PhysicalContext'] = fan['PhysicalContext'] + # fan_info['ReadingUnits'] = '' + # if 'ReadingUnits' in fan: + # fan_info['ReadingUnits'] = fan['ReadingUnits'] + # fan_info['Reading'] = '' + # if 'Reading' in fan: + # fan_info['Reading'] = fan['Reading'] + # fan_info['Value'] = '%s %s' % (fan_info['Reading'], fan_info['ReadingUnits']) + # properties['Fan'].append(fan_info) + + # properties['Fan'] = sorted(properties['Fan'], key=lambda i: i['Name']) + + return properties diff --git a/lib/redfish/hpe/__init__.py b/lib/redfish/hpe/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/hpe/__pycache__/__init__.cpython-310.pyc b/lib/redfish/hpe/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a3352c94 Binary files /dev/null and b/lib/redfish/hpe/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/redfish/hpe/__pycache__/endpoint.cpython-310.pyc b/lib/redfish/hpe/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..ae33dab4 Binary files /dev/null and b/lib/redfish/hpe/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/redfish/hpe/__pycache__/identity.cpython-310.pyc b/lib/redfish/hpe/__pycache__/identity.cpython-310.pyc new file mode 100644 index 00000000..ddecec04 Binary files /dev/null and b/lib/redfish/hpe/__pycache__/identity.cpython-310.pyc differ diff --git a/lib/redfish/hpe/__pycache__/power.cpython-310.pyc b/lib/redfish/hpe/__pycache__/power.cpython-310.pyc new file mode 100644 index 00000000..28737c94 Binary files /dev/null and b/lib/redfish/hpe/__pycache__/power.cpython-310.pyc differ diff --git a/lib/redfish/hpe/__pycache__/template.cpython-310.pyc b/lib/redfish/hpe/__pycache__/template.cpython-310.pyc new file mode 100644 index 00000000..d741272c Binary files /dev/null and b/lib/redfish/hpe/__pycache__/template.cpython-310.pyc differ diff --git a/lib/redfish/hpe/__pycache__/thermal.cpython-310.pyc b/lib/redfish/hpe/__pycache__/thermal.cpython-310.pyc new file mode 100644 index 00000000..e05858eb Binary files /dev/null and b/lib/redfish/hpe/__pycache__/thermal.cpython-310.pyc differ diff --git a/lib/redfish/hpe/endpoint.py b/lib/redfish/hpe/endpoint.py new file mode 100644 index 00000000..e7a48304 --- /dev/null +++ b/lib/redfish/hpe/endpoint.py @@ -0,0 +1,53 @@ +from lib.redfish.standard.endpoint import RedfishEndpointStandard +from lib.redfish.hpe.template import RedfishEndpointHpeTemplate + + +class RedfishEndpointHpe(RedfishEndpointStandard, RedfishEndpointHpeTemplate): + def __init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=None, + auto_connect=True, + deep_search_exlusions=True, + get_timeout=10, + ssl_verify=False, + log_id=None + ): + RedfishEndpointStandard.__init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + cache_filename=cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + RedfishEndpointHpeTemplate.__init__( + self + ) + + self.endpoint_type = 'hpe' + + def get_excluded_tree_uri(self): + if not self.deep_search_exclusions: + return [] + + uri = [ + '/redfish/v1/TelemetryService', + '/redfish/v1/Managers/1/LogServices', + '/redfish/v1/Systems/1/LogServices', + '/redfish/v1/JsonSchemas', + '/redfish/v1/UpdateService/SoftwareInventory', + '/redfish/v1/SessionService/Sessions' + ] + + return uri diff --git a/lib/redfish/hpe/identity.py b/lib/redfish/hpe/identity.py new file mode 100644 index 00000000..96cf6554 --- /dev/null +++ b/lib/redfish/hpe/identity.py @@ -0,0 +1,52 @@ +import uuid + + +class RedfishEndpointHpeTemplateIdentity(): + def __init__(self): + self.identity_main_url = '/' + self.chassis_url = '/Chassis/1' + self.system_url = '/Systems/1' + + def get_identity_default_cache_name(self, properties): + firmware = properties['Firmware'] + if len(firmware) > 0: + firmware = firmware.replace('(', '.').replace(')', '') + + product = properties['Product'].replace(' ', '-') + + name = 'hpe-%s-%s-%s-%s' % ( + product.lower(), + properties['SerialNumber'].lower(), + firmware.lower(), + properties['PowerState'].lower() + ) + return name + + def get_template_identity_properties(self): + main = self.get_properties(self.identity_main_url) + chassis = self.get_properties(self.chassis_url) + system = self.get_properties(self.system_url) + + if main is None or chassis is None or system is None: + return None + + properties = {} + properties['Product'] = main['Product'] + properties['Model'] = system['Model'] + properties['Vendor'] = main['Vendor'] + properties['UUID'] = main['UUID'] + properties['Firmware'] = main['Oem']['Hpe']['Manager'][0]['ManagerFirmwareVersion'] + properties['HostName'] = main['Oem']['Hpe']['Manager'][0]['HostName'] + properties['Name'] = system['Name'] + properties['SerialNumber'] = chassis['SerialNumber'] + properties['PowerState'] = chassis['PowerState'] + properties['BiosVersion'] = system['BiosVersion'] + properties['RedfishVersion'] = main['RedfishVersion'] + + properties['DefaultCacheName'] = self.get_identity_default_cache_name(properties) + if properties['UUID'] == '': + properties['CacheFileName'] = str(uuid.uuid4()).lower() + else: + properties['CacheFileName'] = properties['UUID'].lower() + + return properties diff --git a/lib/redfish/hpe/output.py b/lib/redfish/hpe/output.py new file mode 100644 index 00000000..26dd5c6c --- /dev/null +++ b/lib/redfish/hpe/output.py @@ -0,0 +1,193 @@ +class RedfishEndpointHpeOutput( + ): + def __init__(self): + pass + + def print_hpe_properties(self, template_name, properties): + if template_name.lower() == 'identity': + self.print_hpe_identity_properties(properties) + + if template_name.lower() == 'power': + self.print_hpe_power_properties(properties) + + if template_name.lower() == 'thermal': + self.print_hpe_thermal_properties(properties) + + def print_hpe_identity_properties(self, properties): + keys = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'HostName', + 'SerialNumber', + 'UUID', + 'BiosVersion', + 'Firmware', + 'PowerState', + 'RedfishVersion' + ] + + headers = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'Hostname', + 'Serial Number', + 'UUID', + 'Bios Version', + 'Firmware', + 'Power State', + 'Redfish Version' + ] + + self.my_output.dictionary( + properties, + title='HPE Redfish Endpoint', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_hpe_power_consumption_properties(self, properties): + keys = [ + 'PowerConsumedWatts', + 'MinConsumedWatts', + 'AverageConsumedWatts', + 'MaxConsumedWatts' + ] + + headers = [ + 'Current', + 'Min', + 'Average', + 'Max' + ] + + self.my_output.dictionary( + properties['Data']['PowerControl'], + title='Power Consumption (Watt)', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_hpe_power_supply_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'SerialNumber', + 'FirmwareVersion', + 'LastPowerOutputWatts', + 'LineInputVoltage' + ] + + headers = [ + 'PSU Name', + 'State', + 'Health', + 'Serial', + 'Firmware', + 'Output (Watt)', + 'Input (V)' + ] + + self.my_output.my_table( + properties['Data']['PowerSupply'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_hpe_power_properties(self, properties): + self.print_hpe_power_consumption_properties(properties) + self.print_hpe_power_supply_properties(properties) + + def print_hpe_thermal_summary_properties(self, properties): + keys = [ + 'SensorHealth', + 'HighestTemperature', + 'SmallestGap', + 'OverThreshold', + 'FanHealth' + ] + + headers = [ + 'Sensors Health', + 'Highest (C)', + 'Smallest Gap (C)', + 'Over Threshold', + 'Fans Health' + ] + + self.my_output.dictionary( + properties['Summary'], + title='Thermal Summary', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_hpe_thermal_temperature_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + + headers = [ + 'Sensor Name', + 'State', + 'Health', + 'Location', + 'Value (Celcius)', + 'Upper Threshold (Celcius)' + ] + + self.my_output.my_table( + properties['Data']['Temperature'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_hpe_thermal_fan_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'Value' + ] + + headers = [ + 'Fan Name', + 'State', + 'Health', + 'Value' + ] + + self.my_output.my_table( + properties['Data']['Fan'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_hpe_thermal_properties(self, properties): + self.print_hpe_thermal_summary_properties(properties) + self.print_hpe_thermal_temperature_properties(properties) + self.print_hpe_thermal_fan_properties(properties) diff --git a/lib/redfish/hpe/power.py b/lib/redfish/hpe/power.py new file mode 100644 index 00000000..01f2323f --- /dev/null +++ b/lib/redfish/hpe/power.py @@ -0,0 +1,91 @@ +class RedfishEndpointHpeTemplatePower(): + def __init__(self): + pass + + def get_template_power_properties(self): + uri = '/redfish/v1/Chassis/1/Power' + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Data']['PowerControl'] = {} + + # { + # "PhysicalContext": "PowerSupply", + # "PowerMetrics": { + # "MinConsumedWatts": 186, + # "AverageConsumedWatts": 349, + # "MaxConsumedWatts": 495 + # }, + # "MemberId": "1", + # "PowerLimit": { + # "LimitException": "NoAction" + # }, + # "PowerConsumedWatts": 360, + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerControl/1" + # } + power_control_data = data['PowerControl'][0] + properties['Data']['PowerControl']['PowerConsumedWatts'] = power_control_data['PowerConsumedWatts'] + for key in power_control_data['PowerMetrics']: + properties['Data']['PowerControl'][key] = power_control_data['PowerMetrics'][key] + + # { + # "@odata.id": "/redfish/v1/Chassis/1/Power#PowerSupplies/0", + # "FirmwareVersion": "1.00", + # "LastPowerOutputWatts": 89, + # "LineInputVoltage": 206, + # "LineInputVoltageType": "ACHighLine", + # "Manufacturer": "DELTA", + # "MemberId": "0", + # "Model": "865438-B21", + # "Name": "HpeServerPowerSupply", + # "Oem": { + # "Hpe": { + # "@odata.context": "/redfish/v1/$metadata#HpeServerPowerSupply.HpeServerPowerSupply", + # "@odata.type": "#HpeServerPowerSupply.v2_0_0.HpeServerPowerSupply", + # "AveragePowerOutputWatts": 89, + # "BayNumber": 1, + # "HotplugCapable": true, + # "MaxPowerOutputWatts": 96, + # "Mismatched": false, + # "PowerSupplyStatus": { + # "State": "Ok" + # }, + # "iPDUCapable": false + # } + # }, + # "PowerCapacityWatts": 800, + # "PowerSupplyType": "AC", + # "SerialNumber": "5WBYE0D4DEF1FM", + # "SparePartNumber": "866793-001", + # "Status": { + # "Health": "OK", + # "State": "Enabled" + # } + # }, + properties['Data']['PowerSupply'] = [] + for power_supply in data['PowerSupplies']: + power_supply_info = {} + power_supply_info['Name'] = power_supply['Name'] + power_supply_info['Model'] = power_supply['Model'] + power_supply_info['SerialNumber'] = power_supply['SerialNumber'] + power_supply_info['SparePartNumber'] = power_supply['SparePartNumber'] + power_supply_info['Manufacturer'] = power_supply['Manufacturer'] + power_supply_info['FirmwareVersion'] = power_supply['FirmwareVersion'] + power_supply_info['State'] = power_supply['Status']['State'] + power_supply_info['Health'] = power_supply['Status']['Health'] + power_supply_info['PowerSupplyType'] = power_supply['PowerSupplyType'] + power_supply_info['LastPowerOutputWatts'] = power_supply['LastPowerOutputWatts'] + power_supply_info['LineInputVoltage'] = power_supply['LineInputVoltage'] + properties['Data']['PowerSupply'].append(power_supply_info) + + properties['Summary'] = {} + properties['Summary']['Source'] = 'Redfish' + properties['Summary']['PowerNow'] = properties['Data']['PowerControl']['PowerConsumedWatts'] + properties['Summary']['PowerMin'] = properties['Data']['PowerControl']['MinConsumedWatts'] + properties['Summary']['PowerAvg'] = properties['Data']['PowerControl']['AverageConsumedWatts'] + properties['Summary']['PowerMax'] = properties['Data']['PowerControl']['MaxConsumedWatts'] + + return properties diff --git a/lib/redfish/hpe/template.py b/lib/redfish/hpe/template.py new file mode 100644 index 00000000..5a7d27e9 --- /dev/null +++ b/lib/redfish/hpe/template.py @@ -0,0 +1,32 @@ +from lib.redfish.hpe.identity import RedfishEndpointHpeTemplateIdentity +from lib.redfish.hpe.power import RedfishEndpointHpeTemplatePower +from lib.redfish.hpe.thermal import RedfishEndpointHpeTemplateThermal + + +class RedfishEndpointHpeTemplate(RedfishEndpointHpeTemplateIdentity, RedfishEndpointHpeTemplatePower, RedfishEndpointHpeTemplateThermal): + def __init__(self): + RedfishEndpointHpeTemplateIdentity.__init__( + self + ) + RedfishEndpointHpeTemplatePower.__init__( + self + ) + RedfishEndpointHpeTemplateThermal.__init__( + self + ) + + def get_template_properties(self, template_name): + if template_name.lower() == 'identity': + return self.get_template_identity_properties() + + if template_name.lower() == 'power': + return self.get_template_power_properties() + + if template_name.lower() == 'thermal': + return self.get_template_thermal_properties() + + self.log.error( + 'get_template_properties', + 'Unsupported template: %s' % (template_name) + ) + return None diff --git a/lib/redfish/hpe/thermal.py b/lib/redfish/hpe/thermal.py new file mode 100644 index 00000000..cf6d2339 --- /dev/null +++ b/lib/redfish/hpe/thermal.py @@ -0,0 +1,129 @@ +class RedfishEndpointHpeTemplateThermal(): + def __init__(self): + pass + + def get_template_thermal_properties(self): + uri = '/redfish/v1/Chassis/1/Thermal' + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Summary'] = {} + properties['Summary']['FanHealth'] = True + properties['Summary']['SensorHealth'] = True + properties['Summary']['HighestTemperature'] = None + properties['Summary']['SmallestGap'] = None + properties['Summary']['OverThreshold'] = 0 + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Temperatures/MLOM_TEMP", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # }, + # "SensorNumber": 60, + # "Name": "MLOM_TEMP", + # "PhysicalContext": "NetworkingDevice", + # "MemberId": "1", + # "UpperThresholdCritical": 90, + # "ReadingCelsius": 55 + # }, + properties['Data']['Temperature'] = [] + for sensor in data['Temperatures']: + sensor_info = {} + sensor_info['State'] = sensor['Status']['State'] + sensor_info['Health'] = '' + if 'Health' in sensor['Status']: + sensor_info['Health'] = sensor['Status']['Health'] + if sensor_info['State'] == 'Enabled': + if sensor_info['Health'].lower() != 'ok': + properties['Summary']['SensorHealth'] = False + + sensor_info['SensorNumber'] = sensor['SensorNumber'] + sensor_info['Name'] = sensor['Name'] + sensor_info['PhysicalContext'] = sensor['PhysicalContext'] + sensor_info['ReadingCelsius'] = sensor['ReadingCelsius'] + sensor_info['UpperThresholdCritical'] = sensor['UpperThresholdCritical'] + + properties['Data']['Temperature'].append(sensor_info) + + try: + value = int(sensor_info['ReadingCelsius']) + if properties['Summary']['HighestTemperature'] is None: + properties['Summary']['HighestTemperature'] = value + else: + properties['Summary']['HighestTemperature'] = max( + properties['Summary']['HighestTemperature'], + value + ) + except BaseException: + pass + + try: + value = int(sensor_info['UpperThresholdCritical']) - int(sensor_info['ReadingCelsius']) + if value < 0: + properties['Summary']['OverThreshold'] = properties['Summary']['OverThreshold'] + 1 + else: + if properties['Summary']['SmallestGap'] is None: + properties['Summary']['SmallestGap'] = value + else: + properties['Summary']['SmallestGap'] = min( + properties['Summary']['SmallestGap'], + value + ) + except BaseException: + pass + + properties['Data']['Temperature'] = sorted(properties['Data']['Temperature'], key=lambda i: i['Name']) + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Fans/MOD1_FAN1", + # "ReadingUnits": "RPM", + # "Reading": 7070, + # "PhysicalContext": "Fan", + # "MemberId": "1", + # "Name": "MOD1_FAN1_SPEED", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + properties['Data']['Fan'] = [] + for fan in data['Fans']: + fan_info = {} + fan_info['Name'] = fan['Name'] + fan_info['State'] = fan['Status']['State'] + fan_info['Health'] = '' + if 'Health' in fan['Status']: + fan_info['Health'] = fan['Status']['Health'] + if fan_info['State'] == 'Enabled': + if fan_info['Health'].lower() != 'ok': + properties['Summary']['FanHealth'] = False + + fan_info['PhysicalContext'] = '' + if 'PhysicalContext' in fan: + fan_info['PhysicalContext'] = fan['PhysicalContext'] + fan_info['ReadingUnits'] = '' + if 'ReadingUnits' in fan: + fan_info['ReadingUnits'] = fan['ReadingUnits'] + fan_info['Reading'] = '' + if 'Reading' in fan: + fan_info['Reading'] = fan['Reading'] + fan_info['Value'] = '%s %s' % (fan_info['Reading'], fan_info['ReadingUnits']) + properties['Data']['Fan'].append(fan_info) + + properties['Data']['Fan'] = sorted(properties['Data']['Fan'], key=lambda i: i['Name']) + + return properties diff --git a/lib/redfish/output.py b/lib/redfish/output.py new file mode 100644 index 00000000..e1fe9591 --- /dev/null +++ b/lib/redfish/output.py @@ -0,0 +1,213 @@ +import json +from lib import output_helper + +from lib.redfish.dell.output import RedfishEndpointDellOutput +from lib.redfish.fi.output import RedfishEndpointFabricInterconnectOutput +from lib.redfish.hpe.output import RedfishEndpointHpeOutput +from lib.redfish.ucs_rack.output import RedfishEndpointUcsRackOutput + + +class RedfishOutput( + RedfishEndpointDellOutput, + RedfishEndpointFabricInterconnectOutput, + RedfishEndpointHpeOutput, + RedfishEndpointUcsRackOutput + ): + def __init__(self, verbose=False, debug=False, log_id=None): + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + + RedfishEndpointDellOutput.__init__(self) + RedfishEndpointFabricInterconnectOutput.__init__(self) + RedfishEndpointHpeOutput.__init__(self) + RedfishEndpointUcsRackOutput.__init__(self) + + def print_redfish_endpoint_settings(self, endpoints, verify=False, show_password=True, title=False): + if title: + self.my_output.default( + 'RedFish Endpoint [#%s]' % (len(endpoints)), + underline=True, + before_newline=True + ) + + if len(endpoints) == 0: + self.my_output.default('None') + return + + entries = [] + for item in endpoints: + entry = item['endpoint'] + entry['__Output'] = {} + + if 'verified' in entry: + if entry['verified']: + entry['AuthenticatedTick'] = '\u2713' + entry['__Output']['AuthenticatedTick'] = 'Green' + else: + entry['AuthenticatedTick'] = '\u2717' + entry['__Output']['AuthenticatedTick'] = 'Red' + + for key in ['Product', 'SerialNumber', 'HostName']: + entry[key] = item['identity'][key] + + if len(entry['inventory_type']) == 0: + entry['inventory_type'] = '--' + + if len(entry['inventory_id']) == 0: + entry['inventory_id'] = '--' + + entries.append(entry) + + if not show_password: + for item in entries: + item['password'] = '******' + + order = [ + 'SerialNumber', + 'Product', + 'HostName', + 'type', + 'ip', + 'port', + 'username', + 'password', + 'inventory_type', + 'inventory_id' + ] + + headers = [ + 'S/N', + 'Product', + 'Name', + 'Type', + 'IP', + 'Port', + 'Username', + 'Password', + 'FI Inventory Type', + 'FI Inventory ID' + ] + + if verify: + order.append('AuthenticatedTick') + headers.append('Authenticated') + + self.my_output.my_table( + entries, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_redfish_cache(self, info, title=False): + if title: + self.my_output.default( + 'RedFish Cache [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'CacheName', + 'Product', + 'SerialNumber', + 'Firmware', + 'PowerState', + 'EndpointType', + 'EndpointIp', + 'EndpointInventoryType', + 'EndpointInventoryId' + ] + + headers = [ + 'Cache Name', + 'Product', + 'S/N', + 'Firmware', + 'Power', + 'Type', + 'IP', + 'Inventory', + 'Id' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_children(self, path, children, deep, output): + if output == 'default': + self.my_output.default('') + if deep: + self.my_output.default('Redfish resource references (recursively): %s' % (path), underline=True) + else: + self.my_output.default('Redfish resource references: %s' % (path), underline=True) + + for child in children: + if child != path: + self.my_output.default(child) + + if output == 'json': + self.my_output.default(json.dumps(children, indent=4)) + + def print_tree(self, data, output): + if data is None: + return + + if output == 'json': + self.my_output.default( + json.dumps( + data, + indent=4 + ) + ) + + if output == 'default': + self.my_output.default('') + for uri in data: + self.my_output.default(uri, underline=True) + if data[uri] is None: + self.my_output.default('No properties') + continue + + self.my_output.default( + json.dumps( + data[uri], + indent=4 + ) + ) + + self.my_output.default('') + + def print_redfish_settings(self, settings): + order = [ + 'CacheEnabled', + 'CacheDirectory' + ] + + headers = [ + 'Cache Enabled', + 'Cache Directory' + ] + + self.my_output.dictionary( + settings, + title='Redfish Settings', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) diff --git a/lib/redfish/settings.py b/lib/redfish/settings.py new file mode 100644 index 00000000..2ef56ff0 --- /dev/null +++ b/lib/redfish/settings.py @@ -0,0 +1,60 @@ +import os +import json +import traceback + +from lib import log_helper +from lib.settings_helper import Settings + + +class RedfishSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self) + + self.log = log_helper.Log(log_id=log_id) + self.log_id = log_id + + self.redfish_settings_filename = os.path.join( + self.settings_dir, + 'redfish' + ) + + if not self.initialize_redfish_settings(): + raise ValueError('Redfish settings initialization failed') + + def initialize_redfish_settings(self): + if not os.path.isfile(self.redfish_settings_filename): + settings = self.get_redfish_default_settings() + if not self.set_redfish_settings(settings): + return False + return True + + def get_redfish_settings(self): + if not os.path.isfile(self.redfish_settings_filename): + return None + + try: + with open(self.redfish_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_redfish_settings', traceback.format_exc()) + return None + + return settings + + def set_redfish_settings(self, settings): + try: + with open(self.redfish_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_redfish_settings', traceback.format_exc()) + return False + + return True + + def get_redfish_default_settings(self): + settings = {} + settings['CacheEnabled'] = False + settings['CacheDirectory'] = '/tmp/redfish' + return settings diff --git a/lib/redfish/standard/__init__.py b/lib/redfish/standard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/standard/__pycache__/__init__.cpython-310.pyc b/lib/redfish/standard/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..66de3592 Binary files /dev/null and b/lib/redfish/standard/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/redfish/standard/__pycache__/endpoint.cpython-310.pyc b/lib/redfish/standard/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..c04b9304 Binary files /dev/null and b/lib/redfish/standard/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/redfish/standard/endpoint.py b/lib/redfish/standard/endpoint.py new file mode 100644 index 00000000..297cadf7 --- /dev/null +++ b/lib/redfish/standard/endpoint.py @@ -0,0 +1,416 @@ +import json +import time +import traceback +import requests + +from lib.redfish.common import RedfishEndpointCommon + +# mypy: ignore-errors +requests.packages.urllib3.disable_warnings() + + +class RedfishEndpointStandard(RedfishEndpointCommon): + def __init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=None, + cache_filename=None, + auto_connect=True, + get_timeout=10, + ssl_verify=False, + deep_search_exlusions=True, + log_id=None + ): + RedfishEndpointCommon.__init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=system_id, + cache_filename=cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + + self.endpoint_type = 'standard' + if auto_connect: + self.connect() + + def __del__(self): + self.disconnect() + + def extract_session_id(self, authentication_response): + if 'Location' in authentication_response.headers: + return authentication_response.headers['Location'].split('/')[-1] + + # {\n "@odata.id":"/redfish/v1/SessionService/Sessions/5819",\n "Description":"Session of user: admin",\n "Name":"User Session #5819",\n "Id":5819\n} + try: + content = json.loads(authentication_response.content.decode('utf-8')) + return content['@odata.id'].split('/')[-1] + except BaseException: + pass + + return None + + def connect(self): + if self.is_cache_enabled(): + return True + + if self.session_handler is not None: + return True + + start_time = int(time.time() * 1000) + self.session_handler = requests.Session() + + url = 'https://%s:%s/redfish/v1/SessionService/Sessions' % (self.endpoint_ip, self.endpoint_port) + data = {} + data['UserName'] = self.redfish_username + data['Password'] = self.redfish_password + + try: + response = self.session_handler.post( + url, + data=json.dumps(data), + verify=self.ssl_verify + ) + + except BaseException: + self.log.error( + 'connect', + 'Redfish authentication exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'connect', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'connect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + if response.status_code >= 300: + self.log.error( + 'connect', + 'Redfish authentication failed: %s %s %s' % ( + self.endpoint_ip, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'connect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + self.session_id = self.extract_session_id(response) + if self.session_id is None: + self.log.error( + 'connect', + 'Failed to get session_id from authentication response' + ) + self.log.debug( + 'connect', + 'Response headers: %s' % (str(response.headers)) + ) + self.log.debug( + 'connect', + 'Response content: %s' % (str(response.content)) + ) + return False + + self.session_token = response.headers['X-Auth-Token'] + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.debug( + 'connect', + 'Redfish connected to %s in %s ms' % (self.endpoint_ip, duration_ms) + ) + self.log.redfish( + 'connect %s' % (self.endpoint_ip), + True, + duration_ms + ) + + return True + + def disconnect(self): + if self.is_cache_enabled(): + return True + + if self.session_handler is None: + return True + + start_time = int(time.time() * 1000) + url = 'https://%s:%s/redfish/v1/SessionService/Sessions/%s' % ( + self.endpoint_ip, + self.endpoint_port, + self.session_id + ) + headers = {} + headers['X-Auth-Token'] = self.session_token + + success = True + try: + response = self.session_handler.delete( + url, + headers=headers, + verify=self.ssl_verify + ) + except BaseException: + success = False + + if not success: + try: + self.session_handler = requests.Session() + response = self.session_handler.delete( + url, + headers=headers, + verify=self.ssl_verify + ) + except BaseException: + self.log.error( + 'disconnect', + 'Redfish session close exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'disconnect', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'disconnect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + if response.status_code >= 300: + self.log.error( + 'disconnect', + 'Redfish session close failed: %s %s %s' % ( + self.endpoint_ip, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'disconnect %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + self.session_handler = None + self.session_id = None + self.session_token = None + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.debug( + 'disconnect', + 'Redfish disconnected from %s in %s ms' % (self.endpoint_ip, duration_ms) + ) + self.log.redfish( + 'disconnect %s' % (self.endpoint_ip), + True, + duration_ms + ) + + return True + + def patch(self, url, data=None): + if self.session_handler is None: + return False + + start_time = int(time.time() * 1000) + + headers = {} + headers['X-Auth-Token'] = self.session_token + + try: + if data is None: + response = self.session_handler.patch( + url, + headers=headers, + verify=self.ssl_verify + ) + else: + response = self.session_handler.patch( + url, + headers=headers, + data=json.dumps(data), + verify=self.ssl_verify + ) + + except BaseException: + self.log.error( + 'patch', + 'Redfish exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'patch', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'patch %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + if response.status_code >= 300: + self.log.error( + 'patch', + 'Redfish failed: %s %s %s' % ( + self.endpoint_ip, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'patch %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.debug( + 'patch', + 'Redfish patch successful to %s in %s ms' % (self.endpoint_ip, duration_ms) + ) + self.log.debug( + 'patch', + '%s %s %s' % ( + url, + response.status_code, + str(response.content) + ) + ) + self.log.redfish( + 'patch %s' % (self.endpoint_ip), + True, + duration_ms + ) + + return True + + def post(self, url, data=None): + if self.session_handler is None: + return False + + start_time = int(time.time() * 1000) + + headers = {} + headers['X-Auth-Token'] = self.session_token + + try: + if data is None: + response = self.session_handler.post( + url, + headers=headers, + verify=self.ssl_verify + ) + else: + response = self.session_handler.post( + url, + headers=headers, + data=json.dumps(data), + verify=self.ssl_verify + ) + + except BaseException: + self.log.error( + 'post', + 'Redfish exception: %s' % (self.endpoint_ip) + ) + + self.log.error( + 'post', + traceback.format_exc() + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'post %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + if response.status_code >= 300: + self.log.error( + 'post', + 'Redfish failed: %s %s %s' % ( + self.endpoint_ip, + response.status_code, + str(response.content) + ) + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.redfish( + 'post %s' % (self.endpoint_ip), + False, + duration_ms + ) + + return False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.debug( + 'post', + 'Redfish post successful to %s in %s ms' % (self.endpoint_ip, duration_ms) + ) + self.log.redfish( + 'post %s' % (self.endpoint_ip), + True, + duration_ms + ) + + return True diff --git a/lib/redfish/tree.py b/lib/redfish/tree.py new file mode 100644 index 00000000..25b25ea7 --- /dev/null +++ b/lib/redfish/tree.py @@ -0,0 +1,157 @@ +import time +import json + +from lib import log_helper + + +class RedfishTree(): + def __init__(self, endpoint_handler): + self.endpoint_handler = endpoint_handler + self.log = log_helper.Log() + + self.tree = {} + self.tree_root = None + self.tree_deep_search = False + self.tree_max_execution_time = 0 + self.tree_start_time = None + self.tree_max_execution_time_reached = False + + def initialize_tree(self, path, deep, max_time): + self.log.debug( + 'initalize_tree', + 'Initialize tree: %s %s %s' % (path, deep, max_time) + ) + + self.tree = {} + self.tree_root = self.endpoint_handler.path_fixup(path) + self.tree_deep_search = deep + self.tree_start_time = int(time.time()) + self.tree_max_execution_time = max_time + self.tree_max_execution_time_reached = False + + def find_odata_id(self, data): + # https://www.dmtf.org/sites/default/files/standards/documents/DSP2052_1.0.0.pdf + # section 2.2.3 + # + # odata.id may contain URI only e.g. /redfish/v1/Chassis/1/Power + # odata.id may cotain URI and JSON fragment identifier e.g. /redfish/v1/Chassis/1/Power + # the goal here is to find URI(s) only + # + items = [] + if data is None: + return items + + json_nice_output = json.dumps(data, indent=4) + for line in json_nice_output.split('\n'): + # get rid of all whitespaces + line = line.strip(' ').replace(' ', '') + + # search for "key":"value" lines + if len(line.split(':')) == 2: + # remove " from key and value" + (key, value) = line.split(':') + key = key.strip('"') + value = value.rstrip(',').strip('"') + + if key == '@odata.id': + # Make sure to get URI value only + if '#' in value: + value = value.split('#')[0] + + if value == '/redfish/v1': + value = '/redfish/v1/' + + value = self.endpoint_handler.path_fixup(value) + if value not in items: + items.append(value) + + return items + + def get_branch(self, branch): + self.log.debug( + 'get_branch', + 'Get branch: %s' % (branch) + ) + + # Make sure get_tree does not run for too long + if self.tree_max_execution_time > 0: + if int(time.time()) - self.tree_start_time > self.tree_max_execution_time: + self.tree_max_execution_time_reached = True + return + + # No need to duplicate + if branch in self.tree: + self.log.debug( + 'get_branch', + 'Branch already in the tree:%s' % (branch) + ) + return + + # Get JSON properties of branch URI + self.tree[branch] = self.endpoint_handler.get_properties(branch) + if self.tree[branch] is None: + self.log.debug( + 'get_branch', + 'Branch properties not found: %s' % (branch) + ) + return + + # Find all odata.id references in JSON properties + leaves = self.find_odata_id( + self.tree[branch] + ) + + if not self.tree_deep_search: + # If no deep search/walk in redfish api tree, just note the existence of leaves (children) and exit + for leaf in leaves: + self.log.debug( + 'get_branch', + 'No deep search: %s' % (leaf) + ) + self.tree[leaf] = None + + return + + # Now the recursion... + for leaf in leaves: + # Make sure to only recurse withing the tree_root + # For example if tree_root is 'Chassis/1' but odata.id reference is 'System/...' then we do not go there + # just note the existence of such leaf and exit + if not leaf.startswith(self.tree_root): + self.log.debug( + 'get_branch', + 'No deep outside of root: %s' % (leaf) + ) + self.tree[leaf] = None + continue + + # Do not go deep on excluded branches + if leaf in self.endpoint_handler.get_excluded_tree_uri(): + self.tree[leaf] = None + self.log.debug( + 'get_branch', + 'No deep direct match: %s' % (leaf) + ) + continue + + for excluded_tree_uri in self.endpoint_handler.get_excluded_tree_uri(): + if leaf.startswith(excluded_tree_uri): + self.tree[leaf] = None + self.log.debug( + 'get_branch', + 'No deep partial match: %s' % (leaf) + ) + continue + + # Let's go deeper in the tree... + self.get_branch(leaf) + + def get_tree(self): + self.get_branch( + self.tree_root + ) + + if self.tree_max_execution_time_reached: + return False + + return True diff --git a/lib/redfish/ucs_rack/__init__.py b/lib/redfish/ucs_rack/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/__pycache__/__init__.cpython-310.pyc b/lib/redfish/ucs_rack/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4d86d405 Binary files /dev/null and b/lib/redfish/ucs_rack/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/redfish/ucs_rack/__pycache__/endpoint.cpython-310.pyc b/lib/redfish/ucs_rack/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..c9d4c3cd Binary files /dev/null and b/lib/redfish/ucs_rack/__pycache__/endpoint.cpython-310.pyc differ diff --git a/lib/redfish/ucs_rack/__pycache__/identity.cpython-310.pyc b/lib/redfish/ucs_rack/__pycache__/identity.cpython-310.pyc new file mode 100644 index 00000000..fa90319d Binary files /dev/null and b/lib/redfish/ucs_rack/__pycache__/identity.cpython-310.pyc differ diff --git a/lib/redfish/ucs_rack/__pycache__/power.cpython-310.pyc b/lib/redfish/ucs_rack/__pycache__/power.cpython-310.pyc new file mode 100644 index 00000000..611ea6a2 Binary files /dev/null and b/lib/redfish/ucs_rack/__pycache__/power.cpython-310.pyc differ diff --git a/lib/redfish/ucs_rack/__pycache__/template.cpython-310.pyc b/lib/redfish/ucs_rack/__pycache__/template.cpython-310.pyc new file mode 100644 index 00000000..bf974ab3 Binary files /dev/null and b/lib/redfish/ucs_rack/__pycache__/template.cpython-310.pyc differ diff --git a/lib/redfish/ucs_rack/__pycache__/thermal.cpython-310.pyc b/lib/redfish/ucs_rack/__pycache__/thermal.cpython-310.pyc new file mode 100644 index 00000000..003c6613 Binary files /dev/null and b/lib/redfish/ucs_rack/__pycache__/thermal.cpython-310.pyc differ diff --git a/lib/redfish/ucs_rack/account/__init__.py b/lib/redfish/ucs_rack/account/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/account/main.py b/lib/redfish/ucs_rack/account/main.py new file mode 100644 index 00000000..2da1c12a --- /dev/null +++ b/lib/redfish/ucs_rack/account/main.py @@ -0,0 +1,87 @@ +class RedfishEndpointUcsRackAccount(): + def __init__(self): + self.accounts = None + + def get_accounts(self, include_disabled=False, cache_enabled=True): + if cache_enabled and self.accounts is not None: + return self.accounts + + self.accounts = self.get_template_account_properties( + role_info=True, + include_disabled=include_disabled, + cache_enabled=False + ) + return self.accounts + + def get_account_by_username(self, username, cache_enabled=True): + accounts = self.get_accounts(cache_enabled=cache_enabled) + if accounts is None: + return None + + for account in accounts: + if account['username'] == username: + return account + + return None + + def is_account_username(self, username, cache_enabled=True): + if self.get_account_by_username(username, cache_enabled=cache_enabled): + return True + return False + + def get_account_empty_ids(self, cache_enabled=False): + accounts = self.get_accounts(cache_enabled=cache_enabled) + if accounts is None: + return None + + account_ids = [] + for account in accounts: + account_ids.append( + account['id'] + ) + + empty_ids = [] + for account_id in range(1, 15): + if str(account_id) not in account_ids: + empty_ids.append( + str(account_id) + ) + + return empty_ids + + def get_account_empty_id(self, cache_enabled=False): + accounts = self.get_accounts(cache_enabled=cache_enabled) + if accounts is None: + return None + + account_ids = [] + for account in accounts: + account_ids.append( + account['id'] + ) + + for account_id in range(1, 15): + if str(account_id) not in account_ids: + return str(account_id) + + return None + + def get_non_admin_role_usernames(self, allowed_usernames=[]): + accounts = self.get_accounts(cache_enabled=False) + if accounts is None: + return None + + usernames = [] + for account in accounts: + if account['username'] in allowed_usernames: + usernames.append( + account['username'] + ) + continue + + if account['role_id'] != 'admin': + usernames.append( + account['username'] + ) + + return usernames diff --git a/lib/redfish/ucs_rack/endpoint.py b/lib/redfish/ucs_rack/endpoint.py new file mode 100644 index 00000000..77b6ee84 --- /dev/null +++ b/lib/redfish/ucs_rack/endpoint.py @@ -0,0 +1,179 @@ +import time + +from lib.redfish.standard.endpoint import RedfishEndpointStandard +from lib.redfish.ucs_rack.account.main import RedfishEndpointUcsRackAccount +from lib.redfish.ucs_rack.template.main import RedfishEndpointUcsRackTemplate + + +class RedfishEndpointUcsRack( + RedfishEndpointStandard, + RedfishEndpointUcsRackAccount, + RedfishEndpointUcsRackTemplate + ): + def __init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=None, + cache_filename=None, + auto_connect=True, + get_timeout=10, + ssl_verify=False, + deep_search_exlusions=True, + log_id=None + ): + RedfishEndpointStandard.__init__( + self, + endpoint_handler, + endpoint_ip, + endpoint_port, + redfish_username, + redfish_password, + system_id=system_id, + cache_filename=cache_filename, + auto_connect=auto_connect, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=deep_search_exlusions, + log_id=log_id + ) + RedfishEndpointUcsRackAccount.__init__(self) + RedfishEndpointUcsRackTemplate.__init__( + self, + endpoint_handler + ) + + self.endpoint_type = 'ucsc' + self.default_chassis_uri = '/redfish/v1/Chassis/1' + self.chassis_uri = None + + def __del__(self): + self.disconnect() + + def get_chassis_uri(self): + if self.chassis_uri is not None: + return self.chassis_uri + + uri = '/redfish/v1/Chassis' + children = self.endpoint_handler.get_odata_ids(uri) + if children is None: + self.log.error( + 'get_chassis_uri', + 'Failed to discover Chassis: %s' % (uri) + ) + return self.default_chassis_uri + + chassis_uri = None + for child in children: + if child == uri: + continue + + leaf = child.split('/')[-1] + if leaf == 'CMC': + continue + + chassis_uri = child + break + + if chassis_uri is None: + self.log.error( + 'get_chassis_uri', + 'Failed to find Chassis: %s' % (uri) + ) + return self.default_chassis_uri + + self.chassis_uri = chassis_uri + return chassis_uri + + def get_excluded_tree_uri(self): + if not self.deep_search_exclusions: + return [] + + system_id = self.get_system_id() + + uri = [ + '/redfish/v1/JsonSchemas', + '%s/LogServices' % (self.get_chassis_uri()), + '/redfish/v1/Chassis/CMC/LogServices', + '/redfish/v1/SessionService', + '/redfish/v1/Managers/CIMC/LogServices', + '/redfish/v1/Systems/%s/LogServices' % (system_id) + ] + + return uri + + def get_virtual_media(self, virtual_media_id=0): + path = 'Managers/CIMC/VirtualMedia/%s' % (virtual_media_id) + response = self.get_properties(path) + return response + + def is_virtual_media_defined(self, virtual_media_id=0): + response = self.get_virtual_media(virtual_media_id=virtual_media_id) + if response is None: + return False + + if response['ConnectedVia'] == 'NotConnected': + return False + + return True + + def is_virtual_media_inserted(self, virtual_media_id=0): + response = self.get_virtual_media(virtual_media_id=virtual_media_id) + if response is None: + return False + return response['Inserted'] + + def wait_virtual_media_inserted(self, virtual_media_id=0, timeout=30): + start_time = int(time.time()) + while True: + if self.is_virtual_media_inserted(virtual_media_id=virtual_media_id): + return True + + time.sleep(5) + + if int(time.time()) - start_time > timeout: + return False + + def insert_media_http(self, iso_url, virtual_media_id=0, protocol='HTTP', safe=True): + if safe: + if self.is_virtual_media_defined(virtual_media_id=virtual_media_id): + if not self.eject_media(virtual_media_id=virtual_media_id): + return False + + url = 'https://%s:%s/redfish/v1/Managers/CIMC/VirtualMedia/%s/Actions/VirtualMedia.InsertMedia' % (self.endpoint_ip, self.endpoint_port, virtual_media_id) + + data = {} + data['Image'] = iso_url + data['WriteProtected'] = True + data['TransferProtocolType'] = protocol + data['TransferMethod'] = 'Stream' + data['Inserted'] = True + + return self.post(url, data=data) + + def eject_media(self, virtual_media_id=0): + url = 'https://%s:%s/redfish/v1/Managers/CIMC/VirtualMedia/%s/Actions/VirtualMedia.EjectMedia' % (self.endpoint_ip, self.endpoint_port, virtual_media_id) + return self.post(url) + + def set_one_time_boot_source(self, target): + system_id = self.get_system_id() + url = 'https://%s:%s/redfish/v1/Systems/%s' % (self.endpoint_ip, self.endpoint_port, system_id) + + data = {} + data['Boot'] = {} + data['Boot']['BootSourceOverrideTarget'] = target + data['Boot']['BootSourceOverrideEnabled'] = 'Once' + + return self.patch(url, data=data) + + def power_cycle(self): + system_id = self.get_system_id() + url = 'https://%s:%s/redfish/v1/Systems/%s/Actions/ComputerSystem.Reset' % (self.endpoint_ip, self.endpoint_port, system_id) + + data = {} + data['ResetType'] = 'PowerCycle' + + return self.post(url, data=data) diff --git a/lib/redfish/ucs_rack/output.py b/lib/redfish/ucs_rack/output.py new file mode 100644 index 00000000..fa3eb83f --- /dev/null +++ b/lib/redfish/ucs_rack/output.py @@ -0,0 +1,54 @@ +from lib.redfish.ucs_rack.template.output import RedfishEndpointUcsRackTemplateOutput + + +class RedfishEndpointUcsRackOutput( + RedfishEndpointUcsRackTemplateOutput + ): + def __init__(self): + RedfishEndpointUcsRackTemplateOutput.__init__(self) + + def print_ucsc_properties(self, template_name, properties, title=False): + if template_name == 'account': + self.print_ucsc_account_properties(properties, title=title) + + if template_name == 'bios': + self.print_ucsc_bios_properties(properties, title=title) + + if template_name == 'bios-diff': + self.print_ucsc_bios_diff_properties(properties, title=title) + + if template_name == 'cpu': + self.print_ucsc_cpu_properties(properties, title=title) + + if template_name == 'fan': + self.print_ucsc_fan_properties(properties, title=title) + + if template_name == 'gpu': + self.print_ucsc_gpu_properties(properties, title=title) + + if template_name == 'identity': + self.print_ucsc_identity_properties(properties) + + if template_name == 'mem': + self.print_ucsc_mem_properties(properties, title=title) + + if template_name == 'net': + self.print_ucsc_net_properties(properties, title=title) + + if template_name == 'pci': + self.print_ucsc_pci_properties(properties, title=title) + + if template_name == 'power': + self.print_ucsc_power_properties(properties) + + if template_name == 'psu': + self.print_ucsc_psu_properties(properties, title=title) + + if template_name == 'role': + self.print_ucsc_role_properties(properties, title=title) + + if template_name == 'storage': + self.print_ucsc_storage_properties(properties) + + if template_name == 'thermal': + self.print_ucsc_thermal_properties(properties) diff --git a/lib/redfish/ucs_rack/template/__init__.py b/lib/redfish/ucs_rack/template/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/account/__init__.py b/lib/redfish/ucs_rack/template/account/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/account/main.py b/lib/redfish/ucs_rack/template/account/main.py new file mode 100644 index 00000000..f3044934 --- /dev/null +++ b/lib/redfish/ucs_rack/template/account/main.py @@ -0,0 +1,131 @@ +class RedfishEndpointUcsRackTemplateAccount(): + def __init__(self): + self.account_uri = '/redfish/v1/AccountService/Accounts' + self.account = None + + def get_account_uri(self): + return self.defult_account_uri + + def get_account_mo(self, cache_enabled=True): + if cache_enabled: + if self.account is not None: + return self.account + + account_uris = self.endpoint_handler.get_odata_ids(self.account_uri) + if account_uris is None: + return None + + self.account = [] + for account_uri in account_uris: + if account_uri == self.account_uri: + continue + + account_info = self.get_account_info( + account_uri + ) + + self.account.append( + account_info + ) + + return self.account + + def get_account_info(self, uri): + info = {} + info['__Output'] = {} + info['Uri'] = uri + + data = self.get_properties(uri) + + info['id'] = self.get_property_value( + data, + 'Id' + ) + + info['role_id'] = self.get_property_value( + data, + 'RoleId' + ) + + info['name'] = self.get_property_value( + data, + 'Name' + ) + + info['description'] = self.get_property_value( + data, + 'Description' + ) + + info['username'] = self.get_property_value( + data, + 'UserName' + ) + + info['enabled'] = self.get_property_value( + data, + 'Enabled' + ) + + if info['enabled']: + info['enabledTick'] = '\u2713' + info['__Output']['enabledTick'] = 'Green' + else: + info['enabledTick'] = '\u2717' + info['__Output']['enabledTick'] = 'Red' + + info['change_required'] = self.get_property_value( + data, + 'PasswordChangeRequired' + ) + + if info['change_required']: + info['changeTick'] = '\u2713' + info['__Output']['changeTick'] = 'Red' + else: + info['changeTick'] = '\u2717' + info['__Output']['changeTick'] = 'Green' + + info['type'] = self.get_property_value( + data, + 'AccountTypes' + ) + + return info + + def get_template_account_properties(self, role_info=False, include_disabled=False, cache_enabled=True): + all_accounts = self.get_account_mo(cache_enabled=cache_enabled) + if all_accounts is None: + return None + + accounts = [] + for account in all_accounts: + if not account['enabled'] and not include_disabled: + continue + + if role_info: + account_role_info = self.get_role_by_id( + account['role_id'] + ) + if account_role_info is None: + account['privileges'] = [] + account['oem'] = [] + else: + account['privileges'] = account_role_info['privileges'] + account['oem'] = account_role_info['oem'] + + accounts.append( + account + ) + + return accounts + + def get_accounts_with_role_id(self, role_id): + accounts = self.get_template_account_properties() + role_accounts = [] + for account in accounts: + if account['role_id'] == role_id: + role_accounts.append( + account + ) + return role_accounts diff --git a/lib/redfish/ucs_rack/template/account/output.py b/lib/redfish/ucs_rack/template/account/output.py new file mode 100644 index 00000000..cb2b6d68 --- /dev/null +++ b/lib/redfish/ucs_rack/template/account/output.py @@ -0,0 +1,59 @@ +class RedfishEndpointUcsRackTemplateAccountOutput( + ): + def __init__(self): + pass + + def print_ucsc_account_properties(self, info, title=False): + if title: + self.my_output.default( + 'Account [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + + for item in info: + if len(item['privileges']) == 0: + item['privileges'].append('--') + if len(item['oem']) == 0: + item['oem'].append('--') + + order = [ + 'username', + 'id', + 'role_id', + 'name', + 'description', + 'enabledTick', + 'changeTick', + 'privileges', + 'oem' + ] + + headers = [ + 'Username', + 'Id', + 'Role Id', + 'Name', + 'Description', + 'Enabled', + 'Change Req', + 'Role Privileges', + 'Role Oem Privileges' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['privileges', 'oem'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/bios/__init__.py b/lib/redfish/ucs_rack/template/bios/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/bios/main.py b/lib/redfish/ucs_rack/template/bios/main.py new file mode 100644 index 00000000..10ce43fb --- /dev/null +++ b/lib/redfish/ucs_rack/template/bios/main.py @@ -0,0 +1,42 @@ +class RedfishEndpointUcsRackTemplateBios(): + def __init__(self): + self.default_bios_uri = '/redfish/v1/Systems/SYSTEM_ID/Bios' + self.bios = None + + def get_bios_uri(self): + return self.path_fixup(self.default_bios_uri) + + def get_bios_mo(self, cache_enabled=True): + if cache_enabled: + if self.bios is not None: + return self.bios + + bios_mo = self.get_properties( + self.get_bios_uri() + ) + if bios_mo is None: + return None + + self.bios = self.get_property_value( + bios_mo, + 'Attributes' + ) + + return self.bios + + def get_bios_info(self, bios_mo): + info = {} + for key in bios_mo: + info[key] = bios_mo[key] + return info + + def get_template_bios_properties(self, cache_enabled=True): + bios_mo = self.get_bios_mo(cache_enabled=cache_enabled) + if bios_mo is None: + return None + + bios_info = self.get_bios_info( + bios_mo + ) + + return bios_info diff --git a/lib/redfish/ucs_rack/template/bios/output.py b/lib/redfish/ucs_rack/template/bios/output.py new file mode 100644 index 00000000..70cc70ac --- /dev/null +++ b/lib/redfish/ucs_rack/template/bios/output.py @@ -0,0 +1,98 @@ +class RedfishEndpointUcsRackTemplateBiosOutput( + ): + def __init__(self): + pass + + def print_ucsc_bios_properties(self, info_dict, title=False): + info = [] + for key in info_dict: + if key not in ['__Output']: + item = {} + item['key'] = key + item['value'] = info_dict[key] + info.append(item) + + info = sorted( + info, + key=lambda i: i['key'].lower() + ) + + if title: + self.my_output.default( + 'Bios [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + + order = [ + 'key', + 'value' + ] + + headers = [ + 'Key', + 'Value' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) + + def print_ucsc_bios_diff_properties(self, info, title=False): + order = [ + 'key' + ] + headers = [ + 'Key' + ] + for server_ip in info: + order.append(server_ip) + headers.append(server_ip) + + bios_key = [] + for server_ip in info: + for key in info[server_ip]: + if key not in bios_key: + bios_key.append(key) + + bios_key = sorted(bios_key) + + bios_values = [] + for key in bios_key: + item = {} + item['key'] = key + for server_ip in info: + if key not in info[server_ip]: + item[server_ip] = '--' + else: + item[server_ip] = info[server_ip][key] + + bios_values.append( + item + ) + + if title: + self.my_output.default( + 'Bios [#%s]' % (len(bios_values)), + underline=True, + before_newline=True + ) + + self.my_output.my_table( + bios_values, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/cpu/__init__.py b/lib/redfish/ucs_rack/template/cpu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/cpu/main.py b/lib/redfish/ucs_rack/template/cpu/main.py new file mode 100644 index 00000000..d5a2a9cb --- /dev/null +++ b/lib/redfish/ucs_rack/template/cpu/main.py @@ -0,0 +1,124 @@ +class RedfishEndpointUcsRackTemplateCpu(): + def __init__(self): + self.defult_cpu_uri = '/redfish/v1/Systems/SYSTEM_ID/Processors' + self.cpu = None + + def get_cpu_uri(self): + return self.path_fixup(self.defult_cpu_uri) + + def get_processors_uri(self): + uri = self.get_cpu_uri() + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_processor_info(self, uri): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + keys = [ + 'Id', + 'InstructionSet', + 'Manufacturer', + 'MaxSpeedMHz', + 'Model', + 'Name', + 'ProcessorArchitecture', + 'ProcessorType', + 'Socket', + 'TotalCores', + 'TotalEnabledCores', + 'TotalThreads' + ] + for key in keys: + info[key] = self.get_property_value( + data, + key + ) + + if info['ProcessorType'] not in ['CPU']: + return None + + info['Health'] = self.get_property_value( + data, + 'Status:Health' + ) + info['__Output']['Health'] = 'Red' + if info['Health'] == 'OK': + info['__Output']['Health'] = 'Green' + + info['State'] = self.get_property_value( + data, + 'Status:State' + ) + info['__Output']['State'] = 'Red' + if info['State'] == 'Enabled': + info['__Output']['State'] = 'Green' + + info['EffectiveFamily'] = self.get_property_value( + data, + 'ProcessorId:EffectiveFamily' + ) + + info['EffectiveModel'] = self.get_property_value( + data, + 'ProcessorId:EffectiveModel' + ) + + info['Step'] = self.get_property_value( + data, + 'ProcessorId:Step' + ) + + info['VendorId'] = self.get_property_value( + data, + 'ProcessorId:VendorId' + ) + + return info + + def get_processors_info(self, cache_enabled=True): + if cache_enabled and self.cpu is not None: + return self.cpu + + self.cpu = [] + processors_uri = self.get_processors_uri() + for processor_uri in processors_uri: + processor_info = self.get_processor_info( + processor_uri + ) + if processor_info is not None: + self.cpu.append( + processor_info + ) + + self.cpu = sorted( + self.cpu, + key=lambda i: i['Id'] + ) + + return self.cpu + + def get_template_cpu_properties(self, cache_enabled=True): + all_properties = self.get_processors_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/cpu/output.py b/lib/redfish/ucs_rack/template/cpu/output.py new file mode 100644 index 00000000..3b614ad4 --- /dev/null +++ b/lib/redfish/ucs_rack/template/cpu/output.py @@ -0,0 +1,55 @@ +class RedfishEndpointUcsRackTemplateCpuOutput( + ): + def __init__(self): + pass + + def print_ucsc_cpu_properties(self, info, title=False): + if title: + self.my_output.default( + 'CPU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'Id', + 'Socket', + 'Health', + 'State', + 'Model', + 'TotalCores', + 'TotalThreads', + 'ProcessorArchitecture', + 'InstructionSet', + 'Manufacturer', + 'MaxSpeedMHz', + 'Step' + ] + + headers = [ + 'Id', + 'Socket', + 'Health', + 'State', + 'Model', + 'Cores', + 'Threads', + 'Arch', + 'Instruction', + 'Manufacturer', + 'Speed [MHz]', + 'Step' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=True, + underline=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/fan/__init__.py b/lib/redfish/ucs_rack/template/fan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/fan/main.py b/lib/redfish/ucs_rack/template/fan/main.py new file mode 100644 index 00000000..72916a43 --- /dev/null +++ b/lib/redfish/ucs_rack/template/fan/main.py @@ -0,0 +1,91 @@ +class RedfishEndpointUcsRackTemplateFan(): + def __init__(self): + self.fan_uri = '/redfish/v1/Chassis/1/Thermal' + self.fan = None + + def get_fans_uri(self): + uri = self.fan_uri + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_fan_info(self, fan_mo): + info = {} + info['__Output'] = {} + + keys = [ + 'MemberId', + 'Name', + 'ReadingUnits', + 'Reading' + ] + for key in keys: + info[key] = self.get_property_value( + fan_mo, + key + ) + + try: + info['_index'] = int(info['MemberId']) + except BaseException: + info['_index'] = -1 + + info['Health'] = self.get_property_value( + fan_mo, + 'Status:Health' + ) + info['__Output']['Health'] = 'Red' + if info['Health'] == 'OK': + info['__Output']['Health'] = 'Green' + + info['State'] = self.get_property_value( + fan_mo, + 'Status:State' + ) + info['__Output']['State'] = 'Red' + if info['State'] == 'Enabled': + info['__Output']['State'] = 'Green' + + return info + + def get_fans_info(self, cache_enabled=True): + if cache_enabled and self.fan is not None: + return self.fan + + self.fan = [] + fans_mo = self.get_properties(self.fan_uri) + if fans_mo is not None and 'Fans' in fans_mo: + for fan_mo in fans_mo['Fans']: + fan_info = self.get_fan_info( + fan_mo + ) + self.fan.append( + fan_info + ) + + self.fan = sorted( + self.fan, + key=lambda i: i['_index'] + ) + + return self.fan + + def get_template_fan_properties(self, cache_enabled=True): + all_properties = self.get_fans_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/fan/output.py b/lib/redfish/ucs_rack/template/fan/output.py new file mode 100644 index 00000000..74557036 --- /dev/null +++ b/lib/redfish/ucs_rack/template/fan/output.py @@ -0,0 +1,45 @@ +class RedfishEndpointUcsRackTemplateFanOutput( + ): + def __init__(self): + pass + + def print_ucsc_fan_properties(self, info, title=False): + if title: + self.my_output.default( + 'Fan [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'MemberId', + 'Name', + 'State', + 'Health', + 'Reading', + 'ReadingUnits' + + ] + + headers = [ + 'Id', + 'Name', + 'State', + 'Health', + 'Reading', + 'Units' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/gpu/__init__.py b/lib/redfish/ucs_rack/template/gpu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/gpu/main.py b/lib/redfish/ucs_rack/template/gpu/main.py new file mode 100644 index 00000000..785cd942 --- /dev/null +++ b/lib/redfish/ucs_rack/template/gpu/main.py @@ -0,0 +1,83 @@ +class RedfishEndpointUcsRackTemplateGpu(): + def __init__(self): + self.defult_gpu_uri = '/redfish/v1/Systems/SYSTEM_ID/Processors' + self.gpu = None + + def get_gpu_uri(self): + return self.path_fixup(self.defult_gpu_uri) + + def get_gpus_uri(self): + uri = self.get_gpu_uri() + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_gpu_info(self, uri): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + keys = [ + 'Id', + 'ProcessorType', + 'Description', + 'Name', + 'Model', + 'SerialNumber', + 'FirmwareVersion' + ] + for key in keys: + info[key] = self.get_property_value( + data, + key + ) + + if info['ProcessorType'] not in ['GPU']: + return None + + return info + + def get_gpus_info(self, cache_enabled=True): + if cache_enabled and self.gpu is not None: + return self.gpu + + self.gpu = [] + gpus_uri = self.get_gpus_uri() + for gpu_uri in gpus_uri: + gpu_info = self.get_gpu_info( + gpu_uri + ) + if gpu_info is not None: + self.gpu.append( + gpu_info + ) + + self.gpu = sorted( + self.gpu, + key=lambda i: i['Id'] + ) + + return self.gpu + + def get_template_gpu_properties(self, cache_enabled=True): + all_properties = self.get_gpus_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/gpu/output.py b/lib/redfish/ucs_rack/template/gpu/output.py new file mode 100644 index 00000000..e322fa05 --- /dev/null +++ b/lib/redfish/ucs_rack/template/gpu/output.py @@ -0,0 +1,41 @@ +class RedfishEndpointUcsRackTemplateGpuOutput( + ): + def __init__(self): + pass + + def print_ucsc_gpu_properties(self, info, title=False): + if title: + self.my_output.default( + 'GPU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + + order = [ + 'Id', + 'Name', + 'Model', + 'SerialNumber', + 'FirmwareVersion' + ] + + headers = [ + 'Id', + 'Name', + 'Model', + 'SerialNumber', + 'FirmwareVersion' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/identity/__init__.py b/lib/redfish/ucs_rack/template/identity/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/identity/main.py b/lib/redfish/ucs_rack/template/identity/main.py new file mode 100644 index 00000000..67245107 --- /dev/null +++ b/lib/redfish/ucs_rack/template/identity/main.py @@ -0,0 +1,72 @@ +import uuid + + +class RedfishEndpointUcsRackTemplateIdentity(): + def __init__(self): + self.identity_main_url = '/' + self.identity_system_url = '/Systems/%s' % (self.get_system_id()) + self.identity_firmware_url = '/UpdateService/FirmwareInventory/CIMC' + + def get_identity_default_cache_name(self, properties): + for key in ['Firmware', 'SerialNumber', 'PowerState', 'Product']: + if key not in properties: + return None + + firmware = properties['Firmware'] + if len(firmware) > 0: + firmware = firmware.replace('(', '.').replace(')', '') + + product = properties['Product'].replace('UCSC-', '').replace('UCSS-', '').replace(' ', '-') + + name = 'ucsc-%s-%s-%s-%s' % ( + product.lower(), + properties['SerialNumber'].lower(), + firmware.lower(), + properties['PowerState'].lower() + ) + return name + + def get_template_identity_properties(self): + main = self.get_properties(self.identity_main_url) + system = self.get_properties(self.identity_system_url) + firmware = self.get_properties(self.identity_firmware_url) + + if main is None: + return None + + properties = {} + properties['Product'] = main['Product'] + properties['Vendor'] = main['Vendor'] + properties['RedfishVersion'] = main['RedfishVersion'] + + if system is not None: + keys = [ + 'SerialNumber', + 'PowerState', + 'HostName', + 'UUID', + 'Name', + 'BiosVersion', + 'Model' + + ] + for key in keys: + properties[key] = '' + if key in system: + properties[key] = system[key] + + properties['Firmware'] = '' + if firmware is not None: + if 'Version' in firmware: + properties['Firmware'] = firmware['Version'] + + properties['DefaultCacheName'] = self.get_identity_default_cache_name(properties) + if properties['DefaultCacheName'] is None: + properties['DefaultCacheName'] = str(uuid.uuid4()).lower() + + if 'UUID' not in properties or properties['UUID'] == '': + properties['CacheFileName'] = str(uuid.uuid4()).lower() + else: + properties['CacheFileName'] = properties['UUID'].lower() + + return properties diff --git a/lib/redfish/ucs_rack/template/identity/output.py b/lib/redfish/ucs_rack/template/identity/output.py new file mode 100644 index 00000000..55c59b44 --- /dev/null +++ b/lib/redfish/ucs_rack/template/identity/output.py @@ -0,0 +1,43 @@ +class RedfishEndpointUcsRackTemplateIdentityOutput( + ): + def __init__(self): + pass + + def print_ucsc_identity_properties(self, properties): + keys = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'HostName', + 'SerialNumber', + 'UUID', + 'BiosVersion', + 'Firmware', + 'PowerState', + 'RedfishVersion' + ] + + headers = [ + 'Product', + 'Vendor', + 'Model', + 'Name', + 'Hostname', + 'Serial Number', + 'UUID', + 'Bios Version', + 'Firmware', + 'Power State', + 'Redfish Version' + ] + + self.my_output.dictionary( + properties, + title='UCS Rack Redfish Endpoint', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) diff --git a/lib/redfish/ucs_rack/template/main.py b/lib/redfish/ucs_rack/template/main.py new file mode 100644 index 00000000..b57ab8b2 --- /dev/null +++ b/lib/redfish/ucs_rack/template/main.py @@ -0,0 +1,123 @@ +import time + +from lib.redfish.ucs_rack.template.account.main import RedfishEndpointUcsRackTemplateAccount +from lib.redfish.ucs_rack.template.bios.main import RedfishEndpointUcsRackTemplateBios +from lib.redfish.ucs_rack.template.cpu.main import RedfishEndpointUcsRackTemplateCpu +from lib.redfish.ucs_rack.template.fan.main import RedfishEndpointUcsRackTemplateFan +from lib.redfish.ucs_rack.template.gpu.main import RedfishEndpointUcsRackTemplateGpu +from lib.redfish.ucs_rack.template.identity.main import RedfishEndpointUcsRackTemplateIdentity +from lib.redfish.ucs_rack.template.mem.main import RedfishEndpointUcsRackTemplateMem +from lib.redfish.ucs_rack.template.net.main import RedfishEndpointUcsRackTemplateNet +from lib.redfish.ucs_rack.template.pci.main import RedfishEndpointUcsRackTemplatePci +from lib.redfish.ucs_rack.template.power.main import RedfishEndpointUcsRackTemplatePower +from lib.redfish.ucs_rack.template.psu.main import RedfishEndpointUcsRackTemplatePsu +from lib.redfish.ucs_rack.template.role.main import RedfishEndpointUcsRackTemplateRole +from lib.redfish.ucs_rack.template.storage.main import RedfishEndpointUcsRackTemplateStorage +from lib.redfish.ucs_rack.template.thermal.main import RedfishEndpointUcsRackTemplateThermal + + +class RedfishEndpointUcsRackTemplate( + RedfishEndpointUcsRackTemplateAccount, + RedfishEndpointUcsRackTemplateBios, + RedfishEndpointUcsRackTemplateCpu, + RedfishEndpointUcsRackTemplateFan, + RedfishEndpointUcsRackTemplateGpu, + RedfishEndpointUcsRackTemplateIdentity, + RedfishEndpointUcsRackTemplateMem, + RedfishEndpointUcsRackTemplateNet, + RedfishEndpointUcsRackTemplatePci, + RedfishEndpointUcsRackTemplatePower, + RedfishEndpointUcsRackTemplatePsu, + RedfishEndpointUcsRackTemplateRole, + RedfishEndpointUcsRackTemplateStorage, + RedfishEndpointUcsRackTemplateThermal + ): + def __init__(self, endpoint_handler): + self.endpoint_handler = endpoint_handler + + RedfishEndpointUcsRackTemplateAccount.__init__(self) + RedfishEndpointUcsRackTemplateBios.__init__(self) + RedfishEndpointUcsRackTemplateCpu.__init__(self) + RedfishEndpointUcsRackTemplateFan.__init__(self) + RedfishEndpointUcsRackTemplateGpu.__init__(self) + RedfishEndpointUcsRackTemplateIdentity.__init__(self) + RedfishEndpointUcsRackTemplateMem.__init__(self) + RedfishEndpointUcsRackTemplateNet.__init__(self) + RedfishEndpointUcsRackTemplatePci.__init__(self) + RedfishEndpointUcsRackTemplatePower.__init__(self) + RedfishEndpointUcsRackTemplatePsu.__init__(self) + RedfishEndpointUcsRackTemplateRole.__init__(self) + RedfishEndpointUcsRackTemplateStorage.__init__(self) + RedfishEndpointUcsRackTemplateThermal.__init__(self) + + def get_template_properties(self, template_name, cache_enabled=True, cache_key=None, cache_ttl=0): + if cache_enabled and cache_key is not None: + self.set_system_id( + cache_key + ) + properties = self.endpoint_handler.endpoint_settings_handler.get_endpoint_settings( + cache_key, + filename=template_name + ) + if properties is not None: + if cache_ttl == 0: + return properties['data'] + if int(time.time()) - properties['timestamp'] < cache_ttl: + return properties['data'] + + properties = None + if template_name == 'account': + properties = self.get_template_account_properties(role_info=True, cache_enabled=cache_enabled) + + if template_name == 'bios': + properties = self.get_template_bios_properties(cache_enabled=cache_enabled) + + if template_name == 'cpu': + properties = self.get_template_cpu_properties(cache_enabled=cache_enabled) + + if template_name == 'fan': + properties = self.get_template_fan_properties(cache_enabled=cache_enabled) + + if template_name == 'gpu': + properties = self.get_template_gpu_properties(cache_enabled=cache_enabled) + + if template_name == 'identity': + properties = self.get_template_identity_properties() + + if template_name == 'mem': + properties = self.get_template_mem_properties(cache_enabled=cache_enabled) + + if template_name == 'net': + properties = self.get_template_net_properties(cache_enabled=cache_enabled) + + if template_name == 'pci': + properties = self.get_template_pci_properties(cache_enabled=cache_enabled) + + if template_name == 'power': + properties = self.get_template_power_properties() + + if template_name == 'psu': + properties = self.get_template_psu_properties(cache_enabled=cache_enabled) + + if template_name == 'role': + properties = self.get_template_role_properties(account_info=True, cache_enabled=cache_enabled) + + if template_name == 'storage': + properties = self.get_template_storage_properties() + + if template_name == 'thermal': + properties = self.get_template_thermal_properties() + + if properties is not None: + if cache_enabled and cache_key is not None: + cache_entry = {} + cache_entry['timestamp'] = int(time.time()) + cache_entry['data'] = properties + + self.endpoint_handler.endpoint_settings_handler.set_endpoint_settings( + cache_key, + cache_entry, + filename=template_name + ) + + return properties diff --git a/lib/redfish/ucs_rack/template/mem/__init__.py b/lib/redfish/ucs_rack/template/mem/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/mem/main.py b/lib/redfish/ucs_rack/template/mem/main.py new file mode 100644 index 00000000..16203ac6 --- /dev/null +++ b/lib/redfish/ucs_rack/template/mem/main.py @@ -0,0 +1,122 @@ +class RedfishEndpointUcsRackTemplateMem(): + def __init__(self): + self.defult_mem_uri = '/redfish/v1/Systems/SYSTEM_ID/Memory' + self.mem = None + + def get_mem_uri(self): + return self.path_fixup(self.defult_mem_uri) + + def get_mems_uri(self): + uri = self.get_mem_uri() + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_mem_info(self, uri): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + keys = [ + 'Id', + 'CapacityMiB', + 'Description', + 'DeviceLocator', + 'Manufacturer', + 'MemoryDeviceType', + 'MemoryType', + 'Name', + 'OperatingSpeedMhz', + 'OperatingMemoryModes', + 'SecurityCapabilities', + 'PartNumber', + 'SerialNumber' + ] + for key in keys: + info[key] = self.get_property_value( + data, + key + ) + + try: + info['_index'] = int(info['Id']) + except BaseException: + info['_index'] = -1 + + info['Health'] = self.get_property_value( + data, + 'Status:Health' + ) + info['__Output']['Health'] = 'Red' + if info['Health'] == 'OK': + info['__Output']['Health'] = 'Green' + + info['State'] = self.get_property_value( + data, + 'Status:State' + ) + info['__Output']['State'] = 'Red' + if info['State'] == 'Enabled': + info['__Output']['State'] = 'Green' + + info['Channel'] = self.get_property_value( + data, + 'MemoryLocation:Channel' + ) + + info['Slot'] = self.get_property_value( + data, + 'MemoryLocation:Slot' + ) + + info['Socket'] = self.get_property_value( + data, + 'MemoryLocation:Socket' + ) + + return info + + def get_mems_info(self, cache_enabled=True): + if cache_enabled and self.mem is not None: + return self.mem + + self.mem = [] + mems_uri = self.get_mems_uri() + for mem_uri in mems_uri: + mem_info = self.get_mem_info( + mem_uri + ) + if mem_info is not None: + self.mem.append( + mem_info + ) + + self.mem = sorted( + self.mem, + key=lambda i: i['_index'] + ) + + return self.mem + + def get_template_mem_properties(self, cache_enabled=True): + all_properties = self.get_mems_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/mem/output.py b/lib/redfish/ucs_rack/template/mem/output.py new file mode 100644 index 00000000..8ffefe81 --- /dev/null +++ b/lib/redfish/ucs_rack/template/mem/output.py @@ -0,0 +1,65 @@ +class RedfishEndpointUcsRackTemplateMemOutput( + ): + def __init__(self): + pass + + def print_ucsc_mem_properties(self, info, title=False, show_absent=False): + items = [] + for item in info: + if show_absent or item['State'] != 'Absent': + items.append( + item + ) + + if title: + self.my_output.default( + 'Memory [#%s]' % (len(items)), + underline=True, + before_newline=True + ) + + if len(items) == 0: + self.my_output.default('None') + return + + order = [ + 'Id', + 'Health', + 'State', + 'DeviceLocator', + 'CapacityMiB', + 'OperatingSpeedMhz', + 'Socket', + 'Slot', + 'Channel', + 'MemoryType', + 'MemoryDeviceType', + 'PartNumber', + 'SerialNumber' + ] + + headers = [ + 'Id', + 'Health', + 'State', + 'Locator', + 'CapacityMiB', + 'Speed [Mhz]', + 'Socket', + 'Slot', + 'Channel', + 'Type', + 'Device Type', + 'Part Number', + 'Serial Number' + ] + + self.my_output.my_table( + items, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/net/__init__.py b/lib/redfish/ucs_rack/template/net/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/net/main.py b/lib/redfish/ucs_rack/template/net/main.py new file mode 100644 index 00000000..32b02458 --- /dev/null +++ b/lib/redfish/ucs_rack/template/net/main.py @@ -0,0 +1,77 @@ +class RedfishEndpointUcsRackTemplateNet(): + def __init__(self): + self.defult_net_uri = '/redfish/v1/Systems/SYSTEM_ID/EthernetInterfaces' + self.net = None + + def get_net_uri(self): + return self.path_fixup(self.defult_net_uri) + + def get_nets_uri(self): + uri = self.get_net_uri() + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_net_info(self, uri): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + keys = [ + 'Id', + 'MACAddress', + 'Name', + 'PermanentMACAddress' + ] + for key in keys: + info[key] = self.get_property_value( + data, + key + ) + + return info + + def get_nets_info(self, cache_enabled=True): + if cache_enabled and self.net is not None: + return self.net + + self.net = [] + nets_uri = self.get_nets_uri() + for net_uri in nets_uri: + net_info = self.get_net_info( + net_uri + ) + if net_info is not None: + self.net.append( + net_info + ) + + self.net = sorted( + self.net, + key=lambda i: i['Id'] + ) + + return self.net + + def get_template_net_properties(self, cache_enabled=True): + all_properties = self.get_nets_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/net/output.py b/lib/redfish/ucs_rack/template/net/output.py new file mode 100644 index 00000000..0747c234 --- /dev/null +++ b/lib/redfish/ucs_rack/template/net/output.py @@ -0,0 +1,40 @@ +class RedfishEndpointUcsRackTemplateNetOutput( + ): + def __init__(self): + pass + + def print_ucsc_net_properties(self, info, title=False): + if title: + self.my_output.default( + 'Net [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'Id', + 'Name', + 'PermanentMACAddress', + 'MACAddress' + ] + + headers = [ + 'Id', + 'Name', + 'BIA', + 'MAC' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/output.py b/lib/redfish/ucs_rack/template/output.py new file mode 100644 index 00000000..680d4a1b --- /dev/null +++ b/lib/redfish/ucs_rack/template/output.py @@ -0,0 +1,47 @@ +from lib.redfish.ucs_rack.template.account.output import RedfishEndpointUcsRackTemplateAccountOutput +from lib.redfish.ucs_rack.template.bios.output import RedfishEndpointUcsRackTemplateBiosOutput +from lib.redfish.ucs_rack.template.cpu.output import RedfishEndpointUcsRackTemplateCpuOutput +from lib.redfish.ucs_rack.template.fan.output import RedfishEndpointUcsRackTemplateFanOutput +from lib.redfish.ucs_rack.template.gpu.output import RedfishEndpointUcsRackTemplateGpuOutput +from lib.redfish.ucs_rack.template.identity.output import RedfishEndpointUcsRackTemplateIdentityOutput +from lib.redfish.ucs_rack.template.mem.output import RedfishEndpointUcsRackTemplateMemOutput +from lib.redfish.ucs_rack.template.net.output import RedfishEndpointUcsRackTemplateNetOutput +from lib.redfish.ucs_rack.template.pci.output import RedfishEndpointUcsRackTemplatePciOutput +from lib.redfish.ucs_rack.template.power.output import RedfishEndpointUcsRackTemplatePowerOutput +from lib.redfish.ucs_rack.template.psu.output import RedfishEndpointUcsRackTemplatePsuOutput +from lib.redfish.ucs_rack.template.role.output import RedfishEndpointUcsRackTemplateRoleOutput +from lib.redfish.ucs_rack.template.storage.output import RedfishEndpointUcsRackTemplateStorageOutput +from lib.redfish.ucs_rack.template.thermal.output import RedfishEndpointUcsRackTemplateThermalOutput + + +class RedfishEndpointUcsRackTemplateOutput( + RedfishEndpointUcsRackTemplateAccountOutput, + RedfishEndpointUcsRackTemplateBiosOutput, + RedfishEndpointUcsRackTemplateCpuOutput, + RedfishEndpointUcsRackTemplateFanOutput, + RedfishEndpointUcsRackTemplateGpuOutput, + RedfishEndpointUcsRackTemplateIdentityOutput, + RedfishEndpointUcsRackTemplateMemOutput, + RedfishEndpointUcsRackTemplateNetOutput, + RedfishEndpointUcsRackTemplatePciOutput, + RedfishEndpointUcsRackTemplatePowerOutput, + RedfishEndpointUcsRackTemplatePsuOutput, + RedfishEndpointUcsRackTemplateRoleOutput, + RedfishEndpointUcsRackTemplateStorageOutput, + RedfishEndpointUcsRackTemplateThermalOutput + ): + def __init__(self): + RedfishEndpointUcsRackTemplateAccountOutput.__init__(self) + RedfishEndpointUcsRackTemplateBiosOutput.__init__(self) + RedfishEndpointUcsRackTemplateCpuOutput.__init__(self) + RedfishEndpointUcsRackTemplateFanOutput.__init__(self) + RedfishEndpointUcsRackTemplateGpuOutput.__init__(self) + RedfishEndpointUcsRackTemplateIdentityOutput.__init__(self) + RedfishEndpointUcsRackTemplateMemOutput.__init__(self) + RedfishEndpointUcsRackTemplateNetOutput.__init__(self) + RedfishEndpointUcsRackTemplatePciOutput.__init__(self) + RedfishEndpointUcsRackTemplatePowerOutput.__init__(self) + RedfishEndpointUcsRackTemplatePsuOutput.__init__(self) + RedfishEndpointUcsRackTemplateRoleOutput.__init__(self) + RedfishEndpointUcsRackTemplateStorageOutput.__init__(self) + RedfishEndpointUcsRackTemplateThermalOutput.__init__(self) diff --git a/lib/redfish/ucs_rack/template/pci/__init__.py b/lib/redfish/ucs_rack/template/pci/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/pci/main.py b/lib/redfish/ucs_rack/template/pci/main.py new file mode 100644 index 00000000..9f434dc8 --- /dev/null +++ b/lib/redfish/ucs_rack/template/pci/main.py @@ -0,0 +1,134 @@ +class RedfishEndpointUcsRackTemplatePci(): + def __init__(self): + self.pci_uri = '/redfish/v1/Chassis/1/PCIeDevices' + self.pci = None + + def get_pcis_uri(self): + uri = self.pci_uri + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_pci_info(self, uri): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + furi = self.get_property_value( + data, + 'PCIeFunctions:@odata.id' + ) + functions = [] + if furi is not None: + fdata = self.get_properties(furi) + if fdata is not None: + members = self.get_property_value( + fdata, + 'Members' + ) + if members is not None: + for member in members: + function_data = self.get_properties( + member['@odata.id'] + ) + if function_data is not None: + functions.append( + function_data + ) + + info['Uri'] = uri + info['UriFunctions'] = furi + + keys = [ + 'Id', + 'FirmwareVersion', + 'Name' + ] + for key in keys: + info[key] = self.get_property_value( + data, + key + ) + + try: + info['_index'] = int(info['Id']) + except BaseException: + info['_index'] = -1 + + info['function'] = [] + for function_mo in functions: + function_info = {} + keys = [ + 'Id', + 'DeviceId', + 'Name', + 'SubsystemId', + 'SubsystemVendorId', + 'VendorId' + ] + for key in keys: + function_info[key] = self.get_property_value( + function_mo, + key + ) + + keys = [ + 'Drives', + 'EthernetInterfaces', + 'NetworkDeviceFunctions', + 'StorageControllers' + ] + for key in keys: + function_info[key] = self.get_property_value( + function_mo, + 'Links:%s@odata.count' % (key) + ) + + info['function'].append( + function_info + ) + + return info + + def get_pcis_info(self, cache_enabled=True): + if cache_enabled and self.pci is not None: + return self.pci + + self.pci = [] + pcis_uri = self.get_pcis_uri() + for pci_uri in pcis_uri: + pci_info = self.get_pci_info( + pci_uri + ) + if pci_info is not None: + self.pci.append( + pci_info + ) + + self.pci = sorted( + self.pci, + key=lambda i: i['_index'] + ) + + return self.pci + + def get_template_pci_properties(self, cache_enabled=True): + all_properties = self.get_pcis_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/pci/output.py b/lib/redfish/ucs_rack/template/pci/output.py new file mode 100644 index 00000000..a956af7d --- /dev/null +++ b/lib/redfish/ucs_rack/template/pci/output.py @@ -0,0 +1,59 @@ +class RedfishEndpointUcsRackTemplatePciOutput( + ): + def __init__(self): + pass + + def print_ucsc_pci_properties(self, info, title=False): + if title: + self.my_output.default( + 'PCI [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'Id', + 'Name', + 'FirmwareVersion', + 'function.DeviceId', + 'function.VendorId', + 'function.SubsystemId', + 'function.SubsystemVendorId', + 'function.NetworkDeviceFunctions', + 'function.EthernetInterfaces', + 'function.StorageControllers', + 'function.Drives' + ] + + headers = [ + 'Id', + 'Name', + 'Fw', + 'DevId', + 'Vendor', + 'SubId', + 'SubVendor', + 'Net', + 'Eth', + 'Storage', + 'Drives' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['function'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/power/__init__.py b/lib/redfish/ucs_rack/template/power/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/power/main.py b/lib/redfish/ucs_rack/template/power/main.py new file mode 100644 index 00000000..d42d5311 --- /dev/null +++ b/lib/redfish/ucs_rack/template/power/main.py @@ -0,0 +1,186 @@ +class RedfishEndpointUcsRackTemplatePower(): + def __init__(self): + self.defult_power_uri = '/redfish/v1/Chassis/1/Power' + + def get_power_uri(self): + chassis_uri = self.get_chassis_uri() + children = self.endpoint_handler.get_odata_ids(chassis_uri) + if children is None: + self.log.error( + 'get_power_uri', + 'Failed to discover Power URI: %s' % (chassis_uri) + ) + return self.defult_power_uri + + power_uri = None + for child in children: + if child == chassis_uri: + continue + + leaf = child.split('/')[-1] + if leaf == 'Power': + power_uri = child + break + + if power_uri is None: + self.log.error( + 'get_power_uri', + 'Failed to find power uri: %s' % (chassis_uri) + ) + return self.default_chassis_uri + + return power_uri + + def get_template_power_properties(self): + uri = self.get_power_uri() + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Data']['PowerControl'] = {} + + # { + # "PhysicalContext": "PowerSupply", + # "PowerMetrics": { + # "MinConsumedWatts": 186, + # "AverageConsumedWatts": 349, + # "MaxConsumedWatts": 495 + # }, + # "MemberId": "1", + # "PowerLimit": { + # "LimitException": "NoAction" + # }, + # "PowerConsumedWatts": 360, + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerControl/1" + # } + power_control_data = data['PowerControl'][0] + properties['Data']['PowerControl']['PowerConsumedWatts'] = power_control_data['PowerConsumedWatts'] + + properties['Data']['PowerControl']['LimitException'] = 'N/A' + if 'PowerLimit' in power_control_data: + if 'LimitException' in power_control_data['PowerLimit']: + properties['Data']['PowerControl']['LimitException'] = power_control_data['PowerLimit']['LimitException'] + + for key in ['MinConsumedWatts', 'AverageConsumedWatts', 'MaxConsumedWatts']: + properties['Data']['PowerControl'][key] = 0 + if 'PowerMetrics' in power_control_data: + for key in power_control_data['PowerMetrics']: + properties['Data']['PowerControl'][key] = power_control_data['PowerMetrics'][key] + + # { + # "PhysicalContext": "PowerSupply", + # "SensorNumber": 48, + # "MemberId": "1", + # "@odata.id": "/redfish/v1/Chassis/1/Power#/Voltages/PSU1_VOUT", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # }, + # "UpperThresholdCritical": 14, + # "Name": "PSU1_VOUT", + # "ReadingVolts": 12.2 + # }, + properties['Data']['Voltage'] = [] + for voltage in data['Voltages']: + voltage_info = {} + + keys = [ + 'Name', + 'ReadingVolts', + 'UpperThresholdCritical', + 'PhysicalContext' + ] + for key in keys: + voltage_info[key] = 'N/A' + if key in voltage: + voltage_info[key] = voltage[key] + + keys = [ + 'State', + 'Health' + ] + for key in keys: + voltage_info[key] = 'N/A' + if key in voltage['Status']: + voltage_info[key] = voltage['Status'][key] + + properties['Data']['Voltage'].append(voltage_info) + + # { + # "SerialNumber": "LIT241244RQ", + # "InputRanges": [ + # { + # "InputType": "AC", + # "OutputWattage": 1050, + # "MaximumFrequencyHz": 63, + # "MaximumVoltage": 264, + # "MinimumVoltage": 90, + # "MinimumFrequencyHz": 47 + # } + # ], + # "FirmwareVersion": "10062019", + # "@odata.id": "/redfish/v1/Chassis/1/Power#/PowerSupplies/PSU1", + # "PowerOutputWatts": 171, + # "LineInputVoltage": 229, + # "Name": "PSU1", + # "PowerInputWatts": 186, + # "Manufacturer": "Cisco Systems Inc", + # "LastPowerOutputWatts": 171, + # "MemberId": "1", + # "PartNumber": "341-0638-03", + # "PowerSupplyType": "AC", + # "Model": "PS-2112-9S-LF", + # "SparePartNumber": "341-0638-03", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + properties['Data']['PowerSupply'] = [] + for power_supply in data['PowerSupplies']: + power_supply_info = {} + power_supply_info['Name'] = power_supply['Name'] + power_supply_info['Model'] = power_supply['Model'] + power_supply_info['SerialNumber'] = power_supply['SerialNumber'] + + keys = [ + 'PartNumber', + 'SparePartNumber', + 'Manufacturer', + 'FirmwareVersion', + 'PowerOutputWatts', + 'LastPowerOutputWatts', + 'PowerInputWatts', + 'PowerSupplyType' + ] + for key in keys: + power_supply_info[key] = 'N/A' + if key in power_supply: + power_supply_info[key] = power_supply[key] + + keys = [ + 'State', + 'Health' + ] + for key in keys: + power_supply_info[key] = 'N/A' + if key in power_supply['Status']: + power_supply_info[key] = power_supply['Status'][key] + + for input_range in power_supply['InputRanges']: + for key in input_range: + if key != 'InputType': + power_supply_info[key] = input_range[key] + + properties['Data']['PowerSupply'].append(power_supply_info) + + properties['Summary'] = {} + properties['Summary']['Source'] = 'Redfish' + properties['Summary']['PowerNow'] = properties['Data']['PowerControl']['PowerConsumedWatts'] + properties['Summary']['PowerMin'] = properties['Data']['PowerControl']['MinConsumedWatts'] + properties['Summary']['PowerAvg'] = properties['Data']['PowerControl']['AverageConsumedWatts'] + properties['Summary']['PowerMax'] = properties['Data']['PowerControl']['MaxConsumedWatts'] + + return properties diff --git a/lib/redfish/ucs_rack/template/power/output.py b/lib/redfish/ucs_rack/template/power/output.py new file mode 100644 index 00000000..7effd67c --- /dev/null +++ b/lib/redfish/ucs_rack/template/power/output.py @@ -0,0 +1,98 @@ +class RedfishEndpointUcsRackTemplatePowerOutput( + ): + def __init__(self): + pass + + def print_ucsc_power_consumption_properties(self, properties): + keys = [ + 'PowerConsumedWatts', + 'MinConsumedWatts', + 'AverageConsumedWatts', + 'MaxConsumedWatts', + 'LimitException' + ] + + headers = [ + 'Current', + 'Min', + 'Average', + 'Max', + 'Limit action' + ] + + self.my_output.dictionary( + properties['Data']['PowerControl'], + title='Power Consumption (Watt)', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_ucsc_power_voltage_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'ReadingVolts', + 'UpperThresholdCritical' + ] + + headers = [ + 'Sensor Name', + 'State', + 'Health', + 'Volts', + 'Upper Threshold' + ] + + self.my_output.my_table( + properties['Data']['Voltage'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_ucsc_power_supply_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'SerialNumber', + 'FirmwareVersion', + 'PowerOutputWatts', + 'PowerInputWatts', + 'MaximumVoltage', + 'MinimumVoltage', + 'MaximumFrequencyHz', + 'MinimumFrequencyHz' + ] + + headers = [ + 'PSU Name', + 'State', + 'Health', + 'Serial', + 'Firmware', + 'Output (Watt)', + 'Input (Watt)', + 'Max (V)', + 'Min (V)', + 'Max (Hz)', + 'Min (Hz)' + ] + + self.my_output.my_table( + properties['Data']['PowerSupply'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_ucsc_power_properties(self, properties): + self.print_ucsc_power_consumption_properties(properties) + self.print_ucsc_power_voltage_properties(properties) + self.print_ucsc_power_supply_properties(properties) diff --git a/lib/redfish/ucs_rack/template/psu/__init__.py b/lib/redfish/ucs_rack/template/psu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/psu/main.py b/lib/redfish/ucs_rack/template/psu/main.py new file mode 100644 index 00000000..68abb906 --- /dev/null +++ b/lib/redfish/ucs_rack/template/psu/main.py @@ -0,0 +1,87 @@ +class RedfishEndpointUcsRackTemplatePsu(): + def __init__(self): + self.psu_uri = '/redfish/v1/Chassis/1/Power' + self.psu = None + + def get_psus_uri(self): + uri = self.psu_uri + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_psu_info(self, psu_mo): + info = {} + info['__Output'] = {} + + keys = [ + 'MemberId', + 'FirmwareVersion', + 'Manufacturer', + 'Model', + 'Name', + 'PartNumber', + 'SerialNumber', + 'SparePartNumber' + ] + for key in keys: + info[key] = self.get_property_value( + psu_mo, + key + ) + + try: + info['_index'] = int(info['MemberId']) + except BaseException: + info['_index'] = -1 + + info['State'] = self.get_property_value( + psu_mo, + 'Status:State' + ) + info['__Output']['State'] = 'Red' + if info['State'] == 'Enabled': + info['__Output']['State'] = 'Green' + + return info + + def get_psus_info(self, cache_enabled=True): + if cache_enabled and self.psu is not None: + return self.psu + + self.psu = [] + psus_mo = self.get_properties(self.psu_uri) + if psus_mo is not None and 'PowerSupplies' in psus_mo: + for psu_mo in psus_mo['PowerSupplies']: + psu_info = self.get_psu_info( + psu_mo + ) + self.psu.append( + psu_info + ) + + self.psu = sorted( + self.psu, + key=lambda i: i['_index'] + ) + + return self.psu + + def get_template_psu_properties(self, cache_enabled=True): + all_properties = self.get_psus_info(cache_enabled=cache_enabled) + if all_properties is None: + return None + + redfish_properties = [] + for redfish_property in all_properties: + redfish_properties.append( + redfish_property + ) + + return redfish_properties diff --git a/lib/redfish/ucs_rack/template/psu/output.py b/lib/redfish/ucs_rack/template/psu/output.py new file mode 100644 index 00000000..f5d06b57 --- /dev/null +++ b/lib/redfish/ucs_rack/template/psu/output.py @@ -0,0 +1,50 @@ +class RedfishEndpointUcsRackTemplatePsuOutput( + ): + def __init__(self): + pass + + def print_ucsc_psu_properties(self, info, title=False): + if title: + self.my_output.default( + 'PSU [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'MemberId', + 'Name', + 'State', + 'Manufacturer', + 'Model', + 'PartNumber', + 'SerialNumber', + 'SparePartNumber', + 'FirmwareVersion' + ] + + headers = [ + 'Id', + 'Name', + 'State', + 'Vendor', + 'Model', + 'Part Number', + 'Serial Number', + 'Spare Part Number', + 'Firmware' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/role/__init__.py b/lib/redfish/ucs_rack/template/role/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/role/main.py b/lib/redfish/ucs_rack/template/role/main.py new file mode 100644 index 00000000..37b789d8 --- /dev/null +++ b/lib/redfish/ucs_rack/template/role/main.py @@ -0,0 +1,88 @@ +class RedfishEndpointUcsRackTemplateRole(): + def __init__(self): + self.role_uri = '/redfish/v1/AccountService/Roles' + self.role = None + + def get_role_mo(self, cache_enabled=True): + if cache_enabled: + if self.role is not None: + return self.role + + self.role = [] + + role_uris = self.endpoint_handler.get_odata_ids(self.role_uri) + for role_uri in role_uris: + if role_uri == self.role_uri: + continue + + role_info = self.get_role_info( + role_uri + ) + + self.role.append( + role_info + ) + + return self.role + + def get_role_info(self, uri): + info = {} + info['__Output'] = {} + info['Uri'] = uri + + data = self.get_properties(uri) + + info['id'] = self.get_property_value( + data, + 'Id' + ) + + info['role_id'] = self.get_property_value( + data, + 'RoleId' + ) + + info['name'] = self.get_property_value( + data, + 'Name' + ) + + info['description'] = self.get_property_value( + data, + 'Description' + ) + + info['privileges'] = self.get_property_value( + data, + 'AssignedPrivileges' + ) + + info['oem'] = self.get_property_value( + data, + 'OemPrivileges' + ) + + return info + + def get_template_role_properties(self, account_info=False, cache_enabled=True): + roles = self.get_role_mo(cache_enabled=cache_enabled) + for role in roles: + if account_info: + role['username'] = [] + role_accounts = self.get_accounts_with_role_id( + role['id'] + ) + if role_accounts is not None: + for role_account in role_accounts: + role['username'].append( + role_account['username'] + ) + + return roles + + def get_role_by_id(self, role_id): + roles = self.get_template_role_properties() + for role in roles: + if role['id'] == role_id: + return role + return None diff --git a/lib/redfish/ucs_rack/template/role/output.py b/lib/redfish/ucs_rack/template/role/output.py new file mode 100644 index 00000000..0fc71221 --- /dev/null +++ b/lib/redfish/ucs_rack/template/role/output.py @@ -0,0 +1,57 @@ +class RedfishEndpointUcsRackTemplateRoleOutput( + ): + def __init__(self): + pass + + def print_ucsc_role_properties(self, info, title=False): + if title: + self.my_output.default( + 'Role [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + + for item in info: + if len(item['privileges']) == 0: + item['privileges'].append('--') + if len(item['oem']) == 0: + item['oem'].append('--') + if len(item['username']) == 0: + item['username'].append('--') + + order = [ + 'id', + 'role_id', + 'name', + 'description', + 'privileges', + 'oem', + 'username' + ] + + headers = [ + 'Id', + 'Role Id', + 'Name', + 'Description', + 'Privileges', + 'Oem Privileges', + 'Account' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['privileges', 'oem', 'username'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + row_separator=True, + table=True + ) diff --git a/lib/redfish/ucs_rack/template/storage/__init__.py b/lib/redfish/ucs_rack/template/storage/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/storage/main.py b/lib/redfish/ucs_rack/template/storage/main.py new file mode 100644 index 00000000..b1bc83c4 --- /dev/null +++ b/lib/redfish/ucs_rack/template/storage/main.py @@ -0,0 +1,421 @@ +import json + + +class RedfishEndpointUcsRackTemplateStorage(): + def __init__(self): + self.defult_storage_uri = '/redfish/v1/Systems/SYSTEM_ID/Storage' + + def get_storage_uri(self): + return self.path_fixup(self.defult_storage_uri) + + def get_storage_controllers_uri(self): + uri = self.get_storage_uri() + data = [] + odata_ids = self.endpoint_handler.get_odata_ids(uri) + if odata_ids is not None: + for odata_id in odata_ids: + if odata_id != uri: + data.append( + odata_id + ) + + return data + + def get_storage_controller_info(self, uri): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + info['Id'] = data['Id'] + info['Drive'] = [] + for drive_mo in data['Drives']: + drive_info = {} + drive_info['uri'] = drive_mo['@odata.id'] + info['Drive'].append( + drive_info + ) + + info['PhysicalDiskCount'] = len(info['Drive']) + + info['Volume'] = [] + if 'Volumes' in data: + if data['Volumes'] is not None: + if isinstance(data['Volumes'], dict): + volume_data = self.get_properties(data['Volumes']['@odata.id']) + if volume_data is not None: + for item in volume_data['Members']: + volume_info = {} + volume_info['uri'] = item['@odata.id'] + info['Volume'].append( + volume_info + ) + + info['VirtualDriveCount'] = len(info['Volume']) + + if len(data['StorageControllers']) != 1: + self.log.error( + 'get_storage_controller_info', + 'Unexpected storage controller count: %s' % (uri) + ) + return None + + storage_controller_mo = data['StorageControllers'][0] + info['FirmwareVersion'] = self.get_property_value( + storage_controller_mo, + 'FirmwareVersion' + ) + info['Vendor'] = self.get_property_value( + storage_controller_mo, + 'Manufacturer' + ) + info['Pid'] = self.get_property_value( + storage_controller_mo, + 'Model' + ) + info['Model'] = self.get_property_value( + storage_controller_mo, + 'Name' + ) + info['Oem'] = None + if info['Vendor'] == 'Cisco Systems Inc' or 'Cisco' in storage_controller_mo['Oem']: + info['Oem'] = self.get_property_value( + storage_controller_mo, + 'Oem:Cisco' + ) + else: + self.log.error( + 'get_storage_controller_info', + 'Unrecognized storage controller vendor: %s' % (uri) + ) + + info['PciSlot'] = self.get_property_value( + storage_controller_mo, + 'Oem:Cisco:PCIeSlot' + ) + info['SerialNumber'] = self.get_property_value( + storage_controller_mo, + 'SerialNumber' + ) + info['Health'] = self.get_property_value( + storage_controller_mo, + 'Status:Health' + ) + info['State'] = self.get_property_value( + storage_controller_mo, + 'Status:State' + ) + info['SupportedControllerProtocols'] = self.get_property_value( + storage_controller_mo, + 'SupportedControllerProtocols' + ) + info['SupportedDeviceProtocols'] = self.get_property_value( + storage_controller_mo, + 'SupportedDeviceProtocols' + ) + info['SupportedRAIDTypes'] = self.get_property_value( + storage_controller_mo, + 'SupportedRAIDTypes' + ) + + info['LocationType'] = self.get_property_value( + storage_controller_mo, + 'Location:PartLocation:LocationType' + ) + + info['Slot'] = None + if info['LocationType'] == 'Slot': + info['Slot'] = self.get_property_value( + storage_controller_mo, + 'Location:PartLocation:ServiceLabel' + ) + + return info + + def get_storage_controllers_info(self): + info = [] + controllers_uri = self.get_storage_controllers_uri() + for controller_uri in controllers_uri: + controller_info = self.get_storage_controller_info( + controller_uri + ) + if controller_info is not None: + info.append( + controller_info + ) + return info + + def get_storage_drive_info(self, uri, controller_id): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + info['DiskId'] = self.get_property_value( + data, + 'Id' + ) + info['StorageControllerId'] = controller_id + info['Model'] = self.get_property_value( + data, + 'Name' + ) + info['Type'] = self.get_property_value( + data, + 'MediaType' + ) + info['Pid'] = self.get_property_value( + data, + 'Model' + ) + info['Vendor'] = self.get_property_value( + data, + 'Manufacturer' + ) + info['Revision'] = self.get_property_value( + data, + 'Revision' + ) + info['SerialNumber'] = self.get_property_value( + data, + 'SerialNumber' + ) + info['Protocol'] = self.get_property_value( + data, + 'Protocol' + ) + info['Health'] = self.get_property_value( + data, + 'Status:Health' + ) + info['State'] = self.get_property_value( + data, + 'Status:State' + ) + if info['State'] == 'Absent': + return None + + if info['Health'] in [None, 'OK'] and info['State'] == 'Enabled': + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + print(json.dumps(data, indent=4)) + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + info['LocationType'] = self.get_property_value( + data, + 'PhysicalLocation:PartLocation:LocationType' + ) + info['Slot'] = None + if info['LocationType'] == 'Slot': + info['Slot'] = self.get_property_value( + data, + 'PhysicalLocation:PartLocation:ServiceLabel' + ) + + info['Oem'] = self.get_property_value( + data, + 'Oem:Cisco' + ) + + info['Bootable'] = self.get_property_value( + data, + 'Oem:Cisco:Bootable' + ) + info['BootableTick'] = '\u2717' + info['__Output']['BootableTick'] = 'Red' + + if info['Bootable'] is not None: + if info['Bootable']: + info['BootableTick'] = '\u2713' + info['__Output']['BootableTick'] = 'Green' + + info['BlockSizeBytes'] = self.get_property_value( + data, + 'BlockSizeBytes' + ) + + info['CapableSpeedGbs'] = self.get_property_value( + data, + 'CapableSpeedGbs' + ) + info['LinkSpeed'] = '' + if info['CapableSpeedGbs'] is not None: + info['LinkSpeed'] = '%s gb/s' % ( + info['CapableSpeedGbs'] + ) + + info['EncryptionAbility'] = self.get_property_value( + data, + 'EncryptionAbility' + ) + + info['FailurePredicted'] = self.get_property_value( + data, + 'FailurePredicted' + ) + + info['CapacityBytes'] = self.get_property_value( + data, + 'CapacityBytes' + ) + info['SizeUnit'] = self.info_handler.convert_storage( + info['CapacityBytes'] + ) + + info['HotspareType'] = self.get_property_value( + data, + 'HotspareType' + ) + + info['IndicatorLED'] = self.get_property_value( + data, + 'IndicatorLED' + ) + + info['PredictedMediaLifeLeftPercent'] = self.get_property_value( + data, + 'PredictedMediaLifeLeftPercent' + ) + + return info + + def get_storage_volume_info(self, uri, controller_id): + info = {} + info['__Output'] = {} + + data = self.get_properties(uri) + + info['Uri'] = uri + + info['VirtualDriveId'] = self.get_property_value( + data, + 'Id' + ) + + info['StorageControllerId'] = controller_id + + info['PhysicalDiskUri'] = [] + drives = self.get_property_value( + data, + 'Links:Drives' + ) + if drives is not None: + for drive in drives: + info['PhysicalDiskUri'].append( + drive['@odata.id'] + ) + + info['PhysicalDiskCount'] = len(info['PhysicalDiskUri']) + + info['CapacityBytes'] = self.get_property_value( + data, + 'CapacityBytes' + ) + info['SizeUnit'] = self.info_handler.convert_storage( + info['CapacityBytes'] + ) + + info['Name'] = self.get_property_value( + data, + 'Name' + ) + + info['Type'] = self.get_property_value( + data, + 'RAIDType' + ) + + info['Oem'] = self.get_property_value( + data, + 'Oem:Cisco' + ) + + info['Bootable'] = self.get_property_value( + data, + 'Oem:Cisco:Bootable' + ) + info['BootableTick'] = '\u2717' + info['__Output']['BootableTick'] = 'Red' + + if info['Bootable'] is not None: + if info['Bootable']: + info['BootableTick'] = '\u2713' + info['__Output']['BootableTick'] = 'Green' + + info['Health'] = self.get_property_value( + data, + 'Status:Health' + ) + info['State'] = self.get_property_value( + data, + 'Status:State' + ) + + info['DriveState'] = self.get_property_value( + data, + 'Oem:Cisco:VolumeState' + ) + + if info['DriveState'] == 'Optimal': + info['StateTick'] = '\u2713' + info['__Output']['StateTick'] = 'Green' + else: + info['StateTick'] = '\u2717' + info['__Output']['StateTick'] = 'Red' + + info['ActualWriteCachePolicy'] = self.get_property_value( + data, + 'Oem:Cisco:ConfiguredWriteCachePolicy' + ) + + return info + + def get_template_storage_properties(self): + properties = {} + properties['Controller'] = self.get_storage_controllers_info() + + properties['Drive'] = [] + for controller_info in properties['Controller']: + drive_count = 0 + for drive_mo in controller_info['Drive']: + drive_info = self.get_storage_drive_info( + drive_mo['uri'], + controller_info['Id'] + ) + if drive_info is not None: + properties['Drive'].append( + drive_info + ) + drive_count = drive_count + 1 + + controller_info['PhysicalDiskCount'] = drive_count + + properties['Volume'] = [] + for controller_info in properties['Controller']: + volume_count = 0 + for volume_mo in controller_info['Volume']: + volume_info = self.get_storage_volume_info( + volume_mo['uri'], + controller_info['Id'] + ) + if volume_info is not None: + properties['Volume'].append( + volume_info + ) + volume_count = volume_count + 1 + + controller_info['VirtualDriveCount'] = volume_count + + for volume_info in properties['Volume']: + for disk_uri in volume_info['PhysicalDiskUri']: + for drive_info in properties['Drive']: + if drive_info['Uri'] == disk_uri: + drive_info['VirtualDriveId'] = volume_info['VirtualDriveId'] + + return properties diff --git a/lib/redfish/ucs_rack/template/storage/output.py b/lib/redfish/ucs_rack/template/storage/output.py new file mode 100644 index 00000000..5c7e53ac --- /dev/null +++ b/lib/redfish/ucs_rack/template/storage/output.py @@ -0,0 +1,179 @@ +class RedfishEndpointUcsRackTemplateStorageOutput( + ): + def __init__(self): + pass + + def print_ucsc_storage_controller_properties(self, info, title=False): + if title: + self.my_output.default( + 'Storage Controller [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'Id', + 'Pid', + 'Model', + 'Vendor', + 'SerialNumber', + 'FirmwareVersion', + 'State', + 'Health', + 'PciSlot', + 'SupportedRAIDTypes', + 'PhysicalDiskCount', + 'VirtualDriveCount' + ] + + headers = [ + 'Controller', + 'Pid', + 'Model', + 'Vendor', + 'Serial', + 'Firmware', + 'State', + 'Health', + 'PCI Slot', + 'Raid Support', + 'PD', + 'VD' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info, + order, + ['SupportedRAIDTypes'] + ), + order=order, + headers=headers, + remove_empty_columns=False, + allow_order_subkeys=True, + underline=True, + row_separator=True, + table=True + ) + + def print_ucsc_storage_drive_properties(self, info, title=False): + if title: + self.my_output.default( + 'Physical Disk [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'StateTick', + 'StorageControllerId', + 'DiskId', + 'VirtualDriveId', + 'SizeUnit', + 'Type', + 'Protocol', + 'BootableTick', + 'LinkSpeed', + 'Pid', + 'Model', + 'Vendor', + 'Revision', + 'SerialNumber' + ] + + headers = [ + 'State', + 'Controller', + 'Disk Id', + 'VD', + 'Size', + 'Type', + 'Protocol', + 'Bootable', + 'Link Speed', + 'Pid', + 'Model', + 'Vendor', + 'Fw', + 'Serial' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_ucsc_storage_volume_properties(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Drive [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'StateTick', + 'StorageControllerId', + 'VirtualDriveId', + 'SizeUnit', + 'PhysicalDiskCount', + 'Type', + 'Name', + 'BootableTick', + 'ActualWriteCachePolicy', + 'DriveState' + ] + + headers = [ + 'State', + 'Controller', + 'Drive Id', + 'Size', + 'Disks', + 'Type', + 'Name', + 'Bootable', + 'Write Cache', + 'Drive State' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + remove_empty_columns=False, + underline=True, + table=True + ) + + def print_ucsc_storage_properties(self, properties): + self.print_ucsc_storage_controller_properties( + properties['Controller'], + title=True + ) + + self.print_ucsc_storage_drive_properties( + properties['Drive'], + title=True + ) + + self.print_ucsc_storage_volume_properties( + properties['Volume'], + title=True + ) diff --git a/lib/redfish/ucs_rack/template/thermal/__init__.py b/lib/redfish/ucs_rack/template/thermal/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/redfish/ucs_rack/template/thermal/main.py b/lib/redfish/ucs_rack/template/thermal/main.py new file mode 100644 index 00000000..cdc1f42c --- /dev/null +++ b/lib/redfish/ucs_rack/template/thermal/main.py @@ -0,0 +1,167 @@ +class RedfishEndpointUcsRackTemplateThermal(): + def __init__(self): + self.defult_thermal_uri = '/redfish/v1/Chassis/1/Thermal' + + def get_thermal_uri(self): + chassis_uri = self.get_chassis_uri() + children = self.endpoint_handler.get_odata_ids(chassis_uri) + if children is None: + self.log.error( + 'get_thermal_uri', + 'Failed to discover thermal URI: %s' % (chassis_uri) + ) + return self.defult_thermal_uri + + thermal_uri = None + for child in children: + if child == chassis_uri: + continue + + leaf = child.split('/')[-1] + if leaf == 'Thermal': + thermal_uri = child + break + + if thermal_uri is None: + self.log.error( + 'get_thermal_uri', + 'Failed to find thermal uri: %s' % (chassis_uri) + ) + return self.default_chassis_uri + + return thermal_uri + + def get_template_thermal_properties(self): + uri = self.get_thermal_uri() + data = self.get_properties(uri) + if data is None: + return None + + properties = {} + properties['Data'] = {} + properties['Summary'] = {} + properties['Summary']['FanHealth'] = True + properties['Summary']['SensorHealth'] = True + properties['Summary']['HighestTemperature'] = None + properties['Summary']['SmallestGap'] = None + properties['Summary']['OverThreshold'] = 0 + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Temperatures/MLOM_TEMP", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # }, + # "SensorNumber": 60, + # "Name": "MLOM_TEMP", + # "PhysicalContext": "NetworkingDevice", + # "MemberId": "1", + # "UpperThresholdCritical": 90, + # "ReadingCelsius": 55 + # }, + properties['Data']['Temperature'] = [] + for sensor in data['Temperatures']: + sensor_info = {} + sensor_info['Name'] = sensor['Name'] + sensor_info['State'] = sensor['Status']['State'] + sensor_info['Health'] = sensor['Status']['Health'] + if sensor_info['State'] == 'Enabled': + if sensor_info['Health'].lower() != 'ok': + properties['Summary']['SensorHealth'] = False + + keys = [ + 'SensorNumber', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + for key in keys: + sensor_info[key] = 'N/A' + if key in sensor: + sensor_info[key] = sensor[key] + + try: + value = int(sensor_info['ReadingCelsius']) + if properties['Summary']['HighestTemperature'] is None: + properties['Summary']['HighestTemperature'] = value + else: + properties['Summary']['HighestTemperature'] = max( + properties['Summary']['HighestTemperature'], + value + ) + except BaseException: + pass + + try: + value = int(sensor_info['UpperThresholdCritical']) - int(sensor_info['ReadingCelsius']) + if value < 0: + properties['Summary']['OverThreshold'] = properties['Summary']['OverThreshold'] + 1 + else: + if properties['Summary']['SmallestGap'] is None: + properties['Summary']['SmallestGap'] = value + else: + properties['Summary']['SmallestGap'] = min( + properties['Summary']['SmallestGap'], + value + ) + except BaseException: + pass + + properties['Data']['Temperature'].append(sensor_info) + + properties['Data']['Temperature'] = sorted(properties['Data']['Temperature'], key=lambda i: i['Name']) + + # { + # "RelatedItem": [ + # { + # "@odata.id": "/redfish/v1/Chassis/1" + # } + # ], + # "@odata.id": "/redfish/v1/Chassis/1/Thermal#/Fans/MOD1_FAN1", + # "ReadingUnits": "RPM", + # "Reading": 7070, + # "PhysicalContext": "Fan", + # "MemberId": "1", + # "Name": "MOD1_FAN1_SPEED", + # "Status": { + # "State": "Enabled", + # "Health": "OK" + # } + # }, + properties['Data']['Fan'] = [] + for fan in data['Fans']: + fan_info = {} + fan_info['Name'] = fan['Name'] + fan_info['State'] = fan['Status']['State'] + + fan_info['Health'] = '' + if 'Health' in fan['Status']: + fan_info['Health'] = fan['Status']['Health'] + if fan_info['State'] == 'Enabled': + if fan_info['Health'].lower() != 'ok': + properties['Summary']['FanHealth'] = False + + fan_info['PhysicalContext'] = '' + if 'PhysicalContext' in fan: + fan_info['PhysicalContext'] = fan['PhysicalContext'] + + fan_info['ReadingUnits'] = '' + if 'ReadingUnits' in fan: + fan_info['ReadingUnits'] = fan['ReadingUnits'] + + fan_info['Reading'] = '' + if 'Reading' in fan: + fan_info['Reading'] = fan['Reading'] + + fan_info['Value'] = '%s %s' % (fan_info['Reading'], fan_info['ReadingUnits']) + + properties['Data']['Fan'].append(fan_info) + + properties['Data']['Fan'] = sorted(properties['Data']['Fan'], key=lambda i: i['Name']) + + return properties diff --git a/lib/redfish/ucs_rack/template/thermal/output.py b/lib/redfish/ucs_rack/template/thermal/output.py new file mode 100644 index 00000000..488af23d --- /dev/null +++ b/lib/redfish/ucs_rack/template/thermal/output.py @@ -0,0 +1,86 @@ +class RedfishEndpointUcsRackTemplateThermalOutput( + ): + def __init__(self): + pass + + def print_ucsc_thermal_summary_properties(self, properties): + keys = [ + 'SensorHealth', + 'HighestTemperature', + 'SmallestGap', + 'OverThreshold', + 'FanHealth' + ] + + headers = [ + 'Sensors Health', + 'Highest (C)', + 'Smallest Gap (C)', + 'Over Threshold', + 'Fans Health' + ] + + self.my_output.dictionary( + properties['Summary'], + title='Thermal Summary', + underline=True, + prefix="- ", + justify=True, + keys=keys, + title_keys=headers + ) + + def print_ucsc_thermal_temperature_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'PhysicalContext', + 'ReadingCelsius', + 'UpperThresholdCritical' + ] + + headers = [ + 'Sensor Name', + 'State', + 'Health', + 'Location', + 'Value (Celcius)', + 'Upper Threshold (Celcius)' + ] + + self.my_output.my_table( + properties['Data']['Temperature'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_ucsc_thermal_fan_properties(self, properties): + order = [ + 'Name', + 'State', + 'Health', + 'Value' + ] + + headers = [ + 'Fan Name', + 'State', + 'Health', + 'Value' + ] + + self.my_output.my_table( + properties['Data']['Fan'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_ucsc_thermal_properties(self, properties): + self.print_ucsc_thermal_summary_properties(properties) + self.print_ucsc_thermal_temperature_properties(properties) + self.print_ucsc_thermal_fan_properties(properties) diff --git a/lib/self_doc.py b/lib/self_doc.py new file mode 100644 index 00000000..18c199af --- /dev/null +++ b/lib/self_doc.py @@ -0,0 +1,1154 @@ +import os +import sys +import json +import shutil +import traceback + +from lib import file_helper +from lib import filter_helper +from lib import ip_helper +from lib import template_helper + + +def get_doc_directory(): + main_dir = file_helper.get_main_dir() + return os.path.join( + main_dir, + 'doc' + ) + + +def get_templates_directory(): + return os.path.join( + file_helper.get_main_dir(), + 'doc-templates' + ) + + +def get_template(filename): + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + except BaseException: + print('Test read failed: %s' % (filename)) + print(traceback.format_exc()) + sys.exit(1) + + return content + + +def get_keywords(template_content): + keywords = [] + for line in template_content.split('\n'): + if line.startswith('DOC_TEMPLATE:'): + keywords.append( + dict( + result=line.split(':')[1], + filename=line.split(':')[2] + ) + ) + + return keywords + + +def get_template_names(template_names, include_redfish=False): + templates = {} + templates_directory = get_templates_directory() + for template_subdirectory in os.listdir(templates_directory): + if template_subdirectory.startswith('redfish') and not include_redfish: + continue + + if len(template_names) > 0 and template_subdirectory not in template_names: + continue + + templates[template_subdirectory] = [] + for template_filename in os.listdir(os.path.join(templates_directory, template_subdirectory)): + if template_filename.endswith('.md'): + if 'Template' not in template_filename: + templates[template_subdirectory].append(template_filename) + + return templates + + +def match_templates_with_results(all_templates, results): + templates = {} + templates_directory = get_templates_directory() + for template_group in all_templates: + templates[template_group] = [] + + for template_name in all_templates[template_group]: + template_filename = os.path.join( + os.path.join( + templates_directory, + template_group + ), + template_name + ) + + print('Checking template: %s' % (template_filename)) + template_content = get_template(template_filename) + template_keywords = get_keywords(template_content) + + if len(template_keywords) == 0: + print('- MATCH (no keywords)') + templates[template_group].append( + dict( + filename=template_filename, + content=template_content, + keywords=template_keywords + ) + ) + + if len(template_keywords) > 0: + match = True + for template_keyword in template_keywords: + if template_keyword['result'] not in results: + print('- NOK %s' % (template_keyword['result'])) + match = False + else: + print('- OK %s' % (template_keyword['result'])) + + if match: + print('- MATCH') + templates[template_group].append( + dict( + filename=template_filename, + content=template_content, + keywords=template_keywords + ) + ) + + return templates + + +def mask_password(line, pattern): + if ' %s ' % (pattern) not in line: + return line + + words = line.split(' ') + if pattern not in words: + return line + + index = words.index(pattern) + words[index + 1] = '******' + + return ' '.join(words) + + +def get_command(results_base_directory, results_directory, max_command_length=80): + filename = os.path.join( + os.path.join( + results_base_directory, + results_directory + ), + 'result' + ) + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + command = '# %s' % ( + mask_password( + content['command'], + '--password' + ) + ) + command = command.replace('python3 iserver.py', 'iserver') + command = command.replace('python.exe .\\iserver.py', 'iserver') + if '--help' not in command: + if len(command) > max_command_length: + command = command.replace(' --', '\n --') + + return command + + +def get_result(results_base_directory, results_directory, result_filename): + filename = os.path.join( + os.path.join( + results_base_directory, + results_directory + ), + result_filename + ) + try: + with open(filename, 'r', encoding='utf8', errors='ignore') as file_handler: + content = file_handler.read() + content = content.replace('\u2713', 'TICK_YES') + content = content.replace('\u2717', 'TICK_NO') + content = content.encode("ascii", "ignore") + content = content.decode() + content = content.replace('TICK_YES', 'V') + content = content.replace('TICK_NO', 'X') + content = content.lstrip('\n') + content = content.rstrip('\n') + + except BaseException: + print('Failed to read file: %s' % (filename)) + print(traceback.format_exc()) + sys.exit(1) + + return content + + +def replace_keywords(template_content, results_base_directory): + new_content = '' + for line in template_content.split('\n'): + if line.startswith('DOC_TEMPLATE:'): + results_directory = line.split(':')[1] + result_filename = line.split(':')[2] + command = get_command(results_base_directory, results_directory) + result = get_result(results_base_directory, results_directory, result_filename) + new_content = '%s\n%s\n\n%s' % ( + new_content, + command, + result + ) + continue + + if line.startswith('FILE:'): + results_directory = line.split(':')[1] + result_filename = line.split(':')[2] + + result = get_result(results_base_directory, results_directory, result_filename) + new_content = '%s\n%s' % ( + new_content, + result + ) + + continue + + if line.startswith('ODATA_DEBUG:'): + results_directory = line.split(':')[1] + result_filename = 'odata.debug' + odata = line.split(':')[2] + + command = get_command(results_base_directory, results_directory) + result = json.loads(get_result(results_base_directory, results_directory, result_filename)) + if odata in result: + new_content = '%s%s' % ( + new_content, + json.dumps(result[odata], indent=4) + ) + + continue + + if line.startswith('API_DEBUG:'): + results_directory = line.split(':')[1] + result_filename = 'api.debug' + api_command = ' %s ' % (line.split(':')[2]) + items_count = int(line.split(':')[3]) + + command = get_command(results_base_directory, results_directory) + result = json.loads(get_result(results_base_directory, results_directory, result_filename)) + for key in result: + if api_command in key: + if items_count == 0: + new_content = '%s\n%s\n\n%s' % ( + new_content, + key, + json.dumps(result[key], indent=4) + ) + + if items_count == 1: + new_content = '%s\n%s\n\n%s' % ( + new_content, + key, + json.dumps(result[key][0], indent=4) + ) + + break + + continue + + if new_content == '': + new_content = line + continue + + new_content = '%s\n%s' % ( + new_content, + line + ) + + return new_content + + +def get_results(results_directory): + if not os.path.isdir(results_directory): + print('Results directory not found: %s' % (results_directory)) + return None + + results = [] + for result_directory in os.listdir(results_directory): + directory_name = os.path.join(results_directory, result_directory) + result_filename = os.path.join(directory_name, 'result') + if os.path.isfile(result_filename): + try: + with open(result_filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + if content['success']: + results.append(result_directory) + + except BaseException: + print('[WARNING] Failed to open result file: %s' % (result_filename)) + + results = sorted(results) + return results + + +def get_templates_count(templates): + count = 0 + for template_group in templates: + count = count + len(templates[template_group]) + return count + + +def get_redfish_test_endpoints(): + templates_directory = get_templates_directory() + redfish_templates_directory = os.path.join(templates_directory, 'redfish') + redfish_test_templates_directory = os.path.join(redfish_templates_directory, 'tests') + tests_filename = os.path.join(redfish_test_templates_directory, 'tests.yaml') + if not os.path.isfile(tests_filename): + print('Redfish tests definition not found: %s' % (tests_filename)) + return None + + tests = file_helper.get_file_yaml( + tests_filename + ) + if tests is None: + print('Redfish tests definition read failed: %s' % (tests_filename)) + return None + + tests = sorted(tests, key=lambda i: (i['vendor'], i['model'])) + return tests + + +def get_redfish_test_table_content(tests): + endpoint_map = {} + endpoint_map['standard'] = 'EndpointStandard.md' + endpoint_map['ucsc'] = 'EndpointUcsc.md' + endpoint_map['fi'] = 'EndpointFi.md' + endpoint_map['hpe'] = 'EndpointHpe.md' + endpoint_map['dell'] = 'EndpointDell.md' + + content = '' + for test in tests: + resource = '[link](../redfish-tests-%s-%s/Resource.md)' % ( + test['vendor'].lower(), + test['model'].lower() + ) + oem = '' + if test['oem']: + oem = '[link](../redfish-tests-%s-%s/Oem.md)' % ( + test['vendor'].lower(), + test['model'].lower() + ) + action = '' + if test['action']: + action = '[link](../redfish-tests-%s-%s/Action.md)' % ( + test['vendor'].lower(), + test['model'].lower() + ) + identity = '' + if test['identity']: + identity = '[link](../redfish-tests-%s-%s/Identity.md)' % ( + test['vendor'].lower(), + test['model'].lower() + ) + power = '' + if test['power']: + power = '[link](../redfish-tests-%s-%s/Power.md)' % ( + test['vendor'].lower(), + test['model'].lower() + ) + thermal = '' + if test['thermal']: + thermal = '[link](../redfish-tests-%s-%s/Thermal.md)' % ( + test['vendor'].lower(), + test['model'].lower() + ) + + line = '%s | %s | [%s](./%s) | %s | %s | %s | %s | %s | %s' % ( + test['vendor'], + test['model'], + test['endpoint'], + endpoint_map[test['endpoint']], + resource, + oem, + action, + identity, + power, + thermal + ) + content = '%s%s\n' % (content, line) + + return content + + +def generate_redfish_readme_no_tests(): + redfish_templates_directory = os.path.join( + get_templates_directory(), + 'redfish' + ) + redfish_readme_template_filename = os.path.join( + redfish_templates_directory, + 'README.template_no_tests' + ) + redfish_readme_filename = os.path.join( + redfish_templates_directory, + 'README.md' + ) + + if not os.path.isfile(redfish_readme_template_filename): + print('Redfish readme template not found:%s' % (redfish_readme_template_filename)) + return False + + try: + with open(redfish_readme_template_filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + except BaseException: + print('Redfish readme read failed:%s' % (redfish_readme_template_filename)) + print(traceback.format_exc()) + return False + + try: + with open(redfish_readme_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(str(content)) + + except BaseException: + print('Redfish readme file write failed:%s' % (redfish_readme_filename)) + return False + + print('Readme generated: %s' % (redfish_readme_filename)) + return True + + +def generate_redfish_readme_tests(tests): + table_content = get_redfish_test_table_content(tests) + if table_content is None: + print('Redfish endpoints test table content generation failed') + return False + + redfish_templates_directory = os.path.join( + get_templates_directory(), + 'redfish' + ) + redfish_readme_template_filename = os.path.join( + redfish_templates_directory, + 'README.template_tests' + ) + redfish_readme_filename = os.path.join( + redfish_templates_directory, + 'README.md' + ) + + if not os.path.isfile(redfish_readme_template_filename): + print('Redfish readme template not found:%s' % (redfish_readme_template_filename)) + return False + + try: + with open(redfish_readme_template_filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + except BaseException: + print('Redfish readme read failed:%s' % (redfish_readme_template_filename)) + print(traceback.format_exc()) + return False + + new_content = '' + replaced = False + for line in content.split('\n'): + if line == 'REDFISH_TESTED_ENDPOINTS_TABLE': + replaced = True + new_content = '%s\n%s' % (new_content, table_content) + continue + + new_content = '%s\n%s' % (new_content, line) + + if not replaced: + print('Redfish readme table replacement failed') + return False + + try: + with open(redfish_readme_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(str(new_content)) + + except BaseException: + print('Redfish readme file write failed:%s' % (redfish_readme_filename)) + return False + + print('Readme generated: %s' % (redfish_readme_filename)) + return True + + +def clean_redfish_test_templates(): + base_directory = get_templates_directory() + for item in os.listdir(base_directory): + if item.startswith('redfish-tests-'): + dirname = os.path.join( + base_directory, + item + ) + if os.path.isdir(dirname): + shutil.rmtree(dirname) + + +def clean_redfish_test_doc(): + base_directory = get_doc_directory() + for item in os.listdir(base_directory): + if item.startswith('redfish-tests-'): + dirname = os.path.join( + base_directory, + item + ) + if os.path.isdir(dirname): + shutil.rmtree(dirname) + + +def get_redfish_tree(test, results_directory): + result = get_result( + results_directory, + '%s.tree' % (test['result']), + 'iserver.output.default' + ) + if result is None: + print('No result found: %s' % ('%s.tree' % (test['result']))) + sys.exit(1) + + try: + tree = json.loads(result) + except BaseException: + print('JSON format expected: %s' % ('%s.tree' % (test['result']))) + sys.exit(1) + + return tree + + +def get_redfish_root_children(test, results_directory): + result = get_result( + results_directory, + '%s.children' % (test['result']), + 'iserver.output.default' + ) + return json.loads(result) + + +def get_redfish_root_children_links(test, results_directory): + children = get_redfish_root_children(test, results_directory) + + children_names = [] + links = [] + for child in children: + if test['base_uri'] not in child: + continue + + if child == test['base_uri']: + continue + + child_name = child.lstrip(test['base_uri']).split('/')[0] + if child_name in children_names: + continue + + children_names.append(child_name) + links.append( + dict( + uri=child, + name=child_name + ) + ) + + return links + + +def get_redfish_root_children_links_content(test, results_directory): + links = get_redfish_root_children_links(test, results_directory) + + content = '' + for link in links: + line = '- [%s](./Uri%s.md)' % ( + link['uri'], + link['name'] + ) + content = '%s%s\n' % (content, line) + + return content + + +def generate_redfish_test_template(redfish_test_templates_directory, test_directory_name, template_name, test, results_directory): + template_handler = template_helper.TemplateHelper() + + template_filename = os.path.join( + redfish_test_templates_directory, + '%s.template' % (template_name) + ) + if not os.path.isfile(template_filename): + print('Template file not found: %s' % (template_filename)) + return False + + try: + with open(template_filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + except BaseException: + print('Redfish readme read failed:%s' % (template_filename)) + print(traceback.format_exc()) + return False + + variables = {} + variables['TEST_VENDOR'] = test['vendor'] + variables['TEST_MODEL'] = test['model'] + variables['TEST_RESULT'] = test['result'] + variables['ROOT_CHILDREN_LINKS'] = get_redfish_root_children_links_content(test, results_directory) + + new_content = template_handler.replace_variables(content, variables) + + target_template_filename = os.path.join( + test_directory_name, + '%s.md' % (template_name) + ) + try: + with open(target_template_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(str(new_content)) + + except BaseException: + print('Template file write failed:%s' % (target_template_filename)) + return False + + print('Template created: %s' % (target_template_filename)) + return True + + +def generate_redfish_resource_template(test_template_directory_name, test, results_directory): + links = get_redfish_root_children_links(test, results_directory) + tree = get_redfish_tree(test, results_directory) + for link in links: + target_template_filename = os.path.join( + test_template_directory_name, + 'Uri%s.md' % (link['name']) + ) + try: + content = '# Resource: %s\n\n' % (link['uri']) + content = '%s%s\n' % (content, 'Vendor | Model') + content = '%s%s\n' % (content, '--- | ---') + content = '%s%s\n\n' % (content, '%s | %s' % (test['vendor'], test['model'])) + for branch in tree: + if branch.startswith(link['uri']): + content = '%s%s\n\n' % (content, '## %s' % (branch)) + content = '%s%s\n' % (content, '```') + content = '%s%s\n' % (content, 'ODATA_DEBUG:%s.tree:%s' % (test['result'], branch)) + content = '%s%s\n\n' % (content, '```') + + with open(target_template_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(content) + + except BaseException: + print('Template file write failed:%s' % (target_template_filename)) + print(traceback.format_exc()) + return False + + print('Template created: %s' % (target_template_filename)) + + return True + + +def generate_redfish_tests(tests, results_directory): + redfish_templates_directory = os.path.join( + get_templates_directory(), + 'redfish' + ) + redfish_test_templates_directory = os.path.join( + redfish_templates_directory, + 'tests' + ) + + for test in tests: + test_template_directory_name = os.path.join( + get_templates_directory(), + 'redfish-tests-%s-%s' % ( + test['vendor'].lower(), + test['model'].lower() + ) + ) + if os.path.isdir(test_template_directory_name): + print('Test template not expected to exist: %s' % (test_template_directory_name)) + return False + + os.mkdir(test_template_directory_name) + + test_doc_directory_name = os.path.join( + get_doc_directory(), + 'redfish-tests-%s-%s' % ( + test['vendor'].lower(), + test['model'].lower() + ) + ) + + if os.path.isdir(test_doc_directory_name): + print('Test doc directory not expected to exist: %s' % (test_doc_directory_name)) + return False + + os.mkdir(test_doc_directory_name) + + for template_name in ['Resource', 'Oem', 'Action', 'Identity', 'Power', 'Thermal']: + if not generate_redfish_test_template(redfish_test_templates_directory, test_template_directory_name, template_name, test, results_directory): + print('Generating test %s template %s failed' % ( + test['model'], + template_name + )) + return False + + if not generate_redfish_resource_template(test_template_directory_name, test, results_directory): + print('Generating test %s resources failed' % ( + test['model'] + )) + return False + + return True + + +def generate_redfish_test_templates(results_directory): + tests = get_redfish_test_endpoints() + if tests is None: + return False + + if not generate_redfish_readme_tests(tests): + return False + + if not generate_redfish_tests(tests, results_directory): + return False + + return True + + +def generate_docs_from_templates(results_directory, template_names, include_redfish=False, replace={}): + results_directory = os.path.join( + file_helper.get_main_dir(), + results_directory + ) + results = get_results(results_directory) + if results is None: + return False + + selected_templates = get_template_names( + template_names, + include_redfish=include_redfish + ) + selected_templates_count = get_templates_count( + selected_templates + ) + + templates = match_templates_with_results( + selected_templates, + results + ) + templates_count = get_templates_count( + templates + ) + + print('\nMatching Templates:') + for template_group in templates: + for template_info in templates[template_group]: + print('- %s' % (template_info['filename'])) + + content = replace_keywords(template_info['content'], results_directory) + filename = os.path.join( + os.path.join( + get_doc_directory(), + template_group + ), + os.path.basename(template_info['filename']) + ) + for key in replace: + content = content.replace(key, replace[key]) + + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(str(content)) + + if templates_count < selected_templates_count: + print('\nFailed Templates:') + for all_template_group in selected_templates: + for all_template_filename in selected_templates[all_template_group]: + found = False + + reference_filename = os.path.join( + os.path.join( + get_templates_directory(), + all_template_group + ), + all_template_filename + ) + + for template_group in templates: + for template_info in templates[template_group]: + if template_info['filename'] == reference_filename: + found = True + break + + if not found: + print('- %s' % (reference_filename)) + + print('\nSummary') + print('All templates: %s' % (selected_templates_count)) + print('Matching templates: %s' % (templates_count)) + if selected_templates_count != templates_count: + return False + + return True + + +def generate_docs(results_directory, template_names=[], include_redfish=False, redfish_tests=False, replace={}): + if include_redfish: + clean_redfish_test_templates() + clean_redfish_test_doc() + if redfish_tests: + if not generate_redfish_test_templates(results_directory): + print('Redfish tests templates generation failed...') + return False + else: + generate_redfish_readme_no_tests() + + if not generate_docs_from_templates(results_directory, template_names, include_redfish=include_redfish, replace=replace): + print('Not all docs generated from templates...') + return False + + return True + + +def generate_template_docs(template_names=[]): + template_handler = template_helper.TemplateHelper() + + # {'aci': ['PolicyTemplate.md', 'PolicyTemplateAll.md', 'PolicyTemplateIntf.md', 'PolicyTemplateJson.md', 'PolicyTemplateName.md', 'PolicyTemplateUsage.md', 'PolicyTemplateVerbose.md']} + for template_name in template_names: + templates = {} + templates_directory = get_templates_directory() + for template_subdirectory in os.listdir(templates_directory): + if len(template_names) > 0 and template_subdirectory not in template_names: + continue + + templates[template_subdirectory] = [] + for template_filename in os.listdir(os.path.join(templates_directory, template_subdirectory)): + if template_filename.endswith('.md'): + if 'Template' in template_filename: + templates[template_subdirectory].append(template_filename) + + items = [] + items.append(['Slow Drain', 'Drain', 'drain']) + items.append(['Fibre Channel', 'Fc', 'fc']) + items.append(['Link Flap', 'Flap', 'flap']) + items.append(['L2', 'L2', 'l2']) + items.append(['Port Channel', 'Lacp', 'lacp']) + items.append(['Port Channel Member', 'Lacpm', 'lacpm']) + items.append(['Link Level', 'Link', 'link']) + items.append(['Link Level Flow Control', 'LinkFc', 'linkfc']) + items.append(['LLDP', 'Lldp', 'lldp']) + items.append(['MCP', 'Mcp', 'mcp']) + items.append(['Priority Flow Control', 'Pfc', 'pfc']) + items.append(['Port Security', 'Portsec', 'portsec']) + items.append(['Storm Control', 'Storm', 'storm']) + items.append(['Spanning Tree', 'Stp', 'stp']) + items.append(['Synchronous Ethernet', 'Synce', 'synce']) + items.append(['Transceiver', 'Trans', 'trans']) + + for key in templates: + for filename in templates[key]: + template_filename = os.path.join( + os.path.join( + templates_directory, + key + ), + filename + ) + + if not os.path.isfile(template_filename): + print('File not found: %s' % (template_filename)) + continue + + print('File found: %s' % (template_filename)) + for item in items: + new_filename = template_filename.replace('Template', item[1]) + print(new_filename) + if os.path.isfile(new_filename): + print('Already exists...') + continue + + try: + with open(template_filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + except BaseException: + print('Failed to read: %s' % (template_filename)) + return False + + variables = {} + variables['TITLE'] = item[0] + variables['NAME'] = item[1] + variables['TEST'] = item[2] + + new_content = template_handler.replace_variables(content, variables) + + try: + with open(new_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(str(new_content)) + + except BaseException: + print('Template file write failed:%s' % (new_filename)) + return False + + print('Created') + + return True + + +def sanitize_anonymize_content(content): + new_content = [] + for line in content.split('\r\n'): + new_content.append(line) + return '\n'.join(new_content) + + +def anonymize_line(line, rule, allowed): + if rule['key'] == '__IP__': + ips = ip_helper.get_string_ipv4s(line) + for ip_address in ips: + if ip_address not in allowed: + if rule['value'] == '__MASK__': + line = line.replace( + ip_address, + ip_helper.get_obscured_ipv4(ip_address) + ) + else: + line = line.replace( + ip_address, + rule['value'] + ) + + return line + + if rule['key'] == '__MAC__': + macs = ip_helper.get_string_macs(line) + for mac in macs: + if mac not in allowed: + if rule['value'] == '__MASK__': + line = line.replace( + mac, + ip_helper.get_obscured_mac(mac) + ) + else: + line = line.replace( + mac, + rule['value'] + ) + + return line + + if filter_helper.match_string('*%s*' % (rule['key']), line): + line = line.replace(rule['key'], rule['value']) + + return line + + +def anonymize_file(content, rule, allowed): + count = 0 + started = False + if 'after' not in rule: + started = True + + new_content = [] + for line in content.split('\n'): + if not started: + new_content.append( + line + ) + if 'after' in rule: + if filter_helper.match_string(rule['after'], line): + started = True + + continue + + new_line = anonymize_line(line, rule, allowed) + if line != new_line: + count = count + 1 + + new_content.append(new_line) + + return '\n'.join(new_content), count + + +def anonymize_section(section): + directory = get_doc_directory() + for subdir in section['directory'].split(','): + directory = os.path.join( + directory, + subdir + ) + + if not os.path.isdir(directory): + print('Target directory not found: %s' % (directory)) + return False + + print('Directory: %s' % (directory)) + + for file_in_dir in os.listdir(directory): + filename = os.path.join( + directory, + file_in_dir + ) + if not os.path.isfile(filename): + continue + + file_match = False + for file_match_rule in section['files']: + if filter_helper.match_string(file_match_rule, file_in_dir): + file_match = True + + if not file_match: + continue + + content = file_helper.get_file(filename) + if content is None: + print('File read failed: %s' % (filename)) + return False + + content = sanitize_anonymize_content(content) + + total_count = 0 + for rule in section['rules']: + content, count = anonymize_file(content, rule, section['allowed']) + if content is None: + return False + + total_count = total_count + count + + print('- %s [%s]' % (os.path.basename(filename), total_count)) + + if total_count > 0: + if not file_helper.set_file(filename, content): + print('File anonymize failed') + return False + + return True + + +def verify_anonymized_string(line, forbidden, allowed): + ips = ip_helper.get_string_ipv4s(line) + macs = ip_helper.get_string_macs(line) + + success = True + + for rule in forbidden: + if rule == '__IP__': + if len(ips) > 0: + print('Failed on IP check: %s' % (ips)) + success = False + + if rule == '__MAC__': + if len(macs) > 0: + print('Failed on MAC check: %s' % (macs)) + success = False + + if rule not in ['__IP__', '__MAC__']: + if filter_helper.match_string('*%s*' % (rule), line): + overruled = False + for item in allowed: + if rule in item: + if filter_helper.match_string('*%s*' % (item), line): + overruled = True + + if not overruled: + print('Failed on string check: %s' % (rule)) + success = False + + if not success: + print('Line: %s' % (line)) + + return success + + +def verify_anonymized_content(content, forbidden, allowed, break_on_error=True): + success = True + for line in content.split('\n'): + success = success and verify_anonymized_string( + line, + forbidden, + allowed + ) + if break_on_error and not success: + return success + + return success + + +def verify_anonymize_docs(directory=None, break_on_error=True): + print('Verify...') + filename = os.path.join( + get_doc_directory(), + 'sanity.json' + ) + if not os.path.isfile(filename): + print('[ERROR] Anonymize rules file not found: %s' % (filename)) + return False + + sanity_rules = file_helper.get_file_json(filename) + if sanity_rules is None: + print('[ERROR] Sanity rules file read failed: %s' % (filename)) + return False + + ignored_directories = ['psirt'] + success = True + for subdirectory in os.listdir(get_doc_directory()): + if subdirectory in ignored_directories: + continue + + if directory is not None and subdirectory not in directory: + continue + + directory_name = os.path.join( + get_doc_directory(), + subdirectory + ) + if os.path.isdir(directory_name): + for child_name in os.listdir(directory_name): + if child_name.endswith('.md'): + filename = os.path.join(directory_name, child_name) + content = file_helper.get_file(filename) + if content is None: + print('File read failed: %s' % (filename)) + return False + + print('- %s' % (filename)) + success = success and verify_anonymized_content( + content, + sanity_rules['forbidden'], + sanity_rules['allowed'], + break_on_error=break_on_error + ) + + if break_on_error and not success: + return success + + return success + + +def anonymize_docs(verify=True): + filename = os.path.join( + get_doc_directory(), + 'anonymize.json' + ) + if not os.path.isfile(filename): + print('[ERROR] Anonymize rules file not found: %s' % (filename)) + return False + + anonymize_rules = file_helper.get_file_json(filename) + if anonymize_rules is None: + print('[ERROR] Anonymize rules file read failed: %s' % (filename)) + return False + + for anonymize_rule in anonymize_rules: + success = anonymize_section(anonymize_rule) + if not success: + return False + + success = True + if verify: + success = verify_anonymize_docs( + break_on_error=True + ) + + return success diff --git a/lib/self_testing.py b/lib/self_testing.py new file mode 100644 index 00000000..6cb9c767 --- /dev/null +++ b/lib/self_testing.py @@ -0,0 +1,901 @@ +import json +import datetime +import os +import re +import sys +import time +import subprocess +import traceback +import shutil +import platform + +from progress.bar import Bar + +from lib import log_helper +from lib import template_helper +from lib import isctl_helper + + +def print_traceback(info): + print(info) + + +def print_error(output): + print('[ERROR] %s' % (output)) + + +def tests_fixup(directory): + if not os.path.isdir(directory): + return + + for test_filename in os.listdir(directory): + print('Test: %s' % (test_filename)) + + filename = os.path.join(directory, test_filename) + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + + except BaseException: + print('Read failed: %s' % (filename)) + sys.exit(1) + + try: + if 'name' in content: + del content['name'] + + with open(filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(content, indent=4)) + + print('- name key removed') + except BaseException: + print('Fixup failed: %s' % (filename)) + sys.exit(1) + + if filename.endswith('.json'): + dst = os.path.join(directory, test_filename.rstrip('json').rstrip('.')) + shutil.move(filename, dst) + print('- filename changed %s' % (dst)) + + if filename.endswith('.collection'): + dst = os.path.join(directory, test_filename.rstrip('collection').rstrip('.')) + shutil.move(filename, dst) + print('- filename changed %s' % (dst)) + + +def get_test_iaccount(test_filename, directory): + test_definition = get_test( + test_filename, + directory + ) + + if test_definition is None: + print('Test not found: %s' % (test_filename)) + sys.exit(1) + + if 'iaccount' not in test_definition: + return None + + return test_definition['iaccount'] + + +def get_test_environment(test_filename, directory): + test_definition = get_test( + test_filename, + directory + ) + + if 'environment' not in test_definition: + return None + + return test_definition['environment'] + + +def get_test_commands(test): + iserver_prefix = get_iserver_prefix() + commands = [] + if 'help' in test: + filename = '%s.%s' % (test['name'], 'help') + command = '%s %s' % (iserver_prefix, test['help']) + commands.append(command) + + if 'functionality' in test: + for key in test['functionality']: + filename = '%s.%s' % (test['name'], key) + command = '%s %s' % (iserver_prefix, test['functionality'][key]) + commands.append(command) + + if 'negative' in test: + for key in test['negative']: + filename = '%s.%s' % (test['name'], key) + command = '%s %s' % (iserver_prefix, test['negative'][key]) + commands.append(command) + + return commands + + +def get_summary(directory, replace=True): + results = get_test_results() + duration = 0 + for result in results: + duration = duration + result['duration'] + + tests, tests_count = get_tests_collection('all', directory) + commands = [] + for test in tests: + test_commands = get_test_commands(test) + for test_command in test_commands: + if replace: + test_command = replace_variables(test, test_command) + if test_command not in commands: + commands.append(test_command) + + print('Defined test commands: %s' % (len(commands))) + + successful = [] + failed = [] + missed = [] + for command in commands: + found = False + for result in results: + if result['command'] == command: + found = True + if result['success']: + successful.append(command) + else: + failed.append(command) + + break + + if not found: + missed.append(command) + + print('Successul tests: %s/%s' % (len(successful), len(commands))) + print('Failed tests: %s/%s' % (len(failed), len(commands))) + print('Missed tests: %s/%s' % (len(missed), len(commands))) + seconds = int(duration / 1000) + print('Total durarion: %s' % (datetime.timedelta(seconds=seconds))) + + print('\nSuccessful tests:') + for success in successful: + print('- %s' % (success)) + + print('\nFailed tests:') + for failure in failed: + print('- %s' % (failure)) + print('\nMissed tests:') + for miss in missed: + print('- %s' % (miss)) + + references = [] + for test in tests: + if test['command'] not in references: + references.append(test['command']) + references = sorted(references) + + print('\nDefined cli groups: %s' % (len(references))) + + not_tested = [] + rs_missed = {} + for reference in references: + rs_missed[reference] = [] + for test in tests: + success = True + if test['command'] == reference: + test_commands = get_test_commands(test) + for test_command in test_commands: + if test_command in failed or test_command in missed: + success = False + rs_missed[reference].append(test_command) + + if not success: + if reference not in not_tested: + not_tested.append(reference) + + tested = [] + for reference in references: + if reference not in not_tested: + if reference not in tested: + tested.append(reference) + + print('Tested cli groups: %s' % (len(tested))) + for item in tested: + print('- %s' % (item)) + print('Not-tested cli groups: %s' % (len(not_tested))) + for item in not_tested: + print('- %s' % (item)) + for miss in rs_missed[item]: + print('\t%s' % (miss)) + + +def get_test_results(): + results = [] + directory = './results' + if os.path.isdir(directory): + for item in os.listdir(directory): + item_dir = os.path.join(directory, item) + result_filename = os.path.join( + os.path.join(directory, item), + 'result' + ) + if not os.path.isfile(result_filename): + continue + + try: + with open(result_filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + except BaseException: + print_error('Result read failed: %s' % (result_filename)) + sys.exit(1) + + results.append(content) + + return results + + +def get_test(test_filename, directory): + filename = os.path.join(directory, test_filename) + content = None + if os.path.isfile(filename): + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = json.loads(file_handler.read()) + content['name'] = test_filename + except BaseException: + print_error('Test read failed: %s' % (filename)) + print_error(traceback.format_exc()) + + return content + + +def match_test(test_definition, test_name): + if test_name is not None and test_definition['name'] == test_name: + return True + + return False + + +def get_tests_count(test_definition, skip=[], exclude_dry_run=False): + count = 0 + if 'help' not in skip and 'help' in test_definition: + count = count + 1 + + if 'functionality' not in skip and 'functionality' in test_definition: + if exclude_dry_run: + for key in test_definition['functionality']: + if '--dry-run' not in test_definition['functionality'][key]: + count = count + 1 + else: + count = count + len(test_definition['functionality']) + + if 'negative' not in skip and 'negative' in test_definition: + count = count + len(test_definition['negative']) + + return count + + +def get_test_by_name(test_name, directory): + if not os.path.isdir(directory): + print_error('Test directory not found: %s' % (directory)) + sys.exit(1) + + tests = [] + tests_count = 0 + for test_filename in os.listdir(directory): + test_definition = get_test(test_filename, directory) + if test_definition is not None: + if test_definition['type'] == 'test': + if match_test(test_definition, test_name): + tests_count = tests_count + get_tests_count(test_definition) + tests.append(test_definition) + + return tests, tests_count + + +def get_tests(directory, names=False): + """Get all tests with type 'test'""" + tests = [] + if not os.path.isdir(directory): + return tests + + for test_filename in os.listdir(directory): + test_definition = get_test(test_filename, directory) + if test_definition is not None: + if test_definition['type'] == 'test': + if names: + tests.append(test_filename) + else: + tests.append(test_definition) + + return tests + + +def get_tests_collections(directory, names=False): + """Get all tests with type 'collection'""" + tests = [] + if not os.path.isdir(directory): + return tests + + for test_filename in os.listdir(directory): + test_definition = get_test(test_filename, directory) + if test_definition is not None: + if test_definition['type'] == 'collection': + if names: + tests.append(test_filename) + else: + tests.append(test_definition) + + if names: + tests = sorted(tests) + + return tests + + +def get_tests_collection_info(test_collection, directory): + tests, tests_count = get_tests_collection(test_collection, directory) + commands = [] + for test in tests: + test_commands = get_test_commands(test) + for test_command in test_commands: + if test_command not in commands: + commands.append(test_command) + commands = sorted(commands) + + all_tests = get_tests(directory) + all_commands = [] + for test in all_tests: + test_commands = get_test_commands(test) + for test_command in test_commands: + if test_command not in all_commands: + all_commands.append(test_command) + all_commands = sorted(all_commands) + + print('Defined test commands: %s' % (len(all_commands))) + print('Test collection commands: %s' % (len(commands))) + + print('Supported commands:') + for command in commands: + print('- %s' % (command)) + print() + + if len(commands) < len(all_commands): + print('Missing commands:') + for command in all_commands: + if command not in commands: + print('- %s' % (command)) + + +def get_tests_collection(test_collection, directory, skip=[], exclude_dry_run=False): + if not os.path.isdir(directory): + print_error('Test directory not found: %s' % (directory)) + sys.exit(1) + + tests = [] + tests_count = 0 + collection_filename = test_collection + collection = get_test(collection_filename, directory) + if collection is not None: + if collection['type'] == 'collection': + if 'collections' in collection: + for collection_item in collection['collections']: + c_tests, c_count = get_tests_collection(collection_item['name'], directory, skip=skip, exclude_dry_run=exclude_dry_run) + for c_test in c_tests: + tests.append(c_test) + tests_count = tests_count + c_count + + if 'tests' in collection: + for test in collection['tests']: + test_definition = get_test(test['name'], directory) + if test_definition is not None: + if test_definition['type'] == 'test': + tests_count = tests_count + get_tests_count(test_definition, skip=skip, exclude_dry_run=exclude_dry_run) + tests.append(test_definition) + + return tests, tests_count + + +def delete_test_result(results_directory, bar_handler, test): + if 'help' in test: + filename = '%s.%s' % (test['name'], 'help') + result_location = os.path.join('./%s/' % (results_directory), filename) + if os.path.isdir(result_location): + shutil.rmtree(result_location) + bar_handler.next() + + if 'functionality' in test: + for key in test['functionality']: + filename = '%s.%s' % (test['name'], key) + result_location = os.path.join('./%s/' % (results_directory), filename) + if os.path.isdir(result_location): + shutil.rmtree(result_location) + bar_handler.next() + + if 'negative' in test: + for key in test['negative']: + filename = '%s.%s' % (test['name'], key) + result_location = os.path.join('./%s/' % (results_directory), filename) + if os.path.isdir(result_location): + shutil.rmtree(result_location) + bar_handler.next() + + return True + + +def escape_ansi(line): + ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]') + line = ansi_escape.sub('', line) + line = line.replace('\u2713', 'v') + line = line.replace('\u2717', 'x') + return line + + +def save_test_result(results_directory, filename, command, ref_command, success, exit_code, output, duration, version): + result_location = os.path.join('./%s/' % (results_directory), filename) + if not os.path.isdir(result_location): + os.makedirs(result_location) + + output_filename = os.path.join(result_location, 'output') + with open(output_filename, 'w', encoding='utf-8', newline='\n') as file_handler: + file_handler.write( + escape_ansi( + output + ) + ) + + result = dict( + reference=ref_command, + command=command, + iserver_version=version, + success=success, + exit_code=exit_code, + duration=duration + ) + result_filename = os.path.join(result_location, 'result') + with open(result_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(result, indent=4)) + + if '--help' not in command: + log = log_helper.Log() + search_command = command.lstrip('python3').lstrip('python.exe').lstrip(' ') + log_directory = log.get_command_directory(search_command, debug=False) + if log_directory is None: + print('Failed to find log directory: %s' % (search_command)) + sys.exit(1) + + for log_filename in os.listdir(log_directory): + source = os.path.join(log_directory, log_filename) + if os.path.isfile(source): + dst = os.path.join(result_location, log_filename) + shutil.copyfile(source, dst) + + +def extend_variables(variables, exec_section, iaccount): + ''' + "exec": { + "isctl": "firmware serverconfigurationutilitydistributable --name \"SCU 6.2.2a\" -o json", + "attribute": "Moid", + "variable": "SCU_ID" + }, + "exec": { + "system": "python iserver.py get workflows --serial ${WORKFLOW_SERIAL} --days 7 --count 1 -o json", + "index": 0, + "attribute": "workflow_id", + "variable": "GET_WORKFLOW_ID" + }, + ''' + template_handler = template_helper.TemplateHelper() + + if 'isctl' in exec_section: + for key in ['attribute', 'variable']: + if key not in exec_section: + print('No key found in exec') + sys.exit(1) + + isctl_handler = isctl_helper.Isctl(iaccount) + command = template_handler.replace_variables(exec_section['isctl'], variables) + response = isctl_handler.get(command, json_conversion=True) + if response is None: + print('Command failed: %s' % (command)) + sys.exit(1) + + if exec_section['attribute'] not in response: + print('Attribute not found in response: %s' % (exec_section['attribute'])) + sys.exit(1) + + variables[exec_section['variable']] = response[exec_section['attribute']] + + if 'system' in exec_section: + command = template_handler.replace_variables(exec_section['system'], variables) + + my_os = platform.system() + if my_os == 'Windows': + command = command.replace('python ', 'python.exe ') + command = command.replace('isctl ', 'isctl.exe ') + else: + command = command.replace('python ', 'python3 ') + + try: + (return_code, output, duration) = get_output(command) + except BaseException: + print('Failed to execute: %s' % (command)) + sys.exit(1) + + if return_code != 0: + print('Command exit code %s: %s' % (return_code, command)) + sys.exit(1) + + try: + response = json.loads(output.replace('\r\n', '')) + except BaseException: + print('Failed to JSON parse out of: %s' % (command)) + print(output) + sys.exit(1) + + if 'index' in exec_section: + if exec_section['attribute'] not in response[exec_section['index']]: + print('Attribute not found in response list: %s' % (exec_section['attribute'])) + sys.exit(1) + + variables[exec_section['variable']] = response[exec_section['index']][exec_section['attribute']] + + else: + if exec_section['attribute'] not in response: + print('Attribute not found in response: %s' % (exec_section['attribute'])) + sys.exit(1) + + variables[exec_section['variable']] = response[exec_section['attribute']] + + return variables + + +def replace_variables(test, command): + new_command = [] + for word in command.split(' '): + if 'variables' in test and word in test['variables']: + exit_code, output, duration = get_output(test['variables'][word]) + if exit_code > 0: + print('Variable %s resolution failed' % (word)) + sys.exit(1) + new_command.append(output) + + else: + new_command.append(word) + + return ' '.join(new_command) + + +def get_output(command): + try: + start_time = int(time.time() * 1000) + with subprocess.Popen( + args=command, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + env=os.environ + ) as process: + output, error = process.communicate() + duration = int(time.time() * 1000) - start_time + return process.returncode, output.decode('utf-8', 'ignore'), duration + + except BaseException: + print_error(traceback.format_exc()) + sys.exit(1) + + +def save_script_result(results_directory, filename, key, directory, script, command, success, exit_code, output, duration): + result_location = os.path.join('./%s/' % (results_directory), filename) + if not os.path.isdir(result_location): + os.makedirs(result_location) + + output_filename = os.path.join(result_location, 'script.%s.%s.output' % (key, script)) + with open(output_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(output) + + result = dict( + success=success, + command=command, + exit_code=exit_code, + duration=duration + ) + result_filename = os.path.join(result_location, 'script.%s.%s.result' % (key, script)) + with open(result_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(result, indent=4)) + + +def is_test_script(script, directory): + script_directory = os.path.join(directory, 'scripts') + script_filename = os.path.join(script_directory, script) + if not os.path.isfile(script_filename): + return False + return True + + +def run_script(results_directory, filename, key, directory, script): + script_directory = os.path.join(directory, 'scripts') + script_filename = os.path.join(script_directory, script[0]) + + command = './%s %s' % (script_filename, ' '.join(script[1:])) + exit_code, output, duration = get_output(command) + success = bool(exit_code == 0) + + save_script_result(results_directory, filename, key, directory, script[0], command, success, exit_code, output, duration) + return success + + +def run_pre_scripts(results_directory, filename, test, key, tests_directory, dry_run=False): + if 'scripts' not in test or key not in test['scripts']: + return True + + if 'pre' not in test['scripts'][key] or len(test['scripts'][key]['pre']) == 0: + return True + + for script in test['scripts'][key]['pre']: + if dry_run: + if is_test_script(script[0], tests_directory): + print('[%s] pre: %s' % (test['name'], script[0])) + else: + print('[%s] pre [NOT FOUND]: %s' % (test['name'], script[0])) + + else: + if not run_script(results_directory, filename, key, tests_directory, script): + print('Pre script failed: [%s] [%s] %s' % (test['name'], key, script[0])) + return False + + return True + + +def run_post_scripts(results_directory, filename, test, key, tests_directory, dry_run=False): + if 'scripts' not in test or key not in test['scripts']: + return True + + if 'post' not in test['scripts'][key] or len(test['scripts'][key]['post']) == 0: + return True + + for script in test['scripts'][key]['post']: + if dry_run: + if is_test_script(script[0], tests_directory): + print('[%s] post: %s' % (test['name'], script[0])) + else: + print('[%s] post [NOT FOUND]: %s' % (test['name'], script[0])) + + else: + if not run_script(results_directory, filename, key, tests_directory, script): + print('Post script failed: [%s] [%s] %s' % (test['name'], key, script[0])) + return False + + return True + + +def run_test(bar_handler, test, tests_directory, results_directory, variables, iaccount, verbose, debug, dry_run, iserver_prefix, iserver_version, save_result=True, skip=[], exclude_dry_run=False, wait=False): + results = [] + template_handler = template_helper.TemplateHelper() + + if 'help' not in skip and 'help' in test: + filename = '%s.%s' % (test['name'], 'help') + command = '%s %s' % (iserver_prefix, test['help']) + command = template_handler.replace_variables(command, variables) + + if dry_run: + print('[%s] %s' % (test['name'], command)) + else: + exit_code, output, duration = get_output(command) + success = bool(exit_code == 0) + + if save_result: + save_test_result(results_directory, filename, command, test['command'], success, exit_code, output, duration, iserver_version) + + results.append( + dict( + command=command, + success=success + ) + ) + if not success: + print('Command failed: %s' % (command)) + sys.exit(1) + + bar_handler.next() + + if 'exec' in test: + variables = extend_variables(variables, test['exec'], iaccount) + + if 'functionality' not in skip and 'functionality' in test: + for key in test['functionality']: + if key.startswith('wait_'): + time.sleep(test['functionality'][key]) + + results.append( + dict( + command='sleep', + success=True + ) + ) + + bar_handler.next() + continue + + filename = '%s.%s' % (test['name'], key) + command = '%s %s' % (iserver_prefix, test['functionality'][key]) + command = template_handler.replace_variables(command, variables) + + if exclude_dry_run and '--dry-run' in command: + continue + + if dry_run: + command = replace_variables(test, command) + run_pre_scripts(results_directory, filename, test, key, tests_directory, dry_run=True) + print('[%s] %s' % (test['name'], command)) + run_post_scripts(results_directory, filename, test, key, tests_directory, dry_run=True) + else: + command = replace_variables(test, command) + if not run_pre_scripts(results_directory, filename, test, key, tests_directory): + sys.exit(1) + + exit_code, output, duration = get_output(command) + success = bool(exit_code == 0) + + if save_result: + save_test_result(results_directory, filename, command, test['command'], success, exit_code, output, duration, iserver_version) + + results.append( + dict( + command=command, + success=success + ) + ) + if not success: + print('\nCommand failed: %s' % (command)) + print(output) + sys.exit(1) + + if not run_post_scripts(results_directory, filename, test, key, tests_directory): + sys.exit(1) + + bar_handler.next() + + if wait: + input("Press Enter to continue...") + + if 'negative' not in skip and 'negative' in test: + for key in test['negative']: + filename = '%s.%s' % (test['name'], key) + command = '%s %s' % (iserver_prefix, test['negative'][key]) + command = template_handler.replace_variables(command, variables) + + if exclude_dry_run and '--dry-run' in command: + continue + + if dry_run: + command = replace_variables(test, command) + run_pre_scripts(results_directory, filename, test, key, tests_directory, dry_run=True) + print('[%s] %s' % (test['name'], command)) + run_post_scripts(results_directory, filename, test, key, tests_directory, dry_run=True) + else: + command = replace_variables(test, command) + if not run_pre_scripts(results_directory, filename, test, key, tests_directory): + sys.exit(1) + + exit_code, output, duration = get_output(command) + success = bool(exit_code > 0) + + if save_result: + save_test_result(results_directory, filename, command, test['command'], success, exit_code, output, duration, iserver_version) + + results.append( + dict( + command=command, + success=success + ) + ) + if not success: + print('Command failed: %s' % (command)) + sys.exit(1) + + if not run_post_scripts(results_directory, filename, test, key, tests_directory): + sys.exit(1) + + bar_handler.next() + + if wait: + input("Press Enter to continue...") + + return results + + +def load_test_variables(directory, environment): + variables = {} + bundle_dir = os.path.dirname(getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))) + tests_directory = os.path.join(bundle_dir, directory) + + if len(environment) > 0: + environment_directory = os.path.join(tests_directory, 'environment') + environment_file = os.path.join(environment_directory, environment) + if not os.path.isfile(environment_file): + print('Environment file not found: %s' % (environment_file)) + return None + + with open(environment_file, 'r', encoding='utf-8') as file_handler: + variables = json.loads(file_handler.read()) + + cloud_init_directory = os.path.join(tests_directory, 'cloud-init') + variables['CLOUD_INIT_DIRECTORY'] = cloud_init_directory + + return variables + + +def get_iserver_prefix(): + iserver_prefix = 'python3 iserver.py' + my_os = platform.system() + if my_os == 'Windows': + iserver_prefix = 'python.exe .\\iserver.py' + return iserver_prefix + + +def run_tests(tests, tests_count, tests_directory, results_directory, environment, iaccount, honor, verbose, debug, dry_run, wait=False): + variables = load_test_variables(tests_directory, environment) + if variables is None: + return [] + + results = [] + version_filename = './version' + with open(version_filename, 'r', encoding='utf-8') as file_handler: + iserver_version = file_handler.read().rstrip('\n') + + if not dry_run: + bar_handler = Bar('Cleanup', max=tests_count) + for test in tests: + if not delete_test_result(results_directory, bar_handler, test): + sys.exit(1) + bar_handler.finish() + + bar_handler = Bar('Processing', max=tests_count) + bar_handler.goto(0) + for test in tests: + if honor: + test_iaccount = iaccount + if 'iaccount' in test: + test_iaccount = test['iaccount'] + + test_variables = variables + if 'environment' in test: + test_variables = load_test_variables(tests_directory, test['environment']) + + test_results = run_test( + bar_handler, + test, + tests_directory, + results_directory, + test_variables, + test_iaccount, + verbose, + debug, + dry_run, + get_iserver_prefix(), + iserver_version, + wait=wait + ) + else: + test_results = run_test( + bar_handler, + test, + tests_directory, + results_directory, + variables, + iaccount, + verbose, + debug, + dry_run, + get_iserver_prefix(), + iserver_version, + wait=wait + ) + for test_result in test_results: + results.append(test_result) + + if wait: + input("Press Enter to continue...") + + bar_handler.finish() + + return results diff --git a/lib/settings_helper.py b/lib/settings_helper.py new file mode 100644 index 00000000..b06de690 --- /dev/null +++ b/lib/settings_helper.py @@ -0,0 +1,154 @@ +import json +import os +import subprocess +import traceback +from pathlib import Path + +from lib import log_helper + + +class Settings(): + def __init__(self, log_id=None): + self.log = log_helper.Log(log_id=log_id) + self.home_dir = self.get_home_directory() + + self.settings_dir = os.path.join( + self.home_dir, + '.itool' + ) + + self.iaccount_dir = os.path.join( + self.settings_dir, + 'iaccount' + ) + + self.ssh_dir = os.path.join( + self.settings_dir, + 'ssh' + ) + + self.settings_filename = os.path.join( + self.settings_dir, + 'settings' + ) + + def get_home_directory(self): + return str(Path.home()) + + def get_settings_dir(self): + return self.settings_dir + + def initialize_settings(self): + for directory in [self.settings_dir, self.iaccount_dir, self.ssh_dir]: + if not os.path.isdir(directory): + os.makedirs(directory) + + if not self.is_settings() or self.get_settings() is None: + if not self.rfd_settings(): + return False + else: + if not self.fixup_settings(): + return False + + return True + + def run(self, command): + try: + with subprocess.Popen( + args=command, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + env=os.environ + ) as process: + output, error = process.communicate() + return process.returncode, output.decode('utf-8') + except BaseException: + return 1, 'Traceback' + + def is_settings(self): + ''' + Returns True if $HOME/.iwectl/settings file exists + Returns False otherwise + ''' + return os.path.isfile(self.settings_filename) + + def get_default_settings(self): + settings = {} + settings['iaccount'] = None + + return settings + + def rfd_settings(self): + settings = self.get_default_settings() + return self.set_settings(settings) + + def fixup_settings(self): + settings = self.get_settings() + default_settings = self.get_default_settings() + + fixup_required = False + for default_setting in default_settings: + if default_setting not in settings: + fixup_required = True + break + + for setting in settings: + if setting not in default_settings: + fixup_required = True + break + + if fixup_required: + new_settings = {} + + # First copy valid settings + for setting in settings: + if setting in default_settings: + new_settings[setting] = settings[setting] + + # Add default settings only if not defined + for default_setting in default_settings: + if default_setting not in new_settings: + new_settings[default_setting] = default_settings[default_setting] + + return self.set_settings(new_settings) + + return True + + def get_settings(self): + if self.is_settings(): + try: + with open(self.settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + return settings + except BaseException: + self.log.error('settings_helper.get_settings', traceback.format_exc()) + return None + + def set_settings(self, settings): + ''' + Returns True/False + ''' + try: + with open(self.settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + except BaseException: + self.log.error('settings_helper.set_settings', traceback.format_exc()) + return False + return True + + def get_setting(self, key, default=None): + settings = self.get_settings() + if settings is not None: + if key in settings: + return settings[key] + if default is not None: + return default + return None + + def set_setting(self, key, value): + settings = self.get_settings() + if settings is not None: + settings[key] = value + return self.set_settings(settings) + return False diff --git a/lib/ssh.py b/lib/ssh.py new file mode 100644 index 00000000..792106aa --- /dev/null +++ b/lib/ssh.py @@ -0,0 +1,787 @@ +import os +import re +import uuid +import time +import hashlib +import traceback +import json +import warnings +import yaml + +warnings.filterwarnings(action='ignore', module='.*paramiko.*') + +# pylint: disable=wrong-import-position +import paramiko +from paramiko import SSHClient + +from lib import template +from lib import file_helper +from lib import log_helper + + +class Ssh(): + def __init__(self, ip_address, username, port=22, password=None, key_filename=None, load_system_host_keys=False, endpoint_type=None, verbose=False, debug=False, log_id=None, timeout=10): + self.log_handler = log_helper.Log(log_id=log_id) + self.ip_address = ip_address + self.username = username + self.password = password + self.port = port + self.key_filename = key_filename + self.timeout = timeout + self.load_system_host_keys = load_system_host_keys + self.endpoint_type = endpoint_type + if self.endpoint_type is None: + self.endpoint_type = 'standard' + + self.template_handler = template.Template(verbose=verbose, debug=debug) + + def create_session(self, max_attempts=1): + attempt = 1 + while True: + try: + success = True + session = SSHClient() + if self.load_system_host_keys: + session.load_system_host_keys() + session.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + if self.endpoint_type not in ['standard', 'cisco']: + self.log_handler.error( + 'create_session', + 'Unsupported endpoint type: %s' % (self.endpoint_type) + ) + return None + + if self.endpoint_type == 'standard': + if self.password is not None: + session.connect( + self.ip_address, + port=self.port, + username=self.username, + password=self.password, + timeout=self.timeout + ) + + if self.key_filename is not None: + session.connect( + self.ip_address, + port=self.port, + username=self.username, + key_filename=self.key_filename, + timeout=self.timeout + ) + + if self.endpoint_type == 'cisco': + session.connect( + self.ip_address, + port=self.port, + username=self.username, + password=self.password, + timeout=self.timeout, + allow_agent=False, + look_for_keys=False + ) + + except BaseException: + self.log_handler.error( + 'create_session', + traceback.format_exc() + ) + success = False + if session is not None: + session.close() + + if success: + self.log_handler.debug( + 'create_session', + 'Session created at %s' % (self.ip_address) + ) + return session + + if attempt == max_attempts: + return None + + time.sleep(1) + attempt = attempt + 1 + + def is_ssh(self): + session = self.create_session(max_attempts=1) + if session is None: + return False + + session.close() + return True + + def wait_ssh(self, timeout): + start_time = int(time.time()) + while True: + if self.is_ssh(): + return True + + if int(time.time()) - start_time > timeout: + return False + + time.sleep(10) + + def scp_directory(self, source, destination, put=True, retry=1, path_fixup=True): + try: + if path_fixup: + destination = self.path_fixup(destination) + + if not put: + self.log_handler.error( + 'scp_directory', + 'download not implemented' + ) + return False + + self.log_handler.debug( + 'scp_directory', + '%s => %s' % (source, destination) + ) + + session = None + loop = 0 + while True: + try: + success = True + + session = SSHClient() + if self.load_system_host_keys: + session.load_system_host_keys() + session.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + if self.password is not None: + session.connect( + self.ip_address, + port=self.port, + username=self.username, + password=self.password, + timeout=self.timeout + ) + + if self.key_filename is not None: + session.connect( + self.ip_address, + port=self.port, + username=self.username, + key_filename=self.key_filename, + timeout=self.timeout + ) + + sftp = paramiko.SFTPClient.from_transport(session.get_transport()) + + for root, dirs, files in os.walk(source, topdown=False): + for name in dirs: + source_directory = os.path.join(root, name) + target_directory = self.path_fixup( + os.path.join( + destination, + self.path_fixup(source_directory[len(source):]).lstrip('/') + ) + ) + + if not self.create_directory(target_directory): + self.log_handler.error( + 'scp_directory', + 'Create directory failed: %s' % (target_directory) + ) + success = False + break + + self.log_handler.debug( + 'scp_directory', + 'Directory created: %s' % (target_directory) + ) + + if not success: + break + + for root, dirs, files in os.walk(source, topdown=False): + for name in files: + source_filename = os.path.join(root, name) + target_directory = os.path.dirname(source_filename)[len(source):] + if target_directory.startswith('/'): + target_directory = target_directory[1:] + if target_directory.startswith('\\'): + target_directory = target_directory[1:] + + if len(target_directory) == 0: + destination_filename = os.path.join( + destination, + name + ) + + if len(target_directory) > 0: + destination_filename = os.path.join( + destination, + os.path.join( + target_directory, + name + ) + ) + + if put: + if os.path.isfile(source_filename): + self.log_handler.debug( + 'scp_directory', + 'File %s => %s' % ( + source_filename, + self.path_fixup(destination_filename) + ) + ) + + sftp.put( + source_filename, + self.path_fixup(destination_filename) + ) + else: + self.log_handler.error( + 'scp_directory', + 'Source file not found %s' % ( + source_filename + ) + ) + + sftp.close() + + session.close() + + except paramiko.ssh_exception.AuthenticationException: + self.log_handler.error( + 'scp_directory', + 'Authentication failed at %s with username: %s, password: %s, key: %s' % ( + self.ip_address, + self.username, + self.password, + self.key_filename + ) + ) + success = False + except BaseException: + self.log_handler.error( + 'scp_directory', + traceback.format_exc() + ) + success = False + finally: + if session is not None: + session.close() + + if success: + return True + + loop = loop + 1 + if loop > retry: + return False + + time.sleep(loop * 5) + + except BaseException: + self.log_handler.error( + 'scp_directory', + traceback.format_exc() + ) + return False + + def scp_file(self, source, destination, put=True, retry=1, path_fixup=True): + try: + if path_fixup: + destination = self.path_fixup(destination) + + session = None + loop = 0 + while True: + try: + success = True + + session = SSHClient() + if self.load_system_host_keys: + session.load_system_host_keys() + session.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + if self.password is not None: + session.connect( + self.ip_address, + port=self.port, + username=self.username, + password=self.password, + timeout=self.timeout + ) + + if self.key_filename is not None: + session.connect( + self.ip_address, + port=self.port, + username=self.username, + key_filename=self.key_filename, + timeout=self.timeout + ) + + sftp = paramiko.SFTPClient.from_transport(session.get_transport()) + if put: + sftp.put(source, destination) + self.log_handler.debug( + 'scp_file', + 'put: %s => %s' % ( + source, + destination + ) + ) + else: + sftp.get(source, destination) + self.log_handler.debug( + 'scp_file', + 'get: %s => %s' % ( + source, + destination + ) + ) + sftp.close() + + session.close() + except paramiko.ssh_exception.AuthenticationException: + self.log_handler.error( + 'scp_file', + 'Authentication failed at %s with username: %s, password: %s, key: %s' % ( + self.ip_address, + self.username, + self.password, + self.key_filename + ) + ) + success = False + except BaseException: + self.log_handler.error( + 'scp_file', + traceback.format_exc() + ) + success = False + finally: + if session is not None: + session.close() + + if success: + return True + + loop = loop + 1 + if loop > retry: + return False + + time.sleep(loop * 5) + + except BaseException: + self.log_handler.error( + 'scp_file', + traceback.format_exc() + ) + return False + + def run_cmd(self, command, live_output=False, timeout=3600, max_attempts=1): + session = None + start_time = int(time.time()) + self.log_handler.debug( + 'run_cmd', + 'Command: %s' % (command) + ) + + try: + success = True + + session = self.create_session(max_attempts=max_attempts) + if session is None: + success = False + output = None + error = 'SSH access failed' + self.log_handler.error('run_cmd', 'IP: %s' % (self.ip_address)) + self.log_handler.error('run_cmd', 'Port: %s' % (self.port)) + self.log_handler.error('run_cmd', 'Username: %s' % (self.username)) + self.log_handler.error('run_cmd', 'Password: %s' % (self.password)) + self.log_handler.error('run_cmd', 'Key: %s' % (self.key_filename)) + else: + stdin, stdout, stderr = session.exec_command( + command, + timeout=timeout, + get_pty=live_output + ) + if live_output: + for line in iter(stdout.readline, ""): + print(line, end="") + + if stdout.channel.recv_exit_status() > 0: + success = False + + stdin.flush() + output = stdout.read().decode('utf-8') + error = stderr.read().decode('utf-8') + + except BaseException: + success = False + output = None + error = traceback.format_exc() + + finally: + if session is not None: + session.close() + end_time = int(time.time()) + self.log_handler.debug('run_cmd', 'Duration: %s seconds' % (end_time - start_time)) + + return success, output, error + + def exec_cmd(self, command, timeout=30, max_attempts=1): + session = None + start_time = int(time.time()) + self.log_handler.debug('exec_cmd', 'Command: %s' % (command)) + try: + success = True + + session = self.create_session(max_attempts=max_attempts) + if session is None: + success = False + else: + session.exec_command( + command, + timeout=timeout + ) + + except BaseException: + success = False + + finally: + if session is not None: + session.close() + end_time = int(time.time()) + self.log_handler.debug('exec_cmd', 'Duration: %s seconds' % (end_time - start_time)) + + return success + + def path_fixup(self, name): + return name.replace('\\', '/') + + def create_file(self, content, filename=None): + source_filename = file_helper.set_tmp_file(content) + if filename is None: + destination_filename = source_filename + else: + destination_filename = filename + + if not self.scp_file(source_filename, destination_filename): + return None + + return destination_filename + + def create_directory(self, directory_name, path_fixup=True): + if path_fixup: + directory_name = self.path_fixup(directory_name) + + cmd = 'mkdir -p %s' % (directory_name) + success, output, error = self.run_cmd(cmd) + if not success: + return False + return True + + def delete_directory(self, directory_name, path_fixup=True): + if path_fixup: + directory_name = self.path_fixup(directory_name) + + if directory_name == '/': + self.log_handler.error( + 'delete_directory', + 'Hell no on root directory delete' + ) + return False + + cmd = 'rm -rf %s' % (directory_name) + success, output, error = self.run_cmd(cmd) + if not success: + return False + return True + + def get_directories(self, path, path_fixup=True): + if path_fixup: + path = self.path_fixup(path) + + cmd = 'ls -la %s' % (path) + success, output, error = self.run_cmd(cmd) + if not success: + return None + + directory_names = [] + for line in output.split('\n'): + line = re.sub(' +', ' ', line) + if len(line.split(' ')) != 9: + continue + + if not line.split(' ')[0].startswith('d'): + continue + + directory_name = line.split(' ')[8] + if directory_name not in ['.', '..']: + directory_names.append( + directory_name + ) + + return directory_names + + def get_filenames(self, path, path_fixup=True, relative=False): + if path_fixup: + path = self.path_fixup(path) + + cmd = 'find %s -type f' % (path) + success, output, error = self.run_cmd(cmd) + if not success: + return None + + filenames = [] + for line in output.split('\n'): + if line == path: + continue + + if relative: + line = line[len(path) + 1:] + + if len(line) > 0: + filenames.append(line) + + return filenames + + def is_file(self, filename, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + cmd = 'file %s' % (filename) + success, output, error = self.run_cmd(cmd) + if not success or 'No such file or directory' in output: + return False + return True + + def touch_file(self, filename, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + cmd = 'touch %s' % (filename) + success, output, error = self.run_cmd(cmd) + if not success: + return False + return True + + def get_file(self, filename, convert_json=False, convert_yaml=False, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + cmd = 'cat %s' % (filename) + success, output, error = self.run_cmd(cmd) + if not success or 'No such file or directory' in output: + return None + + if convert_json: + try: + output = json.loads(output) + except BaseException: + output = None + + if convert_yaml: + try: + output = yaml.safe_load(output) + except BaseException: + output = None + + return output + + def delete_file(self, filename, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + cmd = 'rm -f %s' % (filename) + success, output, error = self.run_cmd(cmd) + return success + + def set_file_chmod(self, filename, chmod, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + cmd = 'chmod %s %s' % (chmod, filename) + success, output, error = self.run_cmd(cmd) + if success: + return True + return False + + def get_file_md5(self, filename, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + cmd = 'md5sum %s' % (filename) + success, output, error = self.run_cmd(cmd) + if success: + return output.split(' ')[0] + return None + + def get_local_file_md5(self, filename, path_fixup=True): + if path_fixup: + filename = self.path_fixup(filename) + + if not os.path.isfile(filename): + return None + hasher = hashlib.md5() + blocksize = 65536 + with open(filename, 'rb') as file_handler: + buf = file_handler.read(blocksize) + while len(buf) > 0: + hasher.update(buf) + buf = file_handler.read(blocksize) + md5 = hasher.hexdigest() + return md5 + + def run_script(self, script_filename, variables={}, live_output=False, timeout=3600, path_fixup=True): + if path_fixup: + script_filename = self.path_fixup(script_filename) + + self.log_handler.debug('run_script', 'IP: %s' % (self.ip_address)) + self.log_handler.debug('run_script', 'Username: %s' % (self.username)) + self.log_handler.debug('run_script', 'Password: %s' % (self.password)) + self.log_handler.debug('run_script', 'Run script: %s' % (script_filename)) + + content = self.template_handler.get_template( + script_filename, + variables + ) + if content is None: + return False + + self.log_handler.debug('run_script', '~~~ script content ~~~') + self.log_handler.debug('run_script', content) + self.log_handler.debug('run_script', '~~~~~~~~~~~~~~~~~~~~~~') + + source_filename = '/tmp/%s' % (str(uuid.uuid4())) + try: + with open(source_filename, 'wb') as file_handler: + file_handler.write(content.encode('utf-8')) + except BaseException: + self.log_handler.error( + 'run_script', + 'Preparation of script file for upload failed' + ) + self.log_handler.error( + 'run_script', + traceback.format_exc() + ) + return False + + self.log_handler.debug('run_script', 'Local script prepared: %s' % (source_filename)) + + destination_filename = str(uuid.uuid4()) + if not self.scp_file(source_filename, destination_filename): + self.log_handler.error( + 'run_script', + 'Script upload failed: %s => %s' % ( + source_filename, + destination_filename + ) + ) + return False + self.log_handler.debug('run_script', 'Script uploaded: %s' % (destination_filename)) + + if not self.set_file_chmod(destination_filename, '755'): + self.log_handler.error( + 'run_script', + 'Script chmod failed: %s' % ( + destination_filename + ) + ) + return False + self.log_handler.debug('run_script', 'Chmod set to 755') + + if live_output: + self.log_handler.debug('run_script', 'Run script with live output...') + else: + self.log_handler.debug('run_script', 'Run script and wait for completion...') + + success, output, error = self.run_cmd( + './%s' % (destination_filename), + live_output=live_output, + timeout=timeout + ) + + if success: + self.log_handler.debug('run_script', 'Remote script execution finished') + if not live_output: + self.log_handler.debug('run_script', '~~~ script output ~~~') + self.log_handler.debug('run_script', output) + self.log_handler.debug('run_script', '~~~~~~~~~~~~~~~~~~~~~') + + if not self.delete_file(destination_filename): + self.log_handler.error( + 'run_script', + 'Remote script delete failed: %s' % ( + destination_filename + ) + ) + return False + + self.log_handler.debug('run_script', 'Remote script deleted') + + if not success: + self.log_handler.error('run_script', 'Remote script execution failed') + self.log_handler.error('run_script', '~~~ script error ~~~') + self.log_handler.error('run_script', error) + self.log_handler.error('run_script', '~~~~~~~~~~~~~~~~~~~~~') + self.log_handler.error('run_script', 'Remote script not deleted for further troubleshooting: %s' % (destination_filename)) + + return success + + def run_file_upload(self, source_filename, destination_filename, destination_chmod='644', is_template=False, variables={}, path_fixup=True): + if path_fixup: + source_filename = self.path_fixup(source_filename) + destination_filename = self.path_fixup(destination_filename) + + if is_template: + content = self.template_handler.get_template( + source_filename, + variables + ) + if content is None: + return False + + self.log_handler.debug('run_file_upload', content) + + source_filename = '/tmp/%s' % (str(uuid.uuid4())) + try: + with open(source_filename, 'wb') as file_handler: + file_handler.write(content.encode('utf-8')) + + except BaseException: + self.log_handler.error( + 'run_file_upload', + 'Preparation of script file for upload failed' + ) + self.log_handler.debug('run_file_upload', traceback.format_exc()) + return False + + self.log_handler.debug('run_file_upload', 'Local file prepared: %s' % (source_filename)) + + self.log_handler.debug('run_file_upload', 'Copy file: %s => %s' % (source_filename, destination_filename)) + + if not os.path.isfile(source_filename): + self.log_handler.error('run_file_upload', 'File not found: %s' % (source_filename)) + return False + self.log_handler.debug('run_file_upload', 'Local file found: %s' % (source_filename)) + + source_md5 = self.get_local_file_md5(source_filename) + destination_md5 = self.get_file_md5(destination_filename) + if source_md5 == destination_md5: + self.log_handler.debug('run_file_upload', 'Checksum (md5) match and upload skipped') + else: + temp_destination_filename = '/tmp/%s' % str((uuid.uuid4())) + if not self.scp_file(source_filename, temp_destination_filename): + self.log_handler.error('run_file_upload', 'File upload failed') + return False + + if not self.exec_cmd('mv %s %s' % (temp_destination_filename, destination_filename)): + self.log_handler.error('run_file_upload', 'File to move uploaded file to final destination') + return False + + if not self.set_file_chmod(destination_filename, destination_chmod): + self.log_handler.error('run_file_upload', 'File chmod failed: %s' % (destination_filename)) + return False + + return True diff --git a/lib/template.py b/lib/template.py new file mode 100644 index 00000000..e07c8120 --- /dev/null +++ b/lib/template.py @@ -0,0 +1,578 @@ +import os +import copy +import traceback +import yaml + +from lib import ip_helper +from lib import file_helper +from lib import log_helper +from lib import output_helper + + +class Template(): + def __init__(self, verbose=False, debug=False, log_id=None): + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper(verbose=verbose, debug=debug) + + def get_template_directory(self, subdirectory): + template_dir = os.path.join( + file_helper.get_main_dir(), + 'templates' + ) + + for item in subdirectory.split('/'): + template_dir = os.path.join( + template_dir, + item + ) + + return template_dir + + def get_template_filename(self, subdirectory, template_type, filename): + template_filename = os.path.join( + os.path.join( + self.get_template_directory(subdirectory), + template_type + ), + filename + ) + if not os.path.isfile(template_filename): + self.my_output.error('File not found: %s' % (template_filename)) + return None + + return template_filename + + def is_template_attributes(self, template): + attributes = self.get_template_attributes(template) + if len(attributes) > 0: + self.my_output.debug('Template attributes:') + for attribute in attributes: + self.my_output.debug('- %s' % (attribute)) + + return True + + return False + + def get_word_attribute(self, word): + if '${' in word: + pattern = word.split('${')[1] + if '}' in pattern: + value = pattern.split('}')[0] + return value + return None + + def get_template_attributes(self, template): + attributes = [] + for line in template.split('\n'): + for word in line.split(' '): + attribute = self.get_word_attribute(word) + if attribute is not None: + attributes.append(attribute) + return attributes + + def replace_attributes(self, content, variables): + if content is None: + return None + + if variables is None: + return content + + my_variables = copy.deepcopy(variables) + for key in my_variables: + try: + pattern = '${%s}' % (key) + content = content.replace(pattern, str(my_variables[key])) + + except BaseException: + self.my_output.error('Variable %s replacement failed' % (key)) + self.my_output.error(traceback.format_exc()) + return None + + return content + + def get_template(self, template_filename, variables, replace_variables_enabled=True, check_remaining_variables=True, yaml_conversion=False, yaml_check=False): + content = file_helper.get_file(template_filename) + if content is None: + self.log.error( + 'get_template', + 'File read failed: %s' % (template_filename) + ) + return None + + content = self.replace_attributes(content, variables) + if content is None: + self.log.error( + 'get_template', + 'Variable replace failed: %s' % (template_filename) + ) + return None + + if check_remaining_variables: + if self.is_template_attributes(content): + self.my_output.error('Not all attributes replaced: %s' % (template_filename)) + self.my_output.default(content) + return None + + if yaml_check: + try: + content_check = yaml.safe_load(content) + + except BaseException: + self.my_output.error('YAML format required') + self.my_output.traceback(traceback.format_exc()) + return None + + if yaml_conversion: + try: + content = yaml.safe_load(content) + + except BaseException: + self.my_output.error('YAML format required') + self.my_output.traceback(traceback.format_exc()) + return None + + return content + + def is_key_in_section(self, key, section): + try: + value = None + for field in key.split('.'): + if value is None: + value = section[field] + continue + + value = value[field] + + except BaseException: + return False + + return True + + def get_key_value(self, key, section): + try: + value = None + for field in key.split('.'): + if value is None: + value = section[field] + continue + + value = value[field] + + except BaseException: + return None + + return value + + def add_key_value(self, section, key, value): + try: + if len(key.split('.')) == 1: + section[key] = value + return section + + subsection = None + for subdict in key.split('.')[:-1]: + if subsection is None: + if subdict not in section: + section[subdict] = {} + subsection = section[subdict] + continue + + if subdict not in subsection: + subsection[subdict] = {} + subsection = subsection[subdict] + + subsection[key.split('.')[-1]] = value + + except BaseException: + return None + + return section + + def validate_key_value(self, section_name, key, rules, value): + attribute_name = '%s.%s' % (section_name, key) + + if rules['type'] not in ['str', 'int', 'bool', 'list_of_ip', 'list_of_str', 'opaque']: + self.my_output.error('Unsupported attribute type: %s' % (rules['type'])) + self.my_output.default('Section: %s' % (section_name)) + self.my_output.default('Key: %s' % (key)) + self.my_output.default('Rules: %s' % (rules)) + self.my_output.default('Value: %s' % (value)) + return False, None + + if rules['type'] == 'str': + if value is None and rules['check'] == 'local-file-null-accepted': + pass + else: + if not isinstance(value, str): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'int': + if not isinstance(value, int): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'bool': + if not isinstance(value, bool): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'list_of_ip': + if not isinstance(value, list): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + for item in value: + if not ip_helper.is_valid_ipv4_address(item): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['type'] == 'list_of_ip': + if not isinstance(value, list): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + for item in value: + if not isinstance(item, str): + self.my_output.error('Expected attribute %s type is %s' % (attribute_name, rules['type'])) + return False, None + + if rules['check'] is not None: + if rules['type'] == 'bool': + if rules['check'] == 'must-be-true': + if not value: + self.my_output.error('Expected attribute %s value is True: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'must-be-false': + if value: + self.my_output.error('Expected attribute %s value is False: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['type'] == 'str': + if rules['check'] == 'ipv4': + if not ip_helper.is_valid_ipv4_address(value): + self.my_output.error('Expected attribute %s value is valid IPv4 address: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'ipv4s': + for item in value.split(','): + if not ip_helper.is_valid_ipv4_address(item): + self.my_output.error('Expected attribute %s value is list of valid IPv4 addresses: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'ipv6': + if not ip_helper.is_valid_ipv6_address(value): + self.my_output.error('Expected attribute %s value is valid IPv6 address: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'cidrv4': + if not ip_helper.is_valid_ipv4_cidr(value): + self.my_output.error('Expected attribute %s value is valid IPv4 CIDR: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'cidrv6': + if not ip_helper.is_valid_ipv6_cidr(value): + self.my_output.error('Expected attribute %s value is valid IPv6 CIDR: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'url': + if not ip_helper.is_url_valid(value): + self.my_output.error('Expected attribute %s value is valid URL: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'dhcp-v4-range': + if len(value.split('-')) != 2: + self.my_output.error('Expected attribute %s value is valid IPv4 address ranges: %s' % (attribute_name, value)) + return False, None + + (start_ip, end_ip) = value.split('-') + if not ip_helper.is_valid_ipv4_address(start_ip) or not ip_helper.is_valid_ipv4_address(end_ip): + self.my_output.error('Expected attribute %s value is valid IPv4 address ranges: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['check'] == 'not-empty-no-spaces': + if value is None: + value = '' + value = value.strip() + + if len(value) == 0: + self.my_output.error('Expected attribute %s value is non-empty string without spaces: %s' % (attribute_name, value)) + return False, None + + if ' ' in value: + self.my_output.error('Expected attribute %s value is non-empty string without spaces: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['check'] == 'not-empty': + if value is None: + value = '' + value = value.strip() + + if len(value) == 0: + self.my_output.error('Expected attribute %s value is non-empty string: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['check'].startswith('values:'): + reference_values = rules['check'].lstrip('values').lstrip(':') + if value not in reference_values.split(','): + self.my_output.error('Expected attribute %s value is one of %s: %s' % (attribute_name, reference_values, value)) + return False, None + return True, value + + if rules['check'] == 'local-file': + if not os.path.isfile(value): + self.my_output.error('Expected attribute %s value is existing local file: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'local-file-null-accepted': + if value is None: + return True, None + + if len(value) == 0: + return True, None + + if not os.path.isfile(value): + self.my_output.error('Expected attribute %s value is existing local file: %s' % (attribute_name, value)) + return False, None + + return True, value + + if rules['type'] == 'int': + if rules['check'] == 'port': + if value < 1 or value > 65535: + self.my_output.error('Expected attribute %s value is within TCP/UDP port range: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'host-prefix-v4': + if value < 1 or value > 30: + self.my_output.error('Expected attribute %s value is within <1,30> range: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'] == 'host-prefix-v6': + if value > 127 or value < 64: + self.my_output.error('Expected attribute %s value is within <64,127> range: %s' % (attribute_name, value)) + return False, None + return True, value + + if rules['check'].startswith('ge'): + reference_value = int(rules['check'].lstrip('ge')) + if value < reference_value: + self.my_output.error('Expected attribute %s value is greater or equal %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('gt'): + reference_value = int(rules['check'].lstrip('gt')) + if value <= reference_value: + self.my_output.error('Expected attribute %s value is greater than %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('le'): + reference_value = int(rules['check'].lstrip('le')) + if value > reference_value: + self.my_output.error('Expected attribute %s value is lower or equal %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('lt'): + reference_value = int(rules['check'].lstrip('lt')) + if value >= reference_value: + self.my_output.error('Expected attribute %s value is lower than %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['check'].startswith('eq'): + reference_value = int(rules['check'].lstrip('eq')) + if value != reference_value: + self.my_output.error('Expected attribute %s value is %s: %s' % (attribute_name, reference_value, value)) + return False, None + return True, value + + if rules['type'] == 'opaque': + return True, value + + self.my_output.error('Unsupported check: %s' % (rules['check'])) + self.my_output.default('Section: %s' % (section_name)) + self.my_output.default('Key: %s' % (key)) + self.my_output.default('Rules: %s' % (rules)) + self.my_output.default('Value: %s' % (value)) + return False, None + + return True, value + + def validate_input(self, rules_subdirectory, input_type, user_input): + rules = file_helper.get_file_yaml( + self.get_template_filename( + rules_subdirectory, + 'rules', + '%s.yaml' % (input_type) + ) + ) + if rules is None: + self.my_output.error('Rules %s not defined for %s' % (input_type, rules_subdirectory)) + return None + + if rules['value'] == 'dict': + if not isinstance(user_input, dict): + self.my_output.error('%s is expected to be dictionary' % (input_type)) + return None + + validated_input = {} + for key in rules['properties']: + if rules['properties'][key]['mandatory']: + if not self.is_key_in_section(key, user_input): + self.my_output.error('Required property %s.%s' % (input_type, key)) + return None + + success, value = self.validate_key_value( + input_type, + key, + rules['properties'][key], + self.get_key_value(key, user_input) + ) + if not success: + return None + + validated_input = self.add_key_value( + validated_input, + key, + value + ) + + if not rules['properties'][key]['mandatory']: + if self.is_key_in_section(key, user_input): + success, value = self.validate_key_value( + input_type, + key, + rules['properties'][key], + self.get_key_value(key, user_input) + ) + if not success: + return None + + validated_input = self.add_key_value( + validated_input, + key, + value + ) + else: + validated_input = self.add_key_value( + validated_input, + key, + rules['properties'][key]['default'] + ) + + if rules['value'] == 'list_of_dict': + if not isinstance(user_input, list): + self.my_output.error('%s is expected to be list' % (input_type)) + return None + + if 'min_length' in rules: + if len(user_input) < rules['min_length']: + self.my_output.error('%s is expected to be list with minimum %s elements: %s' % (input_type, rules['min_length'], len(user_input))) + return None + + if 'max_length' in rules: + if len(user_input) > rules['max_length']: + self.my_output.error('%s is expected to be list with maximum %s elements: %s' % (input_type, rules['max_length'], len(user_input))) + return None + + validated_input = [] + for item in user_input: + if not isinstance(item, dict): + self.my_output.error('%s is expected to be list of dict' % (input_type)) + return None + + validated_item = {} + for key in rules['properties']: + if rules['properties'][key]['mandatory']: + if not self.is_key_in_section(key, item): + self.my_output.error('Required property %s.%s' % (input_type, key)) + return None + + success, value = self.validate_key_value( + input_type, + key, + rules['properties'][key], + self.get_key_value(key, item) + ) + if not success: + return None + + validated_item = self.add_key_value( + validated_item, + key, + value + ) + + if not rules['properties'][key]['mandatory']: + if self.is_key_in_section(key, item): + success, value = self.validate_key_value( + input_type, + key, + rules['properties'][key], + self.get_key_value(key, item) + ) + if not success: + return None + + validated_item = self.add_key_value( + validated_item, + key, + value + ) + else: + validated_item = self.add_key_value( + validated_item, + key, + rules['properties'][key]['default'] + ) + + validated_input.append(validated_item) + + if rules['value'] == 'list_of_str': + if not isinstance(user_input, list): + self.my_output.error('%s is expected to be list' % (input_type)) + return None + + validated_input = [] + for value in user_input: + if not isinstance(value, str): + self.my_output.error('%s is expected to be list of strings' % (input_type)) + return None + + if rules['check'] is None: + validated_input.append(value) + continue + + if rules['check'] is not None: + if rules['check'] == 'ssh-public-key': + if not ip_helper.is_public_key_valid(value): + self.my_output.error('%s is expected to be list of ssh public keys' % (input_type)) + return None + validated_input.append(value) + continue + + self.my_output.error('Unsupported check: %s' % (rules['check'])) + return None + + return validated_input diff --git a/lib/template_helper.py b/lib/template_helper.py new file mode 100644 index 00000000..643bb0c6 --- /dev/null +++ b/lib/template_helper.py @@ -0,0 +1,75 @@ +import json +import copy +import os +import sys +import traceback + +from lib import file_helper +from lib import log_helper + + +class TemplateHelper(): + def __init__(self): + self.base_directory = os.path.join( + file_helper.get_main_dir(), + 'templates' + ) + self.log = log_helper.Log() + + def get_global_variables(self): + try: + content = self.get('global_variables.json') + if content is None: + return None + + variables = json.loads(content) + except BaseException: + self.log.error('template_helper.get_global_variables', traceback.format_exc()) + return None + + return variables + + def get(self, name): + try: + filename = os.path.join(self.base_directory, name) + if not os.path.isfile(filename): + return None + + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + except BaseException: + self.log.error('template_helper.get', traceback.format_exc()) + return None + + return content + + def replace_variables(self, content, variables): + try: + if content is None: + return None + + if variables is None: + return content + + my_variables = copy.deepcopy(variables) + global_variables = self.get_global_variables() + if global_variables is not None: + for key in global_variables: + if key not in variables: + my_variables[key] = global_variables[key] + + for key in my_variables: + pattern = '${%s}' % (key) + if my_variables[key] is None: + self.log.error('template_helper.replace_variables', 'Variable is none: %s' % (key)) + self.log.error('template_helper.replace_variables', json.dumps(my_variables, indent=4)) + return None + + content = content.replace(pattern, my_variables[key]) + + except BaseException: + self.log.error('template_helper.replace_variables', traceback.format_exc()) + return None + + return content diff --git a/lib/ucsm/__init__.py b/lib/ucsm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ucsm/__pycache__/__init__.cpython-310.pyc b/lib/ucsm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a97f8152 Binary files /dev/null and b/lib/ucsm/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/blade.cpython-310.pyc b/lib/ucsm/__pycache__/blade.cpython-310.pyc new file mode 100644 index 00000000..3ede9f6f Binary files /dev/null and b/lib/ucsm/__pycache__/blade.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/chassis.cpython-310.pyc b/lib/ucsm/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..09716d0e Binary files /dev/null and b/lib/ucsm/__pycache__/chassis.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/endpoint_settings.cpython-310.pyc b/lib/ucsm/__pycache__/endpoint_settings.cpython-310.pyc new file mode 100644 index 00000000..cd09dcc7 Binary files /dev/null and b/lib/ucsm/__pycache__/endpoint_settings.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/manager.cpython-310.pyc b/lib/ucsm/__pycache__/manager.cpython-310.pyc new file mode 100644 index 00000000..ffd973cc Binary files /dev/null and b/lib/ucsm/__pycache__/manager.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/power.cpython-310.pyc b/lib/ucsm/__pycache__/power.cpython-310.pyc new file mode 100644 index 00000000..43c2587c Binary files /dev/null and b/lib/ucsm/__pycache__/power.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/settings.cpython-310.pyc b/lib/ucsm/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..b57a5df3 Binary files /dev/null and b/lib/ucsm/__pycache__/settings.cpython-310.pyc differ diff --git a/lib/ucsm/__pycache__/thermal.cpython-310.pyc b/lib/ucsm/__pycache__/thermal.cpython-310.pyc new file mode 100644 index 00000000..9e20696f Binary files /dev/null and b/lib/ucsm/__pycache__/thermal.cpython-310.pyc differ diff --git a/lib/ucsm/blade.py b/lib/ucsm/blade.py new file mode 100644 index 00000000..b3ede70c --- /dev/null +++ b/lib/ucsm/blade.py @@ -0,0 +1,190 @@ +class Blade(): + def __init__(self, log_id=None): + self.mo_blade = None + + def get_blade_info(self, blade_object): + blade_info = {} + blade_info['mo_type'] = 'blade' + + keys = [ + 'association', + 'chassis_id', + 'available_memory', + 'assigned_to_dn', + 'admin_state', + 'dn', + 'model', + 'num_of_adaptors', + 'num_of_cores', + 'num_of_cores_enabled', + 'num_of_cpus', + 'num_of_eth_host_ifs', + 'num_of_fc_host_ifs', + 'num_of_threads', + 'oper_power', + 'oper_state', + 'operability', + 'part_number', + 'rn', + 'serial', + 'server_id', + 'slot_id', + 'total_memory', + 'uuid', + 'vendor' + ] + for key in keys: + blade_info[key] = getattr(blade_object, key) + + blade_info['id'] = blade_info['rn'].split('-')[1] + blade_info['chassis_rn'] = blade_info['dn'].split('/')[1] + + return blade_info + + def get_blade(self, blade_serial=None, chassis_id=None, blade_id=None, power=False, thermal=False): + blades = self.get_blades(power=power, thermal=thermal) + if blades is None: + return None + + for blade in blades: + if blade_serial is not None: + if blade['serial'] == blade_serial: + return blade + + if chassis_id is not None and blade_id is not None: + if blade['chassis_id'] == chassis_id and blade['id'] == blade_id: + return blade + + return None + + def get_blades(self, chassis_rn=None, power=False, thermal=False): + if self.mo_blade is None: + managed_objects = self.query_classid( + 'ComputeBlade' + ) + if managed_objects is None: + return None + + self.mo_blade = managed_objects + + blades = [] + + for managed_object in self.mo_blade: + managed_object_info = self.get_blade_info( + managed_object + ) + if managed_object_info is None: + continue + + if power: + managed_object_info['power'] = self.get_compute_power_stats( + chassis_rn=managed_object_info['chassis_rn'], + blade_rn=managed_object_info['rn'] + ) + + if thermal: + managed_object_info['thermal'] = self.get_compute_thermal_stats( + chassis_rn=managed_object_info['chassis_rn'], + blade_rn=managed_object_info['rn'] + ) + + if chassis_rn is None: + blades.append(managed_object_info) + continue + + if managed_object_info['chassis_rn'] == chassis_rn: + blades.append(managed_object_info) + + blades = sorted(blades, key=lambda i: i['dn']) + + return blades + + def print_blade(self, blade, power=False, thermal=False): + order = [ + 'chassis_rn', + 'rn', + 'model', + 'serial', + 'oper_state', + 'operability', + 'oper_power', + 'association' + ] + + headers = [ + 'Chassis', + 'Blade', + 'Model', + 'Serial', + 'Overal Status', + 'Operability', + 'Power State', + 'Assoc State' + ] + + self.my_output.dictionary( + blade, + title='Blade', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + if power: + self.print_blade_power( + blade['power'] + ) + + if thermal: + self.print_blade_thermal( + blade['thermal'] + ) + + def print_blades(self, blades, power=False, thermal=False, include_chassis_id=True): + order = [ + 'chassis_rn', + 'rn', + 'model', + 'serial', + 'oper_state', + 'operability', + 'oper_power', + 'association' + ] + + headers = [ + 'Chassis', + 'Blade', + 'Model', + 'Serial', + 'Overal Status', + 'Operability', + 'Power State', + 'Assoc State' + ] + + if not include_chassis_id: + order.remove('chassis_rn') + headers.remove('Chassis') + + self.my_output.my_table( + blades, + order=order, + headers=headers, + underline=True, + table=True + ) + + if power: + self.print_blades_power( + blades, + include_chassis_id=include_chassis_id + ) + + if power: + self.print_blades_thermal( + blades, + include_chassis_id=include_chassis_id + ) diff --git a/lib/ucsm/chassis.py b/lib/ucsm/chassis.py new file mode 100644 index 00000000..2ed76d40 --- /dev/null +++ b/lib/ucsm/chassis.py @@ -0,0 +1,251 @@ +class Chassis(): + def __init__(self, log_id=None): + self.mo_chassis = None + + def get_chassis_info(self, chassis_object): + chassis_info = {} + chassis_info['mo_type'] = 'chassis' + + keys = [ + 'dn', + 'rn', + 'id', + 'model', + 'oper_state', + 'part_number', + 'power', + 'serial', + 'service_state', + 'thermal', + 'vendor' + ] + for key in keys: + chassis_info[key] = getattr(chassis_object, key) + + return chassis_info + + def get_chassis_property(self, chassis_id, key): + chassis = self.get_chassis(chassis_id) + if chassis is None: + return None + + if key not in chassis: + return None + + return chassis[key] + + def get_chassis(self, chassis_id, blade=False, power=False, thermal=False): + chassiz = self.get_chassiz() + if chassiz is None: + return None + + for chassis in chassiz: + if str(chassis['id']) == str(chassis_id): + if power: + chassis['power_stats'] = self.get_chassis_power_stats( + chassis_rn=chassis['rn'] + ) + + if thermal: + chassis['thermal_stats'] = self.get_chassis_thermal_stats( + chassis_rn=chassis['rn'] + ) + + if blade: + chassis['blade'] = self.get_blades( + chassis_rn=chassis['rn'], + power=power, + thermal=thermal + ) + + return chassis + + return None + + def is_chassis_id(self, chassis_id): + if self.get_chassis_id(chassis_id=chassis_id) is None: + return False + return True + + def get_chassis_id(self, chassis_rn=None, chassis_serial=None, chassis_id=None): + chassiz = self.get_chassiz() + if chassiz is None: + return None + + for chassis in chassiz: + if chassis_rn is not None: + if chassis['rn'] == chassis_rn: + return chassis['id'] + + if chassis_serial is not None: + if chassis['serial'] == chassis_serial: + return chassis['id'] + + if chassis_id is not None: + if chassis['id'] == chassis_id: + return chassis['id'] + + return None + + def get_chassiz(self, blade=False, power=False, thermal=False): + if self.mo_chassis is None: + managed_objects = self.query_classid( + 'EquipmentChassis' + ) + if managed_objects is None: + return None + + self.mo_chassis = managed_objects + + chassiz = [] + + for managed_object in self.mo_chassis: + managed_object_info = self.get_chassis_info( + managed_object + ) + if managed_object_info is not None: + if blade: + managed_object_info['blade'] = self.get_blades( + chassis_rn=managed_object_info['rn'], + power=power, + thermal=thermal + ) + + if power: + managed_object_info['power_stats'] = self.get_chassis_power_stats( + chassis_rn=managed_object_info['rn'] + ) + + if thermal: + managed_object_info['thermal_stats'] = self.get_chassis_thermal_stats( + chassis_rn=managed_object_info['rn'] + ) + + chassiz.append(managed_object_info) + + chassiz = sorted(chassiz, key=lambda i: i['dn']) + return chassiz + + def print_chassis(self, chassis, power=False, blade=False, thermal=False): + order = [ + 'id', + 'rn', + 'model', + 'serial', + 'oper_state', + 'power', + 'thermal' + ] + + headers = [ + 'Chassis Id', + 'Name', + 'Model', + 'Serial', + 'Operability', + 'Power State', + 'Thermal State' + ] + + self.my_output.dictionary( + chassis, + title='Chassis', + underline=True, + prefix="- ", + justify=True, + keys=order, + title_keys=headers + ) + + if power: + self.print_chassis_power( + chassis['power_stats'] + ) + + self.print_chassis_psu( + chassis['power_stats'] + ) + + if thermal: + self.print_chassis_thermal( + chassis['thermal_stats'] + ) + + if blade: + self.print_blades( + chassis['blade'], + include_chassis_id=False + ) + if power: + self.print_blades_power( + chassis['blade'] + ) + if thermal: + self.print_blades_thermal( + chassis['blade'] + ) + + def print_chassiz(self, chassiz, power=False, thermal=False, blade=False): + order = [ + 'id', + 'rn', + 'model', + 'serial', + 'oper_state', + 'power', + 'thermal' + ] + + headers = [ + 'Chassis Id', + 'Name', + 'Model', + 'Serial', + 'Operability', + 'Power State', + 'Thermal State' + ] + + self.my_output.my_table( + chassiz, + order=order, + headers=headers, + underline=True, + table=True + ) + + if blade: + blades = [] + for chassis in chassiz: + blades = blades + chassis['blade'] + + self.print_blades( + blades, + include_chassis_id=True + ) + + if power: + self.print_chassiz_power( + chassiz + ) + + self.print_chassiz_psu( + chassiz + ) + + if blade: + self.print_blades_power( + blades, + include_chassis_id=True + ) + + if thermal: + self.print_chassiz_thermal( + chassiz + ) + + if blade: + self.print_blades_thermal( + blades, + include_chassis_id=True + ) diff --git a/lib/ucsm/endpoint_settings.py b/lib/ucsm/endpoint_settings.py new file mode 100644 index 00000000..a26c1200 --- /dev/null +++ b/lib/ucsm/endpoint_settings.py @@ -0,0 +1,208 @@ +from lib import log_helper +from lib import output_helper + +from lib.endpoint_helper import EndpointSettings +from lib.ucsm import manager +from lib.ucsm.power_modules import server as power_server +from lib.ucsm.power_modules import chassis as power_chassis +from lib.ucsm.thermal_modules import server as thermal_server +from lib.ucsm.thermal_modules import chassis as thermal_chassis + + +class UcsmEndpointSettings(EndpointSettings): + def __init__(self, log_id=None): + EndpointSettings.__init__(self, log_id=log_id) + + self.log = log_helper.Log(log_id=log_id) + self.log_id = log_id + self.my_output = None + + def get_ucsm_endpoint_id(self, ucsm_mo): + return ucsm_mo['serial'] + + def is_ucsm_endpoint(self, endpoint_id): + if self.get_ucsm_endpoint_settings(endpoint_id) is None: + return False + return True + + def get_ucsm_endpoint_settings(self, endpoint_id): + endpoint_settings = self.get_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return None + + if 'ucsm' in endpoint_settings: + return endpoint_settings['ucsm'] + + return None + + def set_ucsm_endpoint_settings(self, ucsm_mo, ucsm_manager): + endpoint_id = self.get_ucsm_endpoint_id( + ucsm_mo + ) + + endpoint_settings = self.get_endpoint_settings( + endpoint_id + ) + if endpoint_settings is None: + endpoint_settings = {} + endpoint_settings['endpoint_id'] = endpoint_id + + endpoint_settings['ucsm'] = {} + endpoint_settings['ucsm']['mo_type'] = ucsm_mo['mo_type'] + endpoint_settings['ucsm']['ip'] = ucsm_manager['ip'] + endpoint_settings['ucsm']['username'] = ucsm_manager['username'] + endpoint_settings['ucsm']['password'] = ucsm_manager['password'] + + return self.set_endpoint_settings(endpoint_id, endpoint_settings) + + def get_ucsm_endpoint_power_template(self, endpoint_id): + endpoint_settings = self.get_ucsm_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return None + + ucsm_handler = manager.UcsManager( + endpoint_settings['ip'], + endpoint_settings['username'], + endpoint_settings['password'], + log_id=self.log_id + ) + + if not ucsm_handler.is_connected(): + self.log.error('get_ucsm_endpoint_power_template', 'Failed to connect to UCSM') + return None + + chassis_id = ucsm_handler.get_chassis_id( + chassis_serial=endpoint_id + ) + if chassis_id is not None: + chassis_info = ucsm_handler.get_chassis( + chassis_id=chassis_id, + power=True + ) + return chassis_info['power_stats'] + + blade_info = ucsm_handler.get_blade( + blade_serial=endpoint_id, + power=True + ) + if blade_info is not None: + return blade_info['power'] + + return None + + def get_ucsm_endpoint_thermal_template(self, endpoint_id): + endpoint_settings = self.get_ucsm_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return None + + ucsm_handler = manager.UcsManager( + endpoint_settings['ip'], + endpoint_settings['username'], + endpoint_settings['password'], + log_id=self.log_id + ) + + if not ucsm_handler.is_connected(): + self.log.error('get_ucsm_endpoint_power_template', 'Failed to connect to UCSM') + return None + + chassis_id = ucsm_handler.get_chassis_id( + chassis_serial=endpoint_id + ) + if chassis_id is not None: + chassis_info = ucsm_handler.get_chassis( + chassis_id=chassis_id, + thermal=True + ) + return chassis_info['thermal_stats'] + + blade_info = ucsm_handler.get_blade( + blade_serial=endpoint_id, + thermal=True + ) + if blade_info is not None: + return blade_info['thermal'] + + return None + + def get_ucsm_endpoint_template(self, endpoint_id, template_name): + if template_name == 'power': + return self.get_ucsm_endpoint_power_template(endpoint_id) + + if template_name == 'thermal': + return self.get_ucsm_endpoint_thermal_template(endpoint_id) + + return None + + def print_ucsm_endpoint_power_template(self, endpoint_id, data): + if self.my_output is None: + self.my_output = output_helper.OutputHelper( + log_id=self.log_id, + verbose=False, + debug=False + ) + + endpoint_settings = self.get_ucsm_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return + + if endpoint_settings['mo_type'] == 'blade': + power_server_handler = power_server.ServerPower( + log_id=self.log_id + ) + power_server_handler.print_blade_power( + data + ) + + if endpoint_settings['mo_type'] == 'chassis': + power_server_handler = power_chassis.ChassisPower( + log_id=self.log_id + ) + power_server_handler.print_chassis_power( + data + ) + power_server_handler.print_chassis_psu( + data + ) + + def print_ucsm_endpoint_thermal_template(self, endpoint_id, data): + if self.my_output is None: + self.my_output = output_helper.OutputHelper( + log_id=self.log_id, + verbose=False, + debug=False + ) + + endpoint_settings = self.get_ucsm_endpoint_settings(endpoint_id) + if endpoint_settings is None: + return + + if endpoint_settings['mo_type'] == 'blade': + power_server_handler = thermal_server.ServerThermal( + log_id=self.log_id + ) + power_server_handler.print_blade_thermal( + data + ) + + if endpoint_settings['mo_type'] == 'chassis': + power_server_handler = thermal_chassis.ChassisThermal( + log_id=self.log_id + ) + power_server_handler.print_chassis_thermal( + data + ) + + def print_ucsm_endpoint_template(self, endpoint_id, template_name, data): + if self.my_output is None: + self.my_output = output_helper.OutputHelper( + log_id=self.log_id, + verbose=False, + debug=False + ) + + if template_name == 'power': + self.print_ucsm_endpoint_power_template(endpoint_id, data) + + if template_name == 'thermal': + self.print_ucsm_endpoint_thermal_template(endpoint_id, data) diff --git a/lib/ucsm/manager.py b/lib/ucsm/manager.py new file mode 100644 index 00000000..32ed06f3 --- /dev/null +++ b/lib/ucsm/manager.py @@ -0,0 +1,129 @@ +import time +import json + +from ucsmsdk.ucshandle import UcsHandle +from ucsmsdk.ucscoreutils import get_meta_info + +from lib import output_helper +from lib import log_helper + +from lib.ucsm.chassis import Chassis +from lib.ucsm.blade import Blade +from lib.ucsm.power import Power +from lib.ucsm.thermal import Thermal + + +class UcsManager(Chassis, Blade, Power, Thermal): + def __init__(self, ucsm_ip, username, password, verbose=False, debug=False, log_id=None): + Chassis.__init__(self, log_id=log_id) + Blade.__init__(self, log_id=log_id) + Power.__init__(self, log_id=log_id) + Thermal.__init__(self, log_id=log_id) + + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + + self.ucsm_ip = ucsm_ip + self.ucsm_username = username + self.ucsm_password = password + + self.session_handler = None + self.session_connected = False + self.connect() + + def __del__(self): + self.disconnect() + + def debug_object(self, managed_object): + self.log.debug('debug_object', str(managed_object)) + self.log.debug('debug_object', json.dumps(dir(managed_object), indent=4)) + meta = get_meta_info(managed_object.get_class_id()) + if meta is not None: + self.log.debug('debug_object', meta) + + def is_connected(self): + return self.session_connected + + def connect(self): + if self.session_handler is not None: + return True + + start_time = int(time.time() * 1000) + self.session_handler = UcsHandle( + self.ucsm_ip, + self.ucsm_username, + self.ucsm_password + ) + + try: + self.session_connected = self.session_handler.login() + except BaseException: + self.session_connected = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.ucsm( + 'connect %s' % (self.ucsm_ip), + self.session_connected, + duration_ms + ) + + return self.session_connected + + def disconnect(self): + if self.session_handler is None: + return True + + if not self.session_connected: + return True + + start_time = int(time.time() * 1000) + try: + if self.session_handler.logout(): + self.session_connected = False + success = True + except BaseException: + success = False + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.ucsm( + 'disconnect %s' % (self.ucsm_ip), + success, + duration_ms + ) + + return False + + def query_classid(self, class_id): + if not self.is_connected(): + return None + + start_time = int(time.time() * 1000) + managed_objects = self.session_handler.query_classid( + class_id + ) + + end_time = int(time.time() * 1000) + duration_ms = end_time - start_time + self.log.ucsm( + '%s:%s' % (self.ucsm_ip, class_id), + True, + duration_ms + ) + + return managed_objects + + def get_inventory(self): + inventory = {} + inventory['Chassis'] = self.get_chassiz() + inventory['Blades'] = self.get_blades() + return inventory + + def print_inventory(self, inventory): + self.print_chassiz(inventory['Chassis']) + self.print_blades(inventory['Blades']) diff --git a/lib/ucsm/mo/ComputeBlade.md b/lib/ucsm/mo/ComputeBlade.md new file mode 100644 index 00000000..74891b22 --- /dev/null +++ b/lib/ucsm/mo/ComputeBlade.md @@ -0,0 +1,3876 @@ +# Compute Blade + +## Managed Object + +``` +Managed Object : ComputeBlade +-------------- +class_id :ComputeBlade +admin_power :policy +admin_state :in-service +asset_tag : +assigned_to_dn :org-root/org-EU-SPN/ls-esx52-eu-spdc +association :associated +availability :unavailable +available_memory :393216 +chassis_id :2 +check_point :discovered +child_action :None +conn_path :A,B +conn_status :A,B +descr : +discovery :complete +discovery_status : +dn :sys/chassis-2/blade-2 +flt_aggr :0 +fsm_descr : +fsm_flags : +fsm_prev :TurnupSuccess +fsm_progr :100 +fsm_rmt_inv_err_code :none +fsm_rmt_inv_err_descr : +fsm_rmt_inv_rslt : +fsm_stage_descr : +fsm_stamp :2022-12-01T04:36:48.811 +fsm_status :nop +fsm_try :0 +int_id :213098 +kmip_fault :no +kmip_fault_description :Unavailable +lc :discovered +lc_ts :1970-01-01T01:00:00.000 +local_id : +low_voltage_memory :regular-voltage +managing_inst :A +memory_speed :2666 +mfg_time :2020-04-06T01:00:00.000 +model :UCSB-B200-M5 +name : +num_of40_g_adaptors_with_old_fw :0 +num_of40_g_adaptors_with_unknown_fw:0 +num_of_adaptors :2 +num_of_cores :40 +num_of_cores_enabled :40 +num_of_cpus :2 +num_of_eth_host_ifs :8 +num_of_fc_host_ifs :0 +num_of_threads :80 +oper_power :on +oper_pwr_trans_src :software_mcserver +oper_qualifier : +oper_qualifier_reason :N/A +oper_state :ok +operability :operable +original_uuid :7416340d-6922-47f7-8924-050b800c4eb7 +part_number :68-5800-07 +policy_level :0 +policy_owner :local +presence :equipped +revision :0 +rn :blade-2 +sacl :None +scaled_mode :none +serial :FLM24140BJB +server_id :2/2 +slot_id :2 +status :None +storage_oper_qualifier :unknown +total_memory :393216 +usr_lbl : +uuid :315220a5-2121-4e5b-0101-e1dc0000011f +vendor :Cisco Systems Inc +vid :V07 +``` + +## Properties + +``` +[ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "admin_power", + "admin_state", + "asset_tag", + "assigned_to_dn", + "association", + "attr_get", + "attr_set", + "availability", + "available_memory", + "chassis_id", + "check_point", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "conn_path", + "conn_status", + "consts", + "descr", + "dirty_mask", + "discovery", + "discovery_status", + "dn", + "elem_create", + "flt_aggr", + "from_xml", + "fsm_descr", + "fsm_flags", + "fsm_prev", + "fsm_progr", + "fsm_rmt_inv_err_code", + "fsm_rmt_inv_err_descr", + "fsm_rmt_inv_rslt", + "fsm_stage_descr", + "fsm_stamp", + "fsm_status", + "fsm_try", + "get_class_id", + "get_handle", + "int_id", + "is_dirty", + "kmip_fault", + "kmip_fault_description", + "lc", + "lc_ts", + "local_id", + "low_voltage_memory", + "make_rn", + "managing_inst", + "mark_clean", + "mark_dirty", + "memory_speed", + "mfg_time", + "mo_meta", + "model", + "name", + "naming_props", + "num_of40_g_adaptors_with_old_fw", + "num_of40_g_adaptors_with_unknown_fw", + "num_of_adaptors", + "num_of_cores", + "num_of_cores_enabled", + "num_of_cpus", + "num_of_eth_host_ifs", + "num_of_fc_host_ifs", + "num_of_threads", + "oper_power", + "oper_pwr_trans_src", + "oper_qualifier", + "oper_qualifier_reason", + "oper_state", + "operability", + "original_uuid", + "parent_mo", + "part_number", + "policy_level", + "policy_owner", + "presence", + "prop_map", + "prop_meta", + "revision", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "scaled_mode", + "serial", + "server_id", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "slot_id", + "status", + "storage_oper_qualifier", + "sync_mo", + "to_xml", + "total_memory", + "usr_lbl", + "uuid", + "vendor", + "vid", + "write_object" +] +``` + +## Meta + +``` +[EquipmentChassis] + |-ComputeBlade + |-AaaEpAuthProfile + | |-AaaEpUser + | |-AaaCimcSession + |-AaaEpUser + | |-AaaCimcSession + |-AdaptorHostIfConfig + |-AdaptorUnit + | |-AdaptorExtEthIf + | | |-AdaptorEthPortBySizeLargeStats + | | | |-AdaptorEthPortBySizeLargeStatsHist + | | |-AdaptorEthPortBySizeSmallStats + | | | |-AdaptorEthPortBySizeSmallStatsHist + | | |-AdaptorEthPortErrStats + | | | |-AdaptorEthPortErrStatsHist + | | |-AdaptorEthPortMcastStats + | | | |-AdaptorEthPortMcastStatsHist + | | |-AdaptorEthPortOutsizedStats + | | | |-AdaptorEthPortOutsizedStatsHist + | | |-AdaptorEthPortStats + | | | |-AdaptorEthPortStatsHist + | | |-AdaptorExtEthIfFsm + | | | |-AdaptorExtEthIfFsmStage + | | |-AdaptorExtEthIfFsmTask + | | |-DcxVIf + | | | |-FaultInst + | | |-EventInst + | | |-FabricEthMonSrcEp + | | |-FaultInst + | |-AdaptorExtEthIfPc + | | |-AdaptorExtEthIfPcEp + | | |-DcxVIf + | | |-FaultInst + | |-AdaptorHostEthIf + | | |-AdaptorAzureQosProfile + | | |-AdaptorEthAdvFilterProfile + | | |-AdaptorEthArfsProfile + | | |-AdaptorEthCompQueueProfile + | | |-AdaptorEthFailoverProfile + | | |-AdaptorEthGENEVEProfile + | | |-AdaptorEthInterruptProfile + | | |-AdaptorEthInterruptScalingProfile + | | |-AdaptorEthNVGREProfile + | | |-AdaptorEthOffloadProfile + | | |-AdaptorEthPortBySizeLargeStats + | | | |-AdaptorEthPortBySizeLargeStatsHist + | | |-AdaptorEthPortBySizeSmallStats + | | | |-AdaptorEthPortBySizeSmallStatsHist + | | |-AdaptorEthPortErrStats + | | | |-AdaptorEthPortErrStatsHist + | | |-AdaptorEthPortMcastStats + | | | |-AdaptorEthPortMcastStatsHist + | | |-AdaptorEthPortOutsizedStats + | | | |-AdaptorEthPortOutsizedStatsHist + | | |-AdaptorEthPortStats + | | | |-AdaptorEthPortStatsHist + | | |-AdaptorEthRecvQueueProfile + | | |-AdaptorEthRoCEProfile + | | |-AdaptorEthVxLANProfile + | | |-AdaptorEthWorkQueueProfile + | | |-AdaptorExtIpV6RssHashProfile + | | |-AdaptorFcOEIf + | | | |-DcxVIf + | | | |-FaultInst + | | |-AdaptorHostEthIfFsm + | | | |-AdaptorHostEthIfFsmStage + | | |-AdaptorHostEthIfFsmTask + | | |-AdaptorIpV4RssHashProfile + | | |-AdaptorIpV6RssHashProfile + | | |-AdaptorPTP + | | |-AdaptorRssProfile + | | |-AdaptorUsnicConnDef + | | | |-AdaptorEthCompQueueProfile + | | | |-AdaptorEthFailoverProfile + | | | |-AdaptorEthInterruptProfile + | | | |-AdaptorEthInterruptScalingProfile + | | | |-AdaptorEthOffloadProfile + | | | |-AdaptorEthRecvQueueProfile + | | | |-AdaptorEthWorkQueueProfile + | | | |-AdaptorExtIpV6RssHashProfile + | | | |-AdaptorIpV4RssHashProfile + | | | |-AdaptorIpV6RssHashProfile + | | | |-AdaptorRssProfile + | | |-AdaptorVlan + | | | |-AdaptorEtherIfStats + | | | | |-AdaptorEtherIfStatsHist + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | | |-VnicIPv4Dhcp + | | | |-VnicIPv4Dns + | | | |-VnicIPv4IscsiAddr + | | | | |-VnicIPv4Dns + | | | |-VnicIPv4PooledIscsiAddr + | | | | |-FaultInst + | | | | |-VnicIPv4Dns + | | | | |-VnicIpV4History + | | | |-VnicIPv4StaticRoute + | | | |-VnicIScsiAutoTargetIf + | | | |-VnicIScsiStaticTargetIf + | | | | |-FaultInst + | | | | |-VnicLun + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-AdaptorVmmqConnDef + | | | |-AdaptorEthCompQueueProfile + | | | |-AdaptorEthInterruptProfile + | | | |-AdaptorEthRecvQueueProfile + | | | |-AdaptorEthRoCEProfile + | | | |-AdaptorEthWorkQueueProfile + | | | |-AdaptorRssProfile + | | |-AdaptorVnicStats + | | | |-AdaptorVnicStatsHist + | | |-DcxVIf + | | | |-FaultInst + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-NetworkIfStats + | |-AdaptorHostFcIf + | | |-AdaptorFcCdbWorkQueueProfile + | | |-AdaptorFcErrorRecoveryProfile + | | |-AdaptorFcFnicProfile + | | |-AdaptorFcIfEventStats + | | | |-AdaptorFcIfEventStatsHist + | | |-AdaptorFcIfFC4Stats + | | | |-AdaptorFcIfFC4StatsHist + | | |-AdaptorFcIfFrameStats + | | | |-AdaptorFcIfFrameStatsHist + | | |-AdaptorFcInterruptProfile + | | |-AdaptorFcOEIf + | | | |-DcxVIf + | | | |-FaultInst + | | |-AdaptorFcPortFLogiProfile + | | |-AdaptorFcPortPLogiProfile + | | |-AdaptorFcPortProfile + | | |-AdaptorFcPortStats + | | | |-AdaptorFcPortStatsHist + | | |-AdaptorFcRecvQueueProfile + | | |-AdaptorFcVhbaTypeProfile + | | |-AdaptorFcWorkQueueProfile + | | |-AdaptorHostFcIfFsm + | | | |-AdaptorHostFcIfFsmStage + | | |-AdaptorHostFcIfFsmTask + | | |-AdaptorVnicStats + | | | |-AdaptorVnicStatsHist + | | |-AdaptorVsan + | | |-DcxVIf + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-NetworkIfStats + | |-AdaptorHostIscsiIf + | | |-AdaptorIscsiProt + | | |-AdaptorIscsiTargetIf + | | |-AdaptorProtocolProfile + | | |-AdaptorVlan + | | | |-AdaptorEtherIfStats + | | | | |-AdaptorEtherIfStatsHist + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | | |-VnicIPv4Dhcp + | | | |-VnicIPv4Dns + | | | |-VnicIPv4IscsiAddr + | | | | |-VnicIPv4Dns + | | | |-VnicIPv4PooledIscsiAddr + | | | | |-FaultInst + | | | | |-VnicIPv4Dns + | | | | |-VnicIpV4History + | | | |-VnicIPv4StaticRoute + | | | |-VnicIScsiAutoTargetIf + | | | |-VnicIScsiStaticTargetIf + | | | | |-FaultInst + | | | | |-VnicLun + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-AdaptorVnicStats + | | | |-AdaptorVnicStatsHist + | | |-FabricNetflowIPv4Addr + | | |-FaultInst + | | |-NetworkIfStats + | | |-VnicIPv4Dhcp + | | |-VnicIPv4Dns + | | |-VnicIPv4IscsiAddr + | | | |-VnicIPv4Dns + | | |-VnicIPv4PooledIscsiAddr + | | | |-FaultInst + | | | |-VnicIPv4Dns + | | | |-VnicIpV4History + | | |-VnicIPv4StaticRoute + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-AdaptorHostPort + | |-AdaptorHostScsiIf + | | |-AdaptorHostScsiLunRef + | | |-AdaptorVnicStats + | | | |-AdaptorVnicStatsHist + | | |-FaultInst + | | |-NetworkIfStats + | |-AdaptorHostServiceEthIf + | | |-AdaptorVlan + | | | |-AdaptorEtherIfStats + | | | | |-AdaptorEtherIfStatsHist + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | | |-VnicIPv4Dhcp + | | | |-VnicIPv4Dns + | | | |-VnicIPv4IscsiAddr + | | | | |-VnicIPv4Dns + | | | |-VnicIPv4PooledIscsiAddr + | | | | |-FaultInst + | | | | |-VnicIPv4Dns + | | | | |-VnicIpV4History + | | | |-VnicIPv4StaticRoute + | | | |-VnicIScsiAutoTargetIf + | | | |-VnicIScsiStaticTargetIf + | | | | |-FaultInst + | | | | |-VnicLun + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-AdaptorVnicStats + | | | |-AdaptorVnicStatsHist + | | |-DcxVIf + | | | |-FaultInst + | | |-FaultInst + | | |-NetworkIfStats + | |-AdaptorMenloDcePortStats + | | |-AdaptorMenloDcePortStatsHist + | |-AdaptorMenloEthErrorStats + | | |-AdaptorMenloEthErrorStatsHist + | |-AdaptorMenloEthStats + | | |-AdaptorMenloEthStatsHist + | |-AdaptorMenloFcErrorStats + | | |-AdaptorMenloFcErrorStatsHist + | |-AdaptorMenloFcStats + | | |-AdaptorMenloFcStatsHist + | |-AdaptorMenloHostPortStats + | | |-AdaptorMenloHostPortStatsHist + | |-AdaptorMenloMcpuErrorStats + | | |-AdaptorMenloMcpuErrorStatsHist + | |-AdaptorMenloMcpuStats + | | |-AdaptorMenloMcpuStatsHist + | |-AdaptorMenloNetEgStats + | | |-AdaptorMenloNetEgStatsHist + | |-AdaptorMenloNetInStats + | | |-AdaptorMenloNetInStatsHist + | |-AdaptorMenloQErrorStats + | | |-AdaptorMenloQErrorStatsHist + | |-AdaptorMenloQStats + | | |-AdaptorMenloQStatsHist + | |-AdaptorUnitExtn + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-FaultInst + | |-DcxNs + | | |-FaultInst + | |-EquipmentInventoryStatus + | | |-FaultInst + | |-EquipmentPOST + | |-EquipmentPciDef + | |-FaultInst + | |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-BiosUnit + | |-BiosBOT + | | |-BiosBootDevGrp + | | |-BiosBootDev + | |-BiosSettings + | | |-BiosTokenFeatureGroup + | | | |-BiosTokenParam + | | | |-BiosTokenSettings + | | |-BiosTokenParam + | | | |-BiosTokenSettings + | | |-BiosVfACPI10Support + | | |-BiosVfASPMSupport + | | |-BiosVfAllUSBDevices + | | |-BiosVfAltitude + | | |-BiosVfAssertNMIOnPERR + | | |-BiosVfAssertNMIOnSERR + | | |-BiosVfBMEDMAMitigation + | | |-BiosVfBootOptionRetry + | | |-BiosVfCPUHardwarePowerManagement + | | |-BiosVfCPUPerformance + | | |-BiosVfConsistentDeviceNameControl + | | |-BiosVfConsoleRedirection + | | |-BiosVfCoreMultiProcessing + | | |-BiosVfDDR3VoltageSelection + | | |-BiosVfDRAMClockThrottling + | | |-BiosVfDirectCacheAccess + | | |-BiosVfDramRefreshRate + | | |-BiosVfEnergyPerformanceTuning + | | |-BiosVfEnhancedIntelSpeedStepTech + | | |-BiosVfEnhancedPowerCappingSupport + | | |-BiosVfExecuteDisableBit + | | |-BiosVfFRB2Timer + | | |-BiosVfFrequencyFloorOverride + | | |-BiosVfFrontPanelLockout + | | |-BiosVfIOEMezz1OptionROM + | | |-BiosVfIOENVMe1OptionROM + | | |-BiosVfIOENVMe2OptionROM + | | |-BiosVfIOESlot1OptionROM + | | |-BiosVfIOESlot2OptionROM + | | |-BiosVfIntegratedGraphics + | | |-BiosVfIntegratedGraphicsApertureSize + | | |-BiosVfIntelEntrySASRAIDModule + | | |-BiosVfIntelHyperThreadingTech + | | |-BiosVfIntelTrustedExecutionTechnology + | | |-BiosVfIntelTurboBoostTech + | | |-BiosVfIntelVTForDirectedIO + | | |-BiosVfIntelVirtualizationTechnology + | | |-BiosVfInterleaveConfiguration + | | |-BiosVfLocalX2Apic + | | |-BiosVfLvDIMMSupport + | | |-BiosVfMaxVariableMTRRSetting + | | |-BiosVfMaximumMemoryBelow4GB + | | |-BiosVfMemoryMappedIOAbove4GB + | | |-BiosVfMirroringMode + | | |-BiosVfNUMAOptimized + | | |-BiosVfOSBootWatchdogTimer + | | |-BiosVfOSBootWatchdogTimerPolicy + | | |-BiosVfOSBootWatchdogTimerTimeout + | | |-BiosVfOnboardGraphics + | | |-BiosVfOnboardSATAController + | | |-BiosVfOnboardStorage + | | |-BiosVfOptionROMEnable + | | |-BiosVfOptionROMLoad + | | |-BiosVfOutOfBandManagement + | | |-BiosVfPCHSATAMode + | | |-BiosVfPCILOMPortsConfiguration + | | |-BiosVfPCIROMCLP + | | |-BiosVfPCISlotLinkSpeed + | | |-BiosVfPCISlotOptionROMEnable + | | |-BiosVfPOSTErrorPause + | | |-BiosVfPSTATECoordination + | | |-BiosVfPackageCStateLimit + | | |-BiosVfPanicAndHighWatermark + | | |-BiosVfProcessorC1E + | | |-BiosVfProcessorC3Report + | | |-BiosVfProcessorC6Report + | | |-BiosVfProcessorC7Report + | | |-BiosVfProcessorCMCI + | | |-BiosVfProcessorCState + | | |-BiosVfProcessorEnergyConfiguration + | | |-BiosVfProcessorPrefetchConfig + | | |-BiosVfQPILinkFrequencySelect + | | |-BiosVfQPISnoopMode + | | |-BiosVfQuietBoot + | | |-BiosVfRedirectionAfterBIOSPOST + | | |-BiosVfResumeOnACPowerLoss + | | |-BiosVfSBMezz1OptionROM + | | |-BiosVfSBNVMe1OptionROM + | | |-BiosVfSIOC1OptionROM + | | |-BiosVfSIOC2OptionROM + | | |-BiosVfScrubPolicies + | | |-BiosVfSelectMemoryRASConfiguration + | | |-BiosVfSerialPortAEnable + | | |-BiosVfSparingMode + | | |-BiosVfSriovConfig + | | |-BiosVfTPMPendingOperation + | | |-BiosVfTPMSupport + | | |-BiosVfTrustedPlatformModule + | | |-BiosVfUCSMBootModeControl + | | |-BiosVfUCSMBootOrderRuleControl + | | |-BiosVfUEFIOSUseLegacyVideo + | | |-BiosVfUSBBootConfig + | | |-BiosVfUSBConfiguration + | | |-BiosVfUSBFrontPanelAccessLock + | | |-BiosVfUSBPortConfiguration + | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | |-BiosVfVGAPriority + | | |-BiosVfWorkloadConfiguration + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | |-FaultInst + | |-FirmwareInstallable + | |-FirmwareUcscInfo + |-BiosVIdentityParams + |-CimcvmediaMountConfigDef + | |-CimcvmediaConfigMountEntry + |-ComputeAdminAck + | |-FaultInst + | |-TrigLocalSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-ComputeBladeFsm + | |-ComputeBladeFsmStage + |-ComputeBladeFsmTask + |-ComputeBoard + | |-ComputeIOHub + | | |-ComputeIOHubEnvStats + | | | |-ComputeIOHubEnvStatsHist + | | |-FaultInst + | |-ComputeMbPowerStats + | | |-ComputeMbPowerStatsHist + | |-ComputeMbTempStats + | | |-ComputeMbTempStatsHist + | |-ComputePCIeFatalCompletionStats + | |-ComputePCIeFatalProtocolStats + | |-ComputePCIeFatalReceiveStats + | |-ComputePCIeFatalStats + | |-ComputeRackUnitMbTempStats + | | |-ComputeRackUnitMbTempStatsHist + | |-ComputeRtcBattery + | | |-FaultInst + | |-CoprocessorCard + | |-EquipmentTpm + | | |-FaultInst + | |-FaultInst + | |-GraphicsCard + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-GraphicsController + | |-LstorageLocal + | |-LstorageLocalDef + | |-LstorageRemote + | | |-LstorageLogin + | |-LstorageRemoteDef + | | |-LstorageLogin + | |-MemoryArray + | | |-FaultInst + | | |-MemoryArrayEnvStats + | | | |-MemoryArrayEnvStatsHist + | | |-MemoryPersistentMemoryUnit + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MemoryErrorStats + | | | |-MemoryUnitEnvStats + | | | |-MemoryUnitEnvStatsHist + | | |-MemoryUnit + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-FaultInst + | | |-MemoryErrorStats + | | |-MemoryUnitEnvStats + | | |-MemoryUnitEnvStatsHist + | |-MemoryBufferUnit + | | |-FaultInst + | | |-MemoryBufferUnitEnvStats + | | |-MemoryBufferUnitEnvStatsHist + | |-MemoryPersistentMemoryConfiguration + | | |-FaultInst + | | |-MemoryPersistentMemoryConfigResult + | | | |-FaultInst + | | | |-MemoryPersistentMemoryNamespaceConfigResult + | | | |-FaultInst + | | |-MemoryPersistentMemoryRegion + | | |-MemoryPersistentMemoryNamespace + | | |-FaultInst + | |-PciSwitch + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-PciLink + | |-ProcessorUnit + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-FaultInst + | | |-ProcessorCacheMemStats + | | |-ProcessorCore + | | | |-ProcessorThread + | | |-ProcessorEnvStats + | | | |-ProcessorEnvStatsHist + | | |-ProcessorErrorStats + | | |-ProcessorExecStats + | | |-ProcessorIOStats + | | |-ProcessorMiscStats + | | |-ProcessorPCIBusStats + | | |-ProcessorPMUStats + | | |-ProcessorSecurityStats + | |-SecurityUnit + | | |-EquipmentInventoryStatus + | | |-FaultInst + | |-StorageController + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-LstorageControllerDef + | | | |-LstorageControllerModeConfig + | | | |-LstorageControllerQualifier + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageDrive + | | |-StorageEmbeddedStorage + | | |-StorageEnclosure + | | | |-EventInst + | | | |-FaultInst + | | | |-StorageEnclosureDiskSlotEp + | | | | |-FaultInst + | | | | |-StorageControllerRef + | | | |-StorageEnclosureFsm + | | | | |-StorageEnclosureFsmStage + | | | |-StorageEnclosureFsmTask + | | | |-StorageHddMotherBoardTempStats + | | | | |-StorageHddMotherBoardTempStatsHist + | | | |-StorageLocalDisk + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageControllerEp + | | | |-StorageDiskEnvStats + | | | | |-StorageDiskEnvStatsHist + | | | |-StorageLocalDiskFsm + | | | | |-StorageLocalDiskFsmStage + | | | |-StorageLocalDiskFsmTask + | | | |-StorageLocalDiskPartition + | | | |-StorageOperation + | | | |-StorageSasPort + | | | |-StorageSsdHealthStats + | | | |-StorageSsdHealthStatsHist + | | |-StorageLocalDisk + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageControllerEp + | | | |-StorageDiskEnvStats + | | | | |-StorageDiskEnvStatsHist + | | | |-StorageLocalDiskFsm + | | | | |-StorageLocalDiskFsmStage + | | | |-StorageLocalDiskFsmTask + | | | |-StorageLocalDiskPartition + | | | |-StorageOperation + | | | |-StorageSasPort + | | | |-StorageSsdHealthStats + | | | |-StorageSsdHealthStatsHist + | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-StorageLocalDiskEp + | | |-StorageLocalLun + | | |-StorageMezzFlashLife + | | | |-FaultInst + | | |-StorageNvmeStats + | | | |-StorageNvmeStatsHist + | | |-StorageNvmeStorage + | | |-StorageOnboardDevice + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-StorageOperation + | | |-StorageRaidBattery + | | | |-FaultInst + | | | |-StorageOperation + | | | |-StorageTransportableFlashModule + | | |-StorageVirtualDrive + | | | |-FaultInst + | | | |-StorageControllerEp + | | | |-StorageLunDisk + | | | |-StorageOperation + | | | |-StorageScsiLunRef + | | | |-StorageVDMemberEp + | | | |-FaultInst + | | |-StorageVirtualDriveEp + | |-StorageFlexFlashController + | | |-EventInst + | | |-FaultInst + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-StorageFlexFlashCard + | | | |-FaultInst + | | | |-StorageFlexFlashDrive + | | | |-FaultInst + | | |-StorageFlexFlashControllerFsm + | | | |-StorageFlexFlashControllerFsmStage + | | |-StorageFlexFlashControllerFsmTask + | | |-StorageFlexFlashVirtualDrive + | | | |-FaultInst + | | |-StorageLocalDiskConfigDef + | | |-LstorageSecurity + | | | |-LstorageDriveSecurity + | | | |-LstorageLocal + | | | |-LstorageRemote + | | | |-LstorageLogin + | | |-StorageLocalDiskPartition + | |-StorageLocalDiskSlotEp + | | |-FaultInst + | |-StorageMiniStorage + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-StorageControllerReference + | |-StorageNvmeSwitch + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | |-FirmwareServicePack + | |-StorageSasExpander + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-StorageOnboardDevice + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-StorageSasUpLink + |-ComputeBoardConnector + |-ComputeBoardController + | |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-ComputeExtBoard + | |-BiosUnit + | | |-BiosBOT + | | | |-BiosBootDevGrp + | | | |-BiosBootDev + | | |-BiosSettings + | | | |-BiosTokenFeatureGroup + | | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosVfACPI10Support + | | | |-BiosVfASPMSupport + | | | |-BiosVfAllUSBDevices + | | | |-BiosVfAltitude + | | | |-BiosVfAssertNMIOnPERR + | | | |-BiosVfAssertNMIOnSERR + | | | |-BiosVfBMEDMAMitigation + | | | |-BiosVfBootOptionRetry + | | | |-BiosVfCPUHardwarePowerManagement + | | | |-BiosVfCPUPerformance + | | | |-BiosVfConsistentDeviceNameControl + | | | |-BiosVfConsoleRedirection + | | | |-BiosVfCoreMultiProcessing + | | | |-BiosVfDDR3VoltageSelection + | | | |-BiosVfDRAMClockThrottling + | | | |-BiosVfDirectCacheAccess + | | | |-BiosVfDramRefreshRate + | | | |-BiosVfEnergyPerformanceTuning + | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | |-BiosVfEnhancedPowerCappingSupport + | | | |-BiosVfExecuteDisableBit + | | | |-BiosVfFRB2Timer + | | | |-BiosVfFrequencyFloorOverride + | | | |-BiosVfFrontPanelLockout + | | | |-BiosVfIOEMezz1OptionROM + | | | |-BiosVfIOENVMe1OptionROM + | | | |-BiosVfIOENVMe2OptionROM + | | | |-BiosVfIOESlot1OptionROM + | | | |-BiosVfIOESlot2OptionROM + | | | |-BiosVfIntegratedGraphics + | | | |-BiosVfIntegratedGraphicsApertureSize + | | | |-BiosVfIntelEntrySASRAIDModule + | | | |-BiosVfIntelHyperThreadingTech + | | | |-BiosVfIntelTrustedExecutionTechnology + | | | |-BiosVfIntelTurboBoostTech + | | | |-BiosVfIntelVTForDirectedIO + | | | |-BiosVfIntelVirtualizationTechnology + | | | |-BiosVfInterleaveConfiguration + | | | |-BiosVfLocalX2Apic + | | | |-BiosVfLvDIMMSupport + | | | |-BiosVfMaxVariableMTRRSetting + | | | |-BiosVfMaximumMemoryBelow4GB + | | | |-BiosVfMemoryMappedIOAbove4GB + | | | |-BiosVfMirroringMode + | | | |-BiosVfNUMAOptimized + | | | |-BiosVfOSBootWatchdogTimer + | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | |-BiosVfOnboardGraphics + | | | |-BiosVfOnboardSATAController + | | | |-BiosVfOnboardStorage + | | | |-BiosVfOptionROMEnable + | | | |-BiosVfOptionROMLoad + | | | |-BiosVfOutOfBandManagement + | | | |-BiosVfPCHSATAMode + | | | |-BiosVfPCILOMPortsConfiguration + | | | |-BiosVfPCIROMCLP + | | | |-BiosVfPCISlotLinkSpeed + | | | |-BiosVfPCISlotOptionROMEnable + | | | |-BiosVfPOSTErrorPause + | | | |-BiosVfPSTATECoordination + | | | |-BiosVfPackageCStateLimit + | | | |-BiosVfPanicAndHighWatermark + | | | |-BiosVfProcessorC1E + | | | |-BiosVfProcessorC3Report + | | | |-BiosVfProcessorC6Report + | | | |-BiosVfProcessorC7Report + | | | |-BiosVfProcessorCMCI + | | | |-BiosVfProcessorCState + | | | |-BiosVfProcessorEnergyConfiguration + | | | |-BiosVfProcessorPrefetchConfig + | | | |-BiosVfQPILinkFrequencySelect + | | | |-BiosVfQPISnoopMode + | | | |-BiosVfQuietBoot + | | | |-BiosVfRedirectionAfterBIOSPOST + | | | |-BiosVfResumeOnACPowerLoss + | | | |-BiosVfSBMezz1OptionROM + | | | |-BiosVfSBNVMe1OptionROM + | | | |-BiosVfSIOC1OptionROM + | | | |-BiosVfSIOC2OptionROM + | | | |-BiosVfScrubPolicies + | | | |-BiosVfSelectMemoryRASConfiguration + | | | |-BiosVfSerialPortAEnable + | | | |-BiosVfSparingMode + | | | |-BiosVfSriovConfig + | | | |-BiosVfTPMPendingOperation + | | | |-BiosVfTPMSupport + | | | |-BiosVfTrustedPlatformModule + | | | |-BiosVfUCSMBootModeControl + | | | |-BiosVfUCSMBootOrderRuleControl + | | | |-BiosVfUEFIOSUseLegacyVideo + | | | |-BiosVfUSBBootConfig + | | | |-BiosVfUSBConfiguration + | | | |-BiosVfUSBFrontPanelAccessLock + | | | |-BiosVfUSBPortConfiguration + | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | |-BiosVfVGAPriority + | | | |-BiosVfWorkloadConfiguration + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-ComputeBoardController + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-ComputeMbPowerStats + | | |-ComputeMbPowerStatsHist + | |-ComputeMbTempStats + | | |-ComputeMbTempStatsHist + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-FaultInst + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-PowerBudget + | |-FaultInst + | |-PowerProfiledPower + |-ComputeFactoryResetOperation + |-ComputeFwSyncAck + | |-FaultInst + | |-TrigLocalSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-ComputeHostUtilityOs + | |-MgmtUsbNicMgmtIf + |-ComputeKvmMgmtPolicy + | |-MgmtKvmCertificate + | |-FaultInst + |-ComputeMemoryConfiguration + |-ComputePersonality + |-ComputePhysicalExtension + | |-FaultInst + |-ComputePhysicalFsm + | |-ComputePhysicalFsmStage + |-ComputePhysicalFsmTask + |-ComputePnuOSImage + |-ComputePoolable + | |-ComputePoolPolicyRef + |-ComputeRebootLog + |-ComputeScrubPolicy + |-DiagSrvCtrl + | |-DiagRslt + | | |-DiagLogEp + | |-DiagRunPolicy + | | |-DiagMemoryTest + | |-EtherServerIntFIo + | |-EquipmentXcvr + | |-EtherErrStats + | | |-EtherErrStatsHist + | |-EtherLossStats + | | |-EtherLossStatsHist + | |-EtherPauseStats + | | |-EtherPauseStatsHist + | |-EtherRxStats + | | |-EtherRxStatsHist + | |-EtherServerIntFIoFsm + | | |-EtherServerIntFIoFsmStage + | |-EtherServerIntFIoFsmTask + | |-EtherTxStats + | | |-EtherTxStatsHist + | |-EventInst + | |-FaultInst + | |-LldpAcquired + | |-PortDomainEp + | |-PortTrustMode + | |-SwUlan + |-EquipmentBeaconLed + | |-EquipmentBeaconLedFsm + | | |-EquipmentBeaconLedFsmStage + | |-EquipmentBeaconLedFsmTask + | |-EventInst + | |-FaultInst + |-EquipmentHealthLed + | |-ComputeHealthLedSensorAlarm + | |-FaultInst + |-EquipmentIOExpander + |-EquipmentIndicatorLed + |-EquipmentInventoryStatus + | |-FaultInst + |-EquipmentLocatorLed + | |-EquipmentLocatorLedFsm + | | |-EquipmentLocatorLedFsmStage + | |-EquipmentLocatorLedFsmTask + | |-EventInst + | |-FaultInst + |-EquipmentPOST + |-EventInst + |-FabricLocale + | |-AdaptorExtEthIfPc + | | |-AdaptorExtEthIfPcEp + | | |-DcxVIf + | | |-FaultInst + | |-DcxVc + | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-FabricSanGroupRef + | | | |-FaultInst + | | |-FaultInst + | | |-SwCmclan + | | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-SwNetflowMonitorRef + | | |-SwUlan + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVsan + | | |-SwFcZoneSet + | | |-SwFcServerZoneGroup + | | | |-SwZoneInitiatorMember + | | | |-SwFcZone + | | | |-SwZoneTargetMember + | | |-SwFcUserZoneGroup + | | |-SwFcUserZone + | | |-SwFcEndpoint + | |-FabricPath + | |-DcxVc + | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-FabricSanGroupRef + | | | |-FaultInst + | | |-FaultInst + | | |-SwCmclan + | | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-SwNetflowMonitorRef + | | |-SwUlan + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVsan + | | |-SwFcZoneSet + | | |-SwFcServerZoneGroup + | | | |-SwZoneInitiatorMember + | | | |-SwFcZone + | | | |-SwZoneTargetMember + | | |-SwFcUserZoneGroup + | | |-SwFcUserZone + | | |-SwFcEndpoint + | |-FabricPathConn + | | |-FabricPathEp + | | |-PortTrustMode + | |-FabricPathEp + | |-PortTrustMode + |-FaultInst + |-FaultSuppressTask + | |-FaultInst + | |-TrigLocalSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-FirmwareImageLock + |-FirmwareStatus + | |-FaultInst + |-LsIdentityInfo + | |-FaultInst + |-LsbootDef + | |-LsbootBootSecurity + | |-LsbootEFIShell + | |-LsbootIScsi + | | |-LsbootIScsiImagePath + | | |-LsbootUEFIBootParam + | |-LsbootLan + | | |-LsbootLanImagePath + | | |-LsbootUEFIBootParam + | | |-VnicIpV4StaticAddr + | |-LsbootSan + | | |-LsbootSanCatSanImage + | | |-LsbootSanCatSanImagePath + | | |-LsbootUEFIBootParam + | |-LsbootStorage + | | |-LsbootLocalStorage + | | | |-LsbootDefaultLocalImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootEmbeddedLocalDiskImage + | | | | |-LsbootEmbeddedLocalDiskImagePath + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUEFIBootParam + | | | |-LsbootEmbeddedLocalLunImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootLocalDiskImage + | | | | |-LsbootLocalDiskImagePath + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUEFIBootParam + | | | |-LsbootLocalHddImage + | | | | |-LsbootLocalLunImagePath + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUEFIBootParam + | | | |-LsbootNvme + | | | | |-LsbootNvmeDiskSsd + | | | | |-LsbootNvmePciSsd + | | | | |-LsbootUEFIBootParam + | | | |-LsbootUsbExternalImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootUsbFlashStorageImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootUsbInternalImage + | | | |-LsbootUEFIBootParam + | | |-LsbootSanImage + | | |-LsbootSanImagePath + | | |-LsbootUEFIBootParam + | |-LsbootVirtualMedia + |-LstorageProfile + | |-LstorageControllerDef + | | |-LstorageControllerModeConfig + | | |-LstorageControllerQualifier + | |-LstorageDasScsiLun + | | |-FaultInst + | | |-StorageLocalDiskConfigDef + | | |-LstorageSecurity + | | | |-LstorageDriveSecurity + | | | |-LstorageLocal + | | | |-LstorageRemote + | | | |-LstorageLogin + | | |-StorageLocalDiskPartition + | |-LstorageLunSetConfig + | | |-LstorageLunSetDiskSlot + | | |-LstorageVirtualDriveDef + | |-LstorageSecurity + | |-LstorageDriveSecurity + | |-LstorageLocal + | |-LstorageRemote + | |-LstorageLogin + |-MemoryRuntime + | |-MemoryRuntimeHist + |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-MgmtKmipCertPolicy + |-MgmtSecurity + | |-MgmtKmip + |-MgmtSpdmCertificatePolicy + | |-MgmtSpdmCertificate + |-MoKvCfgHolder + | |-MoIpV4AddrKv + | | |-FaultInst + | |-MoIpV6AddrKv + | | |-FaultInst + | |-MoKv + | |-MoVnicKv + |-MoKvInvHolder + | |-MoInvKv + |-OsAgent + |-OsInstance + | |-OsEthBondIntf + | | |-OsARPLinkMonitoringPolicy + | | | |-OsARPTarget + | | |-OsEthBondModeActiveBackup + | | | |-OsPrimarySlave + | | |-OsEthBondModeBalancedALB + | | | |-OsPrimarySlave + | | |-OsEthBondModeBalancedRR + | | | |-OsPrimarySlave + | | |-OsEthBondModeBalancedTLB + | | | |-OsPrimarySlave + | | |-OsEthBondModeBalancedXOR + | | | |-OsPrimarySlave + | | |-OsEthBondModeBroadcast + | | | |-OsPrimarySlave + | | |-OsEthIntf + | | |-OsMiiLinkMonitoringPolicy + | |-OsEthIntf + |-PciEquipSlot + | |-FaultInst + |-PciUnit + |-PowerBudget + | |-FaultInst + | |-PowerProfiledPower + |-ProcessorRuntime + | |-ProcessorRuntimeHist + |-SolIf + |-StorageEnclosure + | |-EventInst + | |-FaultInst + | |-StorageEnclosureDiskSlotEp + | | |-FaultInst + | | |-StorageControllerRef + | |-StorageEnclosureFsm + | | |-StorageEnclosureFsmStage + | |-StorageEnclosureFsmTask + | |-StorageHddMotherBoardTempStats + | | |-StorageHddMotherBoardTempStatsHist + | |-StorageLocalDisk + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EventInst + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-StorageControllerEp + | |-StorageDiskEnvStats + | | |-StorageDiskEnvStatsHist + | |-StorageLocalDiskFsm + | | |-StorageLocalDiskFsmStage + | |-StorageLocalDiskFsmTask + | |-StorageLocalDiskPartition + | |-StorageOperation + | |-StorageSasPort + | |-StorageSsdHealthStats + | |-StorageSsdHealthStatsHist + |-StorageVirtualDriveContainer + | |-StorageVirtualDrive + | |-FaultInst + | |-StorageControllerEp + | |-StorageLunDisk + | |-StorageOperation + | |-StorageScsiLunRef + | |-StorageVDMemberEp + | |-FaultInst + |-SwUlan + |-SysdebugDiagnosticLog + +ClassId ComputeBlade +------- ------------ +xml_attribute :computeBlade +rn :blade-[slot_id] +min_version :1.0(1e) +access :InputOutput +access_privilege :['admin', 'pn-equipment', 'pn-maintenance', 'pn-policy'] +parents :['equipmentChassis'] +children :['aaaEpAuthProfile', 'aaaEpUser', 'adaptorHostIfConfig', 'adaptorUnit', 'biosUnit', 'biosVIdentityParams', 'cimcvmediaMountConfigDef', 'computeAdminAck', 'computeBladeFsm', 'computeBladeFsmTask', 'computeBoard', 'computeBoardConnector', 'computeBoardController', 'computeExtBoard', 'computeFactoryResetOperation', 'computeFwSyncAck', 'computeHostUtilityOs', 'computeKvmMgmtPolicy', 'computeMemoryConfiguration', 'computePersonality', 'computePhysicalExtension', 'computePhysicalFsm', 'computePhysicalFsmTask', 'computePnuOSImage', 'computePoolable', 'computeRebootLog', 'computeScrubPolicy', 'diagSrvCtrl', 'equipmentBeaconLed', 'equipmentHealthLed', 'equipmentIOExpander', 'equipmentIndicatorLed', 'equipmentInventoryStatus', 'equipmentLocatorLed', 'equipmentPOST', 'eventInst', 'fabricLocale', 'faultInst', 'faultSuppressTask', 'firmwareImageLock', 'firmwareStatus', 'lsIdentityInfo', 'lsbootDef', 'lstorageProfile', 'memoryRuntime', 'mgmtController', 'mgmtKmipCertPolicy', 'mgmtSecurity', 'mgmtSpdmCertificatePolicy', 'moKvCfgHolder', 'moKvInvHolder', 'osAgent', 'osInstance', 'pciEquipSlot', 'pciUnit', 'powerBudget', 'processorRuntime', 'solIf', 'storageEnclosure', 'storageVirtualDriveContainer', 'swUlan', 'sysdebugDiagnosticLog'] + +Property admin_power +-------- ----------- +xml_attribute :adminPower +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :None +value_set :['admin-down', 'admin-up', 'bios-password-reset-immediate', 'bmc-reset-immediate', 'bmc-reset-wait', 'cmos-reset-immediate', 'cycle-immediate', 'cycle-wait', 'diagnostic-interrupt', 'hard-reset-immediate', 'hard-reset-wait', 'ipmi-reset', 'kvm-reset', 'policy'] +range_val :[] + +Property admin_state +-------- ----------- +xml_attribute :adminState +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['in-maintenance', 'in-service', 'out-of-service'] +range_val :[] + +Property asset_tag +-------- --------- +xml_attribute :assetTag +field_type :string +min_version :3.2(1d) +access :READ_ONLY +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,32} +value_set :[] +range_val :[] + +Property assigned_to_dn +-------- -------------- +xml_attribute :assignedToDn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property association +-------- ----------- +xml_attribute :association +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['associated', 'establishing', 'failed', 'none', 'removing', 'throttled'] +range_val :[] + +Property availability +-------- ------------ +xml_attribute :availability +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['available', 'unavailable'] +range_val :[] + +Property available_memory +-------- ---------------- +xml_attribute :availableMemory +field_type :uint +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_id +-------- ---------- +xml_attribute :chassisId +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['N/A'] +range_val :['0-255'] + +Property check_point +-------- ----------- +xml_attribute :checkPoint +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['deep-checkpoint', 'discovered', 'removing', 'shallow-checkpoint', 'unknown'] +range_val :[] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property conn_path +-------- --------- +xml_attribute :connPath +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|unknown|A|B),){0,3}(defaultValue|unknown|A|B){0,1} +value_set :[] +range_val :[] + +Property conn_status +-------- ----------- +xml_attribute :connStatus +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|unknown|A|B),){0,3}(defaultValue|unknown|A|B){0,1} +value_set :[] +range_val :[] + +Property descr +-------- ----- +xml_attribute :descr +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,256} +value_set :[] +range_val :[] + +Property discovery +-------- --------- +xml_attribute :discovery +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['complete', 'diagnostics-complete', 'diagnostics-failed', 'diagnostics-in-progress', 'efidiagnostics-in-progress', 'failed', 'fru-identity-indeterminate', 'fru-not-ready', 'fru-state-indeterminate', 'illegal-fru', 'in-progress', 'insufficiently-equipped', 'invalid-adaptor-iocard', 'malformed-fru-info', 'retry', 'throttled', 'undiscovered', 'user-acknowledged', 'waiting-for-mgmt-ack', 'waiting-for-user-ack'] +range_val :[] + +Property discovery_status +-------- ---------------- +xml_attribute :discoveryStatus +field_type :string +min_version :2.5(1a) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|unknown|A|B),){0,3}(defaultValue|unknown|A|B){0,1} +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property flt_aggr +-------- -------- +xml_attribute :fltAggr +field_type :ulong +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property fsm_descr +-------- --------- +xml_attribute :fsmDescr +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property fsm_flags +-------- --------- +xml_attribute :fsmFlags +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :['0-4294967295'] + +Property fsm_prev +-------- -------- +xml_attribute :fsmPrev +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['ActivateAdaptorActivateLocal', 'ActivateAdaptorActivatePeer', 'ActivateAdaptorAssertBypassWait', 'ActivateAdaptorBegin', 'ActivateAdaptorCheckPowerAvailability', 'ActivateAdaptorDeassertResetBypass', 'ActivateAdaptorFail', 'ActivateAdaptorPowerDeployWait', 'ActivateAdaptorPowerOn', 'ActivateAdaptorReset', 'ActivateAdaptorSuccess', 'ActivateBIOSActivate', 'ActivateBIOSBegin', 'ActivateBIOSCheckPowerAvailability', 'ActivateBIOSClear', 'ActivateBIOSFail', 'ActivateBIOSPollActivateStatus', 'ActivateBIOSPollClearStatus', 'ActivateBIOSPowerDeployWait', 'ActivateBIOSPowerOff', 'ActivateBIOSPowerOn', 'ActivateBIOSSuccess', 'ActivateBIOSUpdateTokens', 'AssociateActivateAdaptorNwFwLocal', 'AssociateActivateAdaptorNwFwPeer', 'AssociateActivateBios', 'AssociateActivateIBMCFw', 'AssociateAssertBypassWait', 'AssociateBegin', 'AssociateBiosImgUpdate', 'AssociateBiosPostCompletion', 'AssociateBladePowerOff', 'AssociateBmcConfigPnuOS', 'AssociateBmcPreconfigPnuOSLocal', 'AssociateBmcPreconfigPnuOSPeer', 'AssociateBmcUnconfigPnuOS', 'AssociateBootHost', 'AssociateBootPnuos', 'AssociateBootWait', 'AssociateCalculateVlanGroupForHostOSLocal', 'AssociateCalculateVlanGroupForHostOSPeer', 'AssociateCheckPowerAvailability', 'AssociateCiscoOSOpenGate', 'AssociateClearBiosUpdate', 'AssociateConfigCimcVMedia', 'AssociateConfigExtMgmtGw', 'AssociateConfigExtMgmtRules', 'AssociateConfigFanSpeed', 'AssociateConfigFlexFlash', 'AssociateConfigHostOsAnnotations', 'AssociateConfigMgmtIpRules', 'AssociateConfigServerIdentity', 'AssociateConfigSoL', 'AssociateConfigUserAccess', 'AssociateConfigUuid', 'AssociateCopyRemote', 'AssociateDeassertResetBypass', 'AssociateDeleteCurlDownloadedImages', 'AssociateDeleteImagesRemote', 'AssociateDownloadImages', 'AssociateFail', 'AssociateGraphicsImageUpdate', 'AssociateHagHostOSConnect', 'AssociateHagPnuOSConnect', 'AssociateHagPnuOSDisconnect', 'AssociateHbaImgUpdate', 'AssociateHostOSConfig', 'AssociateHostOSConnect', 'AssociateHostOSIdent', 'AssociateHostOSPolicy', 'AssociateHostOSValidate', 'AssociateLocalDiskFwUpdate', 'AssociateMarkAdapterForReboot', 'AssociateMswitchImgUpdate', 'AssociateNicConfigHostOSLocal', 'AssociateNicConfigHostOSPeer', 'AssociateNicConfigParamsHostOSLocal', 'AssociateNicConfigParamsHostOSPeer', 'AssociateNicConfigPnuOSLocal', 'AssociateNicConfigPnuOSPeer', 'AssociateNicConfigServiceInfraLocal', 'AssociateNicConfigServiceInfraPeer', 'AssociateNicImgUpdate', 'AssociateNicUnconfigPnuOSLocal', 'AssociateNicUnconfigPnuOSPeer', 'AssociateOobPollSasExpanderActivateStatus', 'AssociateOobPollSasExpanderBootImgActivateStatus', 'AssociateOobPollSasExpanderUpdateStatus', 'AssociateOobSasExpanderBootImgActivate', 'AssociateOobSasExpanderImgActivate', 'AssociateOobSasExpanderImgUpdate', 'AssociateOobStorageConfig', 'AssociateOobStorageInventory', 'AssociatePciSwitchImageUpdate', 'AssociatePersistentMemoryDimmFwUpdate', 'AssociatePnuOSCatalog', 'AssociatePnuOSConfig', 'AssociatePnuOSIdent', 'AssociatePnuOSInventory', 'AssociatePnuOSLocalDiskConfig', 'AssociatePnuOSPeripheralComponentConfig', 'AssociatePnuOSPolicy', 'AssociatePnuOSSelfTest', 'AssociatePnuOSUnloadDrivers', 'AssociatePnuOSValidate', 'AssociatePollBiosActivateStatus', 'AssociatePollBiosUpdateStatus', 'AssociatePollBoardCtrlPowerCycle', 'AssociatePollBoardCtrlUpdateStatus', 'AssociatePollClearBiosUpdateStatus', 'AssociatePowerCycleBoard', 'AssociatePowerDeployWait', 'AssociatePowerOn', 'AssociatePowerOnPreConfig', 'AssociatePreSanitize', 'AssociatePrepareForBoot', 'AssociateResetIBMC', 'AssociateRestoreVdStatus', 'AssociateSanitize', 'AssociateSasExpanderImgUpdate', 'AssociateSerialDebugPnuOSConnect', 'AssociateSerialDebugPnuOSDisconnect', 'AssociateSharedComponentsOobInventory', 'AssociateSharedComponentsOobInventoryPeer', 'AssociateSolRedirectDisable', 'AssociateSolRedirectEnable', 'AssociateStorageCtlrImgUpdate', 'AssociateSuccess', 'AssociateSwConfigHostOSLocal', 'AssociateSwConfigHostOSPeer', 'AssociateSwConfigPnuOSLocal', 'AssociateSwConfigPnuOSPeer', 'AssociateSwConfigPortNivLocal', 'AssociateSwConfigPortNivPeer', 'AssociateSwConfigServiceInfraLocal', 'AssociateSwConfigServiceInfraPeer', 'AssociateSwUnconfigPnuOSLocal', 'AssociateSwUnconfigPnuOSPeer', 'AssociateSyncPowerState', 'AssociateUnconfigCimcVMedia', 'AssociateUnconfigExtMgmtGw', 'AssociateUnconfigExtMgmtRules', 'AssociateUnlockFirmwareImage', 'AssociateUpdateAdaptorNwFwLocal', 'AssociateUpdateAdaptorNwFwPeer', 'AssociateUpdateBiosRequest', 'AssociateUpdateBoardCtrlRequest', 'AssociateUpdateIBMCFw', 'AssociateVerifyFcZoneConfig', 'AssociateWaitForAdaptorNwFwUpdateLocal', 'AssociateWaitForAdaptorNwFwUpdatePeer', 'AssociateWaitForBorderConfigCompletionLocal', 'AssociateWaitForBorderConfigCompletionPeer', 'AssociateWaitForIBMCFwUpdate', 'BiosPasswordResetBegin', 'BiosPasswordResetBladePowerOn', 'BiosPasswordResetCheckPowerAvailability', 'BiosPasswordResetExecute', 'BiosPasswordResetFail', 'BiosPasswordResetPowerDeployWait', 'BiosPasswordResetPreSanitize', 'BiosPasswordResetReconfigBios', 'BiosPasswordResetReconfigUuid', 'BiosPasswordResetSanitize', 'BiosPasswordResetSuccess', 'BiosRecoveryBegin', 'BiosRecoveryCheckPowerAvailability', 'BiosRecoveryCleanup', 'BiosRecoveryFail', 'BiosRecoveryPowerDeployWait', 'BiosRecoveryPreSanitize', 'BiosRecoveryReset', 'BiosRecoverySanitize', 'BiosRecoverySetupVmediaLocal', 'BiosRecoverySetupVmediaPeer', 'BiosRecoveryShutdown', 'BiosRecoveryStart', 'BiosRecoveryStopVMediaLocal', 'BiosRecoveryStopVMediaPeer', 'BiosRecoverySuccess', 'BiosRecoveryTeardownVmediaLocal', 'BiosRecoveryTeardownVmediaPeer', 'BiosRecoveryWait', 'CimcSecurityConfigBegin', 'CimcSecurityConfigFail', 'CimcSecurityConfigKmipCertConfig', 'CimcSecurityConfigKmipSaveCert', 'CimcSecurityConfigSuccess', 'CimcSecurityUnconfigBegin', 'CimcSecurityUnconfigFail', 'CimcSecurityUnconfigKmipDelCert', 'CimcSecurityUnconfigSuccess', 'CimcSessionDeleteBegin', 'CimcSessionDeleteExecute', 'CimcSessionDeleteFail', 'CimcSessionDeleteSuccess', 'CmosResetBegin', 'CmosResetBladePowerOn', 'CmosResetCheckPowerAvailability', 'CmosResetExecute', 'CmosResetFail', 'CmosResetPowerDeployWait', 'CmosResetPreSanitize', 'CmosResetReconfigBios', 'CmosResetReconfigUuid', 'CmosResetSanitize', 'CmosResetSuccess', 'ConfigBoardBegin', 'ConfigBoardConfigMemoryPolicy', 'ConfigBoardFail', 'ConfigBoardSuccess', 'ConfigSoLBegin', 'ConfigSoLExecute', 'ConfigSoLFail', 'ConfigSoLSuccess', 'ConfigureServerPersonalityBegin', 'ConfigureServerPersonalityExecute', 'ConfigureServerPersonalityFail', 'ConfigureServerPersonalitySuccess', 'DecommissionBegin', 'DecommissionCleanupCIMC', 'DecommissionCleanupPortConfigLocal', 'DecommissionCleanupPortConfigPeer', 'DecommissionExecute', 'DecommissionFail', 'DecommissionPrecleanupPortConfig', 'DecommissionStopVMediaLocal', 'DecommissionStopVMediaPeer', 'DecommissionSuccess', 'DecommissionUnconfigExtMgmtGw', 'DecommissionUnconfigExtMgmtRules', 'DiagBegin', 'DiagBiosPostCompletion', 'DiagCheckPowerAvailability', 'DiagDisableScriptableVMedia', 'DiagFail', 'DiagHagConnect', 'DiagHagDisconnect', 'DiagLogTransfer', 'DiagPnuOSIdent', 'DiagPowerOn', 'DiagPowerOnWait', 'DiagPreSanitize', 'DiagPreconfigVmediaLocal', 'DiagPreconfigVmediaPeer', 'DiagRunTests', 'DiagSanitize', 'DiagSerialDebugConnect', 'DiagSerialDebugDisconnect', 'DiagSetupBootEnvironment', 'DiagSetupVmediaLocal', 'DiagSetupVmediaPeer', 'DiagShutdown', 'DiagSuccess', 'DiagTearDownBootEnvironment', 'DiagTeardownVmediaLocal', 'DiagTeardownVmediaPeer', 'DiagWaitForDebug', 'DiagnosticInterruptBegin', 'DiagnosticInterruptExecute', 'DiagnosticInterruptFail', 'DiagnosticInterruptSuccess', 'DisassociateBegin', 'DisassociateBiosPostCompletion', 'DisassociateBmcConfigPnuOS', 'DisassociateBmcPreconfigPnuOSLocal', 'DisassociateBmcPreconfigPnuOSPeer', 'DisassociateBmcUnconfigPnuOS', 'DisassociateBootPnuos', 'DisassociateBootWait', 'DisassociateCheckPowerAvailability', 'DisassociateConfigBios', 'DisassociateConfigFlexFlashScrub', 'DisassociateConfigKvmMgmtDefaultSetting', 'DisassociateConfigUserAccess', 'DisassociateDeassertResetBypass', 'DisassociateFail', 'DisassociateHagPnuOSConnect', 'DisassociateHagPnuOSDisconnect', 'DisassociateHandlePooling', 'DisassociateNicConfigPnuOSLocal', 'DisassociateNicConfigPnuOSPeer', 'DisassociateNicUnconfigHostOSLocal', 'DisassociateNicUnconfigHostOSPeer', 'DisassociateNicUnconfigPnuOSLocal', 'DisassociateNicUnconfigPnuOSPeer', 'DisassociateNicUnconfigServiceInfraLocal', 'DisassociateNicUnconfigServiceInfraPeer', 'DisassociateOobDiskScrub', 'DisassociatePnuOSCatalog', 'DisassociatePnuOSIdent', 'DisassociatePnuOSPolicy', 'DisassociatePnuOSScrub', 'DisassociatePnuOSSelfTest', 'DisassociatePnuOSUnconfig', 'DisassociatePnuOSValidate', 'DisassociatePowerDeployWait', 'DisassociatePowerOn', 'DisassociatePreSanitize', 'DisassociateResetSecureBootConfig', 'DisassociateSanitize', 'DisassociateSerialDebugPnuOSConnect', 'DisassociateSerialDebugPnuOSDisconnect', 'DisassociateShutdown', 'DisassociateSolRedirectDisable', 'DisassociateSolRedirectEnable', 'DisassociateSuccess', 'DisassociateSwConfigPnuOSLocal', 'DisassociateSwConfigPnuOSPeer', 'DisassociateSwConfigPortNivLocal', 'DisassociateSwConfigPortNivPeer', 'DisassociateSwUnconfigHostOSLocal', 'DisassociateSwUnconfigHostOSPeer', 'DisassociateSwUnconfigPnuOSLocal', 'DisassociateSwUnconfigPnuOSPeer', 'DisassociateUnconfigBios', 'DisassociateUnconfigCimcVMedia', 'DisassociateUnconfigExtMgmtGw', 'DisassociateUnconfigExtMgmtRules', 'DisassociateUnconfigFlexFlash', 'DisassociateUnconfigServerIdentity', 'DisassociateUnconfigSoL', 'DisassociateUnconfigUuid', 'DisassociateVerifyFcZoneConfig', 'DiscoverBegin', 'DiscoverBiosPostCompletion', 'DiscoverBladeBootPnuos', 'DiscoverBladeBootWait', 'DiscoverBladePowerOn', 'DiscoverBladeReadSmbios', 'DiscoverBmcConfigPnuOS', 'DiscoverBmcFactoryReset', 'DiscoverBmcInventory', 'DiscoverBmcPreConfigPnuOSLocal', 'DiscoverBmcPreConfigPnuOSPeer', 'DiscoverBmcPresence', 'DiscoverBmcShutdownDiscovered', 'DiscoverCheckAdaptorFw40GCap', 'DiscoverCheckPowerAvailability', 'DiscoverConfigBMCPowerParams', 'DiscoverConfigFeLocal', 'DiscoverConfigFePeer', 'DiscoverConfigFlexFlashScrub', 'DiscoverConfigUserAccess', 'DiscoverFail', 'DiscoverHagConnect', 'DiscoverHagDisconnect', 'DiscoverHandlePooling', 'DiscoverNicConfigPnuOSLocal', 'DiscoverNicConfigPnuOSPeer', 'DiscoverNicPresenceLocal', 'DiscoverNicPresencePeer', 'DiscoverNicUnconfigPnuOSLocal', 'DiscoverNicUnconfigPnuOSPeer', 'DiscoverOobStorageInventory', 'DiscoverPnuOSCatalog', 'DiscoverPnuOSIdent', 'DiscoverPnuOSInventory', 'DiscoverPnuOSPolicy', 'DiscoverPnuOSPowerProfiling', 'DiscoverPnuOSScrub', 'DiscoverPnuOSSelfTest', 'DiscoverPostScrubOobStorageInventory', 'DiscoverPowerDeployWait', 'DiscoverPreSanitize', 'DiscoverSanitize', 'DiscoverSendBmcProfilingDone', 'DiscoverSendBmcProfilingInit', 'DiscoverSerialDebugConnect', 'DiscoverSerialDebugDisconnect', 'DiscoverSetupVmediaLocal', 'DiscoverSetupVmediaPeer', 'DiscoverSharedComponentsOobInventory', 'DiscoverSharedComponentsOobInventoryPeer', 'DiscoverSolRedirectDisable', 'DiscoverSolRedirectEnable', 'DiscoverSuccess', 'DiscoverSwConfigPnuOSLocal', 'DiscoverSwConfigPnuOSPeer', 'DiscoverSwUnconfigPnuOSLocal', 'DiscoverSwUnconfigPnuOSPeer', 'DiscoverTeardownVmediaLocal', 'DiscoverTeardownVmediaPeer', 'DiscoverUnconfigCimcVMedia', 'DiscoverUnconfigExtMgmtGw', 'DiscoverUnconfigExtMgmtRules', 'DiskZoningInventoryBegin', 'DiskZoningInventoryBootHost', 'DiskZoningInventoryBootWait', 'DiskZoningInventoryFail', 'DiskZoningInventoryPreSanitize', 'DiskZoningInventorySanitize', 'DiskZoningInventoryShutdown', 'DiskZoningInventoryStorageInventory', 'DiskZoningInventorySuccess', 'EnableCimcSecureBootActivate', 'EnableCimcSecureBootBegin', 'EnableCimcSecureBootFail', 'EnableCimcSecureBootPollUpdateStatus', 'EnableCimcSecureBootReset', 'EnableCimcSecureBootSuccess', 'EnableCimcSecureBootUpdateRequest', 'ExecuteActionsBegin', 'ExecuteActionsBiosPostCompletion', 'ExecuteActionsExecutePMAction', 'ExecuteActionsFail', 'ExecuteActionsPowerOn', 'ExecuteActionsSoftShutdown', 'ExecuteActionsSuccess', 'FlashControllerBegin', 'FlashControllerFail', 'FlashControllerSuccess', 'FlashControllerUpdateFlashLife', 'FwUpgradeActivateAdaptorNwFwLocal', 'FwUpgradeActivateAdaptorNwFwPeer', 'FwUpgradeActivateBios', 'FwUpgradeActivateIBMCFw', 'FwUpgradeAssertBypassWait', 'FwUpgradeBegin', 'FwUpgradeBiosImgUpdate', 'FwUpgradeBiosPostCompletion', 'FwUpgradeBladePowerOff', 'FwUpgradeBmcConfigPnuOS', 'FwUpgradeBmcPreconfigPnuOSLocal', 'FwUpgradeBmcPreconfigPnuOSPeer', 'FwUpgradeBmcUnconfigPnuOS', 'FwUpgradeBootPnuos', 'FwUpgradeBootWait', 'FwUpgradeCheckPowerAvailability', 'FwUpgradeCiscoOSOpenGate', 'FwUpgradeClearBiosUpdate', 'FwUpgradeCopyRemote', 'FwUpgradeDeassertResetBypass', 'FwUpgradeDeleteCurlDownloadedImages', 'FwUpgradeDeleteImagesRemote', 'FwUpgradeDownloadImages', 'FwUpgradeFail', 'FwUpgradeGraphicsImageUpdate', 'FwUpgradeHagPnuOSConnect', 'FwUpgradeHagPnuOSDisconnect', 'FwUpgradeHbaImgUpdate', 'FwUpgradeLocalDiskFwUpdate', 'FwUpgradeMswitchImgUpdate', 'FwUpgradeNicConfigPnuOSLocal', 'FwUpgradeNicConfigPnuOSPeer', 'FwUpgradeNicImgUpdate', 'FwUpgradeNicUnconfigPnuOSLocal', 'FwUpgradeNicUnconfigPnuOSPeer', 'FwUpgradeOobPollSasExpanderActivateStatus', 'FwUpgradeOobPollSasExpanderBootImgActivateStatus', 'FwUpgradeOobPollSasExpanderUpdateStatus', 'FwUpgradeOobSasExpanderBootImgActivate', 'FwUpgradeOobSasExpanderImgActivate', 'FwUpgradeOobSasExpanderImgUpdate', 'FwUpgradeOobStorageInventory', 'FwUpgradePciSwitchImageUpdate', 'FwUpgradePersistentMemoryDimmFwUpdate', 'FwUpgradePnuOSCatalog', 'FwUpgradePnuOSConfig', 'FwUpgradePnuOSIdent', 'FwUpgradePnuOSInventory', 'FwUpgradePnuOSPolicy', 'FwUpgradePnuOSSelfTest', 'FwUpgradePnuOSUnloadDrivers', 'FwUpgradePnuOSValidate', 'FwUpgradePollBiosActivateStatus', 'FwUpgradePollBiosUpdateStatus', 'FwUpgradePollBoardCtrlPowerCycle', 'FwUpgradePollBoardCtrlUpdateStatus', 'FwUpgradePollClearBiosUpdateStatus', 'FwUpgradePowerCycleBoard', 'FwUpgradePowerDeployWait', 'FwUpgradePowerOn', 'FwUpgradePreSanitize', 'FwUpgradeResetIBMC', 'FwUpgradeSanitize', 'FwUpgradeSasExpanderImgUpdate', 'FwUpgradeSerialDebugPnuOSConnect', 'FwUpgradeSerialDebugPnuOSDisconnect', 'FwUpgradeShutdown', 'FwUpgradeSolRedirectDisable', 'FwUpgradeSolRedirectEnable', 'FwUpgradeStorageCtlrImgUpdate', 'FwUpgradeSuccess', 'FwUpgradeSwConfigPnuOSLocal', 'FwUpgradeSwConfigPnuOSPeer', 'FwUpgradeSwConfigPortNivLocal', 'FwUpgradeSwConfigPortNivPeer', 'FwUpgradeSwUnconfigPnuOSLocal', 'FwUpgradeSwUnconfigPnuOSPeer', 'FwUpgradeUnconfigCimcVMedia', 'FwUpgradeUnconfigExtMgmtGw', 'FwUpgradeUnconfigExtMgmtRules', 'FwUpgradeUnlockFirmwareImage', 'FwUpgradeUpdateAdaptorNwFwLocal', 'FwUpgradeUpdateAdaptorNwFwPeer', 'FwUpgradeUpdateBiosRequest', 'FwUpgradeUpdateBoardCtrlRequest', 'FwUpgradeUpdateIBMCFw', 'FwUpgradeWaitForAdaptorNwFwUpdateLocal', 'FwUpgradeWaitForAdaptorNwFwUpdatePeer', 'FwUpgradeWaitForIBMCFwUpdate', 'HardShutdownBegin', 'HardShutdownExecute', 'HardShutdownFail', 'HardShutdownSuccess', 'HardresetBegin', 'HardresetCheckPowerAvailability', 'HardresetExecute', 'HardresetFail', 'HardresetPowerDeployWait', 'HardresetPreSanitize', 'HardresetSanitize', 'HardresetSuccess', 'NvmeSwitchRecoveryBegin', 'NvmeSwitchRecoveryCheckStatus', 'NvmeSwitchRecoveryExecute', 'NvmeSwitchRecoveryFail', 'NvmeSwitchRecoverySuccess', 'NvmeSwitchRecoveryWaitForAck', 'OobStorageAdminConfigBegin', 'OobStorageAdminConfigBootHost', 'OobStorageAdminConfigBootWait', 'OobStorageAdminConfigCheckPowerAvailability', 'OobStorageAdminConfigFail', 'OobStorageAdminConfigOobStorageConfig', 'OobStorageAdminConfigOobStorageInventory', 'OobStorageAdminConfigPowerDeployWait', 'OobStorageAdminConfigPreSanitize', 'OobStorageAdminConfigSanitize', 'OobStorageAdminConfigShutdown', 'OobStorageAdminConfigSuccess', 'OobStorageAdminConfigTearDownVMediaLocal', 'OobStorageAdminConfigTearDownVMediaPeer', 'PowerCapBegin', 'PowerCapConfig', 'PowerCapFail', 'PowerCapSuccess', 'PowercycleBegin', 'PowercycleCheckPowerAvailability', 'PowercycleExecute', 'PowercycleFail', 'PowercyclePowerDeployWait', 'PowercyclePreSanitize', 'PowercycleSanitize', 'PowercycleSuccess', 'ReinitializeVirtualDriveBegin', 'ReinitializeVirtualDriveExecuteVDAction', 'ReinitializeVirtualDriveFail', 'ReinitializeVirtualDriveSuccess', 'ResetBmcBegin', 'ResetBmcExecute', 'ResetBmcFail', 'ResetBmcSuccess', 'ResetIpmiBegin', 'ResetIpmiExecute', 'ResetIpmiFail', 'ResetIpmiSuccess', 'ResetKvmBegin', 'ResetKvmExecute', 'ResetKvmFail', 'ResetKvmSuccess', 'ResetMemoryErrorsBegin', 'ResetMemoryErrorsExecute', 'ResetMemoryErrorsFail', 'ResetMemoryErrorsSuccess', 'ServiceInfraDeployBegin', 'ServiceInfraDeployFail', 'ServiceInfraDeployNicConfigLocal', 'ServiceInfraDeployNicConfigPeer', 'ServiceInfraDeploySuccess', 'ServiceInfraDeploySwConfigLocal', 'ServiceInfraDeploySwConfigPeer', 'ServiceInfraWithdrawBegin', 'ServiceInfraWithdrawFail', 'ServiceInfraWithdrawNicUnConfigLocal', 'ServiceInfraWithdrawNicUnConfigPeer', 'ServiceInfraWithdrawSuccess', 'ServiceInfraWithdrawSwUnConfigLocal', 'ServiceInfraWithdrawSwUnConfigPeer', 'SoftShutdownBegin', 'SoftShutdownExecute', 'SoftShutdownFail', 'SoftShutdownSuccess', 'SoftresetBegin', 'SoftresetCheckPowerAvailability', 'SoftresetExecute', 'SoftresetFail', 'SoftresetPowerDeployWait', 'SoftresetPreSanitize', 'SoftresetSanitize', 'SoftresetSuccess', 'SwConnUpdA', 'SwConnUpdB', 'SwConnUpdBegin', 'SwConnUpdFail', 'SwConnUpdSuccess', 'TurnupBegin', 'TurnupCheckPowerAvailability', 'TurnupExecute', 'TurnupFail', 'TurnupPowerDeployWait', 'TurnupSuccess', 'UnconfigSoLBegin', 'UnconfigSoLExecute', 'UnconfigSoLFail', 'UnconfigSoLSuccess', 'UpdateAdaptorBegin', 'UpdateAdaptorCheckPowerAvailability', 'UpdateAdaptorFail', 'UpdateAdaptorPollUpdateStatusLocal', 'UpdateAdaptorPollUpdateStatusPeer', 'UpdateAdaptorPowerDeployWait', 'UpdateAdaptorPowerOff', 'UpdateAdaptorPowerOn', 'UpdateAdaptorSuccess', 'UpdateAdaptorUpdateRequestLocal', 'UpdateAdaptorUpdateRequestPeer', 'UpdateBIOSBegin', 'UpdateBIOSClear', 'UpdateBIOSFail', 'UpdateBIOSPollClearStatus', 'UpdateBIOSPollUpdateStatus', 'UpdateBIOSSuccess', 'UpdateBIOSUpdateRequest', 'UpdateBoardControllerBegin', 'UpdateBoardControllerCheckPowerAvailability', 'UpdateBoardControllerFail', 'UpdateBoardControllerPollBoardCtrlPowerCycle', 'UpdateBoardControllerPollUpdateStatus', 'UpdateBoardControllerPowerCycleBoard', 'UpdateBoardControllerPowerDeployWait', 'UpdateBoardControllerPrepareForUpdate', 'UpdateBoardControllerServerPowerOff', 'UpdateBoardControllerServerPowerOn', 'UpdateBoardControllerSuccess', 'UpdateBoardControllerUpdateRequest', 'clearTPMBegin', 'clearTPMBiosPostCompletion', 'clearTPMBladePowerOff', 'clearTPMBladePowerOn', 'clearTPMBootHost', 'clearTPMClear', 'clearTPMFail', 'clearTPMPreSanitize', 'clearTPMReadSmBios', 'clearTPMReconfigBios', 'clearTPMSanitize', 'clearTPMSetupVmedia', 'clearTPMStopVMediaLocal', 'clearTPMStopVMediaPeer', 'clearTPMSuccess', 'clearTPMUnconfigVmedia', 'nop', 'updateExtUsersBegin', 'updateExtUsersDeploy', 'updateExtUsersFail', 'updateExtUsersSuccess'] +range_val :[] + +Property fsm_progr +-------- --------- +xml_attribute :fsmProgr +field_type :byte +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :['0-100'] + +Property fsm_rmt_inv_err_code +-------- -------------------- +xml_attribute :fsmRmtInvErrCode +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['ERR-2fa-auth-retry', 'ERR-ACTIVATE-failed', 'ERR-ACTIVATE-in-progress', 'ERR-ACTIVATE-retry', 'ERR-BIOS-TOKENS-OLD-BIOS', 'ERR-BIOS-TOKENS-OLD-CIMC', 'ERR-BIOS-network-boot-order-not-found', 'ERR-BOARDCTRLUPDATE-ignore', 'ERR-DIAG-cancelled', 'ERR-DIAG-fsm-restarted', 'ERR-DIAG-test-failed', 'ERR-DNLD-authentication-failure', 'ERR-DNLD-hostkey-mismatch', 'ERR-DNLD-invalid-image', 'ERR-DNLD-no-file', 'ERR-DNLD-no-space', 'ERR-DNLD-usb-unmounted', 'ERR-DNS-delete-error', 'ERR-DNS-get-error', 'ERR-DNS-set-error', 'ERR-Diagnostics-in-progress', 'ERR-Diagnostics-memtest-in-progress', 'ERR-Diagnostics-network-in-progress', 'ERR-FILTER-illegal-format', 'ERR-FSM-no-such-state', 'ERR-HOST-fru-identity-mismatch', 'ERR-HTTP-set-error', 'ERR-HTTPS-set-error', 'ERR-IBMC-analyze-results', 'ERR-IBMC-connect-error', 'ERR-IBMC-connector-info-retrieval-error', 'ERR-IBMC-fru-retrieval-error', 'ERR-IBMC-invalid-end-point-config', 'ERR-IBMC-results-not-ready', 'ERR-MAX-subscriptions-allowed-error', 'ERR-MO-CONFIG-child-object-cant-be-configured', 'ERR-MO-META-no-such-object-class', 'ERR-MO-PROPERTY-no-such-property', 'ERR-MO-PROPERTY-value-out-of-range', 'ERR-MO-access-denied', 'ERR-MO-deletion-rule-violation', 'ERR-MO-duplicate-object', 'ERR-MO-illegal-containment', 'ERR-MO-illegal-creation', 'ERR-MO-illegal-iterator-state', 'ERR-MO-illegal-object-lifecycle-transition', 'ERR-MO-naming-rule-violation', 'ERR-MO-object-not-found', 'ERR-MO-resource-allocation', 'ERR-NTP-delete-error', 'ERR-NTP-get-error', 'ERR-NTP-set-error', 'ERR-POWER-CAP-UNSUPPORTED', 'ERR-POWER-PROFILE-IN-PROGRESS', 'ERR-SERVER-mis-connect', 'ERR-SWITCH-invalid-if-config', 'ERR-TOKEN-request-denied', 'ERR-UNABLE-TO-FETCH-BIOS-SETTINGS', 'ERR-UPDATE-failed', 'ERR-UPDATE-in-progress', 'ERR-UPDATE-retry', 'ERR-aaa-config-modify-error', 'ERR-acct-realm-set-error', 'ERR-admin-passwd-set', 'ERR-auth-issue', 'ERR-auth-realm-get-error', 'ERR-auth-realm-set-error', 'ERR-authentication', 'ERR-authorization-required', 'ERR-cli-session-limit-reached', 'ERR-create-keyring', 'ERR-create-locale', 'ERR-create-role', 'ERR-create-tp', 'ERR-create-user', 'ERR-delete-locale', 'ERR-delete-role', 'ERR-delete-session', 'ERR-delete-user', 'ERR-downgrade-fail', 'ERR-efi-Diagnostics--in-progress', 'ERR-enable-mgmt-conn', 'ERR-ep-set-error', 'ERR-get-max-http-user-sessions', 'ERR-http-initializing', 'ERR-insufficiently-equipped', 'ERR-internal-error', 'ERR-ldap-delete-error', 'ERR-ldap-get-error', 'ERR-ldap-group-modify-error', 'ERR-ldap-group-set-error', 'ERR-ldap-set-error', 'ERR-locale-set-error', 'ERR-max-userid-sessions-reached', 'ERR-missing-method', 'ERR-modify-locale', 'ERR-modify-role', 'ERR-modify-user', 'ERR-modify-user-locale', 'ERR-modify-user-role', 'ERR-provider-group-modify-error', 'ERR-provider-group-set-error', 'ERR-radius-get-error', 'ERR-radius-global-set-error', 'ERR-radius-group-set-error', 'ERR-radius-set-error', 'ERR-request-timeout', 'ERR-reset-adapter', 'ERR-role-set-error', 'ERR-secondary-node', 'ERR-service-not-ready', 'ERR-session-cache-full', 'ERR-session-not-found', 'ERR-set-key-cert', 'ERR-set-login-profile', 'ERR-set-min-passphrase-length', 'ERR-set-network', 'ERR-set-password-strength-check', 'ERR-set-port-channel', 'ERR-store-pre-login-banner-msg', 'ERR-tacacs-enable-error', 'ERR-tacacs-global-set-error', 'ERR-tacacs-group-set-error', 'ERR-tacacs-plus-get-error', 'ERR-tacacs-set-error', 'ERR-test-error-1', 'ERR-test-error-2', 'ERR-timezone-set-error', 'ERR-user-account-expired', 'ERR-user-passwd-expired', 'ERR-user-set-error', 'ERR-xml-parse-error', 'none'] +range_val :['0-4294967295'] + +Property fsm_rmt_inv_err_descr +-------- --------------------- +xml_attribute :fsmRmtInvErrDescr +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property fsm_rmt_inv_rslt +-------- ---------------- +xml_attribute :fsmRmtInvRslt +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :((defaultValue|not-applicable|resource-unavailable|service-unavailable|intermittent-error|sw-defect|service-not-implemented-ignore|extend-timeout|capability-not-implemented-failure|illegal-fru|end-point-unavailable|failure|resource-capacity-exceeded|service-protocol-error|fw-defect|service-not-implemented-fail|task-reset|unidentified-fail|capability-not-supported|end-point-failed|fru-state-indeterminate|resource-dependency|fru-identity-indeterminate|internal-error|hw-defect|service-not-supported|fru-not-supported|end-point-protocol-error|capability-unavailable|fru-not-ready|capability-not-implemented-ignore|fru-info-malformed|timeout),){0,32}(defaultValue|not-applicable|resource-unavailable|service-unavailable|intermittent-error|sw-defect|service-not-implemented-ignore|extend-timeout|capability-not-implemented-failure|illegal-fru|end-point-unavailable|failure|resource-capacity-exceeded|service-protocol-error|fw-defect|service-not-implemented-fail|task-reset|unidentified-fail|capability-not-supported|end-point-failed|fru-state-indeterminate|resource-dependency|fru-identity-indeterminate|internal-error|hw-defect|service-not-supported|fru-not-supported|end-point-protocol-error|capability-unavailable|fru-not-ready|capability-not-implemented-ignore|fru-info-malformed|timeout){0,1} +value_set :[] +range_val :[] + +Property fsm_stage_descr +-------- --------------- +xml_attribute :fsmStageDescr +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property fsm_stamp +-------- --------- +xml_attribute :fsmStamp +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :['never'] +range_val :[] + +Property fsm_status +-------- ---------- +xml_attribute :fsmStatus +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['ActivateAdaptorActivateLocal', 'ActivateAdaptorActivatePeer', 'ActivateAdaptorAssertBypassWait', 'ActivateAdaptorBegin', 'ActivateAdaptorCheckPowerAvailability', 'ActivateAdaptorDeassertResetBypass', 'ActivateAdaptorFail', 'ActivateAdaptorPowerDeployWait', 'ActivateAdaptorPowerOn', 'ActivateAdaptorReset', 'ActivateAdaptorSuccess', 'ActivateBIOSActivate', 'ActivateBIOSBegin', 'ActivateBIOSCheckPowerAvailability', 'ActivateBIOSClear', 'ActivateBIOSFail', 'ActivateBIOSPollActivateStatus', 'ActivateBIOSPollClearStatus', 'ActivateBIOSPowerDeployWait', 'ActivateBIOSPowerOff', 'ActivateBIOSPowerOn', 'ActivateBIOSSuccess', 'ActivateBIOSUpdateTokens', 'AssociateActivateAdaptorNwFwLocal', 'AssociateActivateAdaptorNwFwPeer', 'AssociateActivateBios', 'AssociateActivateIBMCFw', 'AssociateAssertBypassWait', 'AssociateBegin', 'AssociateBiosImgUpdate', 'AssociateBiosPostCompletion', 'AssociateBladePowerOff', 'AssociateBmcConfigPnuOS', 'AssociateBmcPreconfigPnuOSLocal', 'AssociateBmcPreconfigPnuOSPeer', 'AssociateBmcUnconfigPnuOS', 'AssociateBootHost', 'AssociateBootPnuos', 'AssociateBootWait', 'AssociateCalculateVlanGroupForHostOSLocal', 'AssociateCalculateVlanGroupForHostOSPeer', 'AssociateCheckPowerAvailability', 'AssociateCiscoOSOpenGate', 'AssociateClearBiosUpdate', 'AssociateConfigCimcVMedia', 'AssociateConfigExtMgmtGw', 'AssociateConfigExtMgmtRules', 'AssociateConfigFanSpeed', 'AssociateConfigFlexFlash', 'AssociateConfigHostOsAnnotations', 'AssociateConfigMgmtIpRules', 'AssociateConfigServerIdentity', 'AssociateConfigSoL', 'AssociateConfigUserAccess', 'AssociateConfigUuid', 'AssociateCopyRemote', 'AssociateDeassertResetBypass', 'AssociateDeleteCurlDownloadedImages', 'AssociateDeleteImagesRemote', 'AssociateDownloadImages', 'AssociateFail', 'AssociateGraphicsImageUpdate', 'AssociateHagHostOSConnect', 'AssociateHagPnuOSConnect', 'AssociateHagPnuOSDisconnect', 'AssociateHbaImgUpdate', 'AssociateHostOSConfig', 'AssociateHostOSConnect', 'AssociateHostOSIdent', 'AssociateHostOSPolicy', 'AssociateHostOSValidate', 'AssociateLocalDiskFwUpdate', 'AssociateMarkAdapterForReboot', 'AssociateMswitchImgUpdate', 'AssociateNicConfigHostOSLocal', 'AssociateNicConfigHostOSPeer', 'AssociateNicConfigParamsHostOSLocal', 'AssociateNicConfigParamsHostOSPeer', 'AssociateNicConfigPnuOSLocal', 'AssociateNicConfigPnuOSPeer', 'AssociateNicConfigServiceInfraLocal', 'AssociateNicConfigServiceInfraPeer', 'AssociateNicImgUpdate', 'AssociateNicUnconfigPnuOSLocal', 'AssociateNicUnconfigPnuOSPeer', 'AssociateOobPollSasExpanderActivateStatus', 'AssociateOobPollSasExpanderBootImgActivateStatus', 'AssociateOobPollSasExpanderUpdateStatus', 'AssociateOobSasExpanderBootImgActivate', 'AssociateOobSasExpanderImgActivate', 'AssociateOobSasExpanderImgUpdate', 'AssociateOobStorageConfig', 'AssociateOobStorageInventory', 'AssociatePciSwitchImageUpdate', 'AssociatePersistentMemoryDimmFwUpdate', 'AssociatePnuOSCatalog', 'AssociatePnuOSConfig', 'AssociatePnuOSIdent', 'AssociatePnuOSInventory', 'AssociatePnuOSLocalDiskConfig', 'AssociatePnuOSPeripheralComponentConfig', 'AssociatePnuOSPolicy', 'AssociatePnuOSSelfTest', 'AssociatePnuOSUnloadDrivers', 'AssociatePnuOSValidate', 'AssociatePollBiosActivateStatus', 'AssociatePollBiosUpdateStatus', 'AssociatePollBoardCtrlPowerCycle', 'AssociatePollBoardCtrlUpdateStatus', 'AssociatePollClearBiosUpdateStatus', 'AssociatePowerCycleBoard', 'AssociatePowerDeployWait', 'AssociatePowerOn', 'AssociatePowerOnPreConfig', 'AssociatePreSanitize', 'AssociatePrepareForBoot', 'AssociateResetIBMC', 'AssociateRestoreVdStatus', 'AssociateSanitize', 'AssociateSasExpanderImgUpdate', 'AssociateSerialDebugPnuOSConnect', 'AssociateSerialDebugPnuOSDisconnect', 'AssociateSharedComponentsOobInventory', 'AssociateSharedComponentsOobInventoryPeer', 'AssociateSolRedirectDisable', 'AssociateSolRedirectEnable', 'AssociateStorageCtlrImgUpdate', 'AssociateSuccess', 'AssociateSwConfigHostOSLocal', 'AssociateSwConfigHostOSPeer', 'AssociateSwConfigPnuOSLocal', 'AssociateSwConfigPnuOSPeer', 'AssociateSwConfigPortNivLocal', 'AssociateSwConfigPortNivPeer', 'AssociateSwConfigServiceInfraLocal', 'AssociateSwConfigServiceInfraPeer', 'AssociateSwUnconfigPnuOSLocal', 'AssociateSwUnconfigPnuOSPeer', 'AssociateSyncPowerState', 'AssociateUnconfigCimcVMedia', 'AssociateUnconfigExtMgmtGw', 'AssociateUnconfigExtMgmtRules', 'AssociateUnlockFirmwareImage', 'AssociateUpdateAdaptorNwFwLocal', 'AssociateUpdateAdaptorNwFwPeer', 'AssociateUpdateBiosRequest', 'AssociateUpdateBoardCtrlRequest', 'AssociateUpdateIBMCFw', 'AssociateVerifyFcZoneConfig', 'AssociateWaitForAdaptorNwFwUpdateLocal', 'AssociateWaitForAdaptorNwFwUpdatePeer', 'AssociateWaitForBorderConfigCompletionLocal', 'AssociateWaitForBorderConfigCompletionPeer', 'AssociateWaitForIBMCFwUpdate', 'BiosPasswordResetBegin', 'BiosPasswordResetBladePowerOn', 'BiosPasswordResetCheckPowerAvailability', 'BiosPasswordResetExecute', 'BiosPasswordResetFail', 'BiosPasswordResetPowerDeployWait', 'BiosPasswordResetPreSanitize', 'BiosPasswordResetReconfigBios', 'BiosPasswordResetReconfigUuid', 'BiosPasswordResetSanitize', 'BiosPasswordResetSuccess', 'BiosRecoveryBegin', 'BiosRecoveryCheckPowerAvailability', 'BiosRecoveryCleanup', 'BiosRecoveryFail', 'BiosRecoveryPowerDeployWait', 'BiosRecoveryPreSanitize', 'BiosRecoveryReset', 'BiosRecoverySanitize', 'BiosRecoverySetupVmediaLocal', 'BiosRecoverySetupVmediaPeer', 'BiosRecoveryShutdown', 'BiosRecoveryStart', 'BiosRecoveryStopVMediaLocal', 'BiosRecoveryStopVMediaPeer', 'BiosRecoverySuccess', 'BiosRecoveryTeardownVmediaLocal', 'BiosRecoveryTeardownVmediaPeer', 'BiosRecoveryWait', 'CimcSecurityConfigBegin', 'CimcSecurityConfigFail', 'CimcSecurityConfigKmipCertConfig', 'CimcSecurityConfigKmipSaveCert', 'CimcSecurityConfigSuccess', 'CimcSecurityUnconfigBegin', 'CimcSecurityUnconfigFail', 'CimcSecurityUnconfigKmipDelCert', 'CimcSecurityUnconfigSuccess', 'CimcSessionDeleteBegin', 'CimcSessionDeleteExecute', 'CimcSessionDeleteFail', 'CimcSessionDeleteSuccess', 'CmosResetBegin', 'CmosResetBladePowerOn', 'CmosResetCheckPowerAvailability', 'CmosResetExecute', 'CmosResetFail', 'CmosResetPowerDeployWait', 'CmosResetPreSanitize', 'CmosResetReconfigBios', 'CmosResetReconfigUuid', 'CmosResetSanitize', 'CmosResetSuccess', 'ConfigBoardBegin', 'ConfigBoardConfigMemoryPolicy', 'ConfigBoardFail', 'ConfigBoardSuccess', 'ConfigSoLBegin', 'ConfigSoLExecute', 'ConfigSoLFail', 'ConfigSoLSuccess', 'ConfigureServerPersonalityBegin', 'ConfigureServerPersonalityExecute', 'ConfigureServerPersonalityFail', 'ConfigureServerPersonalitySuccess', 'DecommissionBegin', 'DecommissionCleanupCIMC', 'DecommissionCleanupPortConfigLocal', 'DecommissionCleanupPortConfigPeer', 'DecommissionExecute', 'DecommissionFail', 'DecommissionPrecleanupPortConfig', 'DecommissionStopVMediaLocal', 'DecommissionStopVMediaPeer', 'DecommissionSuccess', 'DecommissionUnconfigExtMgmtGw', 'DecommissionUnconfigExtMgmtRules', 'DiagBegin', 'DiagBiosPostCompletion', 'DiagCheckPowerAvailability', 'DiagDisableScriptableVMedia', 'DiagFail', 'DiagHagConnect', 'DiagHagDisconnect', 'DiagLogTransfer', 'DiagPnuOSIdent', 'DiagPowerOn', 'DiagPowerOnWait', 'DiagPreSanitize', 'DiagPreconfigVmediaLocal', 'DiagPreconfigVmediaPeer', 'DiagRunTests', 'DiagSanitize', 'DiagSerialDebugConnect', 'DiagSerialDebugDisconnect', 'DiagSetupBootEnvironment', 'DiagSetupVmediaLocal', 'DiagSetupVmediaPeer', 'DiagShutdown', 'DiagSuccess', 'DiagTearDownBootEnvironment', 'DiagTeardownVmediaLocal', 'DiagTeardownVmediaPeer', 'DiagWaitForDebug', 'DiagnosticInterruptBegin', 'DiagnosticInterruptExecute', 'DiagnosticInterruptFail', 'DiagnosticInterruptSuccess', 'DisassociateBegin', 'DisassociateBiosPostCompletion', 'DisassociateBmcConfigPnuOS', 'DisassociateBmcPreconfigPnuOSLocal', 'DisassociateBmcPreconfigPnuOSPeer', 'DisassociateBmcUnconfigPnuOS', 'DisassociateBootPnuos', 'DisassociateBootWait', 'DisassociateCheckPowerAvailability', 'DisassociateConfigBios', 'DisassociateConfigFlexFlashScrub', 'DisassociateConfigKvmMgmtDefaultSetting', 'DisassociateConfigUserAccess', 'DisassociateDeassertResetBypass', 'DisassociateFail', 'DisassociateHagPnuOSConnect', 'DisassociateHagPnuOSDisconnect', 'DisassociateHandlePooling', 'DisassociateNicConfigPnuOSLocal', 'DisassociateNicConfigPnuOSPeer', 'DisassociateNicUnconfigHostOSLocal', 'DisassociateNicUnconfigHostOSPeer', 'DisassociateNicUnconfigPnuOSLocal', 'DisassociateNicUnconfigPnuOSPeer', 'DisassociateNicUnconfigServiceInfraLocal', 'DisassociateNicUnconfigServiceInfraPeer', 'DisassociateOobDiskScrub', 'DisassociatePnuOSCatalog', 'DisassociatePnuOSIdent', 'DisassociatePnuOSPolicy', 'DisassociatePnuOSScrub', 'DisassociatePnuOSSelfTest', 'DisassociatePnuOSUnconfig', 'DisassociatePnuOSValidate', 'DisassociatePowerDeployWait', 'DisassociatePowerOn', 'DisassociatePreSanitize', 'DisassociateResetSecureBootConfig', 'DisassociateSanitize', 'DisassociateSerialDebugPnuOSConnect', 'DisassociateSerialDebugPnuOSDisconnect', 'DisassociateShutdown', 'DisassociateSolRedirectDisable', 'DisassociateSolRedirectEnable', 'DisassociateSuccess', 'DisassociateSwConfigPnuOSLocal', 'DisassociateSwConfigPnuOSPeer', 'DisassociateSwConfigPortNivLocal', 'DisassociateSwConfigPortNivPeer', 'DisassociateSwUnconfigHostOSLocal', 'DisassociateSwUnconfigHostOSPeer', 'DisassociateSwUnconfigPnuOSLocal', 'DisassociateSwUnconfigPnuOSPeer', 'DisassociateUnconfigBios', 'DisassociateUnconfigCimcVMedia', 'DisassociateUnconfigExtMgmtGw', 'DisassociateUnconfigExtMgmtRules', 'DisassociateUnconfigFlexFlash', 'DisassociateUnconfigServerIdentity', 'DisassociateUnconfigSoL', 'DisassociateUnconfigUuid', 'DisassociateVerifyFcZoneConfig', 'DiscoverBegin', 'DiscoverBiosPostCompletion', 'DiscoverBladeBootPnuos', 'DiscoverBladeBootWait', 'DiscoverBladePowerOn', 'DiscoverBladeReadSmbios', 'DiscoverBmcConfigPnuOS', 'DiscoverBmcFactoryReset', 'DiscoverBmcInventory', 'DiscoverBmcPreConfigPnuOSLocal', 'DiscoverBmcPreConfigPnuOSPeer', 'DiscoverBmcPresence', 'DiscoverBmcShutdownDiscovered', 'DiscoverCheckAdaptorFw40GCap', 'DiscoverCheckPowerAvailability', 'DiscoverConfigBMCPowerParams', 'DiscoverConfigFeLocal', 'DiscoverConfigFePeer', 'DiscoverConfigFlexFlashScrub', 'DiscoverConfigUserAccess', 'DiscoverFail', 'DiscoverHagConnect', 'DiscoverHagDisconnect', 'DiscoverHandlePooling', 'DiscoverNicConfigPnuOSLocal', 'DiscoverNicConfigPnuOSPeer', 'DiscoverNicPresenceLocal', 'DiscoverNicPresencePeer', 'DiscoverNicUnconfigPnuOSLocal', 'DiscoverNicUnconfigPnuOSPeer', 'DiscoverOobStorageInventory', 'DiscoverPnuOSCatalog', 'DiscoverPnuOSIdent', 'DiscoverPnuOSInventory', 'DiscoverPnuOSPolicy', 'DiscoverPnuOSPowerProfiling', 'DiscoverPnuOSScrub', 'DiscoverPnuOSSelfTest', 'DiscoverPostScrubOobStorageInventory', 'DiscoverPowerDeployWait', 'DiscoverPreSanitize', 'DiscoverSanitize', 'DiscoverSendBmcProfilingDone', 'DiscoverSendBmcProfilingInit', 'DiscoverSerialDebugConnect', 'DiscoverSerialDebugDisconnect', 'DiscoverSetupVmediaLocal', 'DiscoverSetupVmediaPeer', 'DiscoverSharedComponentsOobInventory', 'DiscoverSharedComponentsOobInventoryPeer', 'DiscoverSolRedirectDisable', 'DiscoverSolRedirectEnable', 'DiscoverSuccess', 'DiscoverSwConfigPnuOSLocal', 'DiscoverSwConfigPnuOSPeer', 'DiscoverSwUnconfigPnuOSLocal', 'DiscoverSwUnconfigPnuOSPeer', 'DiscoverTeardownVmediaLocal', 'DiscoverTeardownVmediaPeer', 'DiscoverUnconfigCimcVMedia', 'DiscoverUnconfigExtMgmtGw', 'DiscoverUnconfigExtMgmtRules', 'DiskZoningInventoryBegin', 'DiskZoningInventoryBootHost', 'DiskZoningInventoryBootWait', 'DiskZoningInventoryFail', 'DiskZoningInventoryPreSanitize', 'DiskZoningInventorySanitize', 'DiskZoningInventoryShutdown', 'DiskZoningInventoryStorageInventory', 'DiskZoningInventorySuccess', 'EnableCimcSecureBootActivate', 'EnableCimcSecureBootBegin', 'EnableCimcSecureBootFail', 'EnableCimcSecureBootPollUpdateStatus', 'EnableCimcSecureBootReset', 'EnableCimcSecureBootSuccess', 'EnableCimcSecureBootUpdateRequest', 'ExecuteActionsBegin', 'ExecuteActionsBiosPostCompletion', 'ExecuteActionsExecutePMAction', 'ExecuteActionsFail', 'ExecuteActionsPowerOn', 'ExecuteActionsSoftShutdown', 'ExecuteActionsSuccess', 'FlashControllerBegin', 'FlashControllerFail', 'FlashControllerSuccess', 'FlashControllerUpdateFlashLife', 'FwUpgradeActivateAdaptorNwFwLocal', 'FwUpgradeActivateAdaptorNwFwPeer', 'FwUpgradeActivateBios', 'FwUpgradeActivateIBMCFw', 'FwUpgradeAssertBypassWait', 'FwUpgradeBegin', 'FwUpgradeBiosImgUpdate', 'FwUpgradeBiosPostCompletion', 'FwUpgradeBladePowerOff', 'FwUpgradeBmcConfigPnuOS', 'FwUpgradeBmcPreconfigPnuOSLocal', 'FwUpgradeBmcPreconfigPnuOSPeer', 'FwUpgradeBmcUnconfigPnuOS', 'FwUpgradeBootPnuos', 'FwUpgradeBootWait', 'FwUpgradeCheckPowerAvailability', 'FwUpgradeCiscoOSOpenGate', 'FwUpgradeClearBiosUpdate', 'FwUpgradeCopyRemote', 'FwUpgradeDeassertResetBypass', 'FwUpgradeDeleteCurlDownloadedImages', 'FwUpgradeDeleteImagesRemote', 'FwUpgradeDownloadImages', 'FwUpgradeFail', 'FwUpgradeGraphicsImageUpdate', 'FwUpgradeHagPnuOSConnect', 'FwUpgradeHagPnuOSDisconnect', 'FwUpgradeHbaImgUpdate', 'FwUpgradeLocalDiskFwUpdate', 'FwUpgradeMswitchImgUpdate', 'FwUpgradeNicConfigPnuOSLocal', 'FwUpgradeNicConfigPnuOSPeer', 'FwUpgradeNicImgUpdate', 'FwUpgradeNicUnconfigPnuOSLocal', 'FwUpgradeNicUnconfigPnuOSPeer', 'FwUpgradeOobPollSasExpanderActivateStatus', 'FwUpgradeOobPollSasExpanderBootImgActivateStatus', 'FwUpgradeOobPollSasExpanderUpdateStatus', 'FwUpgradeOobSasExpanderBootImgActivate', 'FwUpgradeOobSasExpanderImgActivate', 'FwUpgradeOobSasExpanderImgUpdate', 'FwUpgradeOobStorageInventory', 'FwUpgradePciSwitchImageUpdate', 'FwUpgradePersistentMemoryDimmFwUpdate', 'FwUpgradePnuOSCatalog', 'FwUpgradePnuOSConfig', 'FwUpgradePnuOSIdent', 'FwUpgradePnuOSInventory', 'FwUpgradePnuOSPolicy', 'FwUpgradePnuOSSelfTest', 'FwUpgradePnuOSUnloadDrivers', 'FwUpgradePnuOSValidate', 'FwUpgradePollBiosActivateStatus', 'FwUpgradePollBiosUpdateStatus', 'FwUpgradePollBoardCtrlPowerCycle', 'FwUpgradePollBoardCtrlUpdateStatus', 'FwUpgradePollClearBiosUpdateStatus', 'FwUpgradePowerCycleBoard', 'FwUpgradePowerDeployWait', 'FwUpgradePowerOn', 'FwUpgradePreSanitize', 'FwUpgradeResetIBMC', 'FwUpgradeSanitize', 'FwUpgradeSasExpanderImgUpdate', 'FwUpgradeSerialDebugPnuOSConnect', 'FwUpgradeSerialDebugPnuOSDisconnect', 'FwUpgradeShutdown', 'FwUpgradeSolRedirectDisable', 'FwUpgradeSolRedirectEnable', 'FwUpgradeStorageCtlrImgUpdate', 'FwUpgradeSuccess', 'FwUpgradeSwConfigPnuOSLocal', 'FwUpgradeSwConfigPnuOSPeer', 'FwUpgradeSwConfigPortNivLocal', 'FwUpgradeSwConfigPortNivPeer', 'FwUpgradeSwUnconfigPnuOSLocal', 'FwUpgradeSwUnconfigPnuOSPeer', 'FwUpgradeUnconfigCimcVMedia', 'FwUpgradeUnconfigExtMgmtGw', 'FwUpgradeUnconfigExtMgmtRules', 'FwUpgradeUnlockFirmwareImage', 'FwUpgradeUpdateAdaptorNwFwLocal', 'FwUpgradeUpdateAdaptorNwFwPeer', 'FwUpgradeUpdateBiosRequest', 'FwUpgradeUpdateBoardCtrlRequest', 'FwUpgradeUpdateIBMCFw', 'FwUpgradeWaitForAdaptorNwFwUpdateLocal', 'FwUpgradeWaitForAdaptorNwFwUpdatePeer', 'FwUpgradeWaitForIBMCFwUpdate', 'HardShutdownBegin', 'HardShutdownExecute', 'HardShutdownFail', 'HardShutdownSuccess', 'HardresetBegin', 'HardresetCheckPowerAvailability', 'HardresetExecute', 'HardresetFail', 'HardresetPowerDeployWait', 'HardresetPreSanitize', 'HardresetSanitize', 'HardresetSuccess', 'NvmeSwitchRecoveryBegin', 'NvmeSwitchRecoveryCheckStatus', 'NvmeSwitchRecoveryExecute', 'NvmeSwitchRecoveryFail', 'NvmeSwitchRecoverySuccess', 'NvmeSwitchRecoveryWaitForAck', 'OobStorageAdminConfigBegin', 'OobStorageAdminConfigBootHost', 'OobStorageAdminConfigBootWait', 'OobStorageAdminConfigCheckPowerAvailability', 'OobStorageAdminConfigFail', 'OobStorageAdminConfigOobStorageConfig', 'OobStorageAdminConfigOobStorageInventory', 'OobStorageAdminConfigPowerDeployWait', 'OobStorageAdminConfigPreSanitize', 'OobStorageAdminConfigSanitize', 'OobStorageAdminConfigShutdown', 'OobStorageAdminConfigSuccess', 'OobStorageAdminConfigTearDownVMediaLocal', 'OobStorageAdminConfigTearDownVMediaPeer', 'PowerCapBegin', 'PowerCapConfig', 'PowerCapFail', 'PowerCapSuccess', 'PowercycleBegin', 'PowercycleCheckPowerAvailability', 'PowercycleExecute', 'PowercycleFail', 'PowercyclePowerDeployWait', 'PowercyclePreSanitize', 'PowercycleSanitize', 'PowercycleSuccess', 'ReinitializeVirtualDriveBegin', 'ReinitializeVirtualDriveExecuteVDAction', 'ReinitializeVirtualDriveFail', 'ReinitializeVirtualDriveSuccess', 'ResetBmcBegin', 'ResetBmcExecute', 'ResetBmcFail', 'ResetBmcSuccess', 'ResetIpmiBegin', 'ResetIpmiExecute', 'ResetIpmiFail', 'ResetIpmiSuccess', 'ResetKvmBegin', 'ResetKvmExecute', 'ResetKvmFail', 'ResetKvmSuccess', 'ResetMemoryErrorsBegin', 'ResetMemoryErrorsExecute', 'ResetMemoryErrorsFail', 'ResetMemoryErrorsSuccess', 'ServiceInfraDeployBegin', 'ServiceInfraDeployFail', 'ServiceInfraDeployNicConfigLocal', 'ServiceInfraDeployNicConfigPeer', 'ServiceInfraDeploySuccess', 'ServiceInfraDeploySwConfigLocal', 'ServiceInfraDeploySwConfigPeer', 'ServiceInfraWithdrawBegin', 'ServiceInfraWithdrawFail', 'ServiceInfraWithdrawNicUnConfigLocal', 'ServiceInfraWithdrawNicUnConfigPeer', 'ServiceInfraWithdrawSuccess', 'ServiceInfraWithdrawSwUnConfigLocal', 'ServiceInfraWithdrawSwUnConfigPeer', 'SoftShutdownBegin', 'SoftShutdownExecute', 'SoftShutdownFail', 'SoftShutdownSuccess', 'SoftresetBegin', 'SoftresetCheckPowerAvailability', 'SoftresetExecute', 'SoftresetFail', 'SoftresetPowerDeployWait', 'SoftresetPreSanitize', 'SoftresetSanitize', 'SoftresetSuccess', 'SwConnUpdA', 'SwConnUpdB', 'SwConnUpdBegin', 'SwConnUpdFail', 'SwConnUpdSuccess', 'TurnupBegin', 'TurnupCheckPowerAvailability', 'TurnupExecute', 'TurnupFail', 'TurnupPowerDeployWait', 'TurnupSuccess', 'UnconfigSoLBegin', 'UnconfigSoLExecute', 'UnconfigSoLFail', 'UnconfigSoLSuccess', 'UpdateAdaptorBegin', 'UpdateAdaptorCheckPowerAvailability', 'UpdateAdaptorFail', 'UpdateAdaptorPollUpdateStatusLocal', 'UpdateAdaptorPollUpdateStatusPeer', 'UpdateAdaptorPowerDeployWait', 'UpdateAdaptorPowerOff', 'UpdateAdaptorPowerOn', 'UpdateAdaptorSuccess', 'UpdateAdaptorUpdateRequestLocal', 'UpdateAdaptorUpdateRequestPeer', 'UpdateBIOSBegin', 'UpdateBIOSClear', 'UpdateBIOSFail', 'UpdateBIOSPollClearStatus', 'UpdateBIOSPollUpdateStatus', 'UpdateBIOSSuccess', 'UpdateBIOSUpdateRequest', 'UpdateBoardControllerBegin', 'UpdateBoardControllerCheckPowerAvailability', 'UpdateBoardControllerFail', 'UpdateBoardControllerPollBoardCtrlPowerCycle', 'UpdateBoardControllerPollUpdateStatus', 'UpdateBoardControllerPowerCycleBoard', 'UpdateBoardControllerPowerDeployWait', 'UpdateBoardControllerPrepareForUpdate', 'UpdateBoardControllerServerPowerOff', 'UpdateBoardControllerServerPowerOn', 'UpdateBoardControllerSuccess', 'UpdateBoardControllerUpdateRequest', 'clearTPMBegin', 'clearTPMBiosPostCompletion', 'clearTPMBladePowerOff', 'clearTPMBladePowerOn', 'clearTPMBootHost', 'clearTPMClear', 'clearTPMFail', 'clearTPMPreSanitize', 'clearTPMReadSmBios', 'clearTPMReconfigBios', 'clearTPMSanitize', 'clearTPMSetupVmedia', 'clearTPMStopVMediaLocal', 'clearTPMStopVMediaPeer', 'clearTPMSuccess', 'clearTPMUnconfigVmedia', 'nop', 'updateExtUsersBegin', 'updateExtUsersDeploy', 'updateExtUsersFail', 'updateExtUsersSuccess'] +range_val :[] + +Property fsm_try +-------- ------- +xml_attribute :fsmTry +field_type :byte +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property int_id +-------- ------ +xml_attribute :intId +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['none'] +range_val :['0-4294967295'] + +Property kmip_fault +-------- ---------- +xml_attribute :kmipFault +field_type :string +min_version :3.2(1d) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['false', 'no', 'true', 'yes'] +range_val :[] + +Property kmip_fault_description +-------- ---------------------- +xml_attribute :kmipFaultDescription +field_type :string +min_version :3.2(1d) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property lc +-------- -- +xml_attribute :lc +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :None +value_set :['decommission', 'discovered', 'migrate', 'rediscover', 'remove', 'resetToFactory', 'undiscovered', 'upgrade-firmware'] +range_val :[] + +Property lc_ts +-------- ----- +xml_attribute :lcTs +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property local_id +-------- -------- +xml_attribute :localId +field_type :string +min_version :2.1(2a) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property low_voltage_memory +-------- ------------------ +xml_attribute :lowVoltageMemory +field_type :string +min_version :1.4(1i) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['low-voltage', 'not-applicable', 'regular-voltage'] +range_val :[] + +Property managing_inst +-------- ------------- +xml_attribute :managingInst +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['A', 'B', 'NONE'] +range_val :[] + +Property memory_speed +-------- ------------ +xml_attribute :memorySpeed +field_type :string +min_version :1.4(1i) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['not-applicable', 'unspecified'] +range_val :['0-65535'] + +Property mfg_time +-------- -------- +xml_attribute :mfgTime +field_type :string +min_version :2.0(1m) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :['not-applicable'] +range_val :[] + +Property model +-------- ----- +xml_attribute :model +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property name +-------- ---- +xml_attribute :name +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :[\-\.:_a-zA-Z0-9]{0,16} +value_set :[] +range_val :[] + +Property num_of40_g_adaptors_with_old_fw +-------- ------------------------------- +xml_attribute :numOf40GAdaptorsWithOldFw +field_type :byte +min_version :3.1(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of40_g_adaptors_with_unknown_fw +-------- ----------------------------------- +xml_attribute :numOf40GAdaptorsWithUnknownFw +field_type :byte +min_version :3.1(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_adaptors +-------- --------------- +xml_attribute :numOfAdaptors +field_type :byte +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_cores +-------- ------------ +xml_attribute :numOfCores +field_type :ushort +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_cores_enabled +-------- -------------------- +xml_attribute :numOfCoresEnabled +field_type :ushort +min_version :1.3(1c) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_cpus +-------- ----------- +xml_attribute :numOfCpus +field_type :byte +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_eth_host_ifs +-------- ------------------- +xml_attribute :numOfEthHostIfs +field_type :ushort +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_fc_host_ifs +-------- ------------------ +xml_attribute :numOfFcHostIfs +field_type :ushort +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property num_of_threads +-------- -------------- +xml_attribute :numOfThreads +field_type :ushort +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property oper_power +-------- ---------- +xml_attribute :operPower +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['degraded', 'error', 'failed', 'not-supported', 'off', 'offduty', 'offline', 'ok', 'on', 'online', 'power-save', 'test', 'unknown'] +range_val :[] + +Property oper_pwr_trans_src +-------- ------------------ +xml_attribute :operPwrTransSrc +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['software', 'software_mcserver', 'unknown', 'user-fp', 'user-unknown'] +range_val :[] + +Property oper_qualifier +-------- -------------- +xml_attribute :operQualifier +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|not-applicable|cpu-voltage|adaptor-voltage|hba-voltage|compute-post-failure|memory-power|nic-power|memory-inoperable|nic-inoperable|compute-power|power-inoperable|compute-thermal|cpu-perf|adaptor-perf|hba-perf|cpu-thermal|adaptor-thermal|hba-thermal|compute-inoperable|memory-voltage|removed|nic-voltage|network-misconfig|cpu-power|adaptor-power|hba-power|compute-voltage|cpu-inoperable|adaptor-inoperable|hba-inoperable|config|memory-perf|nic-perf|adaptor-mismatch|memory-thermal|nic-thermal|mismatch|compute-perf),){0,38}(defaultValue|not-applicable|cpu-voltage|adaptor-voltage|hba-voltage|compute-post-failure|memory-power|nic-power|memory-inoperable|nic-inoperable|compute-power|power-inoperable|compute-thermal|cpu-perf|adaptor-perf|hba-perf|cpu-thermal|adaptor-thermal|hba-thermal|compute-inoperable|memory-voltage|removed|nic-voltage|network-misconfig|cpu-power|adaptor-power|hba-power|compute-voltage|cpu-inoperable|adaptor-inoperable|hba-inoperable|config|memory-perf|nic-perf|adaptor-mismatch|memory-thermal|nic-thermal|mismatch|compute-perf){0,1} +value_set :[] +range_val :[] + +Property oper_qualifier_reason +-------- --------------------- +xml_attribute :operQualifierReason +field_type :string +min_version :3.2(3a) +access :READ_ONLY +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,256} +value_set :[] +range_val :[] + +Property oper_state +-------- ---------- +xml_attribute :operState +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['bios-password-reset', 'bios-restore', 'cmos-reset', 'compute-failed', 'compute-mismatch', 'config', 'config-failure', 'decomissioning', 'degraded', 'diagnostics', 'diagnostics-failed', 'disabled', 'discovery', 'discovery-failed', 'inaccessible', 'indeterminate', 'inoperable', 'maintenance', 'maintenance-failed', 'ok', 'pending-reassociation', 'pending-reboot', 'power-off', 'power-problem', 'removed', 'restart', 'svnic-not-present', 'test', 'test-failed', 'thermal-problem', 'unassociated', 'unconfig', 'unconfig-failed', 'voltage-problem'] +range_val :[] + +Property operability +-------- ----------- +xml_attribute :operability +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['accessibility-problem', 'auto-upgrade', 'backplane-port-problem', 'bios-post-timeout', 'chassis-intrusion', 'chassis-limit-exceeded', 'config', 'decomissioning', 'degraded', 'dimm-disabled', 'disabled', 'discovery', 'discovery-failed', 'equipment-problem', 'fabric-conn-problem', 'fabric-unsupported-conn', 'identify', 'identity-unestablishable', 'inoperable', 'link-activate-blocked', 'malformed-fru', 'non-optimal', 'non-optimal-severe', 'not-supported', 'operable', 'peer-comm-problem', 'peer-dimm-disabled', 'performance-problem', 'post-failure', 'power-problem', 'powered-off', 'removed', 'thermal-problem', 'unknown', 'unsupported-config', 'upgrade-problem', 'voltage-problem'] +range_val :[] + +Property original_uuid +-------- ------------- +xml_attribute :originalUuid +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :(([0-9a-fA-F]){8}\-([0-9a-fA-F]){4}\-([0-9a-fA-F]){4}\-([0-9a-fA-F]){4}\-([0-9a-fA-F]){12})|0 +value_set :[] +range_val :[] + +Property part_number +-------- ----------- +xml_attribute :partNumber +field_type :string +min_version :2.0(3a) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property policy_level +-------- ------------ +xml_attribute :policyLevel +field_type :uint +min_version :2.1(1a) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property policy_owner +-------- ------------ +xml_attribute :policyOwner +field_type :string +min_version :2.1(1a) +access :READ_WRITE +min_length :None +max_length :None +pattern :None +value_set :['local', 'pending-policy', 'policy'] +range_val :[] + +Property presence +-------- -------- +xml_attribute :presence +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['empty', 'equipped', 'equipped-deprecated', 'equipped-identity-unestablishable', 'equipped-not-primary', 'equipped-slave', 'equipped-unsupported', 'equipped-with-malformed-fru', 'inaccessible', 'mismatch', 'mismatch-identity-unestablishable', 'mismatch-slave', 'missing', 'missing-slave', 'unauthorized', 'unknown'] +range_val :[] + +Property revision +-------- -------- +xml_attribute :revision +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property scaled_mode +-------- ----------- +xml_attribute :scaledMode +field_type :string +min_version :2.2(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['none', 'scaled', 'single'] +range_val :[] + +Property serial +-------- ------ +xml_attribute :serial +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property server_id +-------- --------- +xml_attribute :serverId +field_type :string +min_version :1.4(1i) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property slot_id +-------- ------- +xml_attribute :slotId +field_type :uint +min_version :1.0(1e) +access :NAMING +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :['1-8'] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property storage_oper_qualifier +-------- ---------------------- +xml_attribute :storageOperQualifier +field_type :string +min_version :3.2(3a) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['accessibility-problem', 'auto-upgrade', 'backplane-port-problem', 'bios-post-timeout', 'chassis-intrusion', 'chassis-limit-exceeded', 'config', 'decomissioning', 'degraded', 'dimm-disabled', 'disabled', 'discovery', 'discovery-failed', 'equipment-problem', 'fabric-conn-problem', 'fabric-unsupported-conn', 'identify', 'identity-unestablishable', 'inoperable', 'link-activate-blocked', 'malformed-fru', 'non-optimal', 'non-optimal-severe', 'not-supported', 'operable', 'peer-comm-problem', 'peer-dimm-disabled', 'performance-problem', 'post-failure', 'power-problem', 'powered-off', 'removed', 'thermal-problem', 'unknown', 'unsupported-config', 'upgrade-problem', 'voltage-problem'] +range_val :[] + +Property total_memory +-------- ------------ +xml_attribute :totalMemory +field_type :uint +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property usr_lbl +-------- ------- +xml_attribute :usrLbl +field_type :string +min_version :1.4(1i) +access :READ_WRITE +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,32} +value_set :[] +range_val :[] + +Property uuid +-------- ---- +xml_attribute :uuid +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :(([0-9a-fA-F]){8}\-([0-9a-fA-F]){4}\-([0-9a-fA-F]){4}\-([0-9a-fA-F]){4}\-([0-9a-fA-F]){12})|0 +value_set :[] +range_val :[] + +Property vendor +-------- ------ +xml_attribute :vendor +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property vid +-------- --- +xml_attribute :vid +field_type :string +min_version :2.0(3a) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] +``` \ No newline at end of file diff --git a/lib/ucsm/mo/ComputeMbPowerStats.md b/lib/ucsm/mo/ComputeMbPowerStats.md new file mode 100644 index 00000000..9c7913fa --- /dev/null +++ b/lib/ucsm/mo/ComputeMbPowerStats.md @@ -0,0 +1,423 @@ +# ComputeMbPowerStats + +## Managed Object + +``` +Managed Object : ComputeMbPowerStats +-------------- +class_id :ComputeMbPowerStats +child_action :None +consumed_power :138.000000 +consumed_power_avg :139.800003 +consumed_power_max :144.000000 +consumed_power_min :138.000000 +dn :sys/chassis-1/blade-1/board/power-stats +input_current :11.465603 +input_current_avg :11.615154 +input_current_max :11.964108 +input_current_min :11.465603 +input_voltage :12.036000 +input_voltage_avg :12.036000 +input_voltage_max :12.036000 +input_voltage_min :12.036000 +intervals :58982460 +rn :power-stats +sacl :None +status :None +suspect :no +thresholded : +time_collected :2022-12-02T09:51:08.333 +update :393226 +``` + +## Properties + +``` +[2022-12-02 09:51:45.107775] [debug_object] [ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "attr_get", + "attr_set", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "consts", + "consumed_power", + "consumed_power_avg", + "consumed_power_max", + "consumed_power_min", + "dirty_mask", + "dn", + "elem_create", + "from_xml", + "get_class_id", + "get_handle", + "input_current", + "input_current_avg", + "input_current_max", + "input_current_min", + "input_voltage", + "input_voltage_avg", + "input_voltage_max", + "input_voltage_min", + "intervals", + "is_dirty", + "make_rn", + "mark_clean", + "mark_dirty", + "mo_meta", + "naming_props", + "parent_mo", + "prop_map", + "prop_meta", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "status", + "suspect", + "sync_mo", + "thresholded", + "time_collected", + "to_xml", + "update", + "write_object" +] +``` + +## Meta + +``` +[2022-12-02 09:51:45.108745] [debug_object] [ComputeBoard] +[ComputeExtBoard] + |-ComputeMbPowerStats + |-ComputeMbPowerStatsHist + +ClassId ComputeMbPowerStats +------- ------------------- +xml_attribute :computeMbPowerStats +rn :power-stats +min_version :1.1(1j) +access :OutputOnly +access_privilege :['admin', 'operations', 'read-only'] +parents :['computeBoard', 'computeExtBoard'] +children :['computeMbPowerStatsHist'] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.1(1j) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property consumed_power +-------- -------------- +xml_attribute :consumedPower +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property consumed_power_avg +-------- ------------------ +xml_attribute :consumedPowerAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property consumed_power_max +-------- ------------------ +xml_attribute :consumedPowerMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property consumed_power_min +-------- ------------------ +xml_attribute :consumedPowerMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property input_current +-------- ------------- +xml_attribute :inputCurrent +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_current_avg +-------- ----------------- +xml_attribute :inputCurrentAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_current_max +-------- ----------------- +xml_attribute :inputCurrentMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_current_min +-------- ----------------- +xml_attribute :inputCurrentMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_voltage +-------- ------------- +xml_attribute :inputVoltage +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_voltage_avg +-------- ----------------- +xml_attribute :inputVoltageAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_voltage_max +-------- ----------------- +xml_attribute :inputVoltageMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_voltage_min +-------- ----------------- +xml_attribute :inputVoltageMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property intervals +-------- --------- +xml_attribute :intervals +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.1(1j) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property suspect +-------- ------- +xml_attribute :suspect +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['false', 'no', 'true', 'yes'] +range_val :[] + +Property thresholded +-------- ----------- +xml_attribute :thresholded +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property time_collected +-------- -------------- +xml_attribute :timeCollected +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property update +-------- ------ +xml_attribute :update +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] +``` \ No newline at end of file diff --git a/lib/ucsm/mo/EquipmentChassis.md b/lib/ucsm/mo/EquipmentChassis.md new file mode 100644 index 00000000..24443077 --- /dev/null +++ b/lib/ucsm/mo/EquipmentChassis.md @@ -0,0 +1,9226 @@ +# EquipmentChassis + +## Managed Object + +``` +Managed Object : EquipmentChassis +-------------- +class_id :EquipmentChassis +ack_progress_indicator :ack-not-in-progress +admin_state :acknowledged +asset_tag : +assigned_to_dn : +association :none +availability :unavailable +child_action :None +config_state :ok +conn_path :A,B +conn_status :A,B +discovery :undiscovered +discovery_status : +dn :sys/chassis-1 +fabric_ep_dn :fabric/server/chassis-1 +fan_speed_config_state :Balanced +flt_aggr :5066549580791808 +fsm_descr : +fsm_flags : +fsm_prev :PowerCapSuccess +fsm_progr :100 +fsm_rmt_inv_err_code :none +fsm_rmt_inv_err_descr : +fsm_rmt_inv_rslt : +fsm_stage_descr : +fsm_stamp :2022-11-30T20:05:54.883 +fsm_status :nop +fsm_try :0 +id :1 +lc_ts :1970-01-01T01:00:00.000 +lic_gp :0 +lic_state :license-ok +managing_inst :A +mfg_time :2019-12-17T00:00:00.000 +model :UCSB-5108-AC2 +oper_qualifier : +oper_qualifier_reason :N/A +oper_state :operable +operability :operable +part_number :68-5091-06 +power :ok +presence :unknown +revision :0 +rn :chassis-1 +sacl :None +seeprom_oper_state :unknown +serial :FOX2403P669 +service_state :in-service +status :None +thermal :ok +thermal_state_qualifier : +usr_lbl : +vendor :Cisco Systems Inc +version_holder :yes +vid :V05 +``` + +## Properties + +``` +[ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "ack_progress_indicator", + "admin_state", + "asset_tag", + "assigned_to_dn", + "association", + "attr_get", + "attr_set", + "availability", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "config_state", + "conn_path", + "conn_status", + "consts", + "dirty_mask", + "discovery", + "discovery_status", + "dn", + "elem_create", + "fabric_ep_dn", + "fan_speed_config_state", + "flt_aggr", + "from_xml", + "fsm_descr", + "fsm_flags", + "fsm_prev", + "fsm_progr", + "fsm_rmt_inv_err_code", + "fsm_rmt_inv_err_descr", + "fsm_rmt_inv_rslt", + "fsm_stage_descr", + "fsm_stamp", + "fsm_status", + "fsm_try", + "get_class_id", + "get_handle", + "id", + "is_dirty", + "lc_ts", + "lic_gp", + "lic_state", + "make_rn", + "managing_inst", + "mark_clean", + "mark_dirty", + "mfg_time", + "mo_meta", + "model", + "naming_props", + "oper_qualifier", + "oper_qualifier_reason", + "oper_state", + "operability", + "parent_mo", + "part_number", + "power", + "presence", + "prop_map", + "prop_meta", + "revision", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "seeprom_oper_state", + "serial", + "service_state", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "status", + "sync_mo", + "thermal", + "thermal_state_qualifier", + "to_xml", + "usr_lbl", + "vendor", + "version_holder", + "vid", + "write_object" +] +``` + +## Meta + +``` +[TopSystem] + |-EquipmentChassis + |-ComputeBlade + | |-AaaEpAuthProfile + | | |-AaaEpUser + | | |-AaaCimcSession + | |-AaaEpUser + | | |-AaaCimcSession + | |-AdaptorHostIfConfig + | |-AdaptorUnit + | | |-AdaptorExtEthIf + | | | |-AdaptorEthPortBySizeLargeStats + | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | |-AdaptorEthPortBySizeSmallStats + | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | |-AdaptorEthPortErrStats + | | | | |-AdaptorEthPortErrStatsHist + | | | |-AdaptorEthPortMcastStats + | | | | |-AdaptorEthPortMcastStatsHist + | | | |-AdaptorEthPortOutsizedStats + | | | | |-AdaptorEthPortOutsizedStatsHist + | | | |-AdaptorEthPortStats + | | | | |-AdaptorEthPortStatsHist + | | | |-AdaptorExtEthIfFsm + | | | | |-AdaptorExtEthIfFsmStage + | | | |-AdaptorExtEthIfFsmTask + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-EventInst + | | | |-FabricEthMonSrcEp + | | | |-FaultInst + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-AdaptorHostEthIf + | | | |-AdaptorAzureQosProfile + | | | |-AdaptorEthAdvFilterProfile + | | | |-AdaptorEthArfsProfile + | | | |-AdaptorEthCompQueueProfile + | | | |-AdaptorEthFailoverProfile + | | | |-AdaptorEthGENEVEProfile + | | | |-AdaptorEthInterruptProfile + | | | |-AdaptorEthInterruptScalingProfile + | | | |-AdaptorEthNVGREProfile + | | | |-AdaptorEthOffloadProfile + | | | |-AdaptorEthPortBySizeLargeStats + | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | |-AdaptorEthPortBySizeSmallStats + | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | |-AdaptorEthPortErrStats + | | | | |-AdaptorEthPortErrStatsHist + | | | |-AdaptorEthPortMcastStats + | | | | |-AdaptorEthPortMcastStatsHist + | | | |-AdaptorEthPortOutsizedStats + | | | | |-AdaptorEthPortOutsizedStatsHist + | | | |-AdaptorEthPortStats + | | | | |-AdaptorEthPortStatsHist + | | | |-AdaptorEthRecvQueueProfile + | | | |-AdaptorEthRoCEProfile + | | | |-AdaptorEthVxLANProfile + | | | |-AdaptorEthWorkQueueProfile + | | | |-AdaptorExtIpV6RssHashProfile + | | | |-AdaptorFcOEIf + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorHostEthIfFsm + | | | | |-AdaptorHostEthIfFsmStage + | | | |-AdaptorHostEthIfFsmTask + | | | |-AdaptorIpV4RssHashProfile + | | | |-AdaptorIpV6RssHashProfile + | | | |-AdaptorPTP + | | | |-AdaptorRssProfile + | | | |-AdaptorUsnicConnDef + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthFailoverProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthInterruptScalingProfile + | | | | |-AdaptorEthOffloadProfile + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorExtIpV6RssHashProfile + | | | | |-AdaptorIpV4RssHashProfile + | | | | |-AdaptorIpV6RssHashProfile + | | | | |-AdaptorRssProfile + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVmmqConnDef + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthRoCEProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorRssProfile + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-NetworkIfStats + | | |-AdaptorHostFcIf + | | | |-AdaptorFcCdbWorkQueueProfile + | | | |-AdaptorFcErrorRecoveryProfile + | | | |-AdaptorFcFnicProfile + | | | |-AdaptorFcIfEventStats + | | | | |-AdaptorFcIfEventStatsHist + | | | |-AdaptorFcIfFC4Stats + | | | | |-AdaptorFcIfFC4StatsHist + | | | |-AdaptorFcIfFrameStats + | | | | |-AdaptorFcIfFrameStatsHist + | | | |-AdaptorFcInterruptProfile + | | | |-AdaptorFcOEIf + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorFcPortFLogiProfile + | | | |-AdaptorFcPortPLogiProfile + | | | |-AdaptorFcPortProfile + | | | |-AdaptorFcPortStats + | | | | |-AdaptorFcPortStatsHist + | | | |-AdaptorFcRecvQueueProfile + | | | |-AdaptorFcVhbaTypeProfile + | | | |-AdaptorFcWorkQueueProfile + | | | |-AdaptorHostFcIfFsm + | | | | |-AdaptorHostFcIfFsmStage + | | | |-AdaptorHostFcIfFsmTask + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-AdaptorVsan + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-NetworkIfStats + | | |-AdaptorHostIscsiIf + | | | |-AdaptorIscsiProt + | | | |-AdaptorIscsiTargetIf + | | | |-AdaptorProtocolProfile + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | | |-NetworkIfStats + | | | |-VnicIPv4Dhcp + | | | |-VnicIPv4Dns + | | | |-VnicIPv4IscsiAddr + | | | | |-VnicIPv4Dns + | | | |-VnicIPv4PooledIscsiAddr + | | | | |-FaultInst + | | | | |-VnicIPv4Dns + | | | | |-VnicIpV4History + | | | |-VnicIPv4StaticRoute + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-AdaptorHostPort + | | |-AdaptorHostScsiIf + | | | |-AdaptorHostScsiLunRef + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-FaultInst + | | | |-NetworkIfStats + | | |-AdaptorHostServiceEthIf + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-FaultInst + | | | |-NetworkIfStats + | | |-AdaptorMenloDcePortStats + | | | |-AdaptorMenloDcePortStatsHist + | | |-AdaptorMenloEthErrorStats + | | | |-AdaptorMenloEthErrorStatsHist + | | |-AdaptorMenloEthStats + | | | |-AdaptorMenloEthStatsHist + | | |-AdaptorMenloFcErrorStats + | | | |-AdaptorMenloFcErrorStatsHist + | | |-AdaptorMenloFcStats + | | | |-AdaptorMenloFcStatsHist + | | |-AdaptorMenloHostPortStats + | | | |-AdaptorMenloHostPortStatsHist + | | |-AdaptorMenloMcpuErrorStats + | | | |-AdaptorMenloMcpuErrorStatsHist + | | |-AdaptorMenloMcpuStats + | | | |-AdaptorMenloMcpuStatsHist + | | |-AdaptorMenloNetEgStats + | | | |-AdaptorMenloNetEgStatsHist + | | |-AdaptorMenloNetInStats + | | | |-AdaptorMenloNetInStatsHist + | | |-AdaptorMenloQErrorStats + | | | |-AdaptorMenloQErrorStatsHist + | | |-AdaptorMenloQStats + | | | |-AdaptorMenloQStatsHist + | | |-AdaptorUnitExtn + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | |-DcxNs + | | | |-FaultInst + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EquipmentPciDef + | | |-FaultInst + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-BiosUnit + | | |-BiosBOT + | | | |-BiosBootDevGrp + | | | |-BiosBootDev + | | |-BiosSettings + | | | |-BiosTokenFeatureGroup + | | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosVfACPI10Support + | | | |-BiosVfASPMSupport + | | | |-BiosVfAllUSBDevices + | | | |-BiosVfAltitude + | | | |-BiosVfAssertNMIOnPERR + | | | |-BiosVfAssertNMIOnSERR + | | | |-BiosVfBMEDMAMitigation + | | | |-BiosVfBootOptionRetry + | | | |-BiosVfCPUHardwarePowerManagement + | | | |-BiosVfCPUPerformance + | | | |-BiosVfConsistentDeviceNameControl + | | | |-BiosVfConsoleRedirection + | | | |-BiosVfCoreMultiProcessing + | | | |-BiosVfDDR3VoltageSelection + | | | |-BiosVfDRAMClockThrottling + | | | |-BiosVfDirectCacheAccess + | | | |-BiosVfDramRefreshRate + | | | |-BiosVfEnergyPerformanceTuning + | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | |-BiosVfEnhancedPowerCappingSupport + | | | |-BiosVfExecuteDisableBit + | | | |-BiosVfFRB2Timer + | | | |-BiosVfFrequencyFloorOverride + | | | |-BiosVfFrontPanelLockout + | | | |-BiosVfIOEMezz1OptionROM + | | | |-BiosVfIOENVMe1OptionROM + | | | |-BiosVfIOENVMe2OptionROM + | | | |-BiosVfIOESlot1OptionROM + | | | |-BiosVfIOESlot2OptionROM + | | | |-BiosVfIntegratedGraphics + | | | |-BiosVfIntegratedGraphicsApertureSize + | | | |-BiosVfIntelEntrySASRAIDModule + | | | |-BiosVfIntelHyperThreadingTech + | | | |-BiosVfIntelTrustedExecutionTechnology + | | | |-BiosVfIntelTurboBoostTech + | | | |-BiosVfIntelVTForDirectedIO + | | | |-BiosVfIntelVirtualizationTechnology + | | | |-BiosVfInterleaveConfiguration + | | | |-BiosVfLocalX2Apic + | | | |-BiosVfLvDIMMSupport + | | | |-BiosVfMaxVariableMTRRSetting + | | | |-BiosVfMaximumMemoryBelow4GB + | | | |-BiosVfMemoryMappedIOAbove4GB + | | | |-BiosVfMirroringMode + | | | |-BiosVfNUMAOptimized + | | | |-BiosVfOSBootWatchdogTimer + | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | |-BiosVfOnboardGraphics + | | | |-BiosVfOnboardSATAController + | | | |-BiosVfOnboardStorage + | | | |-BiosVfOptionROMEnable + | | | |-BiosVfOptionROMLoad + | | | |-BiosVfOutOfBandManagement + | | | |-BiosVfPCHSATAMode + | | | |-BiosVfPCILOMPortsConfiguration + | | | |-BiosVfPCIROMCLP + | | | |-BiosVfPCISlotLinkSpeed + | | | |-BiosVfPCISlotOptionROMEnable + | | | |-BiosVfPOSTErrorPause + | | | |-BiosVfPSTATECoordination + | | | |-BiosVfPackageCStateLimit + | | | |-BiosVfPanicAndHighWatermark + | | | |-BiosVfProcessorC1E + | | | |-BiosVfProcessorC3Report + | | | |-BiosVfProcessorC6Report + | | | |-BiosVfProcessorC7Report + | | | |-BiosVfProcessorCMCI + | | | |-BiosVfProcessorCState + | | | |-BiosVfProcessorEnergyConfiguration + | | | |-BiosVfProcessorPrefetchConfig + | | | |-BiosVfQPILinkFrequencySelect + | | | |-BiosVfQPISnoopMode + | | | |-BiosVfQuietBoot + | | | |-BiosVfRedirectionAfterBIOSPOST + | | | |-BiosVfResumeOnACPowerLoss + | | | |-BiosVfSBMezz1OptionROM + | | | |-BiosVfSBNVMe1OptionROM + | | | |-BiosVfSIOC1OptionROM + | | | |-BiosVfSIOC2OptionROM + | | | |-BiosVfScrubPolicies + | | | |-BiosVfSelectMemoryRASConfiguration + | | | |-BiosVfSerialPortAEnable + | | | |-BiosVfSparingMode + | | | |-BiosVfSriovConfig + | | | |-BiosVfTPMPendingOperation + | | | |-BiosVfTPMSupport + | | | |-BiosVfTrustedPlatformModule + | | | |-BiosVfUCSMBootModeControl + | | | |-BiosVfUCSMBootOrderRuleControl + | | | |-BiosVfUEFIOSUseLegacyVideo + | | | |-BiosVfUSBBootConfig + | | | |-BiosVfUSBConfiguration + | | | |-BiosVfUSBFrontPanelAccessLock + | | | |-BiosVfUSBPortConfiguration + | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | |-BiosVfVGAPriority + | | | |-BiosVfWorkloadConfiguration + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-BiosVIdentityParams + | |-CimcvmediaMountConfigDef + | | |-CimcvmediaConfigMountEntry + | |-ComputeAdminAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-ComputeBladeFsm + | | |-ComputeBladeFsmStage + | |-ComputeBladeFsmTask + | |-ComputeBoard + | | |-ComputeIOHub + | | | |-ComputeIOHubEnvStats + | | | | |-ComputeIOHubEnvStatsHist + | | | |-FaultInst + | | |-ComputeMbPowerStats + | | | |-ComputeMbPowerStatsHist + | | |-ComputeMbTempStats + | | | |-ComputeMbTempStatsHist + | | |-ComputePCIeFatalCompletionStats + | | |-ComputePCIeFatalProtocolStats + | | |-ComputePCIeFatalReceiveStats + | | |-ComputePCIeFatalStats + | | |-ComputeRackUnitMbTempStats + | | | |-ComputeRackUnitMbTempStatsHist + | | |-ComputeRtcBattery + | | | |-FaultInst + | | |-CoprocessorCard + | | |-EquipmentTpm + | | | |-FaultInst + | | |-FaultInst + | | |-GraphicsCard + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-GraphicsController + | | |-LstorageLocal + | | |-LstorageLocalDef + | | |-LstorageRemote + | | | |-LstorageLogin + | | |-LstorageRemoteDef + | | | |-LstorageLogin + | | |-MemoryArray + | | | |-FaultInst + | | | |-MemoryArrayEnvStats + | | | | |-MemoryArrayEnvStatsHist + | | | |-MemoryPersistentMemoryUnit + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MemoryErrorStats + | | | | |-MemoryUnitEnvStats + | | | | |-MemoryUnitEnvStatsHist + | | | |-MemoryUnit + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-MemoryErrorStats + | | | |-MemoryUnitEnvStats + | | | |-MemoryUnitEnvStatsHist + | | |-MemoryBufferUnit + | | | |-FaultInst + | | | |-MemoryBufferUnitEnvStats + | | | |-MemoryBufferUnitEnvStatsHist + | | |-MemoryPersistentMemoryConfiguration + | | | |-FaultInst + | | | |-MemoryPersistentMemoryConfigResult + | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryNamespaceConfigResult + | | | | |-FaultInst + | | | |-MemoryPersistentMemoryRegion + | | | |-MemoryPersistentMemoryNamespace + | | | |-FaultInst + | | |-PciSwitch + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-PciLink + | | |-ProcessorUnit + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-ProcessorCacheMemStats + | | | |-ProcessorCore + | | | | |-ProcessorThread + | | | |-ProcessorEnvStats + | | | | |-ProcessorEnvStatsHist + | | | |-ProcessorErrorStats + | | | |-ProcessorExecStats + | | | |-ProcessorIOStats + | | | |-ProcessorMiscStats + | | | |-ProcessorPCIBusStats + | | | |-ProcessorPMUStats + | | | |-ProcessorSecurityStats + | | |-SecurityUnit + | | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-StorageController + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-LstorageControllerDef + | | | | |-LstorageControllerModeConfig + | | | | |-LstorageControllerQualifier + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageDrive + | | | |-StorageEmbeddedStorage + | | | |-StorageEnclosure + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-StorageEnclosureDiskSlotEp + | | | | | |-FaultInst + | | | | | |-StorageControllerRef + | | | | |-StorageEnclosureFsm + | | | | | |-StorageEnclosureFsmStage + | | | | |-StorageEnclosureFsmTask + | | | | |-StorageHddMotherBoardTempStats + | | | | | |-StorageHddMotherBoardTempStatsHist + | | | | |-StorageLocalDisk + | | | | |-EquipmentLocatorLed + | | | | | |-EquipmentLocatorLedFsm + | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | |-EquipmentLocatorLedFsmTask + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageControllerEp + | | | | |-StorageDiskEnvStats + | | | | | |-StorageDiskEnvStatsHist + | | | | |-StorageLocalDiskFsm + | | | | | |-StorageLocalDiskFsmStage + | | | | |-StorageLocalDiskFsmTask + | | | | |-StorageLocalDiskPartition + | | | | |-StorageOperation + | | | | |-StorageSasPort + | | | | |-StorageSsdHealthStats + | | | | |-StorageSsdHealthStatsHist + | | | |-StorageLocalDisk + | | | | |-EquipmentLocatorLed + | | | | | |-EquipmentLocatorLedFsm + | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | |-EquipmentLocatorLedFsmTask + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageControllerEp + | | | | |-StorageDiskEnvStats + | | | | | |-StorageDiskEnvStatsHist + | | | | |-StorageLocalDiskFsm + | | | | | |-StorageLocalDiskFsmStage + | | | | |-StorageLocalDiskFsmTask + | | | | |-StorageLocalDiskPartition + | | | | |-StorageOperation + | | | | |-StorageSasPort + | | | | |-StorageSsdHealthStats + | | | | |-StorageSsdHealthStatsHist + | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-StorageLocalDiskEp + | | | |-StorageLocalLun + | | | |-StorageMezzFlashLife + | | | | |-FaultInst + | | | |-StorageNvmeStats + | | | | |-StorageNvmeStatsHist + | | | |-StorageNvmeStorage + | | | |-StorageOnboardDevice + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-StorageOperation + | | | |-StorageRaidBattery + | | | | |-FaultInst + | | | | |-StorageOperation + | | | | |-StorageTransportableFlashModule + | | | |-StorageVirtualDrive + | | | | |-FaultInst + | | | | |-StorageControllerEp + | | | | |-StorageLunDisk + | | | | |-StorageOperation + | | | | |-StorageScsiLunRef + | | | | |-StorageVDMemberEp + | | | | |-FaultInst + | | | |-StorageVirtualDriveEp + | | |-StorageFlexFlashController + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-StorageFlexFlashCard + | | | | |-FaultInst + | | | | |-StorageFlexFlashDrive + | | | | |-FaultInst + | | | |-StorageFlexFlashControllerFsm + | | | | |-StorageFlexFlashControllerFsmStage + | | | |-StorageFlexFlashControllerFsmTask + | | | |-StorageFlexFlashVirtualDrive + | | | | |-FaultInst + | | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-StorageLocalDiskSlotEp + | | | |-FaultInst + | | |-StorageMiniStorage + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-StorageControllerReference + | | |-StorageNvmeSwitch + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-StorageSasExpander + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageOnboardDevice + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-StorageSasUpLink + | |-ComputeBoardConnector + | |-ComputeBoardController + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-ComputeExtBoard + | | |-BiosUnit + | | | |-BiosBOT + | | | | |-BiosBootDevGrp + | | | | |-BiosBootDev + | | | |-BiosSettings + | | | | |-BiosTokenFeatureGroup + | | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosVfACPI10Support + | | | | |-BiosVfASPMSupport + | | | | |-BiosVfAllUSBDevices + | | | | |-BiosVfAltitude + | | | | |-BiosVfAssertNMIOnPERR + | | | | |-BiosVfAssertNMIOnSERR + | | | | |-BiosVfBMEDMAMitigation + | | | | |-BiosVfBootOptionRetry + | | | | |-BiosVfCPUHardwarePowerManagement + | | | | |-BiosVfCPUPerformance + | | | | |-BiosVfConsistentDeviceNameControl + | | | | |-BiosVfConsoleRedirection + | | | | |-BiosVfCoreMultiProcessing + | | | | |-BiosVfDDR3VoltageSelection + | | | | |-BiosVfDRAMClockThrottling + | | | | |-BiosVfDirectCacheAccess + | | | | |-BiosVfDramRefreshRate + | | | | |-BiosVfEnergyPerformanceTuning + | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | |-BiosVfExecuteDisableBit + | | | | |-BiosVfFRB2Timer + | | | | |-BiosVfFrequencyFloorOverride + | | | | |-BiosVfFrontPanelLockout + | | | | |-BiosVfIOEMezz1OptionROM + | | | | |-BiosVfIOENVMe1OptionROM + | | | | |-BiosVfIOENVMe2OptionROM + | | | | |-BiosVfIOESlot1OptionROM + | | | | |-BiosVfIOESlot2OptionROM + | | | | |-BiosVfIntegratedGraphics + | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | |-BiosVfIntelHyperThreadingTech + | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | |-BiosVfIntelTurboBoostTech + | | | | |-BiosVfIntelVTForDirectedIO + | | | | |-BiosVfIntelVirtualizationTechnology + | | | | |-BiosVfInterleaveConfiguration + | | | | |-BiosVfLocalX2Apic + | | | | |-BiosVfLvDIMMSupport + | | | | |-BiosVfMaxVariableMTRRSetting + | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | |-BiosVfMirroringMode + | | | | |-BiosVfNUMAOptimized + | | | | |-BiosVfOSBootWatchdogTimer + | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | |-BiosVfOnboardGraphics + | | | | |-BiosVfOnboardSATAController + | | | | |-BiosVfOnboardStorage + | | | | |-BiosVfOptionROMEnable + | | | | |-BiosVfOptionROMLoad + | | | | |-BiosVfOutOfBandManagement + | | | | |-BiosVfPCHSATAMode + | | | | |-BiosVfPCILOMPortsConfiguration + | | | | |-BiosVfPCIROMCLP + | | | | |-BiosVfPCISlotLinkSpeed + | | | | |-BiosVfPCISlotOptionROMEnable + | | | | |-BiosVfPOSTErrorPause + | | | | |-BiosVfPSTATECoordination + | | | | |-BiosVfPackageCStateLimit + | | | | |-BiosVfPanicAndHighWatermark + | | | | |-BiosVfProcessorC1E + | | | | |-BiosVfProcessorC3Report + | | | | |-BiosVfProcessorC6Report + | | | | |-BiosVfProcessorC7Report + | | | | |-BiosVfProcessorCMCI + | | | | |-BiosVfProcessorCState + | | | | |-BiosVfProcessorEnergyConfiguration + | | | | |-BiosVfProcessorPrefetchConfig + | | | | |-BiosVfQPILinkFrequencySelect + | | | | |-BiosVfQPISnoopMode + | | | | |-BiosVfQuietBoot + | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | |-BiosVfResumeOnACPowerLoss + | | | | |-BiosVfSBMezz1OptionROM + | | | | |-BiosVfSBNVMe1OptionROM + | | | | |-BiosVfSIOC1OptionROM + | | | | |-BiosVfSIOC2OptionROM + | | | | |-BiosVfScrubPolicies + | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | |-BiosVfSerialPortAEnable + | | | | |-BiosVfSparingMode + | | | | |-BiosVfSriovConfig + | | | | |-BiosVfTPMPendingOperation + | | | | |-BiosVfTPMSupport + | | | | |-BiosVfTrustedPlatformModule + | | | | |-BiosVfUCSMBootModeControl + | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | |-BiosVfUSBBootConfig + | | | | |-BiosVfUSBConfiguration + | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | |-BiosVfUSBPortConfiguration + | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | |-BiosVfVGAPriority + | | | | |-BiosVfWorkloadConfiguration + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-ComputeBoardController + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-ComputeMbPowerStats + | | | |-ComputeMbPowerStatsHist + | | |-ComputeMbTempStats + | | | |-ComputeMbTempStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-ComputeFactoryResetOperation + | |-ComputeFwSyncAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-ComputeHostUtilityOs + | | |-MgmtUsbNicMgmtIf + | |-ComputeKvmMgmtPolicy + | | |-MgmtKvmCertificate + | | |-FaultInst + | |-ComputeMemoryConfiguration + | |-ComputePersonality + | |-ComputePhysicalExtension + | | |-FaultInst + | |-ComputePhysicalFsm + | | |-ComputePhysicalFsmStage + | |-ComputePhysicalFsmTask + | |-ComputePnuOSImage + | |-ComputePoolable + | | |-ComputePoolPolicyRef + | |-ComputeRebootLog + | |-ComputeScrubPolicy + | |-DiagSrvCtrl + | | |-DiagRslt + | | | |-DiagLogEp + | | |-DiagRunPolicy + | | | |-DiagMemoryTest + | | |-EtherServerIntFIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherServerIntFIoFsm + | | | |-EtherServerIntFIoFsmStage + | | |-EtherServerIntFIoFsmTask + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-PortDomainEp + | | |-PortTrustMode + | | |-SwUlan + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIOExpander + | |-EquipmentIndicatorLed + | |-EquipmentInventoryStatus + | | |-FaultInst + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPOST + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FaultSuppressTask + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareImageLock + | |-FirmwareStatus + | | |-FaultInst + | |-LsIdentityInfo + | | |-FaultInst + | |-LsbootDef + | | |-LsbootBootSecurity + | | |-LsbootEFIShell + | | |-LsbootIScsi + | | | |-LsbootIScsiImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootLan + | | | |-LsbootLanImagePath + | | | |-LsbootUEFIBootParam + | | | |-VnicIpV4StaticAddr + | | |-LsbootSan + | | | |-LsbootSanCatSanImage + | | | |-LsbootSanCatSanImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootStorage + | | | |-LsbootLocalStorage + | | | | |-LsbootDefaultLocalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootEmbeddedLocalDiskImage + | | | | | |-LsbootEmbeddedLocalDiskImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootEmbeddedLocalLunImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootLocalDiskImage + | | | | | |-LsbootLocalDiskImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootLocalHddImage + | | | | | |-LsbootLocalLunImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootNvme + | | | | | |-LsbootNvmeDiskSsd + | | | | | |-LsbootNvmePciSsd + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbExternalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbFlashStorageImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbInternalImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootSanImage + | | | |-LsbootSanImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootVirtualMedia + | |-LstorageProfile + | | |-LstorageControllerDef + | | | |-LstorageControllerModeConfig + | | | |-LstorageControllerQualifier + | | |-LstorageDasScsiLun + | | | |-FaultInst + | | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-LstorageLunSetConfig + | | | |-LstorageLunSetDiskSlot + | | | |-LstorageVirtualDriveDef + | | |-LstorageSecurity + | | |-LstorageDriveSecurity + | | |-LstorageLocal + | | |-LstorageRemote + | | |-LstorageLogin + | |-MemoryRuntime + | | |-MemoryRuntimeHist + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-MgmtKmipCertPolicy + | |-MgmtSecurity + | | |-MgmtKmip + | |-MgmtSpdmCertificatePolicy + | | |-MgmtSpdmCertificate + | |-MoKvCfgHolder + | | |-MoIpV4AddrKv + | | | |-FaultInst + | | |-MoIpV6AddrKv + | | | |-FaultInst + | | |-MoKv + | | |-MoVnicKv + | |-MoKvInvHolder + | | |-MoInvKv + | |-OsAgent + | |-OsInstance + | | |-OsEthBondIntf + | | | |-OsARPLinkMonitoringPolicy + | | | | |-OsARPTarget + | | | |-OsEthBondModeActiveBackup + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedALB + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedRR + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedTLB + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedXOR + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBroadcast + | | | | |-OsPrimarySlave + | | | |-OsEthIntf + | | | |-OsMiiLinkMonitoringPolicy + | | |-OsEthIntf + | |-PciEquipSlot + | | |-FaultInst + | |-PciUnit + | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-ProcessorRuntime + | | |-ProcessorRuntimeHist + | |-SolIf + | |-StorageEnclosure + | | |-EventInst + | | |-FaultInst + | | |-StorageEnclosureDiskSlotEp + | | | |-FaultInst + | | | |-StorageControllerRef + | | |-StorageEnclosureFsm + | | | |-StorageEnclosureFsmStage + | | |-StorageEnclosureFsmTask + | | |-StorageHddMotherBoardTempStats + | | | |-StorageHddMotherBoardTempStatsHist + | | |-StorageLocalDisk + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageControllerEp + | | |-StorageDiskEnvStats + | | | |-StorageDiskEnvStatsHist + | | |-StorageLocalDiskFsm + | | | |-StorageLocalDiskFsmStage + | | |-StorageLocalDiskFsmTask + | | |-StorageLocalDiskPartition + | | |-StorageOperation + | | |-StorageSasPort + | | |-StorageSsdHealthStats + | | |-StorageSsdHealthStatsHist + | |-StorageVirtualDriveContainer + | | |-StorageVirtualDrive + | | |-FaultInst + | | |-StorageControllerEp + | | |-StorageLunDisk + | | |-StorageOperation + | | |-StorageScsiLunRef + | | |-StorageVDMemberEp + | | |-FaultInst + | |-SwUlan + | |-SysdebugDiagnosticLog + |-ComputeBoardController + | |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-ComputeCartridge + | |-ComputeServerUnit + | |-AaaEpAuthProfile + | | |-AaaEpUser + | | |-AaaCimcSession + | |-AaaEpUser + | | |-AaaCimcSession + | |-AdaptorHostIfConfig + | |-AdaptorUnit + | | |-AdaptorExtEthIf + | | | |-AdaptorEthPortBySizeLargeStats + | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | |-AdaptorEthPortBySizeSmallStats + | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | |-AdaptorEthPortErrStats + | | | | |-AdaptorEthPortErrStatsHist + | | | |-AdaptorEthPortMcastStats + | | | | |-AdaptorEthPortMcastStatsHist + | | | |-AdaptorEthPortOutsizedStats + | | | | |-AdaptorEthPortOutsizedStatsHist + | | | |-AdaptorEthPortStats + | | | | |-AdaptorEthPortStatsHist + | | | |-AdaptorExtEthIfFsm + | | | | |-AdaptorExtEthIfFsmStage + | | | |-AdaptorExtEthIfFsmTask + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-EventInst + | | | |-FabricEthMonSrcEp + | | | |-FaultInst + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-AdaptorHostEthIf + | | | |-AdaptorAzureQosProfile + | | | |-AdaptorEthAdvFilterProfile + | | | |-AdaptorEthArfsProfile + | | | |-AdaptorEthCompQueueProfile + | | | |-AdaptorEthFailoverProfile + | | | |-AdaptorEthGENEVEProfile + | | | |-AdaptorEthInterruptProfile + | | | |-AdaptorEthInterruptScalingProfile + | | | |-AdaptorEthNVGREProfile + | | | |-AdaptorEthOffloadProfile + | | | |-AdaptorEthPortBySizeLargeStats + | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | |-AdaptorEthPortBySizeSmallStats + | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | |-AdaptorEthPortErrStats + | | | | |-AdaptorEthPortErrStatsHist + | | | |-AdaptorEthPortMcastStats + | | | | |-AdaptorEthPortMcastStatsHist + | | | |-AdaptorEthPortOutsizedStats + | | | | |-AdaptorEthPortOutsizedStatsHist + | | | |-AdaptorEthPortStats + | | | | |-AdaptorEthPortStatsHist + | | | |-AdaptorEthRecvQueueProfile + | | | |-AdaptorEthRoCEProfile + | | | |-AdaptorEthVxLANProfile + | | | |-AdaptorEthWorkQueueProfile + | | | |-AdaptorExtIpV6RssHashProfile + | | | |-AdaptorFcOEIf + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorHostEthIfFsm + | | | | |-AdaptorHostEthIfFsmStage + | | | |-AdaptorHostEthIfFsmTask + | | | |-AdaptorIpV4RssHashProfile + | | | |-AdaptorIpV6RssHashProfile + | | | |-AdaptorPTP + | | | |-AdaptorRssProfile + | | | |-AdaptorUsnicConnDef + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthFailoverProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthInterruptScalingProfile + | | | | |-AdaptorEthOffloadProfile + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorExtIpV6RssHashProfile + | | | | |-AdaptorIpV4RssHashProfile + | | | | |-AdaptorIpV6RssHashProfile + | | | | |-AdaptorRssProfile + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVmmqConnDef + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthRoCEProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorRssProfile + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-NetworkIfStats + | | |-AdaptorHostFcIf + | | | |-AdaptorFcCdbWorkQueueProfile + | | | |-AdaptorFcErrorRecoveryProfile + | | | |-AdaptorFcFnicProfile + | | | |-AdaptorFcIfEventStats + | | | | |-AdaptorFcIfEventStatsHist + | | | |-AdaptorFcIfFC4Stats + | | | | |-AdaptorFcIfFC4StatsHist + | | | |-AdaptorFcIfFrameStats + | | | | |-AdaptorFcIfFrameStatsHist + | | | |-AdaptorFcInterruptProfile + | | | |-AdaptorFcOEIf + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorFcPortFLogiProfile + | | | |-AdaptorFcPortPLogiProfile + | | | |-AdaptorFcPortProfile + | | | |-AdaptorFcPortStats + | | | | |-AdaptorFcPortStatsHist + | | | |-AdaptorFcRecvQueueProfile + | | | |-AdaptorFcVhbaTypeProfile + | | | |-AdaptorFcWorkQueueProfile + | | | |-AdaptorHostFcIfFsm + | | | | |-AdaptorHostFcIfFsmStage + | | | |-AdaptorHostFcIfFsmTask + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-AdaptorVsan + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-NetworkIfStats + | | |-AdaptorHostIscsiIf + | | | |-AdaptorIscsiProt + | | | |-AdaptorIscsiTargetIf + | | | |-AdaptorProtocolProfile + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | | |-NetworkIfStats + | | | |-VnicIPv4Dhcp + | | | |-VnicIPv4Dns + | | | |-VnicIPv4IscsiAddr + | | | | |-VnicIPv4Dns + | | | |-VnicIPv4PooledIscsiAddr + | | | | |-FaultInst + | | | | |-VnicIPv4Dns + | | | | |-VnicIpV4History + | | | |-VnicIPv4StaticRoute + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-AdaptorHostPort + | | |-AdaptorHostScsiIf + | | | |-AdaptorHostScsiLunRef + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-FaultInst + | | | |-NetworkIfStats + | | |-AdaptorHostServiceEthIf + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-FaultInst + | | | |-NetworkIfStats + | | |-AdaptorMenloDcePortStats + | | | |-AdaptorMenloDcePortStatsHist + | | |-AdaptorMenloEthErrorStats + | | | |-AdaptorMenloEthErrorStatsHist + | | |-AdaptorMenloEthStats + | | | |-AdaptorMenloEthStatsHist + | | |-AdaptorMenloFcErrorStats + | | | |-AdaptorMenloFcErrorStatsHist + | | |-AdaptorMenloFcStats + | | | |-AdaptorMenloFcStatsHist + | | |-AdaptorMenloHostPortStats + | | | |-AdaptorMenloHostPortStatsHist + | | |-AdaptorMenloMcpuErrorStats + | | | |-AdaptorMenloMcpuErrorStatsHist + | | |-AdaptorMenloMcpuStats + | | | |-AdaptorMenloMcpuStatsHist + | | |-AdaptorMenloNetEgStats + | | | |-AdaptorMenloNetEgStatsHist + | | |-AdaptorMenloNetInStats + | | | |-AdaptorMenloNetInStatsHist + | | |-AdaptorMenloQErrorStats + | | | |-AdaptorMenloQErrorStatsHist + | | |-AdaptorMenloQStats + | | | |-AdaptorMenloQStatsHist + | | |-AdaptorUnitExtn + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | |-DcxNs + | | | |-FaultInst + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EquipmentPciDef + | | |-FaultInst + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-BiosUnit + | | |-BiosBOT + | | | |-BiosBootDevGrp + | | | |-BiosBootDev + | | |-BiosSettings + | | | |-BiosTokenFeatureGroup + | | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosVfACPI10Support + | | | |-BiosVfASPMSupport + | | | |-BiosVfAllUSBDevices + | | | |-BiosVfAltitude + | | | |-BiosVfAssertNMIOnPERR + | | | |-BiosVfAssertNMIOnSERR + | | | |-BiosVfBMEDMAMitigation + | | | |-BiosVfBootOptionRetry + | | | |-BiosVfCPUHardwarePowerManagement + | | | |-BiosVfCPUPerformance + | | | |-BiosVfConsistentDeviceNameControl + | | | |-BiosVfConsoleRedirection + | | | |-BiosVfCoreMultiProcessing + | | | |-BiosVfDDR3VoltageSelection + | | | |-BiosVfDRAMClockThrottling + | | | |-BiosVfDirectCacheAccess + | | | |-BiosVfDramRefreshRate + | | | |-BiosVfEnergyPerformanceTuning + | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | |-BiosVfEnhancedPowerCappingSupport + | | | |-BiosVfExecuteDisableBit + | | | |-BiosVfFRB2Timer + | | | |-BiosVfFrequencyFloorOverride + | | | |-BiosVfFrontPanelLockout + | | | |-BiosVfIOEMezz1OptionROM + | | | |-BiosVfIOENVMe1OptionROM + | | | |-BiosVfIOENVMe2OptionROM + | | | |-BiosVfIOESlot1OptionROM + | | | |-BiosVfIOESlot2OptionROM + | | | |-BiosVfIntegratedGraphics + | | | |-BiosVfIntegratedGraphicsApertureSize + | | | |-BiosVfIntelEntrySASRAIDModule + | | | |-BiosVfIntelHyperThreadingTech + | | | |-BiosVfIntelTrustedExecutionTechnology + | | | |-BiosVfIntelTurboBoostTech + | | | |-BiosVfIntelVTForDirectedIO + | | | |-BiosVfIntelVirtualizationTechnology + | | | |-BiosVfInterleaveConfiguration + | | | |-BiosVfLocalX2Apic + | | | |-BiosVfLvDIMMSupport + | | | |-BiosVfMaxVariableMTRRSetting + | | | |-BiosVfMaximumMemoryBelow4GB + | | | |-BiosVfMemoryMappedIOAbove4GB + | | | |-BiosVfMirroringMode + | | | |-BiosVfNUMAOptimized + | | | |-BiosVfOSBootWatchdogTimer + | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | |-BiosVfOnboardGraphics + | | | |-BiosVfOnboardSATAController + | | | |-BiosVfOnboardStorage + | | | |-BiosVfOptionROMEnable + | | | |-BiosVfOptionROMLoad + | | | |-BiosVfOutOfBandManagement + | | | |-BiosVfPCHSATAMode + | | | |-BiosVfPCILOMPortsConfiguration + | | | |-BiosVfPCIROMCLP + | | | |-BiosVfPCISlotLinkSpeed + | | | |-BiosVfPCISlotOptionROMEnable + | | | |-BiosVfPOSTErrorPause + | | | |-BiosVfPSTATECoordination + | | | |-BiosVfPackageCStateLimit + | | | |-BiosVfPanicAndHighWatermark + | | | |-BiosVfProcessorC1E + | | | |-BiosVfProcessorC3Report + | | | |-BiosVfProcessorC6Report + | | | |-BiosVfProcessorC7Report + | | | |-BiosVfProcessorCMCI + | | | |-BiosVfProcessorCState + | | | |-BiosVfProcessorEnergyConfiguration + | | | |-BiosVfProcessorPrefetchConfig + | | | |-BiosVfQPILinkFrequencySelect + | | | |-BiosVfQPISnoopMode + | | | |-BiosVfQuietBoot + | | | |-BiosVfRedirectionAfterBIOSPOST + | | | |-BiosVfResumeOnACPowerLoss + | | | |-BiosVfSBMezz1OptionROM + | | | |-BiosVfSBNVMe1OptionROM + | | | |-BiosVfSIOC1OptionROM + | | | |-BiosVfSIOC2OptionROM + | | | |-BiosVfScrubPolicies + | | | |-BiosVfSelectMemoryRASConfiguration + | | | |-BiosVfSerialPortAEnable + | | | |-BiosVfSparingMode + | | | |-BiosVfSriovConfig + | | | |-BiosVfTPMPendingOperation + | | | |-BiosVfTPMSupport + | | | |-BiosVfTrustedPlatformModule + | | | |-BiosVfUCSMBootModeControl + | | | |-BiosVfUCSMBootOrderRuleControl + | | | |-BiosVfUEFIOSUseLegacyVideo + | | | |-BiosVfUSBBootConfig + | | | |-BiosVfUSBConfiguration + | | | |-BiosVfUSBFrontPanelAccessLock + | | | |-BiosVfUSBPortConfiguration + | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | |-BiosVfVGAPriority + | | | |-BiosVfWorkloadConfiguration + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-BiosVIdentityParams + | |-CimcvmediaMountConfigDef + | | |-CimcvmediaConfigMountEntry + | |-ComputeAdminAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-ComputeBoard + | | |-ComputeIOHub + | | | |-ComputeIOHubEnvStats + | | | | |-ComputeIOHubEnvStatsHist + | | | |-FaultInst + | | |-ComputeMbPowerStats + | | | |-ComputeMbPowerStatsHist + | | |-ComputeMbTempStats + | | | |-ComputeMbTempStatsHist + | | |-ComputePCIeFatalCompletionStats + | | |-ComputePCIeFatalProtocolStats + | | |-ComputePCIeFatalReceiveStats + | | |-ComputePCIeFatalStats + | | |-ComputeRackUnitMbTempStats + | | | |-ComputeRackUnitMbTempStatsHist + | | |-ComputeRtcBattery + | | | |-FaultInst + | | |-CoprocessorCard + | | |-EquipmentTpm + | | | |-FaultInst + | | |-FaultInst + | | |-GraphicsCard + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-GraphicsController + | | |-LstorageLocal + | | |-LstorageLocalDef + | | |-LstorageRemote + | | | |-LstorageLogin + | | |-LstorageRemoteDef + | | | |-LstorageLogin + | | |-MemoryArray + | | | |-FaultInst + | | | |-MemoryArrayEnvStats + | | | | |-MemoryArrayEnvStatsHist + | | | |-MemoryPersistentMemoryUnit + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MemoryErrorStats + | | | | |-MemoryUnitEnvStats + | | | | |-MemoryUnitEnvStatsHist + | | | |-MemoryUnit + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-MemoryErrorStats + | | | |-MemoryUnitEnvStats + | | | |-MemoryUnitEnvStatsHist + | | |-MemoryBufferUnit + | | | |-FaultInst + | | | |-MemoryBufferUnitEnvStats + | | | |-MemoryBufferUnitEnvStatsHist + | | |-MemoryPersistentMemoryConfiguration + | | | |-FaultInst + | | | |-MemoryPersistentMemoryConfigResult + | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryNamespaceConfigResult + | | | | |-FaultInst + | | | |-MemoryPersistentMemoryRegion + | | | |-MemoryPersistentMemoryNamespace + | | | |-FaultInst + | | |-PciSwitch + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-PciLink + | | |-ProcessorUnit + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-ProcessorCacheMemStats + | | | |-ProcessorCore + | | | | |-ProcessorThread + | | | |-ProcessorEnvStats + | | | | |-ProcessorEnvStatsHist + | | | |-ProcessorErrorStats + | | | |-ProcessorExecStats + | | | |-ProcessorIOStats + | | | |-ProcessorMiscStats + | | | |-ProcessorPCIBusStats + | | | |-ProcessorPMUStats + | | | |-ProcessorSecurityStats + | | |-SecurityUnit + | | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-StorageController + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-LstorageControllerDef + | | | | |-LstorageControllerModeConfig + | | | | |-LstorageControllerQualifier + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageDrive + | | | |-StorageEmbeddedStorage + | | | |-StorageEnclosure + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-StorageEnclosureDiskSlotEp + | | | | | |-FaultInst + | | | | | |-StorageControllerRef + | | | | |-StorageEnclosureFsm + | | | | | |-StorageEnclosureFsmStage + | | | | |-StorageEnclosureFsmTask + | | | | |-StorageHddMotherBoardTempStats + | | | | | |-StorageHddMotherBoardTempStatsHist + | | | | |-StorageLocalDisk + | | | | |-EquipmentLocatorLed + | | | | | |-EquipmentLocatorLedFsm + | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | |-EquipmentLocatorLedFsmTask + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageControllerEp + | | | | |-StorageDiskEnvStats + | | | | | |-StorageDiskEnvStatsHist + | | | | |-StorageLocalDiskFsm + | | | | | |-StorageLocalDiskFsmStage + | | | | |-StorageLocalDiskFsmTask + | | | | |-StorageLocalDiskPartition + | | | | |-StorageOperation + | | | | |-StorageSasPort + | | | | |-StorageSsdHealthStats + | | | | |-StorageSsdHealthStatsHist + | | | |-StorageLocalDisk + | | | | |-EquipmentLocatorLed + | | | | | |-EquipmentLocatorLedFsm + | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | |-EquipmentLocatorLedFsmTask + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageControllerEp + | | | | |-StorageDiskEnvStats + | | | | | |-StorageDiskEnvStatsHist + | | | | |-StorageLocalDiskFsm + | | | | | |-StorageLocalDiskFsmStage + | | | | |-StorageLocalDiskFsmTask + | | | | |-StorageLocalDiskPartition + | | | | |-StorageOperation + | | | | |-StorageSasPort + | | | | |-StorageSsdHealthStats + | | | | |-StorageSsdHealthStatsHist + | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-StorageLocalDiskEp + | | | |-StorageLocalLun + | | | |-StorageMezzFlashLife + | | | | |-FaultInst + | | | |-StorageNvmeStats + | | | | |-StorageNvmeStatsHist + | | | |-StorageNvmeStorage + | | | |-StorageOnboardDevice + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-StorageOperation + | | | |-StorageRaidBattery + | | | | |-FaultInst + | | | | |-StorageOperation + | | | | |-StorageTransportableFlashModule + | | | |-StorageVirtualDrive + | | | | |-FaultInst + | | | | |-StorageControllerEp + | | | | |-StorageLunDisk + | | | | |-StorageOperation + | | | | |-StorageScsiLunRef + | | | | |-StorageVDMemberEp + | | | | |-FaultInst + | | | |-StorageVirtualDriveEp + | | |-StorageFlexFlashController + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-StorageFlexFlashCard + | | | | |-FaultInst + | | | | |-StorageFlexFlashDrive + | | | | |-FaultInst + | | | |-StorageFlexFlashControllerFsm + | | | | |-StorageFlexFlashControllerFsmStage + | | | |-StorageFlexFlashControllerFsmTask + | | | |-StorageFlexFlashVirtualDrive + | | | | |-FaultInst + | | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-StorageLocalDiskSlotEp + | | | |-FaultInst + | | |-StorageMiniStorage + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-StorageControllerReference + | | |-StorageNvmeSwitch + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-StorageSasExpander + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageOnboardDevice + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-StorageSasUpLink + | |-ComputeBoardController + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-ComputeExtBoard + | | |-BiosUnit + | | | |-BiosBOT + | | | | |-BiosBootDevGrp + | | | | |-BiosBootDev + | | | |-BiosSettings + | | | | |-BiosTokenFeatureGroup + | | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosVfACPI10Support + | | | | |-BiosVfASPMSupport + | | | | |-BiosVfAllUSBDevices + | | | | |-BiosVfAltitude + | | | | |-BiosVfAssertNMIOnPERR + | | | | |-BiosVfAssertNMIOnSERR + | | | | |-BiosVfBMEDMAMitigation + | | | | |-BiosVfBootOptionRetry + | | | | |-BiosVfCPUHardwarePowerManagement + | | | | |-BiosVfCPUPerformance + | | | | |-BiosVfConsistentDeviceNameControl + | | | | |-BiosVfConsoleRedirection + | | | | |-BiosVfCoreMultiProcessing + | | | | |-BiosVfDDR3VoltageSelection + | | | | |-BiosVfDRAMClockThrottling + | | | | |-BiosVfDirectCacheAccess + | | | | |-BiosVfDramRefreshRate + | | | | |-BiosVfEnergyPerformanceTuning + | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | |-BiosVfExecuteDisableBit + | | | | |-BiosVfFRB2Timer + | | | | |-BiosVfFrequencyFloorOverride + | | | | |-BiosVfFrontPanelLockout + | | | | |-BiosVfIOEMezz1OptionROM + | | | | |-BiosVfIOENVMe1OptionROM + | | | | |-BiosVfIOENVMe2OptionROM + | | | | |-BiosVfIOESlot1OptionROM + | | | | |-BiosVfIOESlot2OptionROM + | | | | |-BiosVfIntegratedGraphics + | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | |-BiosVfIntelHyperThreadingTech + | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | |-BiosVfIntelTurboBoostTech + | | | | |-BiosVfIntelVTForDirectedIO + | | | | |-BiosVfIntelVirtualizationTechnology + | | | | |-BiosVfInterleaveConfiguration + | | | | |-BiosVfLocalX2Apic + | | | | |-BiosVfLvDIMMSupport + | | | | |-BiosVfMaxVariableMTRRSetting + | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | |-BiosVfMirroringMode + | | | | |-BiosVfNUMAOptimized + | | | | |-BiosVfOSBootWatchdogTimer + | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | |-BiosVfOnboardGraphics + | | | | |-BiosVfOnboardSATAController + | | | | |-BiosVfOnboardStorage + | | | | |-BiosVfOptionROMEnable + | | | | |-BiosVfOptionROMLoad + | | | | |-BiosVfOutOfBandManagement + | | | | |-BiosVfPCHSATAMode + | | | | |-BiosVfPCILOMPortsConfiguration + | | | | |-BiosVfPCIROMCLP + | | | | |-BiosVfPCISlotLinkSpeed + | | | | |-BiosVfPCISlotOptionROMEnable + | | | | |-BiosVfPOSTErrorPause + | | | | |-BiosVfPSTATECoordination + | | | | |-BiosVfPackageCStateLimit + | | | | |-BiosVfPanicAndHighWatermark + | | | | |-BiosVfProcessorC1E + | | | | |-BiosVfProcessorC3Report + | | | | |-BiosVfProcessorC6Report + | | | | |-BiosVfProcessorC7Report + | | | | |-BiosVfProcessorCMCI + | | | | |-BiosVfProcessorCState + | | | | |-BiosVfProcessorEnergyConfiguration + | | | | |-BiosVfProcessorPrefetchConfig + | | | | |-BiosVfQPILinkFrequencySelect + | | | | |-BiosVfQPISnoopMode + | | | | |-BiosVfQuietBoot + | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | |-BiosVfResumeOnACPowerLoss + | | | | |-BiosVfSBMezz1OptionROM + | | | | |-BiosVfSBNVMe1OptionROM + | | | | |-BiosVfSIOC1OptionROM + | | | | |-BiosVfSIOC2OptionROM + | | | | |-BiosVfScrubPolicies + | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | |-BiosVfSerialPortAEnable + | | | | |-BiosVfSparingMode + | | | | |-BiosVfSriovConfig + | | | | |-BiosVfTPMPendingOperation + | | | | |-BiosVfTPMSupport + | | | | |-BiosVfTrustedPlatformModule + | | | | |-BiosVfUCSMBootModeControl + | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | |-BiosVfUSBBootConfig + | | | | |-BiosVfUSBConfiguration + | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | |-BiosVfUSBPortConfiguration + | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | |-BiosVfVGAPriority + | | | | |-BiosVfWorkloadConfiguration + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-ComputeBoardController + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-ComputeMbPowerStats + | | | |-ComputeMbPowerStatsHist + | | |-ComputeMbTempStats + | | | |-ComputeMbTempStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-ComputeFactoryResetOperation + | |-ComputeFwSyncAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-ComputeHostUtilityOs + | | |-MgmtUsbNicMgmtIf + | |-ComputeKvmMgmtPolicy + | | |-MgmtKvmCertificate + | | |-FaultInst + | |-ComputeMemoryConfiguration + | |-ComputePhysicalExtension + | | |-FaultInst + | |-ComputePhysicalFsm + | | |-ComputePhysicalFsmStage + | |-ComputePhysicalFsmTask + | |-ComputePnuOSImage + | |-ComputePoolable + | | |-ComputePoolPolicyRef + | |-ComputeRebootLog + | |-ComputeScrubPolicy + | |-ComputeServerUnitFsm + | | |-ComputeServerUnitFsmStage + | |-ComputeServerUnitFsmTask + | |-DiagSrvCtrl + | | |-DiagRslt + | | | |-DiagLogEp + | | |-DiagRunPolicy + | | | |-DiagMemoryTest + | | |-EtherServerIntFIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherServerIntFIoFsm + | | | |-EtherServerIntFIoFsmStage + | | |-EtherServerIntFIoFsmTask + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-PortDomainEp + | | |-PortTrustMode + | | |-SwUlan + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIOExpander + | |-EquipmentIndicatorLed + | |-EquipmentInventoryStatus + | | |-FaultInst + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPOST + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FaultSuppressTask + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareImageLock + | |-FirmwareStatus + | | |-FaultInst + | |-LsIdentityInfo + | | |-FaultInst + | |-LsbootDef + | | |-LsbootBootSecurity + | | |-LsbootEFIShell + | | |-LsbootIScsi + | | | |-LsbootIScsiImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootLan + | | | |-LsbootLanImagePath + | | | |-LsbootUEFIBootParam + | | | |-VnicIpV4StaticAddr + | | |-LsbootSan + | | | |-LsbootSanCatSanImage + | | | |-LsbootSanCatSanImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootStorage + | | | |-LsbootLocalStorage + | | | | |-LsbootDefaultLocalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootEmbeddedLocalDiskImage + | | | | | |-LsbootEmbeddedLocalDiskImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootEmbeddedLocalLunImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootLocalDiskImage + | | | | | |-LsbootLocalDiskImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootLocalHddImage + | | | | | |-LsbootLocalLunImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootNvme + | | | | | |-LsbootNvmeDiskSsd + | | | | | |-LsbootNvmePciSsd + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbExternalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbFlashStorageImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbInternalImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootSanImage + | | | |-LsbootSanImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootVirtualMedia + | |-LstorageProfile + | | |-LstorageControllerDef + | | | |-LstorageControllerModeConfig + | | | |-LstorageControllerQualifier + | | |-LstorageDasScsiLun + | | | |-FaultInst + | | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-LstorageLunSetConfig + | | | |-LstorageLunSetDiskSlot + | | | |-LstorageVirtualDriveDef + | | |-LstorageSecurity + | | |-LstorageDriveSecurity + | | |-LstorageLocal + | | |-LstorageRemote + | | |-LstorageLogin + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-MgmtKmipCertPolicy + | |-MgmtSecurity + | | |-MgmtKmip + | |-MgmtSpdmCertificatePolicy + | | |-MgmtSpdmCertificate + | |-MoKvCfgHolder + | | |-MoIpV4AddrKv + | | | |-FaultInst + | | |-MoIpV6AddrKv + | | | |-FaultInst + | | |-MoKv + | | |-MoVnicKv + | |-MoKvInvHolder + | | |-MoInvKv + | |-OsAgent + | |-OsInstance + | | |-OsEthBondIntf + | | | |-OsARPLinkMonitoringPolicy + | | | | |-OsARPTarget + | | | |-OsEthBondModeActiveBackup + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedALB + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedRR + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedTLB + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedXOR + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBroadcast + | | | | |-OsPrimarySlave + | | | |-OsEthIntf + | | | |-OsMiiLinkMonitoringPolicy + | | |-OsEthIntf + | |-PciEquipSlot + | | |-FaultInst + | |-PciUnit + | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-SolIf + | |-StorageEnclosure + | | |-EventInst + | | |-FaultInst + | | |-StorageEnclosureDiskSlotEp + | | | |-FaultInst + | | | |-StorageControllerRef + | | |-StorageEnclosureFsm + | | | |-StorageEnclosureFsmStage + | | |-StorageEnclosureFsmTask + | | |-StorageHddMotherBoardTempStats + | | | |-StorageHddMotherBoardTempStatsHist + | | |-StorageLocalDisk + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageControllerEp + | | |-StorageDiskEnvStats + | | | |-StorageDiskEnvStatsHist + | | |-StorageLocalDiskFsm + | | | |-StorageLocalDiskFsmStage + | | |-StorageLocalDiskFsmTask + | | |-StorageLocalDiskPartition + | | |-StorageOperation + | | |-StorageSasPort + | | |-StorageSsdHealthStats + | | |-StorageSsdHealthStatsHist + | |-StorageVirtualDriveContainer + | | |-StorageVirtualDrive + | | |-FaultInst + | | |-StorageControllerEp + | | |-StorageLunDisk + | | |-StorageOperation + | | |-StorageScsiLunRef + | | |-StorageVDMemberEp + | | |-FaultInst + | |-SwUlan + | |-SysdebugDiagnosticLog + |-ComputePsuControl + |-EquipmentBeaconLed + | |-EquipmentBeaconLedFsm + | | |-EquipmentBeaconLedFsmStage + | |-EquipmentBeaconLedFsmTask + | |-EventInst + | |-FaultInst + |-EquipmentChassisFsm + | |-EquipmentChassisFsmStage + |-EquipmentChassisFsmTask + |-EquipmentChassisStats + | |-EquipmentChassisStatsHist + |-EquipmentComputeConn + | |-FaultInst + |-EquipmentFanModule + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentFan + | | |-EquipmentFanStats + | | | |-EquipmentFanStatsHist + | | |-EquipmentNetworkElementFanStats + | | | |-EquipmentNetworkElementFanStatsHist + | | |-EquipmentRackUnitFanStats + | | | |-EquipmentRackUnitFanStatsHist + | | |-FaultInst + | |-EquipmentFanModuleStats + | | |-EquipmentFanModuleStatsHist + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIndicatorLed + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-FaultInst + |-EquipmentHealthLed + | |-ComputeHealthLedSensorAlarm + | |-FaultInst + |-EquipmentIOCard + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIOCardBaseFsm + | | |-EquipmentIOCardBaseFsmStage + | |-EquipmentIOCardBaseFsmTask + | |-EquipmentIOCardFsm + | | |-EquipmentIOCardFsmStage + | |-EquipmentIOCardFsmTask + | |-EquipmentIOCardStats + | | |-EquipmentIOCardStatsHist + | |-EquipmentIndicatorLed + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPOST + | |-EventInst + | |-FaultInst + | |-FaultSuppressTask + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareStatus + | | |-FaultInst + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-PortGroup + | |-EtherPIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherPIoEndPoint + | | |-EtherPIoFsm + | | | |-EtherPIoFsmStage + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EtherServerIntFIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherServerIntFIoFsm + | | | |-EtherServerIntFIoFsmStage + | | |-EtherServerIntFIoFsmTask + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-PortDomainEp + | | |-PortTrustMode + | | |-SwUlan + | |-EtherServerIntFIoPc + | | |-EtherServerIntFIoPcEp + | |-EtherSwitchIntFIo + | | |-EquipmentXcvr + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-FaultInst + | | |-PortDomainEp + | |-EtherSwitchIntFIoPc + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherSwitchIntFIoPcEp + | | |-FaultInst + | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-PortSubGroup + | |-EtherPIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherPIoEndPoint + | | |-EtherPIoFsm + | | | |-EtherPIoFsmStage + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-FcPIo + | |-EquipmentXcvr + | |-EventInst + | |-FaultInst + | |-FcErrStats + | | |-FcErrStatsHist + | |-FcPIoFsm + | | |-FcPIoFsmStage + | |-FcStats + | | |-FcStatsHist + | |-LldpAcquired + | |-NetworkIfStats + | |-PortDomainEp + | |-PortPIoFsm + | | |-PortPIoFsmStage + | |-PortPIoFsmTask + |-EquipmentIndicatorLed + |-EquipmentLocatorLed + | |-EquipmentLocatorLedFsm + | | |-EquipmentLocatorLedFsmStage + | |-EquipmentLocatorLedFsmTask + | |-EventInst + | |-FaultInst + |-EquipmentPoolable + | |-EquipmentPoolPolicyRef + |-EquipmentPsu + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentFexPsuInputStats + | | |-EquipmentFexPsuInputStatsHist + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIndicatorLed + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPsuFsm + | | |-EquipmentPsuFsmStage + | |-EquipmentPsuFsmTask + | |-EquipmentPsuInputStats + | | |-EquipmentPsuInputStatsHist + | |-EquipmentPsuOutputStats + | | |-EquipmentPsuOutputStatsHist + | |-EquipmentPsuStats + | | |-EquipmentPsuStatsHist + | |-EquipmentRackUnitPsuStats + | | |-EquipmentRackUnitPsuStatsHist + | |-EventInst + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareStatus + | | |-FaultInst + | |-FirmwareUpdatable + | |-FaultInst + | |-FirmwareInstallable + | |-FirmwareUcscInfo + |-EquipmentSharedIOModule + | |-FaultInst + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-PortGroup + | |-EtherPIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherPIoEndPoint + | | |-EtherPIoFsm + | | | |-EtherPIoFsmStage + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EtherServerIntFIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherServerIntFIoFsm + | | | |-EtherServerIntFIoFsmStage + | | |-EtherServerIntFIoFsmTask + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-PortDomainEp + | | |-PortTrustMode + | | |-SwUlan + | |-EtherServerIntFIoPc + | | |-EtherServerIntFIoPcEp + | |-EtherSwitchIntFIo + | | |-EquipmentXcvr + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-FaultInst + | | |-PortDomainEp + | |-EtherSwitchIntFIoPc + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherSwitchIntFIoPcEp + | | |-FaultInst + | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-PortSubGroup + | |-EtherPIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherPIoEndPoint + | | |-EtherPIoFsm + | | | |-EtherPIoFsmStage + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-FcPIo + | |-EquipmentXcvr + | |-EventInst + | |-FaultInst + | |-FcErrStats + | | |-FcErrStatsHist + | |-FcPIoFsm + | | |-FcPIoFsmStage + | |-FcStats + | | |-FcStatsHist + | |-LldpAcquired + | |-NetworkIfStats + | |-PortDomainEp + | |-PortPIoFsm + | | |-PortPIoFsmStage + | |-PortPIoFsmTask + |-EquipmentSwitchIOCard + | |-EquipmentIOCardBaseFsm + | | |-EquipmentIOCardBaseFsmStage + | |-EquipmentIOCardBaseFsmTask + | |-EquipmentIOCardStats + | | |-EquipmentIOCardStatsHist + | |-EquipmentSwitchIOCardFsm + | | |-EquipmentSwitchIOCardFsmStage + | |-EquipmentSwitchIOCardFsmTask + | |-EventInst + | |-FaultInst + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-PortGroup + | |-EtherPIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherPIoEndPoint + | | |-EtherPIoFsm + | | | |-EtherPIoFsmStage + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EtherServerIntFIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherServerIntFIoFsm + | | | |-EtherServerIntFIoFsmStage + | | |-EtherServerIntFIoFsmTask + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-PortDomainEp + | | |-PortTrustMode + | | |-SwUlan + | |-EtherServerIntFIoPc + | | |-EtherServerIntFIoPcEp + | |-EtherSwitchIntFIo + | | |-EquipmentXcvr + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-FaultInst + | | |-PortDomainEp + | |-EtherSwitchIntFIoPc + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherSwitchIntFIoPcEp + | | |-FaultInst + | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-PortSubGroup + | |-EtherPIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherNiErrStats + | | | |-EtherNiErrStatsHist + | | |-EtherPIoEndPoint + | | |-EtherPIoFsm + | | | |-EtherPIoFsmStage + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-FcPIo + | |-EquipmentXcvr + | |-EventInst + | |-FaultInst + | |-FcErrStats + | | |-FcErrStatsHist + | |-FcPIoFsm + | | |-FcPIoFsmStage + | |-FcStats + | | |-FcStatsHist + | |-LldpAcquired + | |-NetworkIfStats + | |-PortDomainEp + | |-PortPIoFsm + | | |-PortPIoFsmStage + | |-PortPIoFsmTask + |-EquipmentSystemIOController + | |-ComputeBoardController + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-EquipmentSharedIOModule + | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PortGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EtherServerIntFIoPc + | | | |-EtherServerIntFIoPcEp + | | |-EtherSwitchIntFIo + | | | |-EquipmentXcvr + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-FaultInst + | | | |-PortDomainEp + | | |-EtherSwitchIntFIoPc + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherSwitchIntFIoPcEp + | | | |-FaultInst + | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-PortSubGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EquipmentSiocTempStats + | | |-EquipmentSiocTempStatsHist + | |-EquipmentSystemIOControllerFsm + | | |-EquipmentSystemIOControllerFsmStage + | |-EquipmentSystemIOControllerFsmTask + | |-EventInst + | |-FaultInst + | |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-EventInst + |-FabricLocale + | |-AdaptorExtEthIfPc + | | |-AdaptorExtEthIfPcEp + | | |-DcxVIf + | | |-FaultInst + | |-DcxVc + | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-FabricSanGroupRef + | | | |-FaultInst + | | |-FaultInst + | | |-SwCmclan + | | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-SwNetflowMonitorRef + | | |-SwUlan + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVsan + | | |-SwFcZoneSet + | | |-SwFcServerZoneGroup + | | | |-SwZoneInitiatorMember + | | | |-SwFcZone + | | | |-SwZoneTargetMember + | | |-SwFcUserZoneGroup + | | |-SwFcUserZone + | | |-SwFcEndpoint + | |-FabricPath + | |-DcxVc + | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-FabricSanGroupRef + | | | |-FaultInst + | | |-FaultInst + | | |-SwCmclan + | | | |-FabricNetGroupRef + | | | |-FaultInst + | | |-SwNetflowMonitorRef + | | |-SwUlan + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVsan + | | |-SwFcZoneSet + | | |-SwFcServerZoneGroup + | | | |-SwZoneInitiatorMember + | | | |-SwFcZone + | | | |-SwZoneTargetMember + | | |-SwFcUserZoneGroup + | | |-SwFcUserZone + | | |-SwFcEndpoint + | |-FabricPathConn + | | |-FabricPathEp + | | |-PortTrustMode + | |-FabricPathEp + | |-PortTrustMode + |-FaultInst + |-FaultSuppressTask + | |-FaultInst + | |-TrigLocalSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-FirmwareActivity + |-FirmwareActivityTrigger + |-FirmwareImageLock + |-FirmwareStatus + | |-FaultInst + |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-PowerBudget + | |-FaultInst + | |-PowerProfiledPower + |-SesEnclosure + | |-SesDiskSlotEp + |-StorageController + | |-EquipmentInventoryStatus + | | |-FaultInst + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-LstorageControllerDef + | | |-LstorageControllerModeConfig + | | |-LstorageControllerQualifier + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-StorageDrive + | |-StorageEmbeddedStorage + | |-StorageEnclosure + | | |-EventInst + | | |-FaultInst + | | |-StorageEnclosureDiskSlotEp + | | | |-FaultInst + | | | |-StorageControllerRef + | | |-StorageEnclosureFsm + | | | |-StorageEnclosureFsmStage + | | |-StorageEnclosureFsmTask + | | |-StorageHddMotherBoardTempStats + | | | |-StorageHddMotherBoardTempStatsHist + | | |-StorageLocalDisk + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageControllerEp + | | |-StorageDiskEnvStats + | | | |-StorageDiskEnvStatsHist + | | |-StorageLocalDiskFsm + | | | |-StorageLocalDiskFsmStage + | | |-StorageLocalDiskFsmTask + | | |-StorageLocalDiskPartition + | | |-StorageOperation + | | |-StorageSasPort + | | |-StorageSsdHealthStats + | | |-StorageSsdHealthStatsHist + | |-StorageLocalDisk + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageControllerEp + | | |-StorageDiskEnvStats + | | | |-StorageDiskEnvStatsHist + | | |-StorageLocalDiskFsm + | | | |-StorageLocalDiskFsmStage + | | |-StorageLocalDiskFsmTask + | | |-StorageLocalDiskPartition + | | |-StorageOperation + | | |-StorageSasPort + | | |-StorageSsdHealthStats + | | |-StorageSsdHealthStatsHist + | |-StorageLocalDiskConfigDef + | | |-LstorageSecurity + | | | |-LstorageDriveSecurity + | | | |-LstorageLocal + | | | |-LstorageRemote + | | | |-LstorageLogin + | | |-StorageLocalDiskPartition + | |-StorageLocalDiskEp + | |-StorageLocalLun + | |-StorageMezzFlashLife + | | |-FaultInst + | |-StorageNvmeStats + | | |-StorageNvmeStatsHist + | |-StorageNvmeStorage + | |-StorageOnboardDevice + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-StorageOperation + | |-StorageRaidBattery + | | |-FaultInst + | | |-StorageOperation + | | |-StorageTransportableFlashModule + | |-StorageVirtualDrive + | | |-FaultInst + | | |-StorageControllerEp + | | |-StorageLunDisk + | | |-StorageOperation + | | |-StorageScsiLunRef + | | |-StorageVDMemberEp + | | |-FaultInst + | |-StorageVirtualDriveEp + |-StorageEnclosure + | |-EventInst + | |-FaultInst + | |-StorageEnclosureDiskSlotEp + | | |-FaultInst + | | |-StorageControllerRef + | |-StorageEnclosureFsm + | | |-StorageEnclosureFsmStage + | |-StorageEnclosureFsmTask + | |-StorageHddMotherBoardTempStats + | | |-StorageHddMotherBoardTempStatsHist + | |-StorageLocalDisk + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EventInst + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-StorageControllerEp + | |-StorageDiskEnvStats + | | |-StorageDiskEnvStatsHist + | |-StorageLocalDiskFsm + | | |-StorageLocalDiskFsmStage + | |-StorageLocalDiskFsmTask + | |-StorageLocalDiskPartition + | |-StorageOperation + | |-StorageSasPort + | |-StorageSsdHealthStats + | |-StorageSsdHealthStatsHist + |-StorageSasExpander + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-StorageOnboardDevice + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-StorageSasUpLink + |-StorageVirtualDriveContainer + | |-StorageVirtualDrive + | |-FaultInst + | |-StorageControllerEp + | |-StorageLunDisk + | |-StorageOperation + | |-StorageScsiLunRef + | |-StorageVDMemberEp + | |-FaultInst + |-VnicRackServerDiscoveryProfile + |-SwVlan + |-FabricNetflowIPv4Addr + |-FaultInst + +ClassId EquipmentChassis +------- ---------------- +xml_attribute :equipmentChassis +rn :chassis-[id] +min_version :1.0(1e) +access :InputOutput +access_privilege :['admin', 'pn-equipment', 'pn-maintenance', 'pn-policy'] +parents :['topSystem'] +children :['computeBlade', 'computeBoardController', 'computeCartridge', 'computePsuControl', 'equipmentBeaconLed', 'equipmentChassisFsm', 'equipmentChassisFsmTask', 'equipmentChassisStats', 'equipmentComputeConn', 'equipmentFanModule', 'equipmentHealthLed', 'equipmentIOCard', 'equipmentIndicatorLed', 'equipmentLocatorLed', 'equipmentPoolable', 'equipmentPsu', 'equipmentSharedIOModule', 'equipmentSwitchIOCard', 'equipmentSystemIOController', 'eventInst', 'fabricLocale', 'faultInst', 'faultSuppressTask', 'firmwareActivity', 'firmwareActivityTrigger', 'firmwareImageLock', 'firmwareStatus', 'mgmtController', 'powerBudget', 'sesEnclosure', 'storageController', 'storageEnclosure', 'storageSasExpander', 'storageVirtualDriveContainer', 'vnicRackServerDiscoveryProfile'] + +Property ack_progress_indicator +-------- ---------------------- +xml_attribute :ackProgressIndicator +field_type :string +min_version :1.4(1i) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['ack-in-progress', 'ack-not-in-progress'] +range_val :[] + +Property admin_state +-------- ----------- +xml_attribute :adminState +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :None +value_set :['acknowledged', 'auto-acknowledge', 'decommission', 'disable-port-channel', 'enable-port-channel', 're-acknowledge', 'remove'] +range_val :[] + +Property asset_tag +-------- --------- +xml_attribute :assetTag +field_type :string +min_version :3.2(1d) +access :READ_ONLY +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,32} +value_set :[] +range_val :[] + +Property assigned_to_dn +-------- -------------- +xml_attribute :assignedToDn +field_type :string +min_version :3.1(2b) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property association +-------- ----------- +xml_attribute :association +field_type :string +min_version :3.1(2b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['associated', 'establishing', 'failed', 'none', 'removing', 'throttled'] +range_val :[] + +Property availability +-------- ------------ +xml_attribute :availability +field_type :string +min_version :3.1(2b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['available', 'unavailable'] +range_val :[] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property config_state +-------- ------------ +xml_attribute :configState +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['ack-in-progress', 'acknowledged', 'auto-ack', 'evaluation', 'ok', 'removing', 'un-acknowledged', 'un-initialized', 'unsupported-connectivity'] +range_val :[] + +Property conn_path +-------- --------- +xml_attribute :connPath +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|unknown|A|B),){0,3}(defaultValue|unknown|A|B){0,1} +value_set :[] +range_val :[] + +Property conn_status +-------- ----------- +xml_attribute :connStatus +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|unknown|A|B),){0,3}(defaultValue|unknown|A|B){0,1} +value_set :[] +range_val :[] + +Property discovery +-------- --------- +xml_attribute :discovery +field_type :string +min_version :3.1(2b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['complete', 'failed', 'fru-identity-indeterminate', 'fru-not-ready', 'fru-state-indeterminate', 'illegal-fru', 'in-progress', 'insufficiently-equipped', 'invalid-adaptor-iocard', 'malformed-fru-info', 'retry', 'throttled', 'undiscovered'] +range_val :[] + +Property discovery_status +-------- ---------------- +xml_attribute :discoveryStatus +field_type :string +min_version :2.5(1a) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|unknown|A|B),){0,3}(defaultValue|unknown|A|B){0,1} +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property fabric_ep_dn +-------- ------------ +xml_attribute :fabricEpDn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property fan_speed_config_state +-------- ---------------------- +xml_attribute :fanSpeedConfigState +field_type :string +min_version :4.1(1a) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['Balanced', 'Low Power'] +range_val :[] + +Property flt_aggr +-------- -------- +xml_attribute :fltAggr +field_type :ulong +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property fsm_descr +-------- --------- +xml_attribute :fsmDescr +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property fsm_flags +-------- --------- +xml_attribute :fsmFlags +field_type :string +min_version :2.5(1a) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :['0-4294967295'] + +Property fsm_prev +-------- -------- +xml_attribute :fsmPrev +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['AssociateActivateAdaptor', 'AssociateActivateBrdCtlr', 'AssociateActivateCmc', 'AssociateActivateLocalDisk', 'AssociateActivateSasExpander', 'AssociateActivateStorageCtlr', 'AssociateBegin', 'AssociateChassisPeerAdapterReboot', 'AssociateConfigChassisAdapterConnectivity', 'AssociateCopyRemote', 'AssociateDeleteCurlDownloadedImages', 'AssociateDeleteImagesRemote', 'AssociateDiskZoningConfig', 'AssociateDownloadImages', 'AssociateFail', 'AssociatePollAdaptorActivation', 'AssociatePollBrdCtlrActivation', 'AssociatePollCmcActivation', 'AssociatePollPostDiskZoneStorageInvCIMC', 'AssociatePollSasExpanderActivate', 'AssociatePollSasExpanderConfig', 'AssociatePollStorageCtlrActivation', 'AssociatePollUpdateAdaptor', 'AssociatePollUpdateCmc', 'AssociatePollUpdateSasExpander', 'AssociatePostDiskZoneStorageInvCIMC', 'AssociatePostDiskZoneStorageInvCMC', 'AssociatePowerOffServers', 'AssociatePowerOnServers', 'AssociateSasExpanderConfig', 'AssociateSuccess', 'AssociateUnlockFirmwareImage', 'AssociateUpdateAdaptor', 'AssociateUpdateCmc', 'AssociateUpdateSasExpander', 'AssociateWaitBeforeInstallation', 'AssociateWaitForPowerOff', 'ChassisUpgradeActivateAdaptor', 'ChassisUpgradeActivateBrdCtlr', 'ChassisUpgradeActivateCmc', 'ChassisUpgradeActivateLocalDisk', 'ChassisUpgradeActivateSasExpander', 'ChassisUpgradeActivateStorageCtlr', 'ChassisUpgradeBegin', 'ChassisUpgradeFail', 'ChassisUpgradePollAdaptorActivation', 'ChassisUpgradePollBrdCtlrActivation', 'ChassisUpgradePollCmcActivation', 'ChassisUpgradePollLocalDiskActivate', 'ChassisUpgradePollSasExpanderActivate', 'ChassisUpgradePollStorageCtlrActivation', 'ChassisUpgradePollUpdateStatus', 'ChassisUpgradePowerOffServers', 'ChassisUpgradePowerOnServers', 'ChassisUpgradeResetSasExpander', 'ChassisUpgradeSuccess', 'ChassisUpgradeUpdateRequest', 'ChassisUpgradeWaitForPowerOff', 'DisassociateBegin', 'DisassociateComplete', 'DisassociateFail', 'DisassociateSuccess', 'DynamicReallocationBegin', 'DynamicReallocationConfig', 'DynamicReallocationFail', 'DynamicReallocationSuccess', 'FanPolicyConfigBegin', 'FanPolicyConfigExecute', 'FanPolicyConfigFail', 'FanPolicyConfigSuccess', 'FwUpgradeBegin', 'FwUpgradeCopyRemote', 'FwUpgradeDeleteCurlDownloadedImages', 'FwUpgradeDeleteImagesRemote', 'FwUpgradeDownloadImages', 'FwUpgradeFail', 'FwUpgradePollUpdateAdaptor', 'FwUpgradePollUpdateCmc', 'FwUpgradePollUpdateSasExpander', 'FwUpgradeSuccess', 'FwUpgradeUnlockFirmwareImage', 'FwUpgradeUpdateAdaptor', 'FwUpgradeUpdateCmc', 'FwUpgradeUpdateSasExpander', 'FwUpgradeWaitBeforeInstallation', 'OobStorageAdminCfgBegin', 'OobStorageAdminCfgFail', 'OobStorageAdminCfgOobStorageConfig', 'OobStorageAdminCfgOobStorageInventory', 'OobStorageAdminCfgSuccess', 'PowerCapBegin', 'PowerCapConfig', 'PowerCapFail', 'PowerCapSuccess', 'PowerCapWait', 'PowerSavePolicyConfigBegin', 'PowerSavePolicyConfigExecute', 'PowerSavePolicyConfigFail', 'PowerSavePolicyConfigSuccess', 'PsuPolicyConfigBegin', 'PsuPolicyConfigExecute', 'PsuPolicyConfigFail', 'PsuPolicyConfigSuccess', 'RemoveChassisBegin', 'RemoveChassisCleanupVnicsLocal', 'RemoveChassisCleanupVnicsPeer', 'RemoveChassisDecomission', 'RemoveChassisDisableEndPoint', 'RemoveChassisFail', 'RemoveChassisSuccess', 'RemoveChassisUnIdentifyLocal', 'RemoveChassisUnIdentifyPeer', 'RemoveChassisWait', 'nop'] +range_val :[] + +Property fsm_progr +-------- --------- +xml_attribute :fsmProgr +field_type :byte +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :['0-100'] + +Property fsm_rmt_inv_err_code +-------- -------------------- +xml_attribute :fsmRmtInvErrCode +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['ERR-2fa-auth-retry', 'ERR-ACTIVATE-failed', 'ERR-ACTIVATE-in-progress', 'ERR-ACTIVATE-retry', 'ERR-BIOS-TOKENS-OLD-BIOS', 'ERR-BIOS-TOKENS-OLD-CIMC', 'ERR-BIOS-network-boot-order-not-found', 'ERR-BOARDCTRLUPDATE-ignore', 'ERR-DIAG-cancelled', 'ERR-DIAG-fsm-restarted', 'ERR-DIAG-test-failed', 'ERR-DNLD-authentication-failure', 'ERR-DNLD-hostkey-mismatch', 'ERR-DNLD-invalid-image', 'ERR-DNLD-no-file', 'ERR-DNLD-no-space', 'ERR-DNLD-usb-unmounted', 'ERR-DNS-delete-error', 'ERR-DNS-get-error', 'ERR-DNS-set-error', 'ERR-Diagnostics-in-progress', 'ERR-Diagnostics-memtest-in-progress', 'ERR-Diagnostics-network-in-progress', 'ERR-FILTER-illegal-format', 'ERR-FSM-no-such-state', 'ERR-HOST-fru-identity-mismatch', 'ERR-HTTP-set-error', 'ERR-HTTPS-set-error', 'ERR-IBMC-analyze-results', 'ERR-IBMC-connect-error', 'ERR-IBMC-connector-info-retrieval-error', 'ERR-IBMC-fru-retrieval-error', 'ERR-IBMC-invalid-end-point-config', 'ERR-IBMC-results-not-ready', 'ERR-MAX-subscriptions-allowed-error', 'ERR-MO-CONFIG-child-object-cant-be-configured', 'ERR-MO-META-no-such-object-class', 'ERR-MO-PROPERTY-no-such-property', 'ERR-MO-PROPERTY-value-out-of-range', 'ERR-MO-access-denied', 'ERR-MO-deletion-rule-violation', 'ERR-MO-duplicate-object', 'ERR-MO-illegal-containment', 'ERR-MO-illegal-creation', 'ERR-MO-illegal-iterator-state', 'ERR-MO-illegal-object-lifecycle-transition', 'ERR-MO-naming-rule-violation', 'ERR-MO-object-not-found', 'ERR-MO-resource-allocation', 'ERR-NTP-delete-error', 'ERR-NTP-get-error', 'ERR-NTP-set-error', 'ERR-POWER-CAP-UNSUPPORTED', 'ERR-POWER-PROFILE-IN-PROGRESS', 'ERR-SERVER-mis-connect', 'ERR-SWITCH-invalid-if-config', 'ERR-TOKEN-request-denied', 'ERR-UNABLE-TO-FETCH-BIOS-SETTINGS', 'ERR-UPDATE-failed', 'ERR-UPDATE-in-progress', 'ERR-UPDATE-retry', 'ERR-aaa-config-modify-error', 'ERR-acct-realm-set-error', 'ERR-admin-passwd-set', 'ERR-auth-issue', 'ERR-auth-realm-get-error', 'ERR-auth-realm-set-error', 'ERR-authentication', 'ERR-authorization-required', 'ERR-cli-session-limit-reached', 'ERR-create-keyring', 'ERR-create-locale', 'ERR-create-role', 'ERR-create-tp', 'ERR-create-user', 'ERR-delete-locale', 'ERR-delete-role', 'ERR-delete-session', 'ERR-delete-user', 'ERR-downgrade-fail', 'ERR-efi-Diagnostics--in-progress', 'ERR-enable-mgmt-conn', 'ERR-ep-set-error', 'ERR-get-max-http-user-sessions', 'ERR-http-initializing', 'ERR-insufficiently-equipped', 'ERR-internal-error', 'ERR-ldap-delete-error', 'ERR-ldap-get-error', 'ERR-ldap-group-modify-error', 'ERR-ldap-group-set-error', 'ERR-ldap-set-error', 'ERR-locale-set-error', 'ERR-max-userid-sessions-reached', 'ERR-missing-method', 'ERR-modify-locale', 'ERR-modify-role', 'ERR-modify-user', 'ERR-modify-user-locale', 'ERR-modify-user-role', 'ERR-provider-group-modify-error', 'ERR-provider-group-set-error', 'ERR-radius-get-error', 'ERR-radius-global-set-error', 'ERR-radius-group-set-error', 'ERR-radius-set-error', 'ERR-request-timeout', 'ERR-reset-adapter', 'ERR-role-set-error', 'ERR-secondary-node', 'ERR-service-not-ready', 'ERR-session-cache-full', 'ERR-session-not-found', 'ERR-set-key-cert', 'ERR-set-login-profile', 'ERR-set-min-passphrase-length', 'ERR-set-network', 'ERR-set-password-strength-check', 'ERR-set-port-channel', 'ERR-store-pre-login-banner-msg', 'ERR-tacacs-enable-error', 'ERR-tacacs-global-set-error', 'ERR-tacacs-group-set-error', 'ERR-tacacs-plus-get-error', 'ERR-tacacs-set-error', 'ERR-test-error-1', 'ERR-test-error-2', 'ERR-timezone-set-error', 'ERR-user-account-expired', 'ERR-user-passwd-expired', 'ERR-user-set-error', 'ERR-xml-parse-error', 'none'] +range_val :['0-4294967295'] + +Property fsm_rmt_inv_err_descr +-------- --------------------- +xml_attribute :fsmRmtInvErrDescr +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property fsm_rmt_inv_rslt +-------- ---------------- +xml_attribute :fsmRmtInvRslt +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :((defaultValue|not-applicable|resource-unavailable|service-unavailable|intermittent-error|sw-defect|service-not-implemented-ignore|extend-timeout|capability-not-implemented-failure|illegal-fru|end-point-unavailable|failure|resource-capacity-exceeded|service-protocol-error|fw-defect|service-not-implemented-fail|task-reset|unidentified-fail|capability-not-supported|end-point-failed|fru-state-indeterminate|resource-dependency|fru-identity-indeterminate|internal-error|hw-defect|service-not-supported|fru-not-supported|end-point-protocol-error|capability-unavailable|fru-not-ready|capability-not-implemented-ignore|fru-info-malformed|timeout),){0,32}(defaultValue|not-applicable|resource-unavailable|service-unavailable|intermittent-error|sw-defect|service-not-implemented-ignore|extend-timeout|capability-not-implemented-failure|illegal-fru|end-point-unavailable|failure|resource-capacity-exceeded|service-protocol-error|fw-defect|service-not-implemented-fail|task-reset|unidentified-fail|capability-not-supported|end-point-failed|fru-state-indeterminate|resource-dependency|fru-identity-indeterminate|internal-error|hw-defect|service-not-supported|fru-not-supported|end-point-protocol-error|capability-unavailable|fru-not-ready|capability-not-implemented-ignore|fru-info-malformed|timeout){0,1} +value_set :[] +range_val :[] + +Property fsm_stage_descr +-------- --------------- +xml_attribute :fsmStageDescr +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property fsm_stamp +-------- --------- +xml_attribute :fsmStamp +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :['never'] +range_val :[] + +Property fsm_status +-------- ---------- +xml_attribute :fsmStatus +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :['AssociateActivateAdaptor', 'AssociateActivateBrdCtlr', 'AssociateActivateCmc', 'AssociateActivateLocalDisk', 'AssociateActivateSasExpander', 'AssociateActivateStorageCtlr', 'AssociateBegin', 'AssociateChassisPeerAdapterReboot', 'AssociateConfigChassisAdapterConnectivity', 'AssociateCopyRemote', 'AssociateDeleteCurlDownloadedImages', 'AssociateDeleteImagesRemote', 'AssociateDiskZoningConfig', 'AssociateDownloadImages', 'AssociateFail', 'AssociatePollAdaptorActivation', 'AssociatePollBrdCtlrActivation', 'AssociatePollCmcActivation', 'AssociatePollPostDiskZoneStorageInvCIMC', 'AssociatePollSasExpanderActivate', 'AssociatePollSasExpanderConfig', 'AssociatePollStorageCtlrActivation', 'AssociatePollUpdateAdaptor', 'AssociatePollUpdateCmc', 'AssociatePollUpdateSasExpander', 'AssociatePostDiskZoneStorageInvCIMC', 'AssociatePostDiskZoneStorageInvCMC', 'AssociatePowerOffServers', 'AssociatePowerOnServers', 'AssociateSasExpanderConfig', 'AssociateSuccess', 'AssociateUnlockFirmwareImage', 'AssociateUpdateAdaptor', 'AssociateUpdateCmc', 'AssociateUpdateSasExpander', 'AssociateWaitBeforeInstallation', 'AssociateWaitForPowerOff', 'ChassisUpgradeActivateAdaptor', 'ChassisUpgradeActivateBrdCtlr', 'ChassisUpgradeActivateCmc', 'ChassisUpgradeActivateLocalDisk', 'ChassisUpgradeActivateSasExpander', 'ChassisUpgradeActivateStorageCtlr', 'ChassisUpgradeBegin', 'ChassisUpgradeFail', 'ChassisUpgradePollAdaptorActivation', 'ChassisUpgradePollBrdCtlrActivation', 'ChassisUpgradePollCmcActivation', 'ChassisUpgradePollLocalDiskActivate', 'ChassisUpgradePollSasExpanderActivate', 'ChassisUpgradePollStorageCtlrActivation', 'ChassisUpgradePollUpdateStatus', 'ChassisUpgradePowerOffServers', 'ChassisUpgradePowerOnServers', 'ChassisUpgradeResetSasExpander', 'ChassisUpgradeSuccess', 'ChassisUpgradeUpdateRequest', 'ChassisUpgradeWaitForPowerOff', 'DisassociateBegin', 'DisassociateComplete', 'DisassociateFail', 'DisassociateSuccess', 'DynamicReallocationBegin', 'DynamicReallocationConfig', 'DynamicReallocationFail', 'DynamicReallocationSuccess', 'FanPolicyConfigBegin', 'FanPolicyConfigExecute', 'FanPolicyConfigFail', 'FanPolicyConfigSuccess', 'FwUpgradeBegin', 'FwUpgradeCopyRemote', 'FwUpgradeDeleteCurlDownloadedImages', 'FwUpgradeDeleteImagesRemote', 'FwUpgradeDownloadImages', 'FwUpgradeFail', 'FwUpgradePollUpdateAdaptor', 'FwUpgradePollUpdateCmc', 'FwUpgradePollUpdateSasExpander', 'FwUpgradeSuccess', 'FwUpgradeUnlockFirmwareImage', 'FwUpgradeUpdateAdaptor', 'FwUpgradeUpdateCmc', 'FwUpgradeUpdateSasExpander', 'FwUpgradeWaitBeforeInstallation', 'OobStorageAdminCfgBegin', 'OobStorageAdminCfgFail', 'OobStorageAdminCfgOobStorageConfig', 'OobStorageAdminCfgOobStorageInventory', 'OobStorageAdminCfgSuccess', 'PowerCapBegin', 'PowerCapConfig', 'PowerCapFail', 'PowerCapSuccess', 'PowerCapWait', 'PowerSavePolicyConfigBegin', 'PowerSavePolicyConfigExecute', 'PowerSavePolicyConfigFail', 'PowerSavePolicyConfigSuccess', 'PsuPolicyConfigBegin', 'PsuPolicyConfigExecute', 'PsuPolicyConfigFail', 'PsuPolicyConfigSuccess', 'RemoveChassisBegin', 'RemoveChassisCleanupVnicsLocal', 'RemoveChassisCleanupVnicsPeer', 'RemoveChassisDecomission', 'RemoveChassisDisableEndPoint', 'RemoveChassisFail', 'RemoveChassisSuccess', 'RemoveChassisUnIdentifyLocal', 'RemoveChassisUnIdentifyPeer', 'RemoveChassisWait', 'nop'] +range_val :[] + +Property fsm_try +-------- ------- +xml_attribute :fsmTry +field_type :byte +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property id +-------- -- +xml_attribute :id +field_type :uint +min_version :1.0(1e) +access :NAMING +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :['1-255'] + +Property lc_ts +-------- ----- +xml_attribute :lcTs +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property lic_gp +-------- ------ +xml_attribute :licGP +field_type :ulong +min_version :1.4(1i) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property lic_state +-------- --------- +xml_attribute :licState +field_type :string +min_version :1.0(2d) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['license-expired', 'license-graceperiod', 'license-insufficient', 'license-ok', 'not-applicable', 'unknown'] +range_val :[] + +Property managing_inst +-------- ------------- +xml_attribute :managingInst +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['A', 'B', 'NONE'] +range_val :[] + +Property mfg_time +-------- -------- +xml_attribute :mfgTime +field_type :string +min_version :2.0(1m) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :['not-applicable'] +range_val :[] + +Property model +-------- ----- +xml_attribute :model +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property oper_qualifier +-------- -------------- +xml_attribute :operQualifier +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :((defaultValue|not-applicable|psu-voltage|iocard-voltage|fabric-unsupported-conn|chassis-post-failure|fan-power|compute-power|fan-inoperable|compute-inoperable|chassis-power|chassis-unsupported|chassis-thermal|psu-perf|iocard-perf|chassis-limit-exceeded|psu-thermal|iocard-thermal|iocard-inaccessible|chassis-inoperable|fan-voltage|removed|compute-voltage|backplane-port-problem|psu-power|iocard-power|chassis-vif-capacity-reduced|chassis-voltage|psu-inoperable|iocard-inoperable|fabric-conn-problem|config|fan-perf|compute-perf|fan-thermal|compute-thermal|chassis-port-channel-enabled|chassis-perf),){0,37}(defaultValue|not-applicable|psu-voltage|iocard-voltage|fabric-unsupported-conn|chassis-post-failure|fan-power|compute-power|fan-inoperable|compute-inoperable|chassis-power|chassis-unsupported|chassis-thermal|psu-perf|iocard-perf|chassis-limit-exceeded|psu-thermal|iocard-thermal|iocard-inaccessible|chassis-inoperable|fan-voltage|removed|compute-voltage|backplane-port-problem|psu-power|iocard-power|chassis-vif-capacity-reduced|chassis-voltage|psu-inoperable|iocard-inoperable|fabric-conn-problem|config|fan-perf|compute-perf|fan-thermal|compute-thermal|chassis-port-channel-enabled|chassis-perf){0,1} +value_set :[] +range_val :[] + +Property oper_qualifier_reason +-------- --------------------- +xml_attribute :operQualifierReason +field_type :string +min_version :2.1(1a) +access :READ_ONLY +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,256} +value_set :[] +range_val :[] + +Property oper_state +-------- ---------- +xml_attribute :operState +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['accessibility-problem', 'auto-upgrade', 'backplane-port-problem', 'bios-post-timeout', 'chassis-intrusion', 'chassis-limit-exceeded', 'config', 'decomissioning', 'degraded', 'dimm-disabled', 'disabled', 'discovery', 'discovery-failed', 'equipment-problem', 'fabric-conn-problem', 'fabric-unsupported-conn', 'identify', 'identity-unestablishable', 'inoperable', 'link-activate-blocked', 'malformed-fru', 'non-optimal', 'non-optimal-severe', 'not-supported', 'operable', 'peer-comm-problem', 'peer-dimm-disabled', 'performance-problem', 'post-failure', 'power-problem', 'powered-off', 'removed', 'thermal-problem', 'unknown', 'unsupported-config', 'upgrade-problem', 'voltage-problem'] +range_val :[] + +Property operability +-------- ----------- +xml_attribute :operability +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['accessibility-problem', 'auto-upgrade', 'backplane-port-problem', 'bios-post-timeout', 'chassis-intrusion', 'chassis-limit-exceeded', 'config', 'decomissioning', 'degraded', 'dimm-disabled', 'disabled', 'discovery', 'discovery-failed', 'equipment-problem', 'fabric-conn-problem', 'fabric-unsupported-conn', 'identify', 'identity-unestablishable', 'inoperable', 'link-activate-blocked', 'malformed-fru', 'non-optimal', 'non-optimal-severe', 'not-supported', 'operable', 'peer-comm-problem', 'peer-dimm-disabled', 'performance-problem', 'post-failure', 'power-problem', 'powered-off', 'removed', 'thermal-problem', 'unknown', 'unsupported-config', 'upgrade-problem', 'voltage-problem'] +range_val :[] + +Property part_number +-------- ----------- +xml_attribute :partNumber +field_type :string +min_version :2.1(3a) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property power +-------- ----- +xml_attribute :power +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['failed', 'input-degraded', 'input-failed', 'ok', 'output-degraded', 'output-failed', 'redundancy-degraded', 'redundancy-failed', 'unknown'] +range_val :[] + +Property presence +-------- -------- +xml_attribute :presence +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['empty', 'equipped', 'equipped-deprecated', 'equipped-disc-error', 'equipped-disc-in-progress', 'equipped-disc-not-started', 'equipped-disc-unknown', 'equipped-identity-unestablishable', 'equipped-not-primary', 'equipped-slave', 'equipped-unsupported', 'equipped-with-malformed-fru', 'inaccessible', 'mismatch', 'mismatch-identity-unestablishable', 'mismatch-slave', 'missing', 'missing-slave', 'not-supported', 'unauthorized', 'unknown'] +range_val :[] + +Property revision +-------- -------- +xml_attribute :revision +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property seeprom_oper_state +-------- ------------------ +xml_attribute :seepromOperState +field_type :string +min_version :1.4(1i) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['accessibility-problem', 'auto-upgrade', 'backplane-port-problem', 'bios-post-timeout', 'chassis-intrusion', 'chassis-limit-exceeded', 'config', 'decomissioning', 'degraded', 'dimm-disabled', 'disabled', 'discovery', 'discovery-failed', 'equipment-problem', 'fabric-conn-problem', 'fabric-unsupported-conn', 'identify', 'identity-unestablishable', 'inoperable', 'link-activate-blocked', 'malformed-fru', 'non-optimal', 'non-optimal-severe', 'not-supported', 'operable', 'peer-comm-problem', 'peer-dimm-disabled', 'performance-problem', 'post-failure', 'power-problem', 'powered-off', 'removed', 'thermal-problem', 'unknown', 'unsupported-config', 'upgrade-problem', 'voltage-problem'] +range_val :[] + +Property serial +-------- ------ +xml_attribute :serial +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property service_state +-------- ------------- +xml_attribute :serviceState +field_type :string +min_version :3.1(2b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['in-maintenance', 'in-service', 'out-of-service'] +range_val :[] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property thermal +-------- ------- +xml_attribute :thermal +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['lower-critical', 'lower-non-critical', 'lower-non-recoverable', 'not-supported', 'ok', 'unknown', 'upper-critical', 'upper-non-critical', 'upper-non-recoverable'] +range_val :[] + +Property thermal_state_qualifier +-------- ----------------------- +xml_attribute :thermalStateQualifier +field_type :string +min_version :2.0(1m) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property usr_lbl +-------- ------- +xml_attribute :usrLbl +field_type :string +min_version :1.4(1i) +access :READ_WRITE +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,32} +value_set :[] +range_val :[] + +Property vendor +-------- ------ +xml_attribute :vendor +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property version_holder +-------- -------------- +xml_attribute :versionHolder +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['false', 'no', 'true', 'yes'] +range_val :[] + +Property vid +-------- --- +xml_attribute :vid +field_type :string +min_version :2.1(3a) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] +``` \ No newline at end of file diff --git a/lib/ucsm/mo/EquipmentChassisStats.md b/lib/ucsm/mo/EquipmentChassisStats.md new file mode 100644 index 00000000..bcecea81 --- /dev/null +++ b/lib/ucsm/mo/EquipmentChassisStats.md @@ -0,0 +1,833 @@ +# EquipmentChassisStats + +## Managed Object + +``` +Managed Object : EquipmentChassisStats +-------------- +class_id :EquipmentChassisStats +chassis_i2_c_errors :0 +chassis_i2_c_errors_avg :0 +chassis_i2_c_errors_max :0 +chassis_i2_c_errors_min :0 +child_action :None +dn :sys/chassis-1/stats +input_power :1128.000000 +input_power_avg :1128.000000 +input_power_max :1152.000000 +input_power_min :1104.000000 +intervals :58982460 +output_power :851.000000 +output_power_avg :852.533386 +output_power_max :920.000000 +output_power_min :782.000000 +rn :stats +sacl :None +status :None +suspect :no +thresholded : +time_collected :2022-12-02T09:10:56.165 +update :131072 +``` + +## Properties + +``` +[2022-12-02 09:11:21.201192] [debug_object] [ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "attr_get", + "attr_set", + "chassis_i2_c_errors", + "chassis_i2_c_errors_avg", + "chassis_i2_c_errors_max", + "chassis_i2_c_errors_min", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "consts", + "dirty_mask", + "dn", + "elem_create", + "from_xml", + "get_class_id", + "get_handle", + "input_power", + "input_power_avg", + "input_power_max", + "input_power_min", + "intervals", + "is_dirty", + "make_rn", + "mark_clean", + "mark_dirty", + "mo_meta", + "naming_props", + "output_power", + "output_power_avg", + "output_power_max", + "output_power_min", + "parent_mo", + "prop_map", + "prop_meta", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "status", + "suspect", + "sync_mo", + "thresholded", + "time_collected", + "to_xml", + "update", + "write_object" +] +``` + +## Meta + +``` +[2022-12-02 09:11:21.202198] [debug_object] [EquipmentChassis] + |-EquipmentChassisStats + |-EquipmentChassisStatsHist + +ClassId EquipmentChassisStats +------- --------------------- +xml_attribute :equipmentChassisStats +rn :stats +min_version :1.1(1j) +access :OutputOnly +access_privilege :['admin', 'operations', 'read-only'] +parents :['equipmentChassis'] +children :['equipmentChassisStatsHist'] + +Property chassis_i2_c_errors +-------- ------------------- +xml_attribute :ChassisI2CErrors +field_type :ulong +min_version :2.2(6c) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_i2_c_errors_avg +-------- ----------------------- +xml_attribute :ChassisI2CErrorsAvg +field_type :ulong +min_version :2.2(7b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_i2_c_errors_max +-------- ----------------------- +xml_attribute :ChassisI2CErrorsMax +field_type :ulong +min_version :2.2(7b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_i2_c_errors_min +-------- ----------------------- +xml_attribute :ChassisI2CErrorsMin +field_type :ulong +min_version :2.2(7b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.1(1j) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property input_power +-------- ----------- +xml_attribute :inputPower +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_power_avg +-------- --------------- +xml_attribute :inputPowerAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_power_max +-------- --------------- +xml_attribute :inputPowerMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_power_min +-------- --------------- +xml_attribute :inputPowerMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property intervals +-------- --------- +xml_attribute :intervals +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power +-------- ------------ +xml_attribute :outputPower +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power_avg +-------- ---------------- +xml_attribute :outputPowerAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power_max +-------- ---------------- +xml_attribute :outputPowerMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power_min +-------- ---------------- +xml_attribute :outputPowerMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.1(1j) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property suspect +-------- ------- +xml_attribute :suspect +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['false', 'no', 'true', 'yes'] +range_val :[] + +Property thresholded +-------- ----------- +xml_attribute :thresholded +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property time_collected +-------- -------------- +xml_attribute :timeCollected +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property update +-------- ------ +xml_attribute :update +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +[2022-12-02 09:11:21.203187] [debug_object] +Managed Object : EquipmentChassisStats +-------------- +class_id :EquipmentChassisStats +chassis_i2_c_errors :0 +chassis_i2_c_errors_avg :0 +chassis_i2_c_errors_max :0 +chassis_i2_c_errors_min :0 +child_action :None +dn :sys/chassis-2/stats +input_power :1416.000000 +input_power_avg :1425.230713 +input_power_max :1488.000000 +input_power_min :1392.000000 +intervals :58982460 +output_power :1058.000000 +output_power_avg :1240.230835 +output_power_max :1472.000000 +output_power_min :1058.000000 +rn :stats +sacl :None +status :None +suspect :no +thresholded : +time_collected :2022-12-02T09:10:59.170 +update :65549 + + +[2022-12-02 09:11:21.204186] [debug_object] [ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "attr_get", + "attr_set", + "chassis_i2_c_errors", + "chassis_i2_c_errors_avg", + "chassis_i2_c_errors_max", + "chassis_i2_c_errors_min", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "consts", + "dirty_mask", + "dn", + "elem_create", + "from_xml", + "get_class_id", + "get_handle", + "input_power", + "input_power_avg", + "input_power_max", + "input_power_min", + "intervals", + "is_dirty", + "make_rn", + "mark_clean", + "mark_dirty", + "mo_meta", + "naming_props", + "output_power", + "output_power_avg", + "output_power_max", + "output_power_min", + "parent_mo", + "prop_map", + "prop_meta", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "status", + "suspect", + "sync_mo", + "thresholded", + "time_collected", + "to_xml", + "update", + "write_object" +] +[2022-12-02 09:11:21.205183] [debug_object] [EquipmentChassis] + |-EquipmentChassisStats + |-EquipmentChassisStatsHist + +ClassId EquipmentChassisStats +------- --------------------- +xml_attribute :equipmentChassisStats +rn :stats +min_version :1.1(1j) +access :OutputOnly +access_privilege :['admin', 'operations', 'read-only'] +parents :['equipmentChassis'] +children :['equipmentChassisStatsHist'] + +Property chassis_i2_c_errors +-------- ------------------- +xml_attribute :ChassisI2CErrors +field_type :ulong +min_version :2.2(6c) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_i2_c_errors_avg +-------- ----------------------- +xml_attribute :ChassisI2CErrorsAvg +field_type :ulong +min_version :2.2(7b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_i2_c_errors_max +-------- ----------------------- +xml_attribute :ChassisI2CErrorsMax +field_type :ulong +min_version :2.2(7b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property chassis_i2_c_errors_min +-------- ----------------------- +xml_attribute :ChassisI2CErrorsMin +field_type :ulong +min_version :2.2(7b) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.1(1j) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property input_power +-------- ----------- +xml_attribute :inputPower +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_power_avg +-------- --------------- +xml_attribute :inputPowerAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_power_max +-------- --------------- +xml_attribute :inputPowerMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property input_power_min +-------- --------------- +xml_attribute :inputPowerMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property intervals +-------- --------- +xml_attribute :intervals +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power +-------- ------------ +xml_attribute :outputPower +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power_avg +-------- ---------------- +xml_attribute :outputPowerAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power_max +-------- ---------------- +xml_attribute :outputPowerMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property output_power_min +-------- ---------------- +xml_attribute :outputPowerMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.1(1j) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property suspect +-------- ------- +xml_attribute :suspect +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['false', 'no', 'true', 'yes'] +range_val :[] + +Property thresholded +-------- ----------- +xml_attribute :thresholded +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property time_collected +-------- -------------- +xml_attribute :timeCollected +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property update +-------- ------ +xml_attribute :update +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +``` diff --git a/lib/ucsm/mo/EquipmentPsuInputStats.md b/lib/ucsm/mo/EquipmentPsuInputStats.md new file mode 100644 index 00000000..02015211 --- /dev/null +++ b/lib/ucsm/mo/EquipmentPsuInputStats.md @@ -0,0 +1,436 @@ +# EquipmentPsuInputStats + +## Managed Object + +``` +Managed Object : EquipmentPsuInputStats +-------------- +class_id :EquipmentPsuInputStats +child_action :None +current :0.421875 +current_avg :0.423438 +current_max :0.429688 +current_min :0.421875 +dn :sys/switch-A/psu-2/input-stats +input_status :ok +intervals :58982460 +power :95.765625 +power_avg :96.310173 +power_max :97.754021 +power_min :95.765625 +rn :input-stats +sacl :None +status :None +suspect :no +thresholded : +time_collected :2022-12-01T19:53:23.943 +update :131082 +voltage :227.000000 +voltage_avg :227.449997 +voltage_max :228.500000 +voltage_min :226.500000 +``` + +## Properties + +``` +[2022-12-01 19:53:41.317507] [debug_object] [ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "attr_get", + "attr_set", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "consts", + "current", + "current_avg", + "current_max", + "current_min", + "dirty_mask", + "dn", + "elem_create", + "from_xml", + "get_class_id", + "get_handle", + "input_status", + "intervals", + "is_dirty", + "make_rn", + "mark_clean", + "mark_dirty", + "mo_meta", + "naming_props", + "parent_mo", + "power", + "power_avg", + "power_max", + "power_min", + "prop_map", + "prop_meta", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "status", + "suspect", + "sync_mo", + "thresholded", + "time_collected", + "to_xml", + "update", + "voltage", + "voltage_avg", + "voltage_max", + "voltage_min", + "write_object" +] +``` + +## Meta + +``` +[2022-12-01 19:53:41.319501] [debug_object] [EquipmentPsu] + |-EquipmentPsuInputStats + |-EquipmentPsuInputStatsHist + +ClassId EquipmentPsuInputStats +------- ---------------------- +xml_attribute :equipmentPsuInputStats +rn :input-stats +min_version :1.1(1j) +access :OutputOnly +access_privilege :['admin', 'operations', 'read-only'] +parents :['equipmentPsu'] +children :['equipmentPsuInputStatsHist'] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.1(1j) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property current +-------- ------- +xml_attribute :current +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property current_avg +-------- ----------- +xml_attribute :currentAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property current_max +-------- ----------- +xml_attribute :currentMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property current_min +-------- ----------- +xml_attribute :currentMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property input_status +-------- ------------ +xml_attribute :inputStatus +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :510 +pattern :None +value_set :[] +range_val :[] + +Property intervals +-------- --------- +xml_attribute :intervals +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property power +-------- ----- +xml_attribute :power +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property power_avg +-------- --------- +xml_attribute :powerAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property power_max +-------- --------- +xml_attribute :powerMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property power_min +-------- --------- +xml_attribute :powerMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.1(1j) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property suspect +-------- ------- +xml_attribute :suspect +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['false', 'no', 'true', 'yes'] +range_val :[] + +Property thresholded +-------- ----------- +xml_attribute :thresholded +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property time_collected +-------- -------------- +xml_attribute :timeCollected +field_type :string +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property update +-------- ------ +xml_attribute :update +field_type :uint +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property voltage +-------- ------- +xml_attribute :voltage +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property voltage_avg +-------- ----------- +xml_attribute :voltageAvg +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property voltage_max +-------- ----------- +xml_attribute :voltageMax +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] + +Property voltage_min +-------- ----------- +xml_attribute :voltageMin +field_type :float +min_version :1.1(1j) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :[] +range_val :[] +``` \ No newline at end of file diff --git a/lib/ucsm/mo/sys.md b/lib/ucsm/mo/sys.md new file mode 100644 index 00000000..5bbab5dd --- /dev/null +++ b/lib/ucsm/mo/sys.md @@ -0,0 +1,14200 @@ +# sys + +## Managed Object + +``` +Managed Object : TopSystem +-------------- +class_id :TopSystem +address : +child_action :None +current_time :2022-12-01T08:54:55.332 +descr : +dn :sys +ipv6_addr ::: +mode :cluster +name :FI-ucsb1-eu-spdc +owner : +rn :sys +sacl :None +site : +status :None +system_up_time :141:11:18:06 +``` + +## Properties + +``` +[ + "DUMMY_DIRTY", + "_ManagedObject__internal_prop", + "_ManagedObject__parent_dn", + "_ManagedObject__parent_mo", + "_ManagedObject__set_prop", + "_ManagedObject__status", + "_ManagedObject__xtra_props", + "_ManagedObject__xtra_props_dirty_mask", + "__class__", + "__deepcopy__", + "__delattr__", + "__dict__", + "__dir__", + "__doc__", + "__eq__", + "__format__", + "__ge__", + "__getattribute__", + "__gt__", + "__hash__", + "__init__", + "__init_subclass__", + "__json__", + "__le__", + "__lt__", + "__module__", + "__ne__", + "__new__", + "__reduce__", + "__reduce_ex__", + "__repr__", + "__setattr__", + "__sizeof__", + "__str__", + "__subclasshook__", + "__weakref__", + "_child", + "_class_id", + "_dirty_mask", + "_dn_set", + "_handle", + "_is_unknown_property", + "_rn_set", + "_set_child_of_parent_mo", + "_set_mo_prop_value", + "_set_parent_mo_or_dn", + "address", + "attr_get", + "attr_set", + "check_prop_match", + "child", + "child_action", + "child_add", + "child_count", + "child_is_dirty", + "child_mark_clean", + "child_remove", + "child_to_xml", + "clone", + "consts", + "current_time", + "descr", + "dirty_mask", + "dn", + "elem_create", + "from_xml", + "get_class_id", + "get_handle", + "ipv6_addr", + "is_dirty", + "make_rn", + "mark_clean", + "mark_dirty", + "mo_meta", + "mode", + "name", + "naming_props", + "owner", + "parent_mo", + "prop_map", + "prop_meta", + "rn", + "rn_get_special_case", + "rn_is_special_case", + "sacl", + "set_prop_multiple", + "show_hierarchy", + "show_tree", + "site", + "status", + "sync_mo", + "system_up_time", + "to_xml", + "write_object" +] +``` + +## Meta + +``` +[TopRoot] + |-TopSystem + |-AaaAuthRealm + | |-AaaAuthRealmFsm + | | |-AaaAuthRealmFsmStage + | |-AaaConsoleAuth + | | |-FaultInst + | |-AaaDefaultAuth + | | |-FaultInst + | |-AaaDomain + | | |-AaaDomainAuth + | | | |-FaultInst + | | |-FaultInst + | |-AaaRealmFsm + | | |-AaaRealmFsmStage + | |-AaaRealmFsmTask + | |-EventInst + | |-FaultInst + |-AaaLdapEp + | |-AaaEpFsm + | | |-AaaEpFsmStage + | |-AaaEpFsmTask + | |-AaaLdapEpFsm + | | |-AaaLdapEpFsmStage + | |-AaaLdapGroup + | | |-AaaUserLocale + | | | |-FaultInst + | | |-AaaUserRole + | | |-FaultInst + | |-AaaLdapGroupRule + | |-AaaLdapProvider + | | |-AaaLdapGroupRule + | |-AaaProviderGroup + | | |-AaaProviderRef + | | |-FaultInst + | |-EventInst + | |-FaultInst + |-AaaRadiusEp + | |-AaaEpFsm + | | |-AaaEpFsmStage + | |-AaaEpFsmTask + | |-AaaProviderGroup + | | |-AaaProviderRef + | | |-FaultInst + | |-AaaRadiusEpFsm + | | |-AaaRadiusEpFsmStage + | |-AaaRadiusProvider + | |-EventInst + | |-FaultInst + |-AaaSessionInfoTable + | |-AaaSessionInfo + |-AaaTacacsPlusEp + | |-AaaEpFsm + | | |-AaaEpFsmStage + | |-AaaEpFsmTask + | |-AaaProviderGroup + | | |-AaaProviderRef + | | |-FaultInst + | |-AaaTacacsPlusEpFsm + | | |-AaaTacacsPlusEpFsmStage + | |-AaaTacacsPlusProvider + | |-EventInst + | |-FaultInst + |-AaaUserEp + | |-AaaEpLogin + | |-AaaExtMgmtCutThruTkn + | |-AaaLocale + | | |-AaaOrg + | | | |-FaultInst + | | |-FaultInst + | |-AaaLoginProfile + | |-AaaPreLoginBanner + | |-AaaPwdProfile + | |-AaaRemoteUser + | | |-AaaCimcSession + | | |-AaaSession + | | |-AaaUserLocale + | | | |-FaultInst + | | |-AaaUserRole + | | |-FaultInst + | |-AaaRole + | | |-FaultInst + | |-AaaShellLogin + | |-AaaUser + | | |-AaaCimcSession + | | |-AaaSession + | | |-AaaSshAuth + | | |-AaaUserData + | | |-AaaUserLocale + | | | |-FaultInst + | | |-AaaUserRole + | | | |-FaultInst + | | |-FaultInst + | |-AaaUserEpFsm + | | |-AaaUserEpFsmStage + | |-AaaUserEpFsmTask + | |-AaaWebLogin + | |-EventInst + | |-FaultInst + |-CloudMgmtSvc + | |-CloudDeviceConnectorEp + | |-FaultInst + |-CommSvcEp + | |-CommCimcWebService + | |-CommCimxml + | |-CommDateTime + | | |-CommNtpProvider + | | |-FaultInst + | |-CommDns + | | |-CommDnsProvider + | |-CommEvtChannel + | |-CommHttp + | |-CommHttps + | |-CommShellSvcLimits + | |-CommSmashCLP + | |-CommSnmp + | | |-CommSnmpTrap + | | |-CommSnmpUser + | | | |-AaaCimcSession + | | | |-FaultInst + | | |-FaultInst + | |-CommSsh + | |-CommSvcEpFsm + | | |-CommSvcEpFsmStage + | |-CommSvcEpFsmTask + | |-CommSyslog + | | |-CommSyslogClient + | | |-CommSyslogConsole + | | |-CommSyslogFile + | | |-CommSyslogMonitor + | | |-CommSyslogSource + | |-CommTelnet + | |-CommWebChannel + | |-CommWebSvcLimits + | |-CommWsman + | |-CommXmlClConnPolicy + | |-EventInst + | |-FaultInst + |-ComputeRackUnit + | |-AaaEpAuthProfile + | | |-AaaEpUser + | | |-AaaCimcSession + | |-AaaEpUser + | | |-AaaCimcSession + | |-AdaptorHostIfConfig + | |-AdaptorUnit + | | |-AdaptorExtEthIf + | | | |-AdaptorEthPortBySizeLargeStats + | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | |-AdaptorEthPortBySizeSmallStats + | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | |-AdaptorEthPortErrStats + | | | | |-AdaptorEthPortErrStatsHist + | | | |-AdaptorEthPortMcastStats + | | | | |-AdaptorEthPortMcastStatsHist + | | | |-AdaptorEthPortOutsizedStats + | | | | |-AdaptorEthPortOutsizedStatsHist + | | | |-AdaptorEthPortStats + | | | | |-AdaptorEthPortStatsHist + | | | |-AdaptorExtEthIfFsm + | | | | |-AdaptorExtEthIfFsmStage + | | | |-AdaptorExtEthIfFsmTask + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-EventInst + | | | |-FabricEthMonSrcEp + | | | |-FaultInst + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-AdaptorHostEthIf + | | | |-AdaptorAzureQosProfile + | | | |-AdaptorEthAdvFilterProfile + | | | |-AdaptorEthArfsProfile + | | | |-AdaptorEthCompQueueProfile + | | | |-AdaptorEthFailoverProfile + | | | |-AdaptorEthGENEVEProfile + | | | |-AdaptorEthInterruptProfile + | | | |-AdaptorEthInterruptScalingProfile + | | | |-AdaptorEthNVGREProfile + | | | |-AdaptorEthOffloadProfile + | | | |-AdaptorEthPortBySizeLargeStats + | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | |-AdaptorEthPortBySizeSmallStats + | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | |-AdaptorEthPortErrStats + | | | | |-AdaptorEthPortErrStatsHist + | | | |-AdaptorEthPortMcastStats + | | | | |-AdaptorEthPortMcastStatsHist + | | | |-AdaptorEthPortOutsizedStats + | | | | |-AdaptorEthPortOutsizedStatsHist + | | | |-AdaptorEthPortStats + | | | | |-AdaptorEthPortStatsHist + | | | |-AdaptorEthRecvQueueProfile + | | | |-AdaptorEthRoCEProfile + | | | |-AdaptorEthVxLANProfile + | | | |-AdaptorEthWorkQueueProfile + | | | |-AdaptorExtIpV6RssHashProfile + | | | |-AdaptorFcOEIf + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorHostEthIfFsm + | | | | |-AdaptorHostEthIfFsmStage + | | | |-AdaptorHostEthIfFsmTask + | | | |-AdaptorIpV4RssHashProfile + | | | |-AdaptorIpV6RssHashProfile + | | | |-AdaptorPTP + | | | |-AdaptorRssProfile + | | | |-AdaptorUsnicConnDef + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthFailoverProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthInterruptScalingProfile + | | | | |-AdaptorEthOffloadProfile + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorExtIpV6RssHashProfile + | | | | |-AdaptorIpV4RssHashProfile + | | | | |-AdaptorIpV6RssHashProfile + | | | | |-AdaptorRssProfile + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVmmqConnDef + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthRoCEProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorRssProfile + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-NetworkIfStats + | | |-AdaptorHostFcIf + | | | |-AdaptorFcCdbWorkQueueProfile + | | | |-AdaptorFcErrorRecoveryProfile + | | | |-AdaptorFcFnicProfile + | | | |-AdaptorFcIfEventStats + | | | | |-AdaptorFcIfEventStatsHist + | | | |-AdaptorFcIfFC4Stats + | | | | |-AdaptorFcIfFC4StatsHist + | | | |-AdaptorFcIfFrameStats + | | | | |-AdaptorFcIfFrameStatsHist + | | | |-AdaptorFcInterruptProfile + | | | |-AdaptorFcOEIf + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorFcPortFLogiProfile + | | | |-AdaptorFcPortPLogiProfile + | | | |-AdaptorFcPortProfile + | | | |-AdaptorFcPortStats + | | | | |-AdaptorFcPortStatsHist + | | | |-AdaptorFcRecvQueueProfile + | | | |-AdaptorFcVhbaTypeProfile + | | | |-AdaptorFcWorkQueueProfile + | | | |-AdaptorHostFcIfFsm + | | | | |-AdaptorHostFcIfFsmStage + | | | |-AdaptorHostFcIfFsmTask + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-AdaptorVsan + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-NetworkIfStats + | | |-AdaptorHostIscsiIf + | | | |-AdaptorIscsiProt + | | | |-AdaptorIscsiTargetIf + | | | |-AdaptorProtocolProfile + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | | |-NetworkIfStats + | | | |-VnicIPv4Dhcp + | | | |-VnicIPv4Dns + | | | |-VnicIPv4IscsiAddr + | | | | |-VnicIPv4Dns + | | | |-VnicIPv4PooledIscsiAddr + | | | | |-FaultInst + | | | | |-VnicIPv4Dns + | | | | |-VnicIpV4History + | | | |-VnicIPv4StaticRoute + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-AdaptorHostPort + | | |-AdaptorHostScsiIf + | | | |-AdaptorHostScsiLunRef + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-FaultInst + | | | |-NetworkIfStats + | | |-AdaptorHostServiceEthIf + | | | |-AdaptorVlan + | | | | |-AdaptorEtherIfStats + | | | | | |-AdaptorEtherIfStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIScsiAutoTargetIf + | | | | |-VnicIScsiStaticTargetIf + | | | | | |-FaultInst + | | | | | |-VnicLun + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorVnicStats + | | | | |-AdaptorVnicStatsHist + | | | |-DcxVIf + | | | | |-FaultInst + | | | |-FaultInst + | | | |-NetworkIfStats + | | |-AdaptorMenloDcePortStats + | | | |-AdaptorMenloDcePortStatsHist + | | |-AdaptorMenloEthErrorStats + | | | |-AdaptorMenloEthErrorStatsHist + | | |-AdaptorMenloEthStats + | | | |-AdaptorMenloEthStatsHist + | | |-AdaptorMenloFcErrorStats + | | | |-AdaptorMenloFcErrorStatsHist + | | |-AdaptorMenloFcStats + | | | |-AdaptorMenloFcStatsHist + | | |-AdaptorMenloHostPortStats + | | | |-AdaptorMenloHostPortStatsHist + | | |-AdaptorMenloMcpuErrorStats + | | | |-AdaptorMenloMcpuErrorStatsHist + | | |-AdaptorMenloMcpuStats + | | | |-AdaptorMenloMcpuStatsHist + | | |-AdaptorMenloNetEgStats + | | | |-AdaptorMenloNetEgStatsHist + | | |-AdaptorMenloNetInStats + | | | |-AdaptorMenloNetInStatsHist + | | |-AdaptorMenloQErrorStats + | | | |-AdaptorMenloQErrorStatsHist + | | |-AdaptorMenloQStats + | | | |-AdaptorMenloQStatsHist + | | |-AdaptorUnitExtn + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | |-DcxNs + | | | |-FaultInst + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EquipmentPciDef + | | |-FaultInst + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-BiosUnit + | | |-BiosBOT + | | | |-BiosBootDevGrp + | | | |-BiosBootDev + | | |-BiosSettings + | | | |-BiosTokenFeatureGroup + | | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosTokenParam + | | | | |-BiosTokenSettings + | | | |-BiosVfACPI10Support + | | | |-BiosVfASPMSupport + | | | |-BiosVfAllUSBDevices + | | | |-BiosVfAltitude + | | | |-BiosVfAssertNMIOnPERR + | | | |-BiosVfAssertNMIOnSERR + | | | |-BiosVfBMEDMAMitigation + | | | |-BiosVfBootOptionRetry + | | | |-BiosVfCPUHardwarePowerManagement + | | | |-BiosVfCPUPerformance + | | | |-BiosVfConsistentDeviceNameControl + | | | |-BiosVfConsoleRedirection + | | | |-BiosVfCoreMultiProcessing + | | | |-BiosVfDDR3VoltageSelection + | | | |-BiosVfDRAMClockThrottling + | | | |-BiosVfDirectCacheAccess + | | | |-BiosVfDramRefreshRate + | | | |-BiosVfEnergyPerformanceTuning + | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | |-BiosVfEnhancedPowerCappingSupport + | | | |-BiosVfExecuteDisableBit + | | | |-BiosVfFRB2Timer + | | | |-BiosVfFrequencyFloorOverride + | | | |-BiosVfFrontPanelLockout + | | | |-BiosVfIOEMezz1OptionROM + | | | |-BiosVfIOENVMe1OptionROM + | | | |-BiosVfIOENVMe2OptionROM + | | | |-BiosVfIOESlot1OptionROM + | | | |-BiosVfIOESlot2OptionROM + | | | |-BiosVfIntegratedGraphics + | | | |-BiosVfIntegratedGraphicsApertureSize + | | | |-BiosVfIntelEntrySASRAIDModule + | | | |-BiosVfIntelHyperThreadingTech + | | | |-BiosVfIntelTrustedExecutionTechnology + | | | |-BiosVfIntelTurboBoostTech + | | | |-BiosVfIntelVTForDirectedIO + | | | |-BiosVfIntelVirtualizationTechnology + | | | |-BiosVfInterleaveConfiguration + | | | |-BiosVfLocalX2Apic + | | | |-BiosVfLvDIMMSupport + | | | |-BiosVfMaxVariableMTRRSetting + | | | |-BiosVfMaximumMemoryBelow4GB + | | | |-BiosVfMemoryMappedIOAbove4GB + | | | |-BiosVfMirroringMode + | | | |-BiosVfNUMAOptimized + | | | |-BiosVfOSBootWatchdogTimer + | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | |-BiosVfOnboardGraphics + | | | |-BiosVfOnboardSATAController + | | | |-BiosVfOnboardStorage + | | | |-BiosVfOptionROMEnable + | | | |-BiosVfOptionROMLoad + | | | |-BiosVfOutOfBandManagement + | | | |-BiosVfPCHSATAMode + | | | |-BiosVfPCILOMPortsConfiguration + | | | |-BiosVfPCIROMCLP + | | | |-BiosVfPCISlotLinkSpeed + | | | |-BiosVfPCISlotOptionROMEnable + | | | |-BiosVfPOSTErrorPause + | | | |-BiosVfPSTATECoordination + | | | |-BiosVfPackageCStateLimit + | | | |-BiosVfPanicAndHighWatermark + | | | |-BiosVfProcessorC1E + | | | |-BiosVfProcessorC3Report + | | | |-BiosVfProcessorC6Report + | | | |-BiosVfProcessorC7Report + | | | |-BiosVfProcessorCMCI + | | | |-BiosVfProcessorCState + | | | |-BiosVfProcessorEnergyConfiguration + | | | |-BiosVfProcessorPrefetchConfig + | | | |-BiosVfQPILinkFrequencySelect + | | | |-BiosVfQPISnoopMode + | | | |-BiosVfQuietBoot + | | | |-BiosVfRedirectionAfterBIOSPOST + | | | |-BiosVfResumeOnACPowerLoss + | | | |-BiosVfSBMezz1OptionROM + | | | |-BiosVfSBNVMe1OptionROM + | | | |-BiosVfSIOC1OptionROM + | | | |-BiosVfSIOC2OptionROM + | | | |-BiosVfScrubPolicies + | | | |-BiosVfSelectMemoryRASConfiguration + | | | |-BiosVfSerialPortAEnable + | | | |-BiosVfSparingMode + | | | |-BiosVfSriovConfig + | | | |-BiosVfTPMPendingOperation + | | | |-BiosVfTPMSupport + | | | |-BiosVfTrustedPlatformModule + | | | |-BiosVfUCSMBootModeControl + | | | |-BiosVfUCSMBootOrderRuleControl + | | | |-BiosVfUEFIOSUseLegacyVideo + | | | |-BiosVfUSBBootConfig + | | | |-BiosVfUSBConfiguration + | | | |-BiosVfUSBFrontPanelAccessLock + | | | |-BiosVfUSBPortConfiguration + | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | |-BiosVfVGAPriority + | | | |-BiosVfWorkloadConfiguration + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-BiosVIdentityParams + | |-CimcvmediaMountConfigDef + | | |-CimcvmediaConfigMountEntry + | |-ComputeAdminAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-ComputeBoard + | | |-ComputeIOHub + | | | |-ComputeIOHubEnvStats + | | | | |-ComputeIOHubEnvStatsHist + | | | |-FaultInst + | | |-ComputeMbPowerStats + | | | |-ComputeMbPowerStatsHist + | | |-ComputeMbTempStats + | | | |-ComputeMbTempStatsHist + | | |-ComputePCIeFatalCompletionStats + | | |-ComputePCIeFatalProtocolStats + | | |-ComputePCIeFatalReceiveStats + | | |-ComputePCIeFatalStats + | | |-ComputeRackUnitMbTempStats + | | | |-ComputeRackUnitMbTempStatsHist + | | |-ComputeRtcBattery + | | | |-FaultInst + | | |-CoprocessorCard + | | |-EquipmentTpm + | | | |-FaultInst + | | |-FaultInst + | | |-GraphicsCard + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-GraphicsController + | | |-LstorageLocal + | | |-LstorageLocalDef + | | |-LstorageRemote + | | | |-LstorageLogin + | | |-LstorageRemoteDef + | | | |-LstorageLogin + | | |-MemoryArray + | | | |-FaultInst + | | | |-MemoryArrayEnvStats + | | | | |-MemoryArrayEnvStatsHist + | | | |-MemoryPersistentMemoryUnit + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MemoryErrorStats + | | | | |-MemoryUnitEnvStats + | | | | |-MemoryUnitEnvStatsHist + | | | |-MemoryUnit + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-MemoryErrorStats + | | | |-MemoryUnitEnvStats + | | | |-MemoryUnitEnvStatsHist + | | |-MemoryBufferUnit + | | | |-FaultInst + | | | |-MemoryBufferUnitEnvStats + | | | |-MemoryBufferUnitEnvStatsHist + | | |-MemoryPersistentMemoryConfiguration + | | | |-FaultInst + | | | |-MemoryPersistentMemoryConfigResult + | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryNamespaceConfigResult + | | | | |-FaultInst + | | | |-MemoryPersistentMemoryRegion + | | | |-MemoryPersistentMemoryNamespace + | | | |-FaultInst + | | |-PciSwitch + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-PciLink + | | |-ProcessorUnit + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-ProcessorCacheMemStats + | | | |-ProcessorCore + | | | | |-ProcessorThread + | | | |-ProcessorEnvStats + | | | | |-ProcessorEnvStatsHist + | | | |-ProcessorErrorStats + | | | |-ProcessorExecStats + | | | |-ProcessorIOStats + | | | |-ProcessorMiscStats + | | | |-ProcessorPCIBusStats + | | | |-ProcessorPMUStats + | | | |-ProcessorSecurityStats + | | |-SecurityUnit + | | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-StorageController + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-LstorageControllerDef + | | | | |-LstorageControllerModeConfig + | | | | |-LstorageControllerQualifier + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageDrive + | | | |-StorageEmbeddedStorage + | | | |-StorageEnclosure + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-StorageEnclosureDiskSlotEp + | | | | | |-FaultInst + | | | | | |-StorageControllerRef + | | | | |-StorageEnclosureFsm + | | | | | |-StorageEnclosureFsmStage + | | | | |-StorageEnclosureFsmTask + | | | | |-StorageHddMotherBoardTempStats + | | | | | |-StorageHddMotherBoardTempStatsHist + | | | | |-StorageLocalDisk + | | | | |-EquipmentLocatorLed + | | | | | |-EquipmentLocatorLedFsm + | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | |-EquipmentLocatorLedFsmTask + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageControllerEp + | | | | |-StorageDiskEnvStats + | | | | | |-StorageDiskEnvStatsHist + | | | | |-StorageLocalDiskFsm + | | | | | |-StorageLocalDiskFsmStage + | | | | |-StorageLocalDiskFsmTask + | | | | |-StorageLocalDiskPartition + | | | | |-StorageOperation + | | | | |-StorageSasPort + | | | | |-StorageSsdHealthStats + | | | | |-StorageSsdHealthStatsHist + | | | |-StorageLocalDisk + | | | | |-EquipmentLocatorLed + | | | | | |-EquipmentLocatorLedFsm + | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | |-EquipmentLocatorLedFsmTask + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageControllerEp + | | | | |-StorageDiskEnvStats + | | | | | |-StorageDiskEnvStatsHist + | | | | |-StorageLocalDiskFsm + | | | | | |-StorageLocalDiskFsmStage + | | | | |-StorageLocalDiskFsmTask + | | | | |-StorageLocalDiskPartition + | | | | |-StorageOperation + | | | | |-StorageSasPort + | | | | |-StorageSsdHealthStats + | | | | |-StorageSsdHealthStatsHist + | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-StorageLocalDiskEp + | | | |-StorageLocalLun + | | | |-StorageMezzFlashLife + | | | | |-FaultInst + | | | |-StorageNvmeStats + | | | | |-StorageNvmeStatsHist + | | | |-StorageNvmeStorage + | | | |-StorageOnboardDevice + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-StorageOperation + | | | |-StorageRaidBattery + | | | | |-FaultInst + | | | | |-StorageOperation + | | | | |-StorageTransportableFlashModule + | | | |-StorageVirtualDrive + | | | | |-FaultInst + | | | | |-StorageControllerEp + | | | | |-StorageLunDisk + | | | | |-StorageOperation + | | | | |-StorageScsiLunRef + | | | | |-StorageVDMemberEp + | | | | |-FaultInst + | | | |-StorageVirtualDriveEp + | | |-StorageFlexFlashController + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-StorageFlexFlashCard + | | | | |-FaultInst + | | | | |-StorageFlexFlashDrive + | | | | |-FaultInst + | | | |-StorageFlexFlashControllerFsm + | | | | |-StorageFlexFlashControllerFsmStage + | | | |-StorageFlexFlashControllerFsmTask + | | | |-StorageFlexFlashVirtualDrive + | | | | |-FaultInst + | | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-StorageLocalDiskSlotEp + | | | |-FaultInst + | | |-StorageMiniStorage + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-StorageControllerReference + | | |-StorageNvmeSwitch + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-StorageSasExpander + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageOnboardDevice + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-StorageSasUpLink + | |-ComputeBoardController + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-ComputeExtBoard + | | |-BiosUnit + | | | |-BiosBOT + | | | | |-BiosBootDevGrp + | | | | |-BiosBootDev + | | | |-BiosSettings + | | | | |-BiosTokenFeatureGroup + | | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosVfACPI10Support + | | | | |-BiosVfASPMSupport + | | | | |-BiosVfAllUSBDevices + | | | | |-BiosVfAltitude + | | | | |-BiosVfAssertNMIOnPERR + | | | | |-BiosVfAssertNMIOnSERR + | | | | |-BiosVfBMEDMAMitigation + | | | | |-BiosVfBootOptionRetry + | | | | |-BiosVfCPUHardwarePowerManagement + | | | | |-BiosVfCPUPerformance + | | | | |-BiosVfConsistentDeviceNameControl + | | | | |-BiosVfConsoleRedirection + | | | | |-BiosVfCoreMultiProcessing + | | | | |-BiosVfDDR3VoltageSelection + | | | | |-BiosVfDRAMClockThrottling + | | | | |-BiosVfDirectCacheAccess + | | | | |-BiosVfDramRefreshRate + | | | | |-BiosVfEnergyPerformanceTuning + | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | |-BiosVfExecuteDisableBit + | | | | |-BiosVfFRB2Timer + | | | | |-BiosVfFrequencyFloorOverride + | | | | |-BiosVfFrontPanelLockout + | | | | |-BiosVfIOEMezz1OptionROM + | | | | |-BiosVfIOENVMe1OptionROM + | | | | |-BiosVfIOENVMe2OptionROM + | | | | |-BiosVfIOESlot1OptionROM + | | | | |-BiosVfIOESlot2OptionROM + | | | | |-BiosVfIntegratedGraphics + | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | |-BiosVfIntelHyperThreadingTech + | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | |-BiosVfIntelTurboBoostTech + | | | | |-BiosVfIntelVTForDirectedIO + | | | | |-BiosVfIntelVirtualizationTechnology + | | | | |-BiosVfInterleaveConfiguration + | | | | |-BiosVfLocalX2Apic + | | | | |-BiosVfLvDIMMSupport + | | | | |-BiosVfMaxVariableMTRRSetting + | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | |-BiosVfMirroringMode + | | | | |-BiosVfNUMAOptimized + | | | | |-BiosVfOSBootWatchdogTimer + | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | |-BiosVfOnboardGraphics + | | | | |-BiosVfOnboardSATAController + | | | | |-BiosVfOnboardStorage + | | | | |-BiosVfOptionROMEnable + | | | | |-BiosVfOptionROMLoad + | | | | |-BiosVfOutOfBandManagement + | | | | |-BiosVfPCHSATAMode + | | | | |-BiosVfPCILOMPortsConfiguration + | | | | |-BiosVfPCIROMCLP + | | | | |-BiosVfPCISlotLinkSpeed + | | | | |-BiosVfPCISlotOptionROMEnable + | | | | |-BiosVfPOSTErrorPause + | | | | |-BiosVfPSTATECoordination + | | | | |-BiosVfPackageCStateLimit + | | | | |-BiosVfPanicAndHighWatermark + | | | | |-BiosVfProcessorC1E + | | | | |-BiosVfProcessorC3Report + | | | | |-BiosVfProcessorC6Report + | | | | |-BiosVfProcessorC7Report + | | | | |-BiosVfProcessorCMCI + | | | | |-BiosVfProcessorCState + | | | | |-BiosVfProcessorEnergyConfiguration + | | | | |-BiosVfProcessorPrefetchConfig + | | | | |-BiosVfQPILinkFrequencySelect + | | | | |-BiosVfQPISnoopMode + | | | | |-BiosVfQuietBoot + | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | |-BiosVfResumeOnACPowerLoss + | | | | |-BiosVfSBMezz1OptionROM + | | | | |-BiosVfSBNVMe1OptionROM + | | | | |-BiosVfSIOC1OptionROM + | | | | |-BiosVfSIOC2OptionROM + | | | | |-BiosVfScrubPolicies + | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | |-BiosVfSerialPortAEnable + | | | | |-BiosVfSparingMode + | | | | |-BiosVfSriovConfig + | | | | |-BiosVfTPMPendingOperation + | | | | |-BiosVfTPMSupport + | | | | |-BiosVfTrustedPlatformModule + | | | | |-BiosVfUCSMBootModeControl + | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | |-BiosVfUSBBootConfig + | | | | |-BiosVfUSBConfiguration + | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | |-BiosVfUSBPortConfiguration + | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | |-BiosVfVGAPriority + | | | | |-BiosVfWorkloadConfiguration + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-ComputeBoardController + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-ComputeMbPowerStats + | | | |-ComputeMbPowerStatsHist + | | |-ComputeMbTempStats + | | | |-ComputeMbTempStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-ComputeFactoryResetOperation + | |-ComputeFwSyncAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-ComputeHostUtilityOs + | | |-MgmtUsbNicMgmtIf + | |-ComputeKvmMgmtPolicy + | | |-MgmtKvmCertificate + | | |-FaultInst + | |-ComputeMemoryConfiguration + | |-ComputePersonality + | |-ComputePhysicalExtension + | | |-FaultInst + | |-ComputePhysicalFsm + | | |-ComputePhysicalFsmStage + | |-ComputePhysicalFsmTask + | |-ComputePnuOSImage + | |-ComputePoolable + | | |-ComputePoolPolicyRef + | |-ComputeRackUnitFsm + | | |-ComputeRackUnitFsmStage + | |-ComputeRackUnitFsmTask + | |-ComputeRebootLog + | |-ComputeScrubPolicy + | |-DiagSrvCtrl + | | |-DiagRslt + | | | |-DiagLogEp + | | |-DiagRunPolicy + | | | |-DiagMemoryTest + | | |-EtherServerIntFIo + | | |-EquipmentXcvr + | | |-EtherErrStats + | | | |-EtherErrStatsHist + | | |-EtherLossStats + | | | |-EtherLossStatsHist + | | |-EtherPauseStats + | | | |-EtherPauseStatsHist + | | |-EtherRxStats + | | | |-EtherRxStatsHist + | | |-EtherServerIntFIoFsm + | | | |-EtherServerIntFIoFsmStage + | | |-EtherServerIntFIoFsmTask + | | |-EtherTxStats + | | | |-EtherTxStatsHist + | | |-EventInst + | | |-FaultInst + | | |-LldpAcquired + | | |-PortDomainEp + | | |-PortTrustMode + | | |-SwUlan + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentFanModule + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFan + | | | |-EquipmentFanStats + | | | | |-EquipmentFanStatsHist + | | | |-EquipmentNetworkElementFanStats + | | | | |-EquipmentNetworkElementFanStatsHist + | | | |-EquipmentRackUnitFanStats + | | | | |-EquipmentRackUnitFanStatsHist + | | | |-FaultInst + | | |-EquipmentFanModuleStats + | | | |-EquipmentFanModuleStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIOExpander + | |-EquipmentIndicatorLed + | |-EquipmentInventoryStatus + | | |-FaultInst + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPOST + | |-EquipmentPsu + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFexPsuInputStats + | | | |-EquipmentFexPsuInputStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPsuFsm + | | | |-EquipmentPsuFsmStage + | | |-EquipmentPsuFsmTask + | | |-EquipmentPsuInputStats + | | | |-EquipmentPsuInputStatsHist + | | |-EquipmentPsuOutputStats + | | | |-EquipmentPsuOutputStatsHist + | | |-EquipmentPsuStats + | | | |-EquipmentPsuStatsHist + | | |-EquipmentRackUnitPsuStats + | | | |-EquipmentRackUnitPsuStatsHist + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareStatus + | | | |-FaultInst + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FaultSuppressTask + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareImageLock + | |-FirmwareStatus + | | |-FaultInst + | |-LsIdentityInfo + | | |-FaultInst + | |-LsbootDef + | | |-LsbootBootSecurity + | | |-LsbootEFIShell + | | |-LsbootIScsi + | | | |-LsbootIScsiImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootLan + | | | |-LsbootLanImagePath + | | | |-LsbootUEFIBootParam + | | | |-VnicIpV4StaticAddr + | | |-LsbootSan + | | | |-LsbootSanCatSanImage + | | | |-LsbootSanCatSanImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootStorage + | | | |-LsbootLocalStorage + | | | | |-LsbootDefaultLocalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootEmbeddedLocalDiskImage + | | | | | |-LsbootEmbeddedLocalDiskImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootEmbeddedLocalLunImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootLocalDiskImage + | | | | | |-LsbootLocalDiskImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootLocalHddImage + | | | | | |-LsbootLocalLunImagePath + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootNvme + | | | | | |-LsbootNvmeDiskSsd + | | | | | |-LsbootNvmePciSsd + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbExternalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbFlashStorageImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootUsbInternalImage + | | | | |-LsbootUEFIBootParam + | | | |-LsbootSanImage + | | | |-LsbootSanImagePath + | | | |-LsbootUEFIBootParam + | | |-LsbootVirtualMedia + | |-LstorageProfile + | | |-LstorageControllerDef + | | | |-LstorageControllerModeConfig + | | | |-LstorageControllerQualifier + | | |-LstorageDasScsiLun + | | | |-FaultInst + | | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-LstorageLunSetConfig + | | | |-LstorageLunSetDiskSlot + | | | |-LstorageVirtualDriveDef + | | |-LstorageSecurity + | | |-LstorageDriveSecurity + | | |-LstorageLocal + | | |-LstorageRemote + | | |-LstorageLogin + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-MgmtKmipCertPolicy + | |-MgmtSecurity + | | |-MgmtKmip + | |-MgmtSpdmCertificatePolicy + | | |-MgmtSpdmCertificate + | |-MoKvCfgHolder + | | |-MoIpV4AddrKv + | | | |-FaultInst + | | |-MoIpV6AddrKv + | | | |-FaultInst + | | |-MoKv + | | |-MoVnicKv + | |-MoKvInvHolder + | | |-MoInvKv + | |-OsAgent + | |-OsInstance + | | |-OsEthBondIntf + | | | |-OsARPLinkMonitoringPolicy + | | | | |-OsARPTarget + | | | |-OsEthBondModeActiveBackup + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedALB + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedRR + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedTLB + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBalancedXOR + | | | | |-OsPrimarySlave + | | | |-OsEthBondModeBroadcast + | | | | |-OsPrimarySlave + | | | |-OsEthIntf + | | | |-OsMiiLinkMonitoringPolicy + | | |-OsEthIntf + | |-PciEquipSlot + | | |-FaultInst + | |-PciUnit + | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-SolIf + | |-StorageEnclosure + | | |-EventInst + | | |-FaultInst + | | |-StorageEnclosureDiskSlotEp + | | | |-FaultInst + | | | |-StorageControllerRef + | | |-StorageEnclosureFsm + | | | |-StorageEnclosureFsmStage + | | |-StorageEnclosureFsmTask + | | |-StorageHddMotherBoardTempStats + | | | |-StorageHddMotherBoardTempStatsHist + | | |-StorageLocalDisk + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageControllerEp + | | |-StorageDiskEnvStats + | | | |-StorageDiskEnvStatsHist + | | |-StorageLocalDiskFsm + | | | |-StorageLocalDiskFsmStage + | | |-StorageLocalDiskFsmTask + | | |-StorageLocalDiskPartition + | | |-StorageOperation + | | |-StorageSasPort + | | |-StorageSsdHealthStats + | | |-StorageSsdHealthStatsHist + | |-StorageVirtualDriveContainer + | | |-StorageVirtualDrive + | | |-FaultInst + | | |-StorageControllerEp + | | |-StorageLunDisk + | | |-StorageOperation + | | |-StorageScsiLunRef + | | |-StorageVDMemberEp + | | |-FaultInst + | |-SwUlan + | |-SysdebugDiagnosticLog + |-ControllerHaController + | |-ControllerOperationalVersionHolder + | |-ControllerPreferedVersionHolder + |-ControllerMgmtDbCheckPol + |-DomainChassisFeatureCont + | |-DomainChassisFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainEnvironmentFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainNetworkFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainServerFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainStorageFeature + | |-DomainChassisParam + | |-DomainEnvironmentParam + | |-DomainNetworkParam + | |-DomainServerParam + | |-DomainStorageParam + |-DomainEnvironmentFeatureCont + | |-DomainChassisFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainEnvironmentFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainNetworkFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainServerFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainStorageFeature + | |-DomainChassisParam + | |-DomainEnvironmentParam + | |-DomainNetworkParam + | |-DomainServerParam + | |-DomainStorageParam + |-DomainNetworkFeatureCont + | |-DomainChassisFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainEnvironmentFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainNetworkFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainServerFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainStorageFeature + | |-DomainChassisParam + | |-DomainEnvironmentParam + | |-DomainNetworkParam + | |-DomainServerParam + | |-DomainStorageParam + |-DomainServerFeatureCont + | |-DomainChassisFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainEnvironmentFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainNetworkFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainServerFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainStorageFeature + | |-DomainChassisParam + | |-DomainEnvironmentParam + | |-DomainNetworkParam + | |-DomainServerParam + | |-DomainStorageParam + |-DomainStorageFeatureCont + | |-DomainChassisFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainEnvironmentFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainNetworkFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainServerFeature + | | |-DomainChassisParam + | | |-DomainEnvironmentParam + | | |-DomainNetworkParam + | | |-DomainServerParam + | | |-DomainStorageParam + | |-DomainStorageFeature + | |-DomainChassisParam + | |-DomainEnvironmentParam + | |-DomainNetworkParam + | |-DomainServerParam + | |-DomainStorageParam + |-EquipmentChassis + | |-ComputeBlade + | | |-AaaEpAuthProfile + | | | |-AaaEpUser + | | | |-AaaCimcSession + | | |-AaaEpUser + | | | |-AaaCimcSession + | | |-AdaptorHostIfConfig + | | |-AdaptorUnit + | | | |-AdaptorExtEthIf + | | | | |-AdaptorEthPortBySizeLargeStats + | | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | | |-AdaptorEthPortBySizeSmallStats + | | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | | |-AdaptorEthPortErrStats + | | | | | |-AdaptorEthPortErrStatsHist + | | | | |-AdaptorEthPortMcastStats + | | | | | |-AdaptorEthPortMcastStatsHist + | | | | |-AdaptorEthPortOutsizedStats + | | | | | |-AdaptorEthPortOutsizedStatsHist + | | | | |-AdaptorEthPortStats + | | | | | |-AdaptorEthPortStatsHist + | | | | |-AdaptorExtEthIfFsm + | | | | | |-AdaptorExtEthIfFsmStage + | | | | |-AdaptorExtEthIfFsmTask + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FabricEthMonSrcEp + | | | | |-FaultInst + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorHostEthIf + | | | | |-AdaptorAzureQosProfile + | | | | |-AdaptorEthAdvFilterProfile + | | | | |-AdaptorEthArfsProfile + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthFailoverProfile + | | | | |-AdaptorEthGENEVEProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthInterruptScalingProfile + | | | | |-AdaptorEthNVGREProfile + | | | | |-AdaptorEthOffloadProfile + | | | | |-AdaptorEthPortBySizeLargeStats + | | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | | |-AdaptorEthPortBySizeSmallStats + | | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | | |-AdaptorEthPortErrStats + | | | | | |-AdaptorEthPortErrStatsHist + | | | | |-AdaptorEthPortMcastStats + | | | | | |-AdaptorEthPortMcastStatsHist + | | | | |-AdaptorEthPortOutsizedStats + | | | | | |-AdaptorEthPortOutsizedStatsHist + | | | | |-AdaptorEthPortStats + | | | | | |-AdaptorEthPortStatsHist + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthRoCEProfile + | | | | |-AdaptorEthVxLANProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorExtIpV6RssHashProfile + | | | | |-AdaptorFcOEIf + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-AdaptorHostEthIfFsm + | | | | | |-AdaptorHostEthIfFsmStage + | | | | |-AdaptorHostEthIfFsmTask + | | | | |-AdaptorIpV4RssHashProfile + | | | | |-AdaptorIpV6RssHashProfile + | | | | |-AdaptorPTP + | | | | |-AdaptorRssProfile + | | | | |-AdaptorUsnicConnDef + | | | | | |-AdaptorEthCompQueueProfile + | | | | | |-AdaptorEthFailoverProfile + | | | | | |-AdaptorEthInterruptProfile + | | | | | |-AdaptorEthInterruptScalingProfile + | | | | | |-AdaptorEthOffloadProfile + | | | | | |-AdaptorEthRecvQueueProfile + | | | | | |-AdaptorEthWorkQueueProfile + | | | | | |-AdaptorExtIpV6RssHashProfile + | | | | | |-AdaptorIpV4RssHashProfile + | | | | | |-AdaptorIpV6RssHashProfile + | | | | | |-AdaptorRssProfile + | | | | |-AdaptorVlan + | | | | | |-AdaptorEtherIfStats + | | | | | | |-AdaptorEtherIfStatsHist + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dhcp + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4IscsiAddr + | | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4PooledIscsiAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIPv4Dns + | | | | | | |-VnicIpV4History + | | | | | |-VnicIPv4StaticRoute + | | | | | |-VnicIScsiAutoTargetIf + | | | | | |-VnicIScsiStaticTargetIf + | | | | | | |-FaultInst + | | | | | | |-VnicLun + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-AdaptorVmmqConnDef + | | | | | |-AdaptorEthCompQueueProfile + | | | | | |-AdaptorEthInterruptProfile + | | | | | |-AdaptorEthRecvQueueProfile + | | | | | |-AdaptorEthRoCEProfile + | | | | | |-AdaptorEthWorkQueueProfile + | | | | | |-AdaptorRssProfile + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-NetworkIfStats + | | | |-AdaptorHostFcIf + | | | | |-AdaptorFcCdbWorkQueueProfile + | | | | |-AdaptorFcErrorRecoveryProfile + | | | | |-AdaptorFcFnicProfile + | | | | |-AdaptorFcIfEventStats + | | | | | |-AdaptorFcIfEventStatsHist + | | | | |-AdaptorFcIfFC4Stats + | | | | | |-AdaptorFcIfFC4StatsHist + | | | | |-AdaptorFcIfFrameStats + | | | | | |-AdaptorFcIfFrameStatsHist + | | | | |-AdaptorFcInterruptProfile + | | | | |-AdaptorFcOEIf + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-AdaptorFcPortFLogiProfile + | | | | |-AdaptorFcPortPLogiProfile + | | | | |-AdaptorFcPortProfile + | | | | |-AdaptorFcPortStats + | | | | | |-AdaptorFcPortStatsHist + | | | | |-AdaptorFcRecvQueueProfile + | | | | |-AdaptorFcVhbaTypeProfile + | | | | |-AdaptorFcWorkQueueProfile + | | | | |-AdaptorHostFcIfFsm + | | | | | |-AdaptorHostFcIfFsmStage + | | | | |-AdaptorHostFcIfFsmTask + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-AdaptorVsan + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-NetworkIfStats + | | | |-AdaptorHostIscsiIf + | | | | |-AdaptorIscsiProt + | | | | |-AdaptorIscsiTargetIf + | | | | |-AdaptorProtocolProfile + | | | | |-AdaptorVlan + | | | | | |-AdaptorEtherIfStats + | | | | | | |-AdaptorEtherIfStatsHist + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dhcp + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4IscsiAddr + | | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4PooledIscsiAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIPv4Dns + | | | | | | |-VnicIpV4History + | | | | | |-VnicIPv4StaticRoute + | | | | | |-VnicIScsiAutoTargetIf + | | | | | |-VnicIScsiStaticTargetIf + | | | | | | |-FaultInst + | | | | | | |-VnicLun + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-NetworkIfStats + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorHostPort + | | | |-AdaptorHostScsiIf + | | | | |-AdaptorHostScsiLunRef + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-FaultInst + | | | | |-NetworkIfStats + | | | |-AdaptorHostServiceEthIf + | | | | |-AdaptorVlan + | | | | | |-AdaptorEtherIfStats + | | | | | | |-AdaptorEtherIfStatsHist + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dhcp + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4IscsiAddr + | | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4PooledIscsiAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIPv4Dns + | | | | | | |-VnicIpV4History + | | | | | |-VnicIPv4StaticRoute + | | | | | |-VnicIScsiAutoTargetIf + | | | | | |-VnicIScsiStaticTargetIf + | | | | | | |-FaultInst + | | | | | | |-VnicLun + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-NetworkIfStats + | | | |-AdaptorMenloDcePortStats + | | | | |-AdaptorMenloDcePortStatsHist + | | | |-AdaptorMenloEthErrorStats + | | | | |-AdaptorMenloEthErrorStatsHist + | | | |-AdaptorMenloEthStats + | | | | |-AdaptorMenloEthStatsHist + | | | |-AdaptorMenloFcErrorStats + | | | | |-AdaptorMenloFcErrorStatsHist + | | | |-AdaptorMenloFcStats + | | | | |-AdaptorMenloFcStatsHist + | | | |-AdaptorMenloHostPortStats + | | | | |-AdaptorMenloHostPortStatsHist + | | | |-AdaptorMenloMcpuErrorStats + | | | | |-AdaptorMenloMcpuErrorStatsHist + | | | |-AdaptorMenloMcpuStats + | | | | |-AdaptorMenloMcpuStatsHist + | | | |-AdaptorMenloNetEgStats + | | | | |-AdaptorMenloNetEgStatsHist + | | | |-AdaptorMenloNetInStats + | | | | |-AdaptorMenloNetInStatsHist + | | | |-AdaptorMenloQErrorStats + | | | | |-AdaptorMenloQErrorStatsHist + | | | |-AdaptorMenloQStats + | | | | |-AdaptorMenloQStatsHist + | | | |-AdaptorUnitExtn + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | |-DcxNs + | | | | |-FaultInst + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-EquipmentPOST + | | | |-EquipmentPciDef + | | | |-FaultInst + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-BiosUnit + | | | |-BiosBOT + | | | | |-BiosBootDevGrp + | | | | |-BiosBootDev + | | | |-BiosSettings + | | | | |-BiosTokenFeatureGroup + | | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosVfACPI10Support + | | | | |-BiosVfASPMSupport + | | | | |-BiosVfAllUSBDevices + | | | | |-BiosVfAltitude + | | | | |-BiosVfAssertNMIOnPERR + | | | | |-BiosVfAssertNMIOnSERR + | | | | |-BiosVfBMEDMAMitigation + | | | | |-BiosVfBootOptionRetry + | | | | |-BiosVfCPUHardwarePowerManagement + | | | | |-BiosVfCPUPerformance + | | | | |-BiosVfConsistentDeviceNameControl + | | | | |-BiosVfConsoleRedirection + | | | | |-BiosVfCoreMultiProcessing + | | | | |-BiosVfDDR3VoltageSelection + | | | | |-BiosVfDRAMClockThrottling + | | | | |-BiosVfDirectCacheAccess + | | | | |-BiosVfDramRefreshRate + | | | | |-BiosVfEnergyPerformanceTuning + | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | |-BiosVfExecuteDisableBit + | | | | |-BiosVfFRB2Timer + | | | | |-BiosVfFrequencyFloorOverride + | | | | |-BiosVfFrontPanelLockout + | | | | |-BiosVfIOEMezz1OptionROM + | | | | |-BiosVfIOENVMe1OptionROM + | | | | |-BiosVfIOENVMe2OptionROM + | | | | |-BiosVfIOESlot1OptionROM + | | | | |-BiosVfIOESlot2OptionROM + | | | | |-BiosVfIntegratedGraphics + | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | |-BiosVfIntelHyperThreadingTech + | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | |-BiosVfIntelTurboBoostTech + | | | | |-BiosVfIntelVTForDirectedIO + | | | | |-BiosVfIntelVirtualizationTechnology + | | | | |-BiosVfInterleaveConfiguration + | | | | |-BiosVfLocalX2Apic + | | | | |-BiosVfLvDIMMSupport + | | | | |-BiosVfMaxVariableMTRRSetting + | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | |-BiosVfMirroringMode + | | | | |-BiosVfNUMAOptimized + | | | | |-BiosVfOSBootWatchdogTimer + | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | |-BiosVfOnboardGraphics + | | | | |-BiosVfOnboardSATAController + | | | | |-BiosVfOnboardStorage + | | | | |-BiosVfOptionROMEnable + | | | | |-BiosVfOptionROMLoad + | | | | |-BiosVfOutOfBandManagement + | | | | |-BiosVfPCHSATAMode + | | | | |-BiosVfPCILOMPortsConfiguration + | | | | |-BiosVfPCIROMCLP + | | | | |-BiosVfPCISlotLinkSpeed + | | | | |-BiosVfPCISlotOptionROMEnable + | | | | |-BiosVfPOSTErrorPause + | | | | |-BiosVfPSTATECoordination + | | | | |-BiosVfPackageCStateLimit + | | | | |-BiosVfPanicAndHighWatermark + | | | | |-BiosVfProcessorC1E + | | | | |-BiosVfProcessorC3Report + | | | | |-BiosVfProcessorC6Report + | | | | |-BiosVfProcessorC7Report + | | | | |-BiosVfProcessorCMCI + | | | | |-BiosVfProcessorCState + | | | | |-BiosVfProcessorEnergyConfiguration + | | | | |-BiosVfProcessorPrefetchConfig + | | | | |-BiosVfQPILinkFrequencySelect + | | | | |-BiosVfQPISnoopMode + | | | | |-BiosVfQuietBoot + | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | |-BiosVfResumeOnACPowerLoss + | | | | |-BiosVfSBMezz1OptionROM + | | | | |-BiosVfSBNVMe1OptionROM + | | | | |-BiosVfSIOC1OptionROM + | | | | |-BiosVfSIOC2OptionROM + | | | | |-BiosVfScrubPolicies + | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | |-BiosVfSerialPortAEnable + | | | | |-BiosVfSparingMode + | | | | |-BiosVfSriovConfig + | | | | |-BiosVfTPMPendingOperation + | | | | |-BiosVfTPMSupport + | | | | |-BiosVfTrustedPlatformModule + | | | | |-BiosVfUCSMBootModeControl + | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | |-BiosVfUSBBootConfig + | | | | |-BiosVfUSBConfiguration + | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | |-BiosVfUSBPortConfiguration + | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | |-BiosVfVGAPriority + | | | | |-BiosVfWorkloadConfiguration + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-BiosVIdentityParams + | | |-CimcvmediaMountConfigDef + | | | |-CimcvmediaConfigMountEntry + | | |-ComputeAdminAck + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-ComputeBladeFsm + | | | |-ComputeBladeFsmStage + | | |-ComputeBladeFsmTask + | | |-ComputeBoard + | | | |-ComputeIOHub + | | | | |-ComputeIOHubEnvStats + | | | | | |-ComputeIOHubEnvStatsHist + | | | | |-FaultInst + | | | |-ComputeMbPowerStats + | | | | |-ComputeMbPowerStatsHist + | | | |-ComputeMbTempStats + | | | | |-ComputeMbTempStatsHist + | | | |-ComputePCIeFatalCompletionStats + | | | |-ComputePCIeFatalProtocolStats + | | | |-ComputePCIeFatalReceiveStats + | | | |-ComputePCIeFatalStats + | | | |-ComputeRackUnitMbTempStats + | | | | |-ComputeRackUnitMbTempStatsHist + | | | |-ComputeRtcBattery + | | | | |-FaultInst + | | | |-CoprocessorCard + | | | |-EquipmentTpm + | | | | |-FaultInst + | | | |-FaultInst + | | | |-GraphicsCard + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-GraphicsController + | | | |-LstorageLocal + | | | |-LstorageLocalDef + | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-LstorageRemoteDef + | | | | |-LstorageLogin + | | | |-MemoryArray + | | | | |-FaultInst + | | | | |-MemoryArrayEnvStats + | | | | | |-MemoryArrayEnvStatsHist + | | | | |-MemoryPersistentMemoryUnit + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-MemoryErrorStats + | | | | | |-MemoryUnitEnvStats + | | | | | |-MemoryUnitEnvStatsHist + | | | | |-MemoryUnit + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-MemoryErrorStats + | | | | |-MemoryUnitEnvStats + | | | | |-MemoryUnitEnvStatsHist + | | | |-MemoryBufferUnit + | | | | |-FaultInst + | | | | |-MemoryBufferUnitEnvStats + | | | | |-MemoryBufferUnitEnvStatsHist + | | | |-MemoryPersistentMemoryConfiguration + | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryConfigResult + | | | | | |-FaultInst + | | | | | |-MemoryPersistentMemoryNamespaceConfigResult + | | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryRegion + | | | | |-MemoryPersistentMemoryNamespace + | | | | |-FaultInst + | | | |-PciSwitch + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-PciLink + | | | |-ProcessorUnit + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-ProcessorCacheMemStats + | | | | |-ProcessorCore + | | | | | |-ProcessorThread + | | | | |-ProcessorEnvStats + | | | | | |-ProcessorEnvStatsHist + | | | | |-ProcessorErrorStats + | | | | |-ProcessorExecStats + | | | | |-ProcessorIOStats + | | | | |-ProcessorMiscStats + | | | | |-ProcessorPCIBusStats + | | | | |-ProcessorPMUStats + | | | | |-ProcessorSecurityStats + | | | |-SecurityUnit + | | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-StorageController + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-LstorageControllerDef + | | | | | |-LstorageControllerModeConfig + | | | | | |-LstorageControllerQualifier + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageDrive + | | | | |-StorageEmbeddedStorage + | | | | |-StorageEnclosure + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-StorageEnclosureDiskSlotEp + | | | | | | |-FaultInst + | | | | | | |-StorageControllerRef + | | | | | |-StorageEnclosureFsm + | | | | | | |-StorageEnclosureFsmStage + | | | | | |-StorageEnclosureFsmTask + | | | | | |-StorageHddMotherBoardTempStats + | | | | | | |-StorageHddMotherBoardTempStatsHist + | | | | | |-StorageLocalDisk + | | | | | |-EquipmentLocatorLed + | | | | | | |-EquipmentLocatorLedFsm + | | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | | |-EquipmentLocatorLedFsmTask + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-MgmtController + | | | | | | |-CimcvmediaActualMountList + | | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | | |-FaultInst + | | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | | |-EventInst + | | | | | | |-FabricLocale + | | | | | | | |-AdaptorExtEthIfPc + | | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | | |-DcxVIf + | | | | | | | | |-FaultInst + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPath + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPathConn + | | | | | | | | |-FabricPathEp + | | | | | | | | |-PortTrustMode + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FaultInst + | | | | | | |-FirmwareBootDefinition + | | | | | | | |-FirmwareBootUnit + | | | | | | | | |-FaultInst + | | | | | | | | |-FirmwareInstallable + | | | | | | | | | |-FirmwareUcscInfo + | | | | | | | | |-FirmwareServicePack + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareImage + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareImageFsm + | | | | | | | | |-FirmwareImageFsmStage + | | | | | | | |-FirmwareImageFsmTask + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareModule + | | | | | | |-FirmwareRunning + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUpdatable + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-MgmtCimcSecureBoot + | | | | | | |-MgmtCmcSecureBoot + | | | | | | |-MgmtConnection + | | | | | | | |-FaultInst + | | | | | | |-MgmtControllerFsm + | | | | | | | |-MgmtControllerFsmStage + | | | | | | |-MgmtControllerFsmTask + | | | | | | |-MgmtHealthStatus + | | | | | | | |-FaultInst + | | | | | | | |-MgmtHealthAttr + | | | | | | |-MgmtIf + | | | | | | | |-DhcpAcquired + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfConfig + | | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | | |-EventInst + | | | | | | | | |-FaultInst + | | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | | |-MgmtIfFsm + | | | | | | | | |-MgmtIfFsmStage + | | | | | | | |-MgmtIfFsmTask + | | | | | | |-MgmtInterface + | | | | | | | |-FaultInst + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtKvmCertificate + | | | | | | | |-FaultInst + | | | | | | |-MgmtProfDerivedInterface + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtSpdmCertificateInventory + | | | | | | | |-MgmtSpdmCertificateData + | | | | | | |-MgmtSwPersonalities + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtUsbNicMgmtIf + | | | | | | |-SysdebugMEpLog + | | | | | | | |-FaultInst + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | | |-VnicIpV4StaticAddr + | | | | | |-StorageControllerEp + | | | | | |-StorageDiskEnvStats + | | | | | | |-StorageDiskEnvStatsHist + | | | | | |-StorageLocalDiskFsm + | | | | | | |-StorageLocalDiskFsmStage + | | | | | |-StorageLocalDiskFsmTask + | | | | | |-StorageLocalDiskPartition + | | | | | |-StorageOperation + | | | | | |-StorageSasPort + | | | | | |-StorageSsdHealthStats + | | | | | |-StorageSsdHealthStatsHist + | | | | |-StorageLocalDisk + | | | | | |-EquipmentLocatorLed + | | | | | | |-EquipmentLocatorLedFsm + | | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | | |-EquipmentLocatorLedFsmTask + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-MgmtController + | | | | | | |-CimcvmediaActualMountList + | | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | | |-FaultInst + | | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | | |-EventInst + | | | | | | |-FabricLocale + | | | | | | | |-AdaptorExtEthIfPc + | | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | | |-DcxVIf + | | | | | | | | |-FaultInst + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPath + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPathConn + | | | | | | | | |-FabricPathEp + | | | | | | | | |-PortTrustMode + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FaultInst + | | | | | | |-FirmwareBootDefinition + | | | | | | | |-FirmwareBootUnit + | | | | | | | | |-FaultInst + | | | | | | | | |-FirmwareInstallable + | | | | | | | | | |-FirmwareUcscInfo + | | | | | | | | |-FirmwareServicePack + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareImage + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareImageFsm + | | | | | | | | |-FirmwareImageFsmStage + | | | | | | | |-FirmwareImageFsmTask + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareModule + | | | | | | |-FirmwareRunning + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUpdatable + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-MgmtCimcSecureBoot + | | | | | | |-MgmtCmcSecureBoot + | | | | | | |-MgmtConnection + | | | | | | | |-FaultInst + | | | | | | |-MgmtControllerFsm + | | | | | | | |-MgmtControllerFsmStage + | | | | | | |-MgmtControllerFsmTask + | | | | | | |-MgmtHealthStatus + | | | | | | | |-FaultInst + | | | | | | | |-MgmtHealthAttr + | | | | | | |-MgmtIf + | | | | | | | |-DhcpAcquired + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfConfig + | | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | | |-EventInst + | | | | | | | | |-FaultInst + | | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | | |-MgmtIfFsm + | | | | | | | | |-MgmtIfFsmStage + | | | | | | | |-MgmtIfFsmTask + | | | | | | |-MgmtInterface + | | | | | | | |-FaultInst + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtKvmCertificate + | | | | | | | |-FaultInst + | | | | | | |-MgmtProfDerivedInterface + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtSpdmCertificateInventory + | | | | | | | |-MgmtSpdmCertificateData + | | | | | | |-MgmtSwPersonalities + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtUsbNicMgmtIf + | | | | | | |-SysdebugMEpLog + | | | | | | | |-FaultInst + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | | |-VnicIpV4StaticAddr + | | | | | |-StorageControllerEp + | | | | | |-StorageDiskEnvStats + | | | | | | |-StorageDiskEnvStatsHist + | | | | | |-StorageLocalDiskFsm + | | | | | | |-StorageLocalDiskFsmStage + | | | | | |-StorageLocalDiskFsmTask + | | | | | |-StorageLocalDiskPartition + | | | | | |-StorageOperation + | | | | | |-StorageSasPort + | | | | | |-StorageSsdHealthStats + | | | | | |-StorageSsdHealthStatsHist + | | | | |-StorageLocalDiskConfigDef + | | | | | |-LstorageSecurity + | | | | | | |-LstorageDriveSecurity + | | | | | | |-LstorageLocal + | | | | | | |-LstorageRemote + | | | | | | |-LstorageLogin + | | | | | |-StorageLocalDiskPartition + | | | | |-StorageLocalDiskEp + | | | | |-StorageLocalLun + | | | | |-StorageMezzFlashLife + | | | | | |-FaultInst + | | | | |-StorageNvmeStats + | | | | | |-StorageNvmeStatsHist + | | | | |-StorageNvmeStorage + | | | | |-StorageOnboardDevice + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-StorageOperation + | | | | |-StorageRaidBattery + | | | | | |-FaultInst + | | | | | |-StorageOperation + | | | | | |-StorageTransportableFlashModule + | | | | |-StorageVirtualDrive + | | | | | |-FaultInst + | | | | | |-StorageControllerEp + | | | | | |-StorageLunDisk + | | | | | |-StorageOperation + | | | | | |-StorageScsiLunRef + | | | | | |-StorageVDMemberEp + | | | | | |-FaultInst + | | | | |-StorageVirtualDriveEp + | | | |-StorageFlexFlashController + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-StorageFlexFlashCard + | | | | | |-FaultInst + | | | | | |-StorageFlexFlashDrive + | | | | | |-FaultInst + | | | | |-StorageFlexFlashControllerFsm + | | | | | |-StorageFlexFlashControllerFsmStage + | | | | |-StorageFlexFlashControllerFsmTask + | | | | |-StorageFlexFlashVirtualDrive + | | | | | |-FaultInst + | | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-StorageLocalDiskSlotEp + | | | | |-FaultInst + | | | |-StorageMiniStorage + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-StorageControllerReference + | | | |-StorageNvmeSwitch + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-StorageSasExpander + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageOnboardDevice + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-StorageSasUpLink + | | |-ComputeBoardConnector + | | |-ComputeBoardController + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-ComputeExtBoard + | | | |-BiosUnit + | | | | |-BiosBOT + | | | | | |-BiosBootDevGrp + | | | | | |-BiosBootDev + | | | | |-BiosSettings + | | | | | |-BiosTokenFeatureGroup + | | | | | | |-BiosTokenParam + | | | | | | |-BiosTokenSettings + | | | | | |-BiosTokenParam + | | | | | | |-BiosTokenSettings + | | | | | |-BiosVfACPI10Support + | | | | | |-BiosVfASPMSupport + | | | | | |-BiosVfAllUSBDevices + | | | | | |-BiosVfAltitude + | | | | | |-BiosVfAssertNMIOnPERR + | | | | | |-BiosVfAssertNMIOnSERR + | | | | | |-BiosVfBMEDMAMitigation + | | | | | |-BiosVfBootOptionRetry + | | | | | |-BiosVfCPUHardwarePowerManagement + | | | | | |-BiosVfCPUPerformance + | | | | | |-BiosVfConsistentDeviceNameControl + | | | | | |-BiosVfConsoleRedirection + | | | | | |-BiosVfCoreMultiProcessing + | | | | | |-BiosVfDDR3VoltageSelection + | | | | | |-BiosVfDRAMClockThrottling + | | | | | |-BiosVfDirectCacheAccess + | | | | | |-BiosVfDramRefreshRate + | | | | | |-BiosVfEnergyPerformanceTuning + | | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | | |-BiosVfExecuteDisableBit + | | | | | |-BiosVfFRB2Timer + | | | | | |-BiosVfFrequencyFloorOverride + | | | | | |-BiosVfFrontPanelLockout + | | | | | |-BiosVfIOEMezz1OptionROM + | | | | | |-BiosVfIOENVMe1OptionROM + | | | | | |-BiosVfIOENVMe2OptionROM + | | | | | |-BiosVfIOESlot1OptionROM + | | | | | |-BiosVfIOESlot2OptionROM + | | | | | |-BiosVfIntegratedGraphics + | | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | | |-BiosVfIntelHyperThreadingTech + | | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | | |-BiosVfIntelTurboBoostTech + | | | | | |-BiosVfIntelVTForDirectedIO + | | | | | |-BiosVfIntelVirtualizationTechnology + | | | | | |-BiosVfInterleaveConfiguration + | | | | | |-BiosVfLocalX2Apic + | | | | | |-BiosVfLvDIMMSupport + | | | | | |-BiosVfMaxVariableMTRRSetting + | | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | | |-BiosVfMirroringMode + | | | | | |-BiosVfNUMAOptimized + | | | | | |-BiosVfOSBootWatchdogTimer + | | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | | |-BiosVfOnboardGraphics + | | | | | |-BiosVfOnboardSATAController + | | | | | |-BiosVfOnboardStorage + | | | | | |-BiosVfOptionROMEnable + | | | | | |-BiosVfOptionROMLoad + | | | | | |-BiosVfOutOfBandManagement + | | | | | |-BiosVfPCHSATAMode + | | | | | |-BiosVfPCILOMPortsConfiguration + | | | | | |-BiosVfPCIROMCLP + | | | | | |-BiosVfPCISlotLinkSpeed + | | | | | |-BiosVfPCISlotOptionROMEnable + | | | | | |-BiosVfPOSTErrorPause + | | | | | |-BiosVfPSTATECoordination + | | | | | |-BiosVfPackageCStateLimit + | | | | | |-BiosVfPanicAndHighWatermark + | | | | | |-BiosVfProcessorC1E + | | | | | |-BiosVfProcessorC3Report + | | | | | |-BiosVfProcessorC6Report + | | | | | |-BiosVfProcessorC7Report + | | | | | |-BiosVfProcessorCMCI + | | | | | |-BiosVfProcessorCState + | | | | | |-BiosVfProcessorEnergyConfiguration + | | | | | |-BiosVfProcessorPrefetchConfig + | | | | | |-BiosVfQPILinkFrequencySelect + | | | | | |-BiosVfQPISnoopMode + | | | | | |-BiosVfQuietBoot + | | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | | |-BiosVfResumeOnACPowerLoss + | | | | | |-BiosVfSBMezz1OptionROM + | | | | | |-BiosVfSBNVMe1OptionROM + | | | | | |-BiosVfSIOC1OptionROM + | | | | | |-BiosVfSIOC2OptionROM + | | | | | |-BiosVfScrubPolicies + | | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | | |-BiosVfSerialPortAEnable + | | | | | |-BiosVfSparingMode + | | | | | |-BiosVfSriovConfig + | | | | | |-BiosVfTPMPendingOperation + | | | | | |-BiosVfTPMSupport + | | | | | |-BiosVfTrustedPlatformModule + | | | | | |-BiosVfUCSMBootModeControl + | | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | | |-BiosVfUSBBootConfig + | | | | | |-BiosVfUSBConfiguration + | | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | | |-BiosVfUSBPortConfiguration + | | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | | |-BiosVfVGAPriority + | | | | | |-BiosVfWorkloadConfiguration + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-ComputeBoardController + | | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-ComputeMbPowerStats + | | | | |-ComputeMbPowerStatsHist + | | | |-ComputeMbTempStats + | | | | |-ComputeMbTempStatsHist + | | | |-EquipmentHealthLed + | | | | |-ComputeHealthLedSensorAlarm + | | | | |-FaultInst + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-FaultInst + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-PowerBudget + | | | |-FaultInst + | | | |-PowerProfiledPower + | | |-ComputeFactoryResetOperation + | | |-ComputeFwSyncAck + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-ComputeHostUtilityOs + | | | |-MgmtUsbNicMgmtIf + | | |-ComputeKvmMgmtPolicy + | | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-ComputeMemoryConfiguration + | | |-ComputePersonality + | | |-ComputePhysicalExtension + | | | |-FaultInst + | | |-ComputePhysicalFsm + | | | |-ComputePhysicalFsmStage + | | |-ComputePhysicalFsmTask + | | |-ComputePnuOSImage + | | |-ComputePoolable + | | | |-ComputePoolPolicyRef + | | |-ComputeRebootLog + | | |-ComputeScrubPolicy + | | |-DiagSrvCtrl + | | | |-DiagRslt + | | | | |-DiagLogEp + | | | |-DiagRunPolicy + | | | | |-DiagMemoryTest + | | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIOExpander + | | |-EquipmentIndicatorLed + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FaultSuppressTask + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-FirmwareImageLock + | | |-FirmwareStatus + | | | |-FaultInst + | | |-LsIdentityInfo + | | | |-FaultInst + | | |-LsbootDef + | | | |-LsbootBootSecurity + | | | |-LsbootEFIShell + | | | |-LsbootIScsi + | | | | |-LsbootIScsiImagePath + | | | | |-LsbootUEFIBootParam + | | | |-LsbootLan + | | | | |-LsbootLanImagePath + | | | | |-LsbootUEFIBootParam + | | | | |-VnicIpV4StaticAddr + | | | |-LsbootSan + | | | | |-LsbootSanCatSanImage + | | | | |-LsbootSanCatSanImagePath + | | | | |-LsbootUEFIBootParam + | | | |-LsbootStorage + | | | | |-LsbootLocalStorage + | | | | | |-LsbootDefaultLocalImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootEmbeddedLocalDiskImage + | | | | | | |-LsbootEmbeddedLocalDiskImagePath + | | | | | | | |-LsbootUEFIBootParam + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootEmbeddedLocalLunImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootLocalDiskImage + | | | | | | |-LsbootLocalDiskImagePath + | | | | | | | |-LsbootUEFIBootParam + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootLocalHddImage + | | | | | | |-LsbootLocalLunImagePath + | | | | | | | |-LsbootUEFIBootParam + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootNvme + | | | | | | |-LsbootNvmeDiskSsd + | | | | | | |-LsbootNvmePciSsd + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUsbExternalImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUsbFlashStorageImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUsbInternalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootSanImage + | | | | |-LsbootSanImagePath + | | | | |-LsbootUEFIBootParam + | | | |-LsbootVirtualMedia + | | |-LstorageProfile + | | | |-LstorageControllerDef + | | | | |-LstorageControllerModeConfig + | | | | |-LstorageControllerQualifier + | | | |-LstorageDasScsiLun + | | | | |-FaultInst + | | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-LstorageLunSetConfig + | | | | |-LstorageLunSetDiskSlot + | | | | |-LstorageVirtualDriveDef + | | | |-LstorageSecurity + | | | |-LstorageDriveSecurity + | | | |-LstorageLocal + | | | |-LstorageRemote + | | | |-LstorageLogin + | | |-MemoryRuntime + | | | |-MemoryRuntimeHist + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-MgmtKmipCertPolicy + | | |-MgmtSecurity + | | | |-MgmtKmip + | | |-MgmtSpdmCertificatePolicy + | | | |-MgmtSpdmCertificate + | | |-MoKvCfgHolder + | | | |-MoIpV4AddrKv + | | | | |-FaultInst + | | | |-MoIpV6AddrKv + | | | | |-FaultInst + | | | |-MoKv + | | | |-MoVnicKv + | | |-MoKvInvHolder + | | | |-MoInvKv + | | |-OsAgent + | | |-OsInstance + | | | |-OsEthBondIntf + | | | | |-OsARPLinkMonitoringPolicy + | | | | | |-OsARPTarget + | | | | |-OsEthBondModeActiveBackup + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedALB + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedRR + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedTLB + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedXOR + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBroadcast + | | | | | |-OsPrimarySlave + | | | | |-OsEthIntf + | | | | |-OsMiiLinkMonitoringPolicy + | | | |-OsEthIntf + | | |-PciEquipSlot + | | | |-FaultInst + | | |-PciUnit + | | |-PowerBudget + | | | |-FaultInst + | | | |-PowerProfiledPower + | | |-ProcessorRuntime + | | | |-ProcessorRuntimeHist + | | |-SolIf + | | |-StorageEnclosure + | | | |-EventInst + | | | |-FaultInst + | | | |-StorageEnclosureDiskSlotEp + | | | | |-FaultInst + | | | | |-StorageControllerRef + | | | |-StorageEnclosureFsm + | | | | |-StorageEnclosureFsmStage + | | | |-StorageEnclosureFsmTask + | | | |-StorageHddMotherBoardTempStats + | | | | |-StorageHddMotherBoardTempStatsHist + | | | |-StorageLocalDisk + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageControllerEp + | | | |-StorageDiskEnvStats + | | | | |-StorageDiskEnvStatsHist + | | | |-StorageLocalDiskFsm + | | | | |-StorageLocalDiskFsmStage + | | | |-StorageLocalDiskFsmTask + | | | |-StorageLocalDiskPartition + | | | |-StorageOperation + | | | |-StorageSasPort + | | | |-StorageSsdHealthStats + | | | |-StorageSsdHealthStatsHist + | | |-StorageVirtualDriveContainer + | | | |-StorageVirtualDrive + | | | |-FaultInst + | | | |-StorageControllerEp + | | | |-StorageLunDisk + | | | |-StorageOperation + | | | |-StorageScsiLunRef + | | | |-StorageVDMemberEp + | | | |-FaultInst + | | |-SwUlan + | | |-SysdebugDiagnosticLog + | |-ComputeBoardController + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-ComputeCartridge + | | |-ComputeServerUnit + | | |-AaaEpAuthProfile + | | | |-AaaEpUser + | | | |-AaaCimcSession + | | |-AaaEpUser + | | | |-AaaCimcSession + | | |-AdaptorHostIfConfig + | | |-AdaptorUnit + | | | |-AdaptorExtEthIf + | | | | |-AdaptorEthPortBySizeLargeStats + | | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | | |-AdaptorEthPortBySizeSmallStats + | | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | | |-AdaptorEthPortErrStats + | | | | | |-AdaptorEthPortErrStatsHist + | | | | |-AdaptorEthPortMcastStats + | | | | | |-AdaptorEthPortMcastStatsHist + | | | | |-AdaptorEthPortOutsizedStats + | | | | | |-AdaptorEthPortOutsizedStatsHist + | | | | |-AdaptorEthPortStats + | | | | | |-AdaptorEthPortStatsHist + | | | | |-AdaptorExtEthIfFsm + | | | | | |-AdaptorExtEthIfFsmStage + | | | | |-AdaptorExtEthIfFsmTask + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FabricEthMonSrcEp + | | | | |-FaultInst + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-AdaptorHostEthIf + | | | | |-AdaptorAzureQosProfile + | | | | |-AdaptorEthAdvFilterProfile + | | | | |-AdaptorEthArfsProfile + | | | | |-AdaptorEthCompQueueProfile + | | | | |-AdaptorEthFailoverProfile + | | | | |-AdaptorEthGENEVEProfile + | | | | |-AdaptorEthInterruptProfile + | | | | |-AdaptorEthInterruptScalingProfile + | | | | |-AdaptorEthNVGREProfile + | | | | |-AdaptorEthOffloadProfile + | | | | |-AdaptorEthPortBySizeLargeStats + | | | | | |-AdaptorEthPortBySizeLargeStatsHist + | | | | |-AdaptorEthPortBySizeSmallStats + | | | | | |-AdaptorEthPortBySizeSmallStatsHist + | | | | |-AdaptorEthPortErrStats + | | | | | |-AdaptorEthPortErrStatsHist + | | | | |-AdaptorEthPortMcastStats + | | | | | |-AdaptorEthPortMcastStatsHist + | | | | |-AdaptorEthPortOutsizedStats + | | | | | |-AdaptorEthPortOutsizedStatsHist + | | | | |-AdaptorEthPortStats + | | | | | |-AdaptorEthPortStatsHist + | | | | |-AdaptorEthRecvQueueProfile + | | | | |-AdaptorEthRoCEProfile + | | | | |-AdaptorEthVxLANProfile + | | | | |-AdaptorEthWorkQueueProfile + | | | | |-AdaptorExtIpV6RssHashProfile + | | | | |-AdaptorFcOEIf + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-AdaptorHostEthIfFsm + | | | | | |-AdaptorHostEthIfFsmStage + | | | | |-AdaptorHostEthIfFsmTask + | | | | |-AdaptorIpV4RssHashProfile + | | | | |-AdaptorIpV6RssHashProfile + | | | | |-AdaptorPTP + | | | | |-AdaptorRssProfile + | | | | |-AdaptorUsnicConnDef + | | | | | |-AdaptorEthCompQueueProfile + | | | | | |-AdaptorEthFailoverProfile + | | | | | |-AdaptorEthInterruptProfile + | | | | | |-AdaptorEthInterruptScalingProfile + | | | | | |-AdaptorEthOffloadProfile + | | | | | |-AdaptorEthRecvQueueProfile + | | | | | |-AdaptorEthWorkQueueProfile + | | | | | |-AdaptorExtIpV6RssHashProfile + | | | | | |-AdaptorIpV4RssHashProfile + | | | | | |-AdaptorIpV6RssHashProfile + | | | | | |-AdaptorRssProfile + | | | | |-AdaptorVlan + | | | | | |-AdaptorEtherIfStats + | | | | | | |-AdaptorEtherIfStatsHist + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dhcp + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4IscsiAddr + | | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4PooledIscsiAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIPv4Dns + | | | | | | |-VnicIpV4History + | | | | | |-VnicIPv4StaticRoute + | | | | | |-VnicIScsiAutoTargetIf + | | | | | |-VnicIScsiStaticTargetIf + | | | | | | |-FaultInst + | | | | | | |-VnicLun + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-AdaptorVmmqConnDef + | | | | | |-AdaptorEthCompQueueProfile + | | | | | |-AdaptorEthInterruptProfile + | | | | | |-AdaptorEthRecvQueueProfile + | | | | | |-AdaptorEthRoCEProfile + | | | | | |-AdaptorEthWorkQueueProfile + | | | | | |-AdaptorRssProfile + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-NetworkIfStats + | | | |-AdaptorHostFcIf + | | | | |-AdaptorFcCdbWorkQueueProfile + | | | | |-AdaptorFcErrorRecoveryProfile + | | | | |-AdaptorFcFnicProfile + | | | | |-AdaptorFcIfEventStats + | | | | | |-AdaptorFcIfEventStatsHist + | | | | |-AdaptorFcIfFC4Stats + | | | | | |-AdaptorFcIfFC4StatsHist + | | | | |-AdaptorFcIfFrameStats + | | | | | |-AdaptorFcIfFrameStatsHist + | | | | |-AdaptorFcInterruptProfile + | | | | |-AdaptorFcOEIf + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-AdaptorFcPortFLogiProfile + | | | | |-AdaptorFcPortPLogiProfile + | | | | |-AdaptorFcPortProfile + | | | | |-AdaptorFcPortStats + | | | | | |-AdaptorFcPortStatsHist + | | | | |-AdaptorFcRecvQueueProfile + | | | | |-AdaptorFcVhbaTypeProfile + | | | | |-AdaptorFcWorkQueueProfile + | | | | |-AdaptorHostFcIfFsm + | | | | | |-AdaptorHostFcIfFsmStage + | | | | |-AdaptorHostFcIfFsmTask + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-AdaptorVsan + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-NetworkIfStats + | | | |-AdaptorHostIscsiIf + | | | | |-AdaptorIscsiProt + | | | | |-AdaptorIscsiTargetIf + | | | | |-AdaptorProtocolProfile + | | | | |-AdaptorVlan + | | | | | |-AdaptorEtherIfStats + | | | | | | |-AdaptorEtherIfStatsHist + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dhcp + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4IscsiAddr + | | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4PooledIscsiAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIPv4Dns + | | | | | | |-VnicIpV4History + | | | | | |-VnicIPv4StaticRoute + | | | | | |-VnicIScsiAutoTargetIf + | | | | | |-VnicIScsiStaticTargetIf + | | | | | | |-FaultInst + | | | | | | |-VnicLun + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | | |-NetworkIfStats + | | | | |-VnicIPv4Dhcp + | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4IscsiAddr + | | | | | |-VnicIPv4Dns + | | | | |-VnicIPv4PooledIscsiAddr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIpV4History + | | | | |-VnicIPv4StaticRoute + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-AdaptorHostPort + | | | |-AdaptorHostScsiIf + | | | | |-AdaptorHostScsiLunRef + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-FaultInst + | | | | |-NetworkIfStats + | | | |-AdaptorHostServiceEthIf + | | | | |-AdaptorVlan + | | | | | |-AdaptorEtherIfStats + | | | | | | |-AdaptorEtherIfStatsHist + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | | |-VnicIPv4Dhcp + | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4IscsiAddr + | | | | | | |-VnicIPv4Dns + | | | | | |-VnicIPv4PooledIscsiAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIPv4Dns + | | | | | | |-VnicIpV4History + | | | | | |-VnicIPv4StaticRoute + | | | | | |-VnicIScsiAutoTargetIf + | | | | | |-VnicIScsiStaticTargetIf + | | | | | | |-FaultInst + | | | | | | |-VnicLun + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-AdaptorVnicStats + | | | | | |-AdaptorVnicStatsHist + | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-NetworkIfStats + | | | |-AdaptorMenloDcePortStats + | | | | |-AdaptorMenloDcePortStatsHist + | | | |-AdaptorMenloEthErrorStats + | | | | |-AdaptorMenloEthErrorStatsHist + | | | |-AdaptorMenloEthStats + | | | | |-AdaptorMenloEthStatsHist + | | | |-AdaptorMenloFcErrorStats + | | | | |-AdaptorMenloFcErrorStatsHist + | | | |-AdaptorMenloFcStats + | | | | |-AdaptorMenloFcStatsHist + | | | |-AdaptorMenloHostPortStats + | | | | |-AdaptorMenloHostPortStatsHist + | | | |-AdaptorMenloMcpuErrorStats + | | | | |-AdaptorMenloMcpuErrorStatsHist + | | | |-AdaptorMenloMcpuStats + | | | | |-AdaptorMenloMcpuStatsHist + | | | |-AdaptorMenloNetEgStats + | | | | |-AdaptorMenloNetEgStatsHist + | | | |-AdaptorMenloNetInStats + | | | | |-AdaptorMenloNetInStatsHist + | | | |-AdaptorMenloQErrorStats + | | | | |-AdaptorMenloQErrorStatsHist + | | | |-AdaptorMenloQStats + | | | | |-AdaptorMenloQStatsHist + | | | |-AdaptorUnitExtn + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | |-DcxNs + | | | | |-FaultInst + | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-EquipmentPOST + | | | |-EquipmentPciDef + | | | |-FaultInst + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-BiosUnit + | | | |-BiosBOT + | | | | |-BiosBootDevGrp + | | | | |-BiosBootDev + | | | |-BiosSettings + | | | | |-BiosTokenFeatureGroup + | | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosTokenParam + | | | | | |-BiosTokenSettings + | | | | |-BiosVfACPI10Support + | | | | |-BiosVfASPMSupport + | | | | |-BiosVfAllUSBDevices + | | | | |-BiosVfAltitude + | | | | |-BiosVfAssertNMIOnPERR + | | | | |-BiosVfAssertNMIOnSERR + | | | | |-BiosVfBMEDMAMitigation + | | | | |-BiosVfBootOptionRetry + | | | | |-BiosVfCPUHardwarePowerManagement + | | | | |-BiosVfCPUPerformance + | | | | |-BiosVfConsistentDeviceNameControl + | | | | |-BiosVfConsoleRedirection + | | | | |-BiosVfCoreMultiProcessing + | | | | |-BiosVfDDR3VoltageSelection + | | | | |-BiosVfDRAMClockThrottling + | | | | |-BiosVfDirectCacheAccess + | | | | |-BiosVfDramRefreshRate + | | | | |-BiosVfEnergyPerformanceTuning + | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | |-BiosVfExecuteDisableBit + | | | | |-BiosVfFRB2Timer + | | | | |-BiosVfFrequencyFloorOverride + | | | | |-BiosVfFrontPanelLockout + | | | | |-BiosVfIOEMezz1OptionROM + | | | | |-BiosVfIOENVMe1OptionROM + | | | | |-BiosVfIOENVMe2OptionROM + | | | | |-BiosVfIOESlot1OptionROM + | | | | |-BiosVfIOESlot2OptionROM + | | | | |-BiosVfIntegratedGraphics + | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | |-BiosVfIntelHyperThreadingTech + | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | |-BiosVfIntelTurboBoostTech + | | | | |-BiosVfIntelVTForDirectedIO + | | | | |-BiosVfIntelVirtualizationTechnology + | | | | |-BiosVfInterleaveConfiguration + | | | | |-BiosVfLocalX2Apic + | | | | |-BiosVfLvDIMMSupport + | | | | |-BiosVfMaxVariableMTRRSetting + | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | |-BiosVfMirroringMode + | | | | |-BiosVfNUMAOptimized + | | | | |-BiosVfOSBootWatchdogTimer + | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | |-BiosVfOnboardGraphics + | | | | |-BiosVfOnboardSATAController + | | | | |-BiosVfOnboardStorage + | | | | |-BiosVfOptionROMEnable + | | | | |-BiosVfOptionROMLoad + | | | | |-BiosVfOutOfBandManagement + | | | | |-BiosVfPCHSATAMode + | | | | |-BiosVfPCILOMPortsConfiguration + | | | | |-BiosVfPCIROMCLP + | | | | |-BiosVfPCISlotLinkSpeed + | | | | |-BiosVfPCISlotOptionROMEnable + | | | | |-BiosVfPOSTErrorPause + | | | | |-BiosVfPSTATECoordination + | | | | |-BiosVfPackageCStateLimit + | | | | |-BiosVfPanicAndHighWatermark + | | | | |-BiosVfProcessorC1E + | | | | |-BiosVfProcessorC3Report + | | | | |-BiosVfProcessorC6Report + | | | | |-BiosVfProcessorC7Report + | | | | |-BiosVfProcessorCMCI + | | | | |-BiosVfProcessorCState + | | | | |-BiosVfProcessorEnergyConfiguration + | | | | |-BiosVfProcessorPrefetchConfig + | | | | |-BiosVfQPILinkFrequencySelect + | | | | |-BiosVfQPISnoopMode + | | | | |-BiosVfQuietBoot + | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | |-BiosVfResumeOnACPowerLoss + | | | | |-BiosVfSBMezz1OptionROM + | | | | |-BiosVfSBNVMe1OptionROM + | | | | |-BiosVfSIOC1OptionROM + | | | | |-BiosVfSIOC2OptionROM + | | | | |-BiosVfScrubPolicies + | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | |-BiosVfSerialPortAEnable + | | | | |-BiosVfSparingMode + | | | | |-BiosVfSriovConfig + | | | | |-BiosVfTPMPendingOperation + | | | | |-BiosVfTPMSupport + | | | | |-BiosVfTrustedPlatformModule + | | | | |-BiosVfUCSMBootModeControl + | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | |-BiosVfUSBBootConfig + | | | | |-BiosVfUSBConfiguration + | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | |-BiosVfUSBPortConfiguration + | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | |-BiosVfVGAPriority + | | | | |-BiosVfWorkloadConfiguration + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-BiosVIdentityParams + | | |-CimcvmediaMountConfigDef + | | | |-CimcvmediaConfigMountEntry + | | |-ComputeAdminAck + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-ComputeBoard + | | | |-ComputeIOHub + | | | | |-ComputeIOHubEnvStats + | | | | | |-ComputeIOHubEnvStatsHist + | | | | |-FaultInst + | | | |-ComputeMbPowerStats + | | | | |-ComputeMbPowerStatsHist + | | | |-ComputeMbTempStats + | | | | |-ComputeMbTempStatsHist + | | | |-ComputePCIeFatalCompletionStats + | | | |-ComputePCIeFatalProtocolStats + | | | |-ComputePCIeFatalReceiveStats + | | | |-ComputePCIeFatalStats + | | | |-ComputeRackUnitMbTempStats + | | | | |-ComputeRackUnitMbTempStatsHist + | | | |-ComputeRtcBattery + | | | | |-FaultInst + | | | |-CoprocessorCard + | | | |-EquipmentTpm + | | | | |-FaultInst + | | | |-FaultInst + | | | |-GraphicsCard + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-GraphicsController + | | | |-LstorageLocal + | | | |-LstorageLocalDef + | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-LstorageRemoteDef + | | | | |-LstorageLogin + | | | |-MemoryArray + | | | | |-FaultInst + | | | | |-MemoryArrayEnvStats + | | | | | |-MemoryArrayEnvStatsHist + | | | | |-MemoryPersistentMemoryUnit + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-MemoryErrorStats + | | | | | |-MemoryUnitEnvStats + | | | | | |-MemoryUnitEnvStatsHist + | | | | |-MemoryUnit + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-MemoryErrorStats + | | | | |-MemoryUnitEnvStats + | | | | |-MemoryUnitEnvStatsHist + | | | |-MemoryBufferUnit + | | | | |-FaultInst + | | | | |-MemoryBufferUnitEnvStats + | | | | |-MemoryBufferUnitEnvStatsHist + | | | |-MemoryPersistentMemoryConfiguration + | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryConfigResult + | | | | | |-FaultInst + | | | | | |-MemoryPersistentMemoryNamespaceConfigResult + | | | | | |-FaultInst + | | | | |-MemoryPersistentMemoryRegion + | | | | |-MemoryPersistentMemoryNamespace + | | | | |-FaultInst + | | | |-PciSwitch + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-PciLink + | | | |-ProcessorUnit + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-ProcessorCacheMemStats + | | | | |-ProcessorCore + | | | | | |-ProcessorThread + | | | | |-ProcessorEnvStats + | | | | | |-ProcessorEnvStatsHist + | | | | |-ProcessorErrorStats + | | | | |-ProcessorExecStats + | | | | |-ProcessorIOStats + | | | | |-ProcessorMiscStats + | | | | |-ProcessorPCIBusStats + | | | | |-ProcessorPMUStats + | | | | |-ProcessorSecurityStats + | | | |-SecurityUnit + | | | | |-EquipmentInventoryStatus + | | | | |-FaultInst + | | | |-StorageController + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-LstorageControllerDef + | | | | | |-LstorageControllerModeConfig + | | | | | |-LstorageControllerQualifier + | | | | |-MgmtController + | | | | | |-CimcvmediaActualMountList + | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | |-FaultInst + | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | |-EventInst + | | | | | |-FabricLocale + | | | | | | |-AdaptorExtEthIfPc + | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | |-DcxVIf + | | | | | | | |-FaultInst + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPath + | | | | | | |-DcxVc + | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FabricSanGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-FaultInst + | | | | | | | |-SwCmclan + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | |-FaultInst + | | | | | | | |-SwNetflowMonitorRef + | | | | | | | |-SwUlan + | | | | | | | |-SwVlan + | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | |-FaultInst + | | | | | | | |-SwVsan + | | | | | | | |-SwFcZoneSet + | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | |-SwFcZone + | | | | | | | | |-SwZoneTargetMember + | | | | | | | |-SwFcUserZoneGroup + | | | | | | | |-SwFcUserZone + | | | | | | | |-SwFcEndpoint + | | | | | | |-FabricPathConn + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareImage + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-FirmwareImageFsm + | | | | | | | |-FirmwareImageFsmStage + | | | | | | |-FirmwareImageFsmTask + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareModule + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-MgmtCimcSecureBoot + | | | | | |-MgmtCmcSecureBoot + | | | | | |-MgmtConnection + | | | | | | |-FaultInst + | | | | | |-MgmtControllerFsm + | | | | | | |-MgmtControllerFsmStage + | | | | | |-MgmtControllerFsmTask + | | | | | |-MgmtHealthStatus + | | | | | | |-FaultInst + | | | | | | |-MgmtHealthAttr + | | | | | |-MgmtIf + | | | | | | |-DhcpAcquired + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfConfig + | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | |-MgmtIfFsm + | | | | | | | |-MgmtIfFsmStage + | | | | | | |-MgmtIfFsmTask + | | | | | |-MgmtInterface + | | | | | | |-FaultInst + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtKvmCertificate + | | | | | | |-FaultInst + | | | | | |-MgmtProfDerivedInterface + | | | | | | |-MgmtVnet + | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4StaticAddr + | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV6History + | | | | | | |-VnicIpV6StaticAddr + | | | | | |-MgmtSpdmCertificateInventory + | | | | | | |-MgmtSpdmCertificateData + | | | | | |-MgmtSwPersonalities + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | |-MgmtSwPersonality + | | | | | |-MgmtUsbNicMgmtIf + | | | | | |-SysdebugMEpLog + | | | | | | |-FaultInst + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | |-VnicIpV4StaticAddr + | | | | |-StorageDrive + | | | | |-StorageEmbeddedStorage + | | | | |-StorageEnclosure + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-StorageEnclosureDiskSlotEp + | | | | | | |-FaultInst + | | | | | | |-StorageControllerRef + | | | | | |-StorageEnclosureFsm + | | | | | | |-StorageEnclosureFsmStage + | | | | | |-StorageEnclosureFsmTask + | | | | | |-StorageHddMotherBoardTempStats + | | | | | | |-StorageHddMotherBoardTempStatsHist + | | | | | |-StorageLocalDisk + | | | | | |-EquipmentLocatorLed + | | | | | | |-EquipmentLocatorLedFsm + | | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | | |-EquipmentLocatorLedFsmTask + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-MgmtController + | | | | | | |-CimcvmediaActualMountList + | | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | | |-FaultInst + | | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | | |-EventInst + | | | | | | |-FabricLocale + | | | | | | | |-AdaptorExtEthIfPc + | | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | | |-DcxVIf + | | | | | | | | |-FaultInst + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPath + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPathConn + | | | | | | | | |-FabricPathEp + | | | | | | | | |-PortTrustMode + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FaultInst + | | | | | | |-FirmwareBootDefinition + | | | | | | | |-FirmwareBootUnit + | | | | | | | | |-FaultInst + | | | | | | | | |-FirmwareInstallable + | | | | | | | | | |-FirmwareUcscInfo + | | | | | | | | |-FirmwareServicePack + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareImage + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareImageFsm + | | | | | | | | |-FirmwareImageFsmStage + | | | | | | | |-FirmwareImageFsmTask + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareModule + | | | | | | |-FirmwareRunning + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUpdatable + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-MgmtCimcSecureBoot + | | | | | | |-MgmtCmcSecureBoot + | | | | | | |-MgmtConnection + | | | | | | | |-FaultInst + | | | | | | |-MgmtControllerFsm + | | | | | | | |-MgmtControllerFsmStage + | | | | | | |-MgmtControllerFsmTask + | | | | | | |-MgmtHealthStatus + | | | | | | | |-FaultInst + | | | | | | | |-MgmtHealthAttr + | | | | | | |-MgmtIf + | | | | | | | |-DhcpAcquired + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfConfig + | | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | | |-EventInst + | | | | | | | | |-FaultInst + | | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | | |-MgmtIfFsm + | | | | | | | | |-MgmtIfFsmStage + | | | | | | | |-MgmtIfFsmTask + | | | | | | |-MgmtInterface + | | | | | | | |-FaultInst + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtKvmCertificate + | | | | | | | |-FaultInst + | | | | | | |-MgmtProfDerivedInterface + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtSpdmCertificateInventory + | | | | | | | |-MgmtSpdmCertificateData + | | | | | | |-MgmtSwPersonalities + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtUsbNicMgmtIf + | | | | | | |-SysdebugMEpLog + | | | | | | | |-FaultInst + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | | |-VnicIpV4StaticAddr + | | | | | |-StorageControllerEp + | | | | | |-StorageDiskEnvStats + | | | | | | |-StorageDiskEnvStatsHist + | | | | | |-StorageLocalDiskFsm + | | | | | | |-StorageLocalDiskFsmStage + | | | | | |-StorageLocalDiskFsmTask + | | | | | |-StorageLocalDiskPartition + | | | | | |-StorageOperation + | | | | | |-StorageSasPort + | | | | | |-StorageSsdHealthStats + | | | | | |-StorageSsdHealthStatsHist + | | | | |-StorageLocalDisk + | | | | | |-EquipmentLocatorLed + | | | | | | |-EquipmentLocatorLedFsm + | | | | | | | |-EquipmentLocatorLedFsmStage + | | | | | | |-EquipmentLocatorLedFsmTask + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-MgmtController + | | | | | | |-CimcvmediaActualMountList + | | | | | | | |-CimcvmediaActualMountEntry + | | | | | | | | |-FaultInst + | | | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | | | |-EventInst + | | | | | | |-FabricLocale + | | | | | | | |-AdaptorExtEthIfPc + | | | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | | | |-DcxVIf + | | | | | | | | |-FaultInst + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPath + | | | | | | | |-DcxVc + | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FabricSanGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-FaultInst + | | | | | | | | |-SwCmclan + | | | | | | | | | |-FabricNetGroupRef + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwNetflowMonitorRef + | | | | | | | | |-SwUlan + | | | | | | | | |-SwVlan + | | | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | | | |-FaultInst + | | | | | | | | |-SwVsan + | | | | | | | | |-SwFcZoneSet + | | | | | | | | |-SwFcServerZoneGroup + | | | | | | | | | |-SwZoneInitiatorMember + | | | | | | | | | |-SwFcZone + | | | | | | | | | |-SwZoneTargetMember + | | | | | | | | |-SwFcUserZoneGroup + | | | | | | | | |-SwFcUserZone + | | | | | | | | |-SwFcEndpoint + | | | | | | | |-FabricPathConn + | | | | | | | | |-FabricPathEp + | | | | | | | | |-PortTrustMode + | | | | | | | |-FabricPathEp + | | | | | | | |-PortTrustMode + | | | | | | |-FaultInst + | | | | | | |-FirmwareBootDefinition + | | | | | | | |-FirmwareBootUnit + | | | | | | | | |-FaultInst + | | | | | | | | |-FirmwareInstallable + | | | | | | | | | |-FirmwareUcscInfo + | | | | | | | | |-FirmwareServicePack + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareImage + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareImageFsm + | | | | | | | | |-FirmwareImageFsmStage + | | | | | | | |-FirmwareImageFsmTask + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareModule + | | | | | | |-FirmwareRunning + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUpdatable + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-MgmtCimcSecureBoot + | | | | | | |-MgmtCmcSecureBoot + | | | | | | |-MgmtConnection + | | | | | | | |-FaultInst + | | | | | | |-MgmtControllerFsm + | | | | | | | |-MgmtControllerFsmStage + | | | | | | |-MgmtControllerFsmTask + | | | | | | |-MgmtHealthStatus + | | | | | | | |-FaultInst + | | | | | | | |-MgmtHealthAttr + | | | | | | |-MgmtIf + | | | | | | | |-DhcpAcquired + | | | | | | | |-EventInst + | | | | | | | |-FaultInst + | | | | | | | |-MgmtIPv6IfConfig + | | | | | | | | |-MgmtIPv6IfAddr + | | | | | | | | |-EventInst + | | | | | | | | |-FaultInst + | | | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | | | |-MgmtIfFsm + | | | | | | | | |-MgmtIfFsmStage + | | | | | | | |-MgmtIfFsmTask + | | | | | | |-MgmtInterface + | | | | | | | |-FaultInst + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtKvmCertificate + | | | | | | | |-FaultInst + | | | | | | |-MgmtProfDerivedInterface + | | | | | | | |-MgmtVnet + | | | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4PooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV4History + | | | | | | | |-VnicIpV4StaticAddr + | | | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | | | |-FaultInst + | | | | | | | | |-VnicIpV6History + | | | | | | | |-VnicIpV6StaticAddr + | | | | | | |-MgmtSpdmCertificateInventory + | | | | | | | |-MgmtSpdmCertificateData + | | | | | | |-MgmtSwPersonalities + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtSwPersonalitiesInventory + | | | | | | | |-MgmtSwPersonality + | | | | | | |-MgmtUsbNicMgmtIf + | | | | | | |-SysdebugMEpLog + | | | | | | | |-FaultInst + | | | | | | |-VnicIpV4PooledAddr + | | | | | | | |-FaultInst + | | | | | | | |-VnicIpV4History + | | | | | | |-VnicIpV4ProfDerivedAddr + | | | | | | |-VnicIpV4StaticAddr + | | | | | |-StorageControllerEp + | | | | | |-StorageDiskEnvStats + | | | | | | |-StorageDiskEnvStatsHist + | | | | | |-StorageLocalDiskFsm + | | | | | | |-StorageLocalDiskFsmStage + | | | | | |-StorageLocalDiskFsmTask + | | | | | |-StorageLocalDiskPartition + | | | | | |-StorageOperation + | | | | | |-StorageSasPort + | | | | | |-StorageSsdHealthStats + | | | | | |-StorageSsdHealthStatsHist + | | | | |-StorageLocalDiskConfigDef + | | | | | |-LstorageSecurity + | | | | | | |-LstorageDriveSecurity + | | | | | | |-LstorageLocal + | | | | | | |-LstorageRemote + | | | | | | |-LstorageLogin + | | | | | |-StorageLocalDiskPartition + | | | | |-StorageLocalDiskEp + | | | | |-StorageLocalLun + | | | | |-StorageMezzFlashLife + | | | | | |-FaultInst + | | | | |-StorageNvmeStats + | | | | | |-StorageNvmeStatsHist + | | | | |-StorageNvmeStorage + | | | | |-StorageOnboardDevice + | | | | | |-FirmwareBootDefinition + | | | | | | |-FirmwareBootUnit + | | | | | | | |-FaultInst + | | | | | | | |-FirmwareInstallable + | | | | | | | | |-FirmwareUcscInfo + | | | | | | | |-FirmwareServicePack + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareRunning + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-StorageOperation + | | | | |-StorageRaidBattery + | | | | | |-FaultInst + | | | | | |-StorageOperation + | | | | | |-StorageTransportableFlashModule + | | | | |-StorageVirtualDrive + | | | | | |-FaultInst + | | | | | |-StorageControllerEp + | | | | | |-StorageLunDisk + | | | | | |-StorageOperation + | | | | | |-StorageScsiLunRef + | | | | | |-StorageVDMemberEp + | | | | | |-FaultInst + | | | | |-StorageVirtualDriveEp + | | | |-StorageFlexFlashController + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-StorageFlexFlashCard + | | | | | |-FaultInst + | | | | | |-StorageFlexFlashDrive + | | | | | |-FaultInst + | | | | |-StorageFlexFlashControllerFsm + | | | | | |-StorageFlexFlashControllerFsmStage + | | | | |-StorageFlexFlashControllerFsmTask + | | | | |-StorageFlexFlashVirtualDrive + | | | | | |-FaultInst + | | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-StorageLocalDiskSlotEp + | | | | |-FaultInst + | | | |-StorageMiniStorage + | | | | |-EquipmentInventoryStatus + | | | | | |-FaultInst + | | | | |-StorageControllerReference + | | | |-StorageNvmeSwitch + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-StorageSasExpander + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageOnboardDevice + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-StorageSasUpLink + | | |-ComputeBoardController + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-ComputeExtBoard + | | | |-BiosUnit + | | | | |-BiosBOT + | | | | | |-BiosBootDevGrp + | | | | | |-BiosBootDev + | | | | |-BiosSettings + | | | | | |-BiosTokenFeatureGroup + | | | | | | |-BiosTokenParam + | | | | | | |-BiosTokenSettings + | | | | | |-BiosTokenParam + | | | | | | |-BiosTokenSettings + | | | | | |-BiosVfACPI10Support + | | | | | |-BiosVfASPMSupport + | | | | | |-BiosVfAllUSBDevices + | | | | | |-BiosVfAltitude + | | | | | |-BiosVfAssertNMIOnPERR + | | | | | |-BiosVfAssertNMIOnSERR + | | | | | |-BiosVfBMEDMAMitigation + | | | | | |-BiosVfBootOptionRetry + | | | | | |-BiosVfCPUHardwarePowerManagement + | | | | | |-BiosVfCPUPerformance + | | | | | |-BiosVfConsistentDeviceNameControl + | | | | | |-BiosVfConsoleRedirection + | | | | | |-BiosVfCoreMultiProcessing + | | | | | |-BiosVfDDR3VoltageSelection + | | | | | |-BiosVfDRAMClockThrottling + | | | | | |-BiosVfDirectCacheAccess + | | | | | |-BiosVfDramRefreshRate + | | | | | |-BiosVfEnergyPerformanceTuning + | | | | | |-BiosVfEnhancedIntelSpeedStepTech + | | | | | |-BiosVfEnhancedPowerCappingSupport + | | | | | |-BiosVfExecuteDisableBit + | | | | | |-BiosVfFRB2Timer + | | | | | |-BiosVfFrequencyFloorOverride + | | | | | |-BiosVfFrontPanelLockout + | | | | | |-BiosVfIOEMezz1OptionROM + | | | | | |-BiosVfIOENVMe1OptionROM + | | | | | |-BiosVfIOENVMe2OptionROM + | | | | | |-BiosVfIOESlot1OptionROM + | | | | | |-BiosVfIOESlot2OptionROM + | | | | | |-BiosVfIntegratedGraphics + | | | | | |-BiosVfIntegratedGraphicsApertureSize + | | | | | |-BiosVfIntelEntrySASRAIDModule + | | | | | |-BiosVfIntelHyperThreadingTech + | | | | | |-BiosVfIntelTrustedExecutionTechnology + | | | | | |-BiosVfIntelTurboBoostTech + | | | | | |-BiosVfIntelVTForDirectedIO + | | | | | |-BiosVfIntelVirtualizationTechnology + | | | | | |-BiosVfInterleaveConfiguration + | | | | | |-BiosVfLocalX2Apic + | | | | | |-BiosVfLvDIMMSupport + | | | | | |-BiosVfMaxVariableMTRRSetting + | | | | | |-BiosVfMaximumMemoryBelow4GB + | | | | | |-BiosVfMemoryMappedIOAbove4GB + | | | | | |-BiosVfMirroringMode + | | | | | |-BiosVfNUMAOptimized + | | | | | |-BiosVfOSBootWatchdogTimer + | | | | | |-BiosVfOSBootWatchdogTimerPolicy + | | | | | |-BiosVfOSBootWatchdogTimerTimeout + | | | | | |-BiosVfOnboardGraphics + | | | | | |-BiosVfOnboardSATAController + | | | | | |-BiosVfOnboardStorage + | | | | | |-BiosVfOptionROMEnable + | | | | | |-BiosVfOptionROMLoad + | | | | | |-BiosVfOutOfBandManagement + | | | | | |-BiosVfPCHSATAMode + | | | | | |-BiosVfPCILOMPortsConfiguration + | | | | | |-BiosVfPCIROMCLP + | | | | | |-BiosVfPCISlotLinkSpeed + | | | | | |-BiosVfPCISlotOptionROMEnable + | | | | | |-BiosVfPOSTErrorPause + | | | | | |-BiosVfPSTATECoordination + | | | | | |-BiosVfPackageCStateLimit + | | | | | |-BiosVfPanicAndHighWatermark + | | | | | |-BiosVfProcessorC1E + | | | | | |-BiosVfProcessorC3Report + | | | | | |-BiosVfProcessorC6Report + | | | | | |-BiosVfProcessorC7Report + | | | | | |-BiosVfProcessorCMCI + | | | | | |-BiosVfProcessorCState + | | | | | |-BiosVfProcessorEnergyConfiguration + | | | | | |-BiosVfProcessorPrefetchConfig + | | | | | |-BiosVfQPILinkFrequencySelect + | | | | | |-BiosVfQPISnoopMode + | | | | | |-BiosVfQuietBoot + | | | | | |-BiosVfRedirectionAfterBIOSPOST + | | | | | |-BiosVfResumeOnACPowerLoss + | | | | | |-BiosVfSBMezz1OptionROM + | | | | | |-BiosVfSBNVMe1OptionROM + | | | | | |-BiosVfSIOC1OptionROM + | | | | | |-BiosVfSIOC2OptionROM + | | | | | |-BiosVfScrubPolicies + | | | | | |-BiosVfSelectMemoryRASConfiguration + | | | | | |-BiosVfSerialPortAEnable + | | | | | |-BiosVfSparingMode + | | | | | |-BiosVfSriovConfig + | | | | | |-BiosVfTPMPendingOperation + | | | | | |-BiosVfTPMSupport + | | | | | |-BiosVfTrustedPlatformModule + | | | | | |-BiosVfUCSMBootModeControl + | | | | | |-BiosVfUCSMBootOrderRuleControl + | | | | | |-BiosVfUEFIOSUseLegacyVideo + | | | | | |-BiosVfUSBBootConfig + | | | | | |-BiosVfUSBConfiguration + | | | | | |-BiosVfUSBFrontPanelAccessLock + | | | | | |-BiosVfUSBPortConfiguration + | | | | | |-BiosVfUSBSystemIdlePowerOptimizingSetting + | | | | | |-BiosVfVGAPriority + | | | | | |-BiosVfWorkloadConfiguration + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-ComputeBoardController + | | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-ComputeMbPowerStats + | | | | |-ComputeMbPowerStatsHist + | | | |-ComputeMbTempStats + | | | | |-ComputeMbTempStatsHist + | | | |-EquipmentHealthLed + | | | | |-ComputeHealthLedSensorAlarm + | | | | |-FaultInst + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-FaultInst + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-PowerBudget + | | | |-FaultInst + | | | |-PowerProfiledPower + | | |-ComputeFactoryResetOperation + | | |-ComputeFwSyncAck + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-ComputeHostUtilityOs + | | | |-MgmtUsbNicMgmtIf + | | |-ComputeKvmMgmtPolicy + | | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-ComputeMemoryConfiguration + | | |-ComputePhysicalExtension + | | | |-FaultInst + | | |-ComputePhysicalFsm + | | | |-ComputePhysicalFsmStage + | | |-ComputePhysicalFsmTask + | | |-ComputePnuOSImage + | | |-ComputePoolable + | | | |-ComputePoolPolicyRef + | | |-ComputeRebootLog + | | |-ComputeScrubPolicy + | | |-ComputeServerUnitFsm + | | | |-ComputeServerUnitFsmStage + | | |-ComputeServerUnitFsmTask + | | |-DiagSrvCtrl + | | | |-DiagRslt + | | | | |-DiagLogEp + | | | |-DiagRunPolicy + | | | | |-DiagMemoryTest + | | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIOExpander + | | |-EquipmentIndicatorLed + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FaultSuppressTask + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-FirmwareImageLock + | | |-FirmwareStatus + | | | |-FaultInst + | | |-LsIdentityInfo + | | | |-FaultInst + | | |-LsbootDef + | | | |-LsbootBootSecurity + | | | |-LsbootEFIShell + | | | |-LsbootIScsi + | | | | |-LsbootIScsiImagePath + | | | | |-LsbootUEFIBootParam + | | | |-LsbootLan + | | | | |-LsbootLanImagePath + | | | | |-LsbootUEFIBootParam + | | | | |-VnicIpV4StaticAddr + | | | |-LsbootSan + | | | | |-LsbootSanCatSanImage + | | | | |-LsbootSanCatSanImagePath + | | | | |-LsbootUEFIBootParam + | | | |-LsbootStorage + | | | | |-LsbootLocalStorage + | | | | | |-LsbootDefaultLocalImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootEmbeddedLocalDiskImage + | | | | | | |-LsbootEmbeddedLocalDiskImagePath + | | | | | | | |-LsbootUEFIBootParam + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootEmbeddedLocalLunImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootLocalDiskImage + | | | | | | |-LsbootLocalDiskImagePath + | | | | | | | |-LsbootUEFIBootParam + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootLocalHddImage + | | | | | | |-LsbootLocalLunImagePath + | | | | | | | |-LsbootUEFIBootParam + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootNvme + | | | | | | |-LsbootNvmeDiskSsd + | | | | | | |-LsbootNvmePciSsd + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUsbExternalImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUsbFlashStorageImage + | | | | | | |-LsbootUEFIBootParam + | | | | | |-LsbootUsbInternalImage + | | | | | |-LsbootUEFIBootParam + | | | | |-LsbootSanImage + | | | | |-LsbootSanImagePath + | | | | |-LsbootUEFIBootParam + | | | |-LsbootVirtualMedia + | | |-LstorageProfile + | | | |-LstorageControllerDef + | | | | |-LstorageControllerModeConfig + | | | | |-LstorageControllerQualifier + | | | |-LstorageDasScsiLun + | | | | |-FaultInst + | | | | |-StorageLocalDiskConfigDef + | | | | |-LstorageSecurity + | | | | | |-LstorageDriveSecurity + | | | | | |-LstorageLocal + | | | | | |-LstorageRemote + | | | | | |-LstorageLogin + | | | | |-StorageLocalDiskPartition + | | | |-LstorageLunSetConfig + | | | | |-LstorageLunSetDiskSlot + | | | | |-LstorageVirtualDriveDef + | | | |-LstorageSecurity + | | | |-LstorageDriveSecurity + | | | |-LstorageLocal + | | | |-LstorageRemote + | | | |-LstorageLogin + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-MgmtKmipCertPolicy + | | |-MgmtSecurity + | | | |-MgmtKmip + | | |-MgmtSpdmCertificatePolicy + | | | |-MgmtSpdmCertificate + | | |-MoKvCfgHolder + | | | |-MoIpV4AddrKv + | | | | |-FaultInst + | | | |-MoIpV6AddrKv + | | | | |-FaultInst + | | | |-MoKv + | | | |-MoVnicKv + | | |-MoKvInvHolder + | | | |-MoInvKv + | | |-OsAgent + | | |-OsInstance + | | | |-OsEthBondIntf + | | | | |-OsARPLinkMonitoringPolicy + | | | | | |-OsARPTarget + | | | | |-OsEthBondModeActiveBackup + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedALB + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedRR + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedTLB + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBalancedXOR + | | | | | |-OsPrimarySlave + | | | | |-OsEthBondModeBroadcast + | | | | | |-OsPrimarySlave + | | | | |-OsEthIntf + | | | | |-OsMiiLinkMonitoringPolicy + | | | |-OsEthIntf + | | |-PciEquipSlot + | | | |-FaultInst + | | |-PciUnit + | | |-PowerBudget + | | | |-FaultInst + | | | |-PowerProfiledPower + | | |-SolIf + | | |-StorageEnclosure + | | | |-EventInst + | | | |-FaultInst + | | | |-StorageEnclosureDiskSlotEp + | | | | |-FaultInst + | | | | |-StorageControllerRef + | | | |-StorageEnclosureFsm + | | | | |-StorageEnclosureFsmStage + | | | |-StorageEnclosureFsmTask + | | | |-StorageHddMotherBoardTempStats + | | | | |-StorageHddMotherBoardTempStatsHist + | | | |-StorageLocalDisk + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageControllerEp + | | | |-StorageDiskEnvStats + | | | | |-StorageDiskEnvStatsHist + | | | |-StorageLocalDiskFsm + | | | | |-StorageLocalDiskFsmStage + | | | |-StorageLocalDiskFsmTask + | | | |-StorageLocalDiskPartition + | | | |-StorageOperation + | | | |-StorageSasPort + | | | |-StorageSsdHealthStats + | | | |-StorageSsdHealthStatsHist + | | |-StorageVirtualDriveContainer + | | | |-StorageVirtualDrive + | | | |-FaultInst + | | | |-StorageControllerEp + | | | |-StorageLunDisk + | | | |-StorageOperation + | | | |-StorageScsiLunRef + | | | |-StorageVDMemberEp + | | | |-FaultInst + | | |-SwUlan + | | |-SysdebugDiagnosticLog + | |-ComputePsuControl + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentChassisFsm + | | |-EquipmentChassisFsmStage + | |-EquipmentChassisFsmTask + | |-EquipmentChassisStats + | | |-EquipmentChassisStatsHist + | |-EquipmentComputeConn + | | |-FaultInst + | |-EquipmentFanModule + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFan + | | | |-EquipmentFanStats + | | | | |-EquipmentFanStatsHist + | | | |-EquipmentNetworkElementFanStats + | | | | |-EquipmentNetworkElementFanStatsHist + | | | |-EquipmentRackUnitFanStats + | | | | |-EquipmentRackUnitFanStatsHist + | | | |-FaultInst + | | |-EquipmentFanModuleStats + | | | |-EquipmentFanModuleStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIOCard + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIOCardBaseFsm + | | | |-EquipmentIOCardBaseFsmStage + | | |-EquipmentIOCardBaseFsmTask + | | |-EquipmentIOCardFsm + | | | |-EquipmentIOCardFsmStage + | | |-EquipmentIOCardFsmTask + | | |-EquipmentIOCardStats + | | | |-EquipmentIOCardStatsHist + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EventInst + | | |-FaultInst + | | |-FaultSuppressTask + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-FirmwareStatus + | | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PortGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EtherServerIntFIoPc + | | | |-EtherServerIntFIoPcEp + | | |-EtherSwitchIntFIo + | | | |-EquipmentXcvr + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-FaultInst + | | | |-PortDomainEp + | | |-EtherSwitchIntFIoPc + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherSwitchIntFIoPcEp + | | | |-FaultInst + | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-PortSubGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EquipmentIndicatorLed + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPoolable + | | |-EquipmentPoolPolicyRef + | |-EquipmentPsu + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFexPsuInputStats + | | | |-EquipmentFexPsuInputStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPsuFsm + | | | |-EquipmentPsuFsmStage + | | |-EquipmentPsuFsmTask + | | |-EquipmentPsuInputStats + | | | |-EquipmentPsuInputStatsHist + | | |-EquipmentPsuOutputStats + | | | |-EquipmentPsuOutputStatsHist + | | |-EquipmentPsuStats + | | | |-EquipmentPsuStatsHist + | | |-EquipmentRackUnitPsuStats + | | | |-EquipmentRackUnitPsuStatsHist + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareStatus + | | | |-FaultInst + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-EquipmentSharedIOModule + | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PortGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EtherServerIntFIoPc + | | | |-EtherServerIntFIoPcEp + | | |-EtherSwitchIntFIo + | | | |-EquipmentXcvr + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-FaultInst + | | | |-PortDomainEp + | | |-EtherSwitchIntFIoPc + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherSwitchIntFIoPcEp + | | | |-FaultInst + | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-PortSubGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EquipmentSwitchIOCard + | | |-EquipmentIOCardBaseFsm + | | | |-EquipmentIOCardBaseFsmStage + | | |-EquipmentIOCardBaseFsmTask + | | |-EquipmentIOCardStats + | | | |-EquipmentIOCardStatsHist + | | |-EquipmentSwitchIOCardFsm + | | | |-EquipmentSwitchIOCardFsmStage + | | |-EquipmentSwitchIOCardFsmTask + | | |-EventInst + | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PortGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EtherServerIntFIoPc + | | | |-EtherServerIntFIoPcEp + | | |-EtherSwitchIntFIo + | | | |-EquipmentXcvr + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-FaultInst + | | | |-PortDomainEp + | | |-EtherSwitchIntFIoPc + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherSwitchIntFIoPcEp + | | | |-FaultInst + | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-PortSubGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EquipmentSystemIOController + | | |-ComputeBoardController + | | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-EquipmentSharedIOModule + | | | |-FaultInst + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-PortGroup + | | | |-EtherPIo + | | | | |-EquipmentXcvr + | | | | |-EtherErrStats + | | | | | |-EtherErrStatsHist + | | | | |-EtherLossStats + | | | | | |-EtherLossStatsHist + | | | | |-EtherNiErrStats + | | | | | |-EtherNiErrStatsHist + | | | | |-EtherPIoEndPoint + | | | | |-EtherPIoFsm + | | | | | |-EtherPIoFsmStage + | | | | |-EtherPauseStats + | | | | | |-EtherPauseStatsHist + | | | | |-EtherRxStats + | | | | | |-EtherRxStatsHist + | | | | |-EtherTxStats + | | | | | |-EtherTxStatsHist + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-LldpAcquired + | | | | |-NetworkIfStats + | | | | |-PortDomainEp + | | | | |-PortPIoFsm + | | | | | |-PortPIoFsmStage + | | | | |-PortPIoFsmTask + | | | |-EtherServerIntFIo + | | | | |-EquipmentXcvr + | | | | |-EtherErrStats + | | | | | |-EtherErrStatsHist + | | | | |-EtherLossStats + | | | | | |-EtherLossStatsHist + | | | | |-EtherPauseStats + | | | | | |-EtherPauseStatsHist + | | | | |-EtherRxStats + | | | | | |-EtherRxStatsHist + | | | | |-EtherServerIntFIoFsm + | | | | | |-EtherServerIntFIoFsmStage + | | | | |-EtherServerIntFIoFsmTask + | | | | |-EtherTxStats + | | | | | |-EtherTxStatsHist + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-LldpAcquired + | | | | |-PortDomainEp + | | | | |-PortTrustMode + | | | | |-SwUlan + | | | |-EtherServerIntFIoPc + | | | | |-EtherServerIntFIoPcEp + | | | |-EtherSwitchIntFIo + | | | | |-EquipmentXcvr + | | | | |-EtherNiErrStats + | | | | | |-EtherNiErrStatsHist + | | | | |-FaultInst + | | | | |-PortDomainEp + | | | |-EtherSwitchIntFIoPc + | | | | |-EtherNiErrStats + | | | | | |-EtherNiErrStatsHist + | | | | |-EtherSwitchIntFIoPcEp + | | | | |-FaultInst + | | | |-FcPIo + | | | | |-EquipmentXcvr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FcErrStats + | | | | | |-FcErrStatsHist + | | | | |-FcPIoFsm + | | | | | |-FcPIoFsmStage + | | | | |-FcStats + | | | | | |-FcStatsHist + | | | | |-LldpAcquired + | | | | |-NetworkIfStats + | | | | |-PortDomainEp + | | | | |-PortPIoFsm + | | | | | |-PortPIoFsmStage + | | | | |-PortPIoFsmTask + | | | |-PortSubGroup + | | | |-EtherPIo + | | | | |-EquipmentXcvr + | | | | |-EtherErrStats + | | | | | |-EtherErrStatsHist + | | | | |-EtherLossStats + | | | | | |-EtherLossStatsHist + | | | | |-EtherNiErrStats + | | | | | |-EtherNiErrStatsHist + | | | | |-EtherPIoEndPoint + | | | | |-EtherPIoFsm + | | | | | |-EtherPIoFsmStage + | | | | |-EtherPauseStats + | | | | | |-EtherPauseStatsHist + | | | | |-EtherRxStats + | | | | | |-EtherRxStatsHist + | | | | |-EtherTxStats + | | | | | |-EtherTxStatsHist + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-LldpAcquired + | | | | |-NetworkIfStats + | | | | |-PortDomainEp + | | | | |-PortPIoFsm + | | | | | |-PortPIoFsmStage + | | | | |-PortPIoFsmTask + | | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EquipmentSiocTempStats + | | | |-EquipmentSiocTempStatsHist + | | |-EquipmentSystemIOControllerFsm + | | | |-EquipmentSystemIOControllerFsmStage + | | |-EquipmentSystemIOControllerFsmTask + | | |-EventInst + | | |-FaultInst + | | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FaultSuppressTask + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareActivity + | |-FirmwareActivityTrigger + | |-FirmwareImageLock + | |-FirmwareStatus + | | |-FaultInst + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-SesEnclosure + | | |-SesDiskSlotEp + | |-StorageController + | | |-EquipmentInventoryStatus + | | | |-FaultInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-LstorageControllerDef + | | | |-LstorageControllerModeConfig + | | | |-LstorageControllerQualifier + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageDrive + | | |-StorageEmbeddedStorage + | | |-StorageEnclosure + | | | |-EventInst + | | | |-FaultInst + | | | |-StorageEnclosureDiskSlotEp + | | | | |-FaultInst + | | | | |-StorageControllerRef + | | | |-StorageEnclosureFsm + | | | | |-StorageEnclosureFsmStage + | | | |-StorageEnclosureFsmTask + | | | |-StorageHddMotherBoardTempStats + | | | | |-StorageHddMotherBoardTempStatsHist + | | | |-StorageLocalDisk + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageControllerEp + | | | |-StorageDiskEnvStats + | | | | |-StorageDiskEnvStatsHist + | | | |-StorageLocalDiskFsm + | | | | |-StorageLocalDiskFsmStage + | | | |-StorageLocalDiskFsmTask + | | | |-StorageLocalDiskPartition + | | | |-StorageOperation + | | | |-StorageSasPort + | | | |-StorageSsdHealthStats + | | | |-StorageSsdHealthStatsHist + | | |-StorageLocalDisk + | | | |-EquipmentLocatorLed + | | | | |-EquipmentLocatorLedFsm + | | | | | |-EquipmentLocatorLedFsmStage + | | | | |-EquipmentLocatorLedFsmTask + | | | | |-EventInst + | | | | |-FaultInst + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-MgmtController + | | | | |-CimcvmediaActualMountList + | | | | | |-CimcvmediaActualMountEntry + | | | | | | |-FaultInst + | | | | | |-CimcvmediaExtMgmtRuleEntry + | | | | |-EventInst + | | | | |-FabricLocale + | | | | | |-AdaptorExtEthIfPc + | | | | | | |-AdaptorExtEthIfPcEp + | | | | | | |-DcxVIf + | | | | | | |-FaultInst + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPath + | | | | | |-DcxVc + | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FabricSanGroupRef + | | | | | | | |-FaultInst + | | | | | | |-FaultInst + | | | | | | |-SwCmclan + | | | | | | | |-FabricNetGroupRef + | | | | | | | |-FaultInst + | | | | | | |-SwNetflowMonitorRef + | | | | | | |-SwUlan + | | | | | | |-SwVlan + | | | | | | | |-FabricNetflowIPv4Addr + | | | | | | | |-FaultInst + | | | | | | |-SwVsan + | | | | | | |-SwFcZoneSet + | | | | | | |-SwFcServerZoneGroup + | | | | | | | |-SwZoneInitiatorMember + | | | | | | | |-SwFcZone + | | | | | | | |-SwZoneTargetMember + | | | | | | |-SwFcUserZoneGroup + | | | | | | |-SwFcUserZone + | | | | | | |-SwFcEndpoint + | | | | | |-FabricPathConn + | | | | | | |-FabricPathEp + | | | | | | |-PortTrustMode + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FaultInst + | | | | |-FirmwareBootDefinition + | | | | | |-FirmwareBootUnit + | | | | | | |-FaultInst + | | | | | | |-FirmwareInstallable + | | | | | | | |-FirmwareUcscInfo + | | | | | | |-FirmwareServicePack + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareImage + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-FirmwareImageFsm + | | | | | | |-FirmwareImageFsmStage + | | | | | |-FirmwareImageFsmTask + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareModule + | | | | |-FirmwareRunning + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUpdatable + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-MgmtCimcSecureBoot + | | | | |-MgmtCmcSecureBoot + | | | | |-MgmtConnection + | | | | | |-FaultInst + | | | | |-MgmtControllerFsm + | | | | | |-MgmtControllerFsmStage + | | | | |-MgmtControllerFsmTask + | | | | |-MgmtHealthStatus + | | | | | |-FaultInst + | | | | | |-MgmtHealthAttr + | | | | |-MgmtIf + | | | | | |-DhcpAcquired + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfConfig + | | | | | | |-MgmtIPv6IfAddr + | | | | | | |-EventInst + | | | | | | |-FaultInst + | | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | | |-MgmtIfFsm + | | | | | | |-MgmtIfFsmStage + | | | | | |-MgmtIfFsmTask + | | | | |-MgmtInterface + | | | | | |-FaultInst + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtKvmCertificate + | | | | | |-FaultInst + | | | | |-MgmtProfDerivedInterface + | | | | | |-MgmtVnet + | | | | | |-VnicIpV4MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4PooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV4History + | | | | | |-VnicIpV4StaticAddr + | | | | | |-VnicIpV6MgmtPooledAddr + | | | | | | |-FaultInst + | | | | | | |-VnicIpV6History + | | | | | |-VnicIpV6StaticAddr + | | | | |-MgmtSpdmCertificateInventory + | | | | | |-MgmtSpdmCertificateData + | | | | |-MgmtSwPersonalities + | | | | | |-MgmtSwPersonality + | | | | |-MgmtSwPersonalitiesInventory + | | | | | |-MgmtSwPersonality + | | | | |-MgmtUsbNicMgmtIf + | | | | |-SysdebugMEpLog + | | | | | |-FaultInst + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4ProfDerivedAddr + | | | | |-VnicIpV4StaticAddr + | | | |-StorageControllerEp + | | | |-StorageDiskEnvStats + | | | | |-StorageDiskEnvStatsHist + | | | |-StorageLocalDiskFsm + | | | | |-StorageLocalDiskFsmStage + | | | |-StorageLocalDiskFsmTask + | | | |-StorageLocalDiskPartition + | | | |-StorageOperation + | | | |-StorageSasPort + | | | |-StorageSsdHealthStats + | | | |-StorageSsdHealthStatsHist + | | |-StorageLocalDiskConfigDef + | | | |-LstorageSecurity + | | | | |-LstorageDriveSecurity + | | | | |-LstorageLocal + | | | | |-LstorageRemote + | | | | |-LstorageLogin + | | | |-StorageLocalDiskPartition + | | |-StorageLocalDiskEp + | | |-StorageLocalLun + | | |-StorageMezzFlashLife + | | | |-FaultInst + | | |-StorageNvmeStats + | | | |-StorageNvmeStatsHist + | | |-StorageNvmeStorage + | | |-StorageOnboardDevice + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-StorageOperation + | | |-StorageRaidBattery + | | | |-FaultInst + | | | |-StorageOperation + | | | |-StorageTransportableFlashModule + | | |-StorageVirtualDrive + | | | |-FaultInst + | | | |-StorageControllerEp + | | | |-StorageLunDisk + | | | |-StorageOperation + | | | |-StorageScsiLunRef + | | | |-StorageVDMemberEp + | | | |-FaultInst + | | |-StorageVirtualDriveEp + | |-StorageEnclosure + | | |-EventInst + | | |-FaultInst + | | |-StorageEnclosureDiskSlotEp + | | | |-FaultInst + | | | |-StorageControllerRef + | | |-StorageEnclosureFsm + | | | |-StorageEnclosureFsmStage + | | |-StorageEnclosureFsmTask + | | |-StorageHddMotherBoardTempStats + | | | |-StorageHddMotherBoardTempStatsHist + | | |-StorageLocalDisk + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageControllerEp + | | |-StorageDiskEnvStats + | | | |-StorageDiskEnvStatsHist + | | |-StorageLocalDiskFsm + | | | |-StorageLocalDiskFsmStage + | | |-StorageLocalDiskFsmTask + | | |-StorageLocalDiskPartition + | | |-StorageOperation + | | |-StorageSasPort + | | |-StorageSsdHealthStats + | | |-StorageSsdHealthStatsHist + | |-StorageSasExpander + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-StorageOnboardDevice + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-StorageSasUpLink + | |-StorageVirtualDriveContainer + | | |-StorageVirtualDrive + | | |-FaultInst + | | |-StorageControllerEp + | | |-StorageLunDisk + | | |-StorageOperation + | | |-StorageScsiLunRef + | | |-StorageVDMemberEp + | | |-FaultInst + | |-VnicRackServerDiscoveryProfile + | |-SwVlan + | |-FabricNetflowIPv4Addr + | |-FaultInst + |-EquipmentFex + | |-EquipmentBeaconLed + | | |-EquipmentBeaconLedFsm + | | | |-EquipmentBeaconLedFsmStage + | | |-EquipmentBeaconLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentFan + | | |-EquipmentFanStats + | | | |-EquipmentFanStatsHist + | | |-EquipmentNetworkElementFanStats + | | | |-EquipmentNetworkElementFanStatsHist + | | |-EquipmentRackUnitFanStats + | | | |-EquipmentRackUnitFanStatsHist + | | |-FaultInst + | |-EquipmentFexEnvStats + | | |-EquipmentFexEnvStatsHist + | |-EquipmentFexFsm + | | |-EquipmentFexFsmStage + | |-EquipmentFexFsmTask + | |-EquipmentFexPowerSummary + | | |-EquipmentFexPowerSummaryHist + | |-EquipmentFexPsuInputStats + | | |-EquipmentFexPsuInputStatsHist + | |-EquipmentFexSystemStats + | | |-EquipmentFexSystemStatsHist + | |-EquipmentHealthLed + | | |-ComputeHealthLedSensorAlarm + | | |-FaultInst + | |-EquipmentIOCard + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIOCardBaseFsm + | | | |-EquipmentIOCardBaseFsmStage + | | |-EquipmentIOCardBaseFsmTask + | | |-EquipmentIOCardFsm + | | | |-EquipmentIOCardFsmStage + | | |-EquipmentIOCardFsmTask + | | |-EquipmentIOCardStats + | | | |-EquipmentIOCardStatsHist + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPOST + | | |-EventInst + | | |-FaultInst + | | |-FaultSuppressTask + | | | |-FaultInst + | | | |-TrigLocalSched + | | | |-TrigAbsWindow + | | | |-TrigLocalAbsWindow + | | | |-TrigRecurrWindow + | | |-FirmwareStatus + | | | |-FaultInst + | | |-MgmtController + | | | |-CimcvmediaActualMountList + | | | | |-CimcvmediaActualMountEntry + | | | | | |-FaultInst + | | | | |-CimcvmediaExtMgmtRuleEntry + | | | |-EventInst + | | | |-FabricLocale + | | | | |-AdaptorExtEthIfPc + | | | | | |-AdaptorExtEthIfPcEp + | | | | | |-DcxVIf + | | | | | |-FaultInst + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPath + | | | | |-DcxVc + | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-FabricSanGroupRef + | | | | | | |-FaultInst + | | | | | |-FaultInst + | | | | | |-SwCmclan + | | | | | | |-FabricNetGroupRef + | | | | | | |-FaultInst + | | | | | |-SwNetflowMonitorRef + | | | | | |-SwUlan + | | | | | |-SwVlan + | | | | | | |-FabricNetflowIPv4Addr + | | | | | | |-FaultInst + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-FabricPathConn + | | | | | |-FabricPathEp + | | | | | |-PortTrustMode + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FaultInst + | | | |-FirmwareBootDefinition + | | | | |-FirmwareBootUnit + | | | | | |-FaultInst + | | | | | |-FirmwareInstallable + | | | | | | |-FirmwareUcscInfo + | | | | | |-FirmwareServicePack + | | | | |-FirmwareUcscInfo + | | | |-FirmwareImage + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-FirmwareImageFsm + | | | | | |-FirmwareImageFsmStage + | | | | |-FirmwareImageFsmTask + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareModule + | | | |-FirmwareRunning + | | | | |-FirmwareServicePack + | | | |-FirmwareUpdatable + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-MgmtCimcSecureBoot + | | | |-MgmtCmcSecureBoot + | | | |-MgmtConnection + | | | | |-FaultInst + | | | |-MgmtControllerFsm + | | | | |-MgmtControllerFsmStage + | | | |-MgmtControllerFsmTask + | | | |-MgmtHealthStatus + | | | | |-FaultInst + | | | | |-MgmtHealthAttr + | | | |-MgmtIf + | | | | |-DhcpAcquired + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfConfig + | | | | | |-MgmtIPv6IfAddr + | | | | | |-EventInst + | | | | | |-FaultInst + | | | | | |-MgmtIPv6IfAddrFsm + | | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | | |-MgmtIPv6IfAddrFsmTask + | | | | |-MgmtIfFsm + | | | | | |-MgmtIfFsmStage + | | | | |-MgmtIfFsmTask + | | | |-MgmtInterface + | | | | |-FaultInst + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtKvmCertificate + | | | | |-FaultInst + | | | |-MgmtProfDerivedInterface + | | | | |-MgmtVnet + | | | | |-VnicIpV4MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4PooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV4History + | | | | |-VnicIpV4StaticAddr + | | | | |-VnicIpV6MgmtPooledAddr + | | | | | |-FaultInst + | | | | | |-VnicIpV6History + | | | | |-VnicIpV6StaticAddr + | | | |-MgmtSpdmCertificateInventory + | | | | |-MgmtSpdmCertificateData + | | | |-MgmtSwPersonalities + | | | | |-MgmtSwPersonality + | | | |-MgmtSwPersonalitiesInventory + | | | | |-MgmtSwPersonality + | | | |-MgmtUsbNicMgmtIf + | | | |-SysdebugMEpLog + | | | | |-FaultInst + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4ProfDerivedAddr + | | | |-VnicIpV4StaticAddr + | | |-PortGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EtherServerIntFIoPc + | | | |-EtherServerIntFIoPcEp + | | |-EtherSwitchIntFIo + | | | |-EquipmentXcvr + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-FaultInst + | | | |-PortDomainEp + | | |-EtherSwitchIntFIoPc + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherSwitchIntFIoPcEp + | | | |-FaultInst + | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-PortSubGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-EquipmentIndicatorLed + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPOST + | |-EquipmentPsu + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFexPsuInputStats + | | | |-EquipmentFexPsuInputStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPsuFsm + | | | |-EquipmentPsuFsmStage + | | |-EquipmentPsuFsmTask + | | |-EquipmentPsuInputStats + | | | |-EquipmentPsuInputStatsHist + | | |-EquipmentPsuOutputStats + | | | |-EquipmentPsuOutputStatsHist + | | |-EquipmentPsuStats + | | | |-EquipmentPsuStatsHist + | | |-EquipmentRackUnitPsuStats + | | | |-EquipmentRackUnitPsuStatsHist + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareStatus + | | | |-FaultInst + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FaultSuppressTask + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-PowerBudget + | |-FaultInst + | |-PowerProfiledPower + |-EquipmentRackEnclosure + | |-EquipmentFanModule + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFan + | | | |-EquipmentFanStats + | | | | |-EquipmentFanStatsHist + | | | |-EquipmentNetworkElementFanStats + | | | | |-EquipmentNetworkElementFanStatsHist + | | | |-EquipmentRackUnitFanStats + | | | | |-EquipmentRackUnitFanStatsHist + | | | |-FaultInst + | | |-EquipmentFanModuleStats + | | | |-EquipmentFanModuleStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | |-EquipmentPsu + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFexPsuInputStats + | | | |-EquipmentFexPsuInputStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPsuFsm + | | | |-EquipmentPsuFsmStage + | | |-EquipmentPsuFsmTask + | | |-EquipmentPsuInputStats + | | | |-EquipmentPsuInputStatsHist + | | |-EquipmentPsuOutputStats + | | | |-EquipmentPsuOutputStatsHist + | | |-EquipmentPsuStats + | | | |-EquipmentPsuStatsHist + | | |-EquipmentRackUnitPsuStats + | | | |-EquipmentRackUnitPsuStatsHist + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareStatus + | | | |-FaultInst + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-EquipmentSlotEp + |-ExtmgmtIfMonPolicy + | |-ExtmgmtArpTargets + | | |-FaultInst + | |-ExtmgmtGatewayPing + | |-ExtmgmtMiiStatus + | |-ExtmgmtNdiscTargets + | |-FaultInst + |-ExtvmmEp + | |-EventInst + | |-ExtvmmEpFsm + | | |-ExtvmmEpFsmStage + | |-ExtvmmEpFsmTask + | |-ExtvmmKeyStore + | | |-EventInst + | | |-ExtvmmKeyRing + | | |-ExtvmmKeyStoreFsm + | | | |-ExtvmmKeyStoreFsmStage + | | |-ExtvmmKeyStoreFsmTask + | | |-FaultInst + | |-ExtvmmMasterExtKey + | | |-EventInst + | | |-ExtvmmMasterExtKeyFsm + | | | |-ExtvmmMasterExtKeyFsmStage + | | |-ExtvmmMasterExtKeyFsmTask + | | |-FaultInst + | |-ExtvmmProvider + | | |-EventInst + | | |-ExtvmmKeyInst + | | |-ExtvmmProviderFsm + | | | |-ExtvmmProviderFsmStage + | | |-ExtvmmProviderFsmTask + | | |-FaultInst + | | |-VmDC + | | | |-VmOrg + | | | |-VmSwitch + | | | |-ExtvmmUpLinkPP + | | | | |-ExtvmmFNDReference + | | | | |-FaultInst + | | | |-VmVnicProfInst + | | | |-VnicOProfileAlias + | | | |-VnicProfileAlias + | | |-VmDCOrg + | | | |-VmDC + | | | |-VmOrg + | | | |-VmSwitch + | | | |-ExtvmmUpLinkPP + | | | | |-ExtvmmFNDReference + | | | | |-FaultInst + | | | |-VmVnicProfInst + | | | |-VnicOProfileAlias + | | | |-VnicProfileAlias + | | |-VmSwitch + | | |-ExtvmmUpLinkPP + | | | |-ExtvmmFNDReference + | | | |-FaultInst + | | |-VmVnicProfInst + | | |-VnicOProfileAlias + | | |-VnicProfileAlias + | |-ExtvmmSwitchDelTask + | | |-EventInst + | | |-ExtvmmSwitchDelTaskFsm + | | | |-ExtvmmSwitchDelTaskFsmStage + | | |-ExtvmmSwitchDelTaskFsmTask + | | |-FaultInst + | |-ExtvmmSwitchSet + | | |-VmSwitch + | | |-ExtvmmUpLinkPP + | | | |-ExtvmmFNDReference + | | | |-FaultInst + | | |-VmVnicProfInst + | | |-VnicOProfileAlias + | | |-VnicProfileAlias + | |-FaultInst + |-FeatureContextEp + | |-FeatureDefinitionInstance + | |-FeatureFruCapProviderInstance + | |-FeatureProviderInstance + |-FirmwareCatalogue + | |-FirmwareCompSource + | | |-FirmwareCompTarget + | |-FirmwareDistributable + | | |-EventInst + | | |-FaultInst + | | |-FirmwareDistImage + | | |-FirmwareDistributableFsm + | | | |-FirmwareDistributableFsmStage + | | |-FirmwareDistributableFsmTask + | |-FirmwareDownloader + | | |-EventInst + | | |-FaultInst + | | |-FirmwareDownloaderFsm + | | | |-FirmwareDownloaderFsmStage + | | |-FirmwareDownloaderFsmTask + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareUcscInfo + |-FirmwareStatus + | |-FaultInst + |-FirmwareSystem + | |-EventInst + | |-FaultInst + | |-FirmwareAck + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareHost + | | |-FirmwareBlade + | | |-FirmwareRack + | |-FirmwareInfra + | | |-FaultInst + | | |-TrigLocalSched + | | |-TrigAbsWindow + | | |-TrigLocalAbsWindow + | | |-TrigRecurrWindow + | |-FirmwareSystemCompCheckResult + | |-FirmwareSystemFsm + | | |-FirmwareSystemFsmStage + | |-FirmwareSystemFsmTask + |-FirmwareUpgradeInfo + | |-FirmwareUpgradeDetail + |-FsmStatus + |-InitiatorRequestorEp + | |-InitiatorGroupEp + | |-InitiatorFcInitiatorEp + | | |-StorageEpUser + | | |-AaaCimcSession + | |-InitiatorIScsiInitiatorEp + | | |-StorageEpUser + | | |-AaaCimcSession + | |-InitiatorStoreEp + | |-StorageNodeEp + | |-StorageIScsiTargetIf + | |-InitiatorLunEp + | |-StorageAuthKey + | |-StorageEtherIf + | |-IpServiceIf + |-InitiatorRequestorGrpEp + | |-InitiatorMemberEp + | |-InitiatorUnitEp + |-LicenseEp + | |-LicenseDownloader + | | |-EventInst + | | |-FaultInst + | | |-LicenseDownloaderFsm + | | | |-LicenseDownloaderFsmStage + | | |-LicenseDownloaderFsmTask + | | |-LicenseProp + | |-LicenseFeature + | | |-LicenseInstance + | | |-EventInst + | | |-FaultInst + | | |-LicenseInstanceFsm + | | | |-LicenseInstanceFsmStage + | | |-LicenseInstanceFsmTask + | | |-LicenseProp + | | |-LicenseSourceFile + | | |-LicenseTarget + | |-LicenseFile + | | |-EventInst + | | |-FaultInst + | | |-LicenseContents + | | | |-LicenseFeatureLine + | | |-LicenseFileFsm + | | | |-LicenseFileFsmStage + | | |-LicenseFileFsmTask + | | |-LicenseSource + | |-LicenseServerHostId + |-MgmtAccessPolicy + | |-MgmtAccessPolicyItem + | |-MgmtAccessPort + |-MgmtBackup + | |-EventInst + | |-FaultInst + | |-MgmtBackupFsm + | | |-MgmtBackupFsmStage + | |-MgmtBackupFsmTask + |-MgmtBackupPolicyConfig + | |-FaultInst + | |-TrigLocalSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-MgmtController + | |-CimcvmediaActualMountList + | | |-CimcvmediaActualMountEntry + | | | |-FaultInst + | | |-CimcvmediaExtMgmtRuleEntry + | |-EventInst + | |-FabricLocale + | | |-AdaptorExtEthIfPc + | | | |-AdaptorExtEthIfPcEp + | | | |-DcxVIf + | | | |-FaultInst + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPath + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-FabricPathConn + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FabricPathEp + | | |-PortTrustMode + | |-FaultInst + | |-FirmwareBootDefinition + | | |-FirmwareBootUnit + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareServicePack + | | |-FirmwareUcscInfo + | |-FirmwareImage + | | |-EventInst + | | |-FaultInst + | | |-FirmwareImageFsm + | | | |-FirmwareImageFsmStage + | | |-FirmwareImageFsmTask + | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-FirmwareModule + | |-FirmwareRunning + | | |-FirmwareServicePack + | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-MgmtCimcSecureBoot + | |-MgmtCmcSecureBoot + | |-MgmtConnection + | | |-FaultInst + | |-MgmtControllerFsm + | | |-MgmtControllerFsmStage + | |-MgmtControllerFsmTask + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIf + | | |-DhcpAcquired + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfConfig + | | | |-MgmtIPv6IfAddr + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfAddrFsm + | | | | |-MgmtIPv6IfAddrFsmStage + | | | |-MgmtIPv6IfAddrFsmTask + | | |-MgmtIfFsm + | | | |-MgmtIfFsmStage + | | |-MgmtIfFsmTask + | |-MgmtInterface + | | |-FaultInst + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtKvmCertificate + | | |-FaultInst + | |-MgmtProfDerivedInterface + | | |-MgmtVnet + | | |-VnicIpV4MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4StaticAddr + | | |-VnicIpV6MgmtPooledAddr + | | | |-FaultInst + | | | |-VnicIpV6History + | | |-VnicIpV6StaticAddr + | |-MgmtSpdmCertificateInventory + | | |-MgmtSpdmCertificateData + | |-MgmtSwPersonalities + | | |-MgmtSwPersonality + | |-MgmtSwPersonalitiesInventory + | | |-MgmtSwPersonality + | |-MgmtUsbNicMgmtIf + | |-SysdebugMEpLog + | | |-FaultInst + | |-VnicIpV4PooledAddr + | | |-FaultInst + | | |-VnicIpV4History + | |-VnicIpV4ProfDerivedAddr + | |-VnicIpV4StaticAddr + |-MgmtEntity + | |-FaultInst + | |-MgmtPmonEntry + | |-FaultInst + |-MgmtImporter + | |-EventInst + | |-FaultInst + | |-MgmtImporterFsm + | | |-MgmtImporterFsmStage + | |-MgmtImporterFsmTask + |-MgmtIntAuthPolicy + |-NetworkElement + | |-EquipmentFan + | | |-EquipmentFanStats + | | | |-EquipmentFanStatsHist + | | |-EquipmentNetworkElementFanStats + | | | |-EquipmentNetworkElementFanStatsHist + | | |-EquipmentRackUnitFanStats + | | | |-EquipmentRackUnitFanStatsHist + | | |-FaultInst + | |-EquipmentFanModule + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFan + | | | |-EquipmentFanStats + | | | | |-EquipmentFanStatsHist + | | | |-EquipmentNetworkElementFanStats + | | | | |-EquipmentNetworkElementFanStatsHist + | | | |-EquipmentRackUnitFanStats + | | | | |-EquipmentRackUnitFanStatsHist + | | | |-FaultInst + | | |-EquipmentFanModuleStats + | | | |-EquipmentFanModuleStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | |-EquipmentLocatorLed + | | |-EquipmentLocatorLedFsm + | | | |-EquipmentLocatorLedFsmStage + | | |-EquipmentLocatorLedFsmTask + | | |-EventInst + | | |-FaultInst + | |-EquipmentPsu + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentFexPsuInputStats + | | | |-EquipmentFexPsuInputStatsHist + | | |-EquipmentHealthLed + | | | |-ComputeHealthLedSensorAlarm + | | | |-FaultInst + | | |-EquipmentIndicatorLed + | | |-EquipmentLocatorLed + | | | |-EquipmentLocatorLedFsm + | | | | |-EquipmentLocatorLedFsmStage + | | | |-EquipmentLocatorLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-EquipmentPsuFsm + | | | |-EquipmentPsuFsmStage + | | |-EquipmentPsuFsmTask + | | |-EquipmentPsuInputStats + | | | |-EquipmentPsuInputStatsHist + | | |-EquipmentPsuOutputStats + | | | |-EquipmentPsuOutputStatsHist + | | |-EquipmentPsuStats + | | | |-EquipmentPsuStatsHist + | | |-EquipmentRackUnitPsuStats + | | | |-EquipmentRackUnitPsuStatsHist + | | |-EventInst + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareStatus + | | | |-FaultInst + | | |-FirmwareUpdatable + | | |-FaultInst + | | |-FirmwareInstallable + | | |-FirmwareUcscInfo + | |-EquipmentSwitchCard + | | |-EquipmentBeaconLed + | | | |-EquipmentBeaconLedFsm + | | | | |-EquipmentBeaconLedFsmStage + | | | |-EquipmentBeaconLedFsmTask + | | | |-EventInst + | | | |-FaultInst + | | |-FaultInst + | | |-PortGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-EtherServerIntFIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherServerIntFIoFsm + | | | | |-EtherServerIntFIoFsmStage + | | | |-EtherServerIntFIoFsmTask + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-PortDomainEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-EtherServerIntFIoPc + | | | |-EtherServerIntFIoPcEp + | | |-EtherSwitchIntFIo + | | | |-EquipmentXcvr + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-FaultInst + | | | |-PortDomainEp + | | |-EtherSwitchIntFIoPc + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherSwitchIntFIoPcEp + | | | |-FaultInst + | | |-FcPIo + | | | |-EquipmentXcvr + | | | |-EventInst + | | | |-FaultInst + | | | |-FcErrStats + | | | | |-FcErrStatsHist + | | | |-FcPIoFsm + | | | | |-FcPIoFsmStage + | | | |-FcStats + | | | | |-FcStatsHist + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-PortSubGroup + | | |-EtherPIo + | | | |-EquipmentXcvr + | | | |-EtherErrStats + | | | | |-EtherErrStatsHist + | | | |-EtherLossStats + | | | | |-EtherLossStatsHist + | | | |-EtherNiErrStats + | | | | |-EtherNiErrStatsHist + | | | |-EtherPIoEndPoint + | | | |-EtherPIoFsm + | | | | |-EtherPIoFsmStage + | | | |-EtherPauseStats + | | | | |-EtherPauseStatsHist + | | | |-EtherRxStats + | | | | |-EtherRxStatsHist + | | | |-EtherTxStats + | | | | |-EtherTxStatsHist + | | | |-EventInst + | | | |-FaultInst + | | | |-LldpAcquired + | | | |-NetworkIfStats + | | | |-PortDomainEp + | | | |-PortPIoFsm + | | | | |-PortPIoFsmStage + | | | |-PortPIoFsmTask + | | |-FcPIo + | | |-EquipmentXcvr + | | |-EventInst + | | |-FaultInst + | | |-FcErrStats + | | | |-FcErrStatsHist + | | |-FcPIoFsm + | | | |-FcPIoFsmStage + | | |-FcStats + | | | |-FcStatsHist + | | |-LldpAcquired + | | |-NetworkIfStats + | | |-PortDomainEp + | | |-PortPIoFsm + | | | |-PortPIoFsmStage + | | |-PortPIoFsmTask + | |-ExtmgmtIf + | | |-FaultInst + | |-FaultInst + | |-FcpoolOuis + | | |-EventInst + | | |-FaultInst + | | |-FcpoolOui + | | |-FcpoolOuisFsm + | | | |-FcpoolOuisFsmStage + | | |-FcpoolOuisFsmTask + | |-FirmwareSecureFPGA + | | |-FaultInst + | |-FirmwareStatus + | | |-FaultInst + | |-MgmtController + | | |-CimcvmediaActualMountList + | | | |-CimcvmediaActualMountEntry + | | | | |-FaultInst + | | | |-CimcvmediaExtMgmtRuleEntry + | | |-EventInst + | | |-FabricLocale + | | | |-AdaptorExtEthIfPc + | | | | |-AdaptorExtEthIfPcEp + | | | | |-DcxVIf + | | | | |-FaultInst + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPath + | | | |-DcxVc + | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-FabricSanGroupRef + | | | | | |-FaultInst + | | | | |-FaultInst + | | | | |-SwCmclan + | | | | | |-FabricNetGroupRef + | | | | | |-FaultInst + | | | | |-SwNetflowMonitorRef + | | | | |-SwUlan + | | | | |-SwVlan + | | | | | |-FabricNetflowIPv4Addr + | | | | | |-FaultInst + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-FabricPathConn + | | | | |-FabricPathEp + | | | | |-PortTrustMode + | | | |-FabricPathEp + | | | |-PortTrustMode + | | |-FaultInst + | | |-FirmwareBootDefinition + | | | |-FirmwareBootUnit + | | | | |-FaultInst + | | | | |-FirmwareInstallable + | | | | | |-FirmwareUcscInfo + | | | | |-FirmwareServicePack + | | | |-FirmwareUcscInfo + | | |-FirmwareImage + | | | |-EventInst + | | | |-FaultInst + | | | |-FirmwareImageFsm + | | | | |-FirmwareImageFsmStage + | | | |-FirmwareImageFsmTask + | | | |-FirmwareInstallable + | | | | |-FirmwareUcscInfo + | | | |-FirmwareModule + | | |-FirmwareRunning + | | | |-FirmwareServicePack + | | |-FirmwareUpdatable + | | | |-FaultInst + | | | |-FirmwareInstallable + | | | |-FirmwareUcscInfo + | | |-MgmtCimcSecureBoot + | | |-MgmtCmcSecureBoot + | | |-MgmtConnection + | | | |-FaultInst + | | |-MgmtControllerFsm + | | | |-MgmtControllerFsmStage + | | |-MgmtControllerFsmTask + | | |-MgmtHealthStatus + | | | |-FaultInst + | | | |-MgmtHealthAttr + | | |-MgmtIf + | | | |-DhcpAcquired + | | | |-EventInst + | | | |-FaultInst + | | | |-MgmtIPv6IfConfig + | | | | |-MgmtIPv6IfAddr + | | | | |-EventInst + | | | | |-FaultInst + | | | | |-MgmtIPv6IfAddrFsm + | | | | | |-MgmtIPv6IfAddrFsmStage + | | | | |-MgmtIPv6IfAddrFsmTask + | | | |-MgmtIfFsm + | | | | |-MgmtIfFsmStage + | | | |-MgmtIfFsmTask + | | |-MgmtInterface + | | | |-FaultInst + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtKvmCertificate + | | | |-FaultInst + | | |-MgmtProfDerivedInterface + | | | |-MgmtVnet + | | | |-VnicIpV4MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4PooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV4History + | | | |-VnicIpV4StaticAddr + | | | |-VnicIpV6MgmtPooledAddr + | | | | |-FaultInst + | | | | |-VnicIpV6History + | | | |-VnicIpV6StaticAddr + | | |-MgmtSpdmCertificateInventory + | | | |-MgmtSpdmCertificateData + | | |-MgmtSwPersonalities + | | | |-MgmtSwPersonality + | | |-MgmtSwPersonalitiesInventory + | | | |-MgmtSwPersonality + | | |-MgmtUsbNicMgmtIf + | | |-SysdebugMEpLog + | | | |-FaultInst + | | |-VnicIpV4PooledAddr + | | | |-FaultInst + | | | |-VnicIpV4History + | | |-VnicIpV4ProfDerivedAddr + | | |-VnicIpV4StaticAddr + | |-MgmtDbState + | | |-FaultInst + | |-MgmtHealthStatus + | | |-FaultInst + | | |-MgmtHealthAttr + | |-MgmtIPv6IfConfig + | | |-MgmtIPv6IfAddr + | | |-EventInst + | | |-FaultInst + | | |-MgmtIPv6IfAddrFsm + | | | |-MgmtIPv6IfAddrFsmStage + | | |-MgmtIPv6IfAddrFsmTask + | |-NetworkLanNeighbors + | | |-NetworkLanNeighborEntry + | |-NetworkLimit + | | |-FaultInst + | |-NetworkLldpNeighbors + | | |-NetworkLldpNeighborEntry + | |-NetworkOperLevel + | | |-FaultInst + | |-NetworkSanNeighbors + | | |-NetworkSanNeighborEntry + | |-NfsMountInst + | | |-EventInst + | | |-FaultInst + | | |-NfsMountInstFsm + | | | |-NfsMountInstFsmStage + | | |-NfsMountInstFsmTask + | |-PowerBudget + | | |-FaultInst + | | |-PowerProfiledPower + | |-StorageItem + | | |-FaultInst + | |-SwAccessDomain + | | |-EventInst + | | |-FaultInst + | | |-SwAccessDomainFsm + | | | |-SwAccessDomainFsmStage + | | |-SwAccessDomainFsmTask + | | |-SwAccessEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-SwSubGroup + | | |-SwAccessEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-SwEthEstcEp + | | | |-SwEthTargetEp + | | | | |-FaultInst + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthLanEp + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthMonDestEp + | | |-SwEthMonSrcEp + | | |-SwFcoeEstcEp + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwFcoeSanEp + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwPhysEtherEp + | | |-SwPhysFcEp + | |-SwCardEnvStats + | | |-SwCardEnvStatsHist + | |-SwEnvStats + | | |-SwEnvStatsHist + | |-SwEthLanBorder + | | |-EventInst + | | |-FaultInst + | | |-SwEthEstcEp + | | | |-SwEthTargetEp + | | | | |-FaultInst + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthEstcPc + | | | |-SwEthTargetEp + | | | | |-FaultInst + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthLanBorderFsm + | | | |-SwEthLanBorderFsmStage + | | |-SwEthLanBorderFsmTask + | | |-SwEthLanEp + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthLanPc + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwSubGroup + | | | |-SwAccessEp + | | | | |-PortTrustMode + | | | | |-SwUlan + | | | |-SwEthEstcEp + | | | | |-SwEthTargetEp + | | | | | |-FaultInst + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthLanEp + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthMonDestEp + | | | |-SwEthMonSrcEp + | | | |-SwFcoeEstcEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwFcoeSanEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwPhysEtherEp + | | | |-SwPhysFcEp + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVlanGroup + | | |-SwVIFRef + | | |-SwVlanRef + | |-SwEthLanFlowMon + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-EventInst + | | |-FaultInst + | | |-SwEthLanFlowMonFsm + | | | |-SwEthLanFlowMonFsmStage + | | |-SwEthLanFlowMonFsmTask + | | |-SwIpRoute + | | |-SwNetflowExporter + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwNetflowMonSession + | | | |-SwNetflowMonitor + | | | | |-SwNFExporterRef + | | | |-SwNetflowMonitorRef + | | |-SwNetflowMonitor + | | | |-SwNFExporterRef + | | |-SwNetflowRecordDef + | | |-SwVirtL3Intf + | |-SwEthLanMon + | | |-SwEthMon + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-EventInst + | | |-FaultInst + | | |-SwEthEstcPc + | | | |-SwEthTargetEp + | | | | |-FaultInst + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthLanPc + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthMonDestEp + | | |-SwEthMonFsm + | | | |-SwEthMonFsmStage + | | |-SwEthMonFsmTask + | | |-SwEthMonSrcEp + | | |-SwSubGroup + | | | |-SwAccessEp + | | | | |-PortTrustMode + | | | | |-SwUlan + | | | |-SwEthEstcEp + | | | | |-SwEthTargetEp + | | | | | |-FaultInst + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthLanEp + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthMonDestEp + | | | |-SwEthMonSrcEp + | | | |-SwFcoeEstcEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwFcoeSanEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwPhysEtherEp + | | | |-SwPhysFcEp + | | |-SwVlan + | | |-FabricNetflowIPv4Addr + | | |-FaultInst + | |-SwExtUtility + | | |-EventInst + | | |-FaultInst + | | |-SwExtUtilityFsm + | | | |-SwExtUtilityFsmStage + | | |-SwExtUtilityFsmTask + | | |-SwPortBreakout + | |-SwFabricZoneNs + | |-SwFcSanBorder + | | |-EventInst + | | |-FaultInst + | | |-SwFcEstcEp + | | |-SwFcSanBorderFsm + | | | |-SwFcSanBorderFsmStage + | | |-SwFcSanBorderFsmTask + | | |-SwFcSanEp + | | |-SwFcSanPc + | | |-SwFcoeEstcEp + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwFcoeSanEp + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwFcoeSanPc + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwSubGroup + | | | |-SwAccessEp + | | | | |-PortTrustMode + | | | | |-SwUlan + | | | |-SwEthEstcEp + | | | | |-SwEthTargetEp + | | | | | |-FaultInst + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthLanEp + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthMonDestEp + | | | |-SwEthMonSrcEp + | | | |-SwFcoeEstcEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwFcoeSanEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwPhysEtherEp + | | | |-SwPhysFcEp + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVsan + | | |-SwFcZoneSet + | | |-SwFcServerZoneGroup + | | | |-SwZoneInitiatorMember + | | | |-SwFcZone + | | | |-SwZoneTargetMember + | | |-SwFcUserZoneGroup + | | |-SwFcUserZone + | | |-SwFcEndpoint + | |-SwFcSanMon + | | |-SwFcMon + | | |-DcxVc + | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-FabricSanGroupRef + | | | | |-FaultInst + | | | |-FaultInst + | | | |-SwCmclan + | | | | |-FabricNetGroupRef + | | | | |-FaultInst + | | | |-SwNetflowMonitorRef + | | | |-SwUlan + | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwVsan + | | | |-SwFcZoneSet + | | | |-SwFcServerZoneGroup + | | | | |-SwZoneInitiatorMember + | | | | |-SwFcZone + | | | | |-SwZoneTargetMember + | | | |-SwFcUserZoneGroup + | | | |-SwFcUserZone + | | | |-SwFcEndpoint + | | |-EventInst + | | |-FaultInst + | | |-SwEthMonDestEp + | | |-SwFcMonDestEp + | | |-SwFcMonFsm + | | | |-SwFcMonFsmStage + | | |-SwFcMonFsmTask + | | |-SwFcMonSrcEp + | | |-SwFcSanPc + | | |-SwFcoeSanPc + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwSubGroup + | | | |-SwAccessEp + | | | | |-PortTrustMode + | | | | |-SwUlan + | | | |-SwEthEstcEp + | | | | |-SwEthTargetEp + | | | | | |-FaultInst + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthLanEp + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwEthMonDestEp + | | | |-SwEthMonSrcEp + | | | |-SwFcoeEstcEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwFcoeSanEp + | | | | |-DcxFcoeVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-DcxVifEp + | | | | | |-SwVsan + | | | | | |-SwFcZoneSet + | | | | | |-SwFcServerZoneGroup + | | | | | | |-SwZoneInitiatorMember + | | | | | | |-SwFcZone + | | | | | | |-SwZoneTargetMember + | | | | | |-SwFcUserZoneGroup + | | | | | |-SwFcUserZone + | | | | | |-SwFcEndpoint + | | | | |-SwVlan + | | | | |-FabricNetflowIPv4Addr + | | | | |-FaultInst + | | | |-SwPhysEtherEp + | | | |-SwPhysFcEp + | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwVsan + | | |-SwFcZoneSet + | | |-SwFcServerZoneGroup + | | | |-SwZoneInitiatorMember + | | | |-SwFcZone + | | | |-SwZoneTargetMember + | | |-SwFcUserZoneGroup + | | |-SwFcUserZone + | | |-SwFcEndpoint + | |-SwPhys + | | |-EventInst + | | |-FaultInst + | | |-SwPhysEtherEp + | | |-SwPhysFcEp + | | |-SwPhysFsm + | | | |-SwPhysFsmStage + | | |-SwPhysFsmTask + | | |-SwSubGroup + | | |-SwAccessEp + | | | |-PortTrustMode + | | | |-SwUlan + | | |-SwEthEstcEp + | | | |-SwEthTargetEp + | | | | |-FaultInst + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthLanEp + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwEthMonDestEp + | | |-SwEthMonSrcEp + | | |-SwFcoeEstcEp + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwFcoeSanEp + | | | |-DcxFcoeVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-DcxVifEp + | | | | |-SwVsan + | | | | |-SwFcZoneSet + | | | | |-SwFcServerZoneGroup + | | | | | |-SwZoneInitiatorMember + | | | | | |-SwFcZone + | | | | | |-SwZoneTargetMember + | | | | |-SwFcUserZoneGroup + | | | | |-SwFcUserZone + | | | | |-SwFcEndpoint + | | | |-SwVlan + | | | |-FabricNetflowIPv4Addr + | | | |-FaultInst + | | |-SwPhysEtherEp + | | |-SwPhysFcEp + | |-SwPortDiscover + | | |-EventInst + | | |-FaultInst + | | |-SwEtherPort + | | |-SwPortDiscoverFsm + | | | |-SwPortDiscoverFsmStage + | | |-SwPortDiscoverFsmTask + | |-SwSystemStats + | | |-FaultInst + | | |-SwSystemStatsHist + | |-SwUtilityDomain + | | |-EventInst + | | |-FaultInst + | | |-SwUlan + | | |-SwUtilityDomainFsm + | | | |-SwUtilityDomainFsmStage + | | |-SwUtilityDomainFsmTask + | |-SwVlanPortNs + | |-FaultInst + |-PkiEp + | |-EventInst + | |-FaultInst + | |-MgmtKmipCertPolicy + | |-PkiEpFsm + | | |-PkiEpFsmStage + | |-PkiEpFsmTask + | |-PkiKeyRing + | | |-FaultInst + | | |-PkiCertReq + | |-PkiTP + | |-FaultInst + |-PolicyControlEp + | |-EventInst + | |-FaultInst + | |-PolicyCentraleSync + | |-PolicyCommunication + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyConfigBackup + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyControlEpFsm + | | |-PolicyControlEpFsmStage + | |-PolicyControlEpFsmTask + | |-PolicyDateTime + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyDestEp + | | |-PolicyDestClass + | | |-PolicyChildClass + | |-PolicyDiscovery + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyDns + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyEquipment + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyFault + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyIdResolvePolicy + | |-PolicyInfraFirmware + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyMEp + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyMonitoring + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyPortConfig + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyPowerMgmt + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicyPsu + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicySecurity + | | |-PolicyControlledInstance + | | |-PolicyControlledType + | | |-EventInst + | | |-FaultInst + | | |-PolicyControlledTypeFsm + | | | |-PolicyControlledTypeFsmStage + | | |-PolicyControlledTypeFsmTask + | |-PolicySourceApp + | | |-PolicyContext + | | |-PolicyScope + | | |-PolicyPolicyDestClass + | | | |-PolicyDestClass + | | | |-PolicyChildClass + | | |-PolicyRequestor + | | |-EventInst + | | |-FaultInst + | | |-PolicyRequestorFsm + | | | |-PolicyRequestorFsmStage + | | |-PolicyRequestorFsmTask + | |-PolicyStorageAutoConfig + | |-PolicyControlledInstance + | |-PolicyControlledType + | |-EventInst + | |-FaultInst + | |-PolicyControlledTypeFsm + | | |-PolicyControlledTypeFsmStage + | |-PolicyControlledTypeFsmTask + |-PowerEp + | |-PowerGroup + | | |-FaultInst + | | |-PowerChassisMember + | | | |-FaultInst + | | |-PowerFIMember + | | |-PowerFexMember + | | |-PowerRackUnitMember + | |-PowerPrioWght + |-SwatInjection + | |-SwatAction + | |-SwatCondition + | |-SwatTarget + | |-SwatTrigger + | |-SwatCondition + | |-SwatTrigger + |-SyntheticDirectory + | |-SyntheticDirectory + | |-SyntheticFile + |-SyntheticFsObj + | |-EventInst + | |-FaultInst + | |-SyntheticFsObjFsm + | | |-SyntheticFsObjFsmStage + | |-SyntheticFsObjFsmTask + |-SysdebugCoreFileRepository + | |-SysdebugCore + | | |-EventInst + | | |-FaultInst + | | |-SysdebugCoreFsm + | | | |-SysdebugCoreFsmStage + | | |-SysdebugCoreFsmTask + | | |-SysdebugManualCoreFileExportTarget + | | | |-EventInst + | | | |-FaultInst + | | | |-SysdebugManualCoreFileExportTargetFsm + | | | | |-SysdebugManualCoreFileExportTargetFsmStage + | | | |-SysdebugManualCoreFileExportTargetFsmTask + | | |-SysfileMutation + | | |-EventInst + | | |-FaultInst + | | |-SysfileMutationFsm + | | | |-SysfileMutationFsmStage + | | |-SysfileMutationFsmTask + | |-SysfileMutation + | |-EventInst + | |-FaultInst + | |-SysfileMutationFsm + | | |-SysfileMutationFsmStage + | |-SysfileMutationFsmTask + |-SysdebugDiagnosticLogRepository + | |-SysdebugDiagnosticLog + |-SysdebugEp + | |-SysdebugAutoCoreFileExportTarget + | | |-EventInst + | | |-FaultInst + | | |-SysdebugAutoCoreFileExportTargetFsm + | | | |-SysdebugAutoCoreFileExportTargetFsmStage + | | |-SysdebugAutoCoreFileExportTargetFsmTask + | |-SysdebugLogControlEp + | | |-EventInst + | | |-FaultInst + | | |-SysdebugLogControlDomain + | | | |-SysdebugLogControlDestinationFile + | | | |-SysdebugLogControlDestinationSyslog + | | | |-SysdebugLogControlModule + | | |-SysdebugLogControlEpFsm + | | | |-SysdebugLogControlEpFsmStage + | | |-SysdebugLogControlEpFsmTask + | |-SysdebugLogExportPolicy + | |-EventInst + | |-FaultInst + | |-SysdebugLogExportPolicyFsm + | | |-SysdebugLogExportPolicyFsmStage + | |-SysdebugLogExportPolicyFsmTask + | |-SysdebugLogExportStatus + | |-FaultInst + |-SysdebugTechSupFileRepository + | |-SysdebugTechSupport + | |-EventInst + | |-FaultInst + | |-SysdebugTechSupportCmdOpt + | |-SysdebugTechSupportFsm + | | |-SysdebugTechSupportFsmStage + | |-SysdebugTechSupportFsmTask + |-TopInfoPolicy + |-TrigLocalSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-TrigMeta + | |-TrigTriggered + | |-TrigClientToken + |-TrigSched + | |-TrigAbsWindow + | |-TrigLocalAbsWindow + | |-TrigRecurrWindow + |-VersionEp + |-VersionApplication + +ClassId TopSystem +------- --------- +xml_attribute :topSystem +rn :sys +min_version :1.0(1e) +access :InputOutput +access_privilege :['admin', 'ext-lan-config'] +parents :['topRoot'] +children :['aaaAuthRealm', 'aaaLdapEp', 'aaaRadiusEp', 'aaaSessionInfoTable', 'aaaTacacsPlusEp', 'aaaUserEp', 'cloudMgmtSvc', 'commSvcEp', 'computeRackUnit', 'controllerHaController', 'controllerMgmtDbCheckPol', 'domainChassisFeatureCont', 'domainEnvironmentFeatureCont', 'domainNetworkFeatureCont', 'domainServerFeatureCont', 'domainStorageFeatureCont', 'equipmentChassis', 'equipmentFex', 'equipmentRackEnclosure', 'extmgmtIfMonPolicy', 'extvmmEp', 'featureContextEp', 'firmwareCatalogue', 'firmwareStatus', 'firmwareSystem', 'firmwareUpgradeInfo', 'fsmStatus', 'initiatorRequestorEp', 'initiatorRequestorGrpEp', 'licenseEp', 'mgmtAccessPolicy', 'mgmtBackup', 'mgmtBackupPolicyConfig', 'mgmtController', 'mgmtEntity', 'mgmtImporter', 'mgmtIntAuthPolicy', 'networkElement', 'pkiEp', 'policyControlEp', 'powerEp', 'swatInjection', 'syntheticDirectory', 'syntheticFsObj', 'sysdebugCoreFileRepository', 'sysdebugDiagnosticLogRepository', 'sysdebugEp', 'sysdebugTechSupFileRepository', 'topInfoPolicy', 'trigLocalSched', 'trigMeta', 'trigSched', 'versionEp'] + +Property address +-------- ------- +xml_attribute :address +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :0 +max_length :256 +pattern :((([0-9]){1,3}\.){3}[0-9]{1,3}) +value_set :[] +range_val :[] + +Property child_action +-------- ------------ +xml_attribute :childAction +field_type :string +min_version :1.0(1e) +access :INTERNAL +min_length :None +max_length :None +pattern :((deleteAll|ignore|deleteNonPresent),){0,2}(deleteAll|ignore|deleteNonPresent){0,1} +value_set :[] +range_val :[] + +Property current_time +-------- ------------ +xml_attribute :currentTime +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :([0-9]){4}-([0-9]){2}-([0-9]){2}T([0-9]){2}:([0-9]){2}:([0-9]){2}((\.([0-9]){3})){0,1} +value_set :[] +range_val :[] + +Property descr +-------- ----- +xml_attribute :descr +field_type :string +min_version :2.1(1a) +access :READ_WRITE +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,256} +value_set :[] +range_val :[] + +Property dn +-------- -- +xml_attribute :dn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property ipv6_addr +-------- --------- +xml_attribute :ipv6Addr +field_type :string +min_version :2.2(1b) +access :READ_WRITE +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property mode +-------- ---- +xml_attribute :mode +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :None +value_set :['cluster', 'stand-alone', 'unspecified'] +range_val :[] + +Property name +-------- ---- +xml_attribute :name +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :[a-zA-Z][a-zA-Z0-9-]{0,29} +value_set :[] +range_val :[] + +Property owner +-------- ----- +xml_attribute :owner +field_type :string +min_version :2.1(1a) +access :READ_WRITE +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,32} +value_set :[] +range_val :[] + +Property rn +-------- -- +xml_attribute :rn +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :0 +max_length :256 +pattern :None +value_set :[] +range_val :[] + +Property sacl +-------- ---- +xml_attribute :sacl +field_type :string +min_version :3.0(2c) +access :READ_ONLY +min_length :None +max_length :None +pattern :((none|del|mod|addchild|cascade),){0,4}(none|del|mod|addchild|cascade){0,1} +value_set :[] +range_val :[] + +Property site +-------- ---- +xml_attribute :site +field_type :string +min_version :2.1(1a) +access :READ_WRITE +min_length :None +max_length :None +pattern :[ !#$%&\(\)\*\+,\-\./:;\?@\[\]_\{\|\}~a-zA-Z0-9]{0,32} +value_set :[] +range_val :[] + +Property status +-------- ------ +xml_attribute :status +field_type :string +min_version :1.0(1e) +access :READ_WRITE +min_length :None +max_length :None +pattern :((removed|created|modified|deleted),){0,3}(removed|created|modified|deleted){0,1} +value_set :[] +range_val :[] + +Property system_up_time +-------- -------------- +xml_attribute :systemUpTime +field_type :string +min_version :1.0(1e) +access :READ_ONLY +min_length :None +max_length :None +pattern :(([1-9]*[0-9]{2}:)|)([0-1][0-9]||[2][0-3]):([0-5][0-9]):([0-5][0-9])||(([0-5][0-9]):|)([0-5][0-9]) +value_set :[] +range_val :[] +``` \ No newline at end of file diff --git a/lib/ucsm/power.py b/lib/ucsm/power.py new file mode 100644 index 00000000..a679c6c7 --- /dev/null +++ b/lib/ucsm/power.py @@ -0,0 +1,10 @@ +from lib.ucsm.power_modules.chassis import ChassisPower +from lib.ucsm.power_modules.server import ServerPower +from lib.ucsm.power_modules.fi import FiPower + + +class Power(ChassisPower, ServerPower, FiPower): + def __init__(self, log_id=None): + ChassisPower.__init__(self, log_id=log_id) + ServerPower.__init__(self, log_id=log_id) + FiPower.__init__(self, log_id=log_id) diff --git a/lib/ucsm/power_modules/__init__.py b/lib/ucsm/power_modules/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ucsm/power_modules/__pycache__/__init__.cpython-310.pyc b/lib/ucsm/power_modules/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..62589211 Binary files /dev/null and b/lib/ucsm/power_modules/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ucsm/power_modules/__pycache__/chassis.cpython-310.pyc b/lib/ucsm/power_modules/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..ea6f1d7d Binary files /dev/null and b/lib/ucsm/power_modules/__pycache__/chassis.cpython-310.pyc differ diff --git a/lib/ucsm/power_modules/__pycache__/fi.cpython-310.pyc b/lib/ucsm/power_modules/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..64eca119 Binary files /dev/null and b/lib/ucsm/power_modules/__pycache__/fi.cpython-310.pyc differ diff --git a/lib/ucsm/power_modules/__pycache__/server.cpython-310.pyc b/lib/ucsm/power_modules/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..6762fc7d Binary files /dev/null and b/lib/ucsm/power_modules/__pycache__/server.cpython-310.pyc differ diff --git a/lib/ucsm/power_modules/chassis.py b/lib/ucsm/power_modules/chassis.py new file mode 100644 index 00000000..f9694a27 --- /dev/null +++ b/lib/ucsm/power_modules/chassis.py @@ -0,0 +1,295 @@ +import json + +from lib import output_helper + + +class ChassisPower(): + def __init__(self, log_id=None): + self.mo_equipment_chassis_stats = None + self.mo_equipment_psu_stats = None + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def get_chassis_power_data(self): + if self.mo_equipment_chassis_stats is None: + managed_objects = self.query_classid( + 'equipmentChassisStats' + ) + self.mo_equipment_chassis_stats = managed_objects + + if self.mo_equipment_psu_stats is None: + managed_objects = self.query_classid( + 'EquipmentPsuStats' + ) + self.mo_equipment_psu_stats = managed_objects + + def get_equipment_chassis_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + + for suffix in ['', '_avg', '_min', '_max']: + info['input_power%s' % (suffix)] = round( + float( + getattr(managed_object, 'input_power%s' % (suffix)) + ), + 2 + ) + info['output_power%s' % (suffix)] = round( + float( + getattr(managed_object, 'output_power%s' % (suffix)) + ), + 2 + ) + + return info + + def get_equipment_chassis_stats(self, chassis_rn=None): + self.get_chassis_power_data() + chassis_stats = [] + + for managed_object in self.mo_equipment_chassis_stats: + chassis_info = self.get_equipment_chassis_stats_info( + managed_object + ) + chassis_stats.append( + chassis_info + ) + if chassis_rn is not None: + if chassis_info['chassis_rn'] == chassis_rn: + return chassis_info + + return chassis_stats + + def get_equipment_psu_power_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['psu_rn'] = info['dn'].split('/')[2] + info['psu_id'] = info['psu_rn'].split('-')[-1] + info['name'] = 'PSU %s' % ( + info['psu_id'] + ) + + for prefix in ['output_power', 'output_current']: + for suffix in ['', '_avg', '_min', '_max']: + info['%s%s' % (prefix, suffix)] = round( + float( + getattr(managed_object, '%s%s' % (prefix, suffix)) + ), + 2 + ) + + return info + + def get_equipment_psu_power(self, chassis_rn=None): + self.get_chassis_power_data() + if self.mo_equipment_psu_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_equipment_psu_stats: + thermal_info = self.get_equipment_psu_power_info( + managed_object + ) + if chassis_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + return thermal_stats + + def get_chassis_power_stats(self, chassis_rn=None): + self.get_chassis_power_data() + + power_stats = {} + power_stats['Data'] = {} + power_stats['Data']['Chassis'] = {} + power_stats['Data']['PSU'] = [] + + power_stats_chassis = self.get_equipment_chassis_stats( + chassis_rn=chassis_rn + ) + if power_stats_chassis is not None: + power_stats['Data']['Chassis'] = power_stats_chassis + + power_stats_psu = self.get_equipment_psu_power( + chassis_rn=chassis_rn + ) + if power_stats_psu is not None: + power_stats['Data']['PSU'] = power_stats_psu + + return power_stats + + def print_chassis_power(self, power): + order = [ + 'type', + 'current', + 'min', + 'avg', + 'max' + ] + + headers = [ + 'Type', + 'Now', + 'Min', + 'Avg', + 'Max' + ] + + data = [] + + item = {} + item['type'] = 'Input Power' + item['current'] = power['Data']['Chassis']['input_power'] + item['min'] = power['Data']['Chassis']['input_power_min'] + item['avg'] = power['Data']['Chassis']['input_power_avg'] + item['max'] = power['Data']['Chassis']['input_power_max'] + data.append(item) + + item = {} + item['type'] = 'Output Power' + item['current'] = power['Data']['Chassis']['output_power'] + item['min'] = power['Data']['Chassis']['output_power_min'] + item['avg'] = power['Data']['Chassis']['output_power_avg'] + item['max'] = power['Data']['Chassis']['output_power_max'] + data.append(item) + + self.my_output.my_table( + data, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassiz_power(self, chassiz): + order = [ + 'rn', + 'power_stats.Data.Chassis.input_power', + 'power_stats.Data.Chassis.input_power_min', + 'power_stats.Data.Chassis.input_power_avg', + 'power_stats.Data.Chassis.input_power_max', + 'power_stats.Data.Chassis.output_power', + 'power_stats.Data.Chassis.output_power_min', + 'power_stats.Data.Chassis.output_power_avg', + 'power_stats.Data.Chassis.output_power_max' + ] + + headers = [ + 'Chassis', + 'Input Power Now', + 'Min', + 'Avg', + 'Max', + 'Output Power Now', + 'Min', + 'Avg', + 'Max' + ] + + self.my_output.my_table( + chassiz, + order=order, + allow_order_subkeys=True, + headers=headers, + underline=True, + table=True + ) + + def print_chassis_psu(self, power): + order = [ + 'name', + 'output_power', + 'output_power_min', + 'output_power_avg', + 'output_power_max', + 'output_current', + 'output_current_min', + 'output_current_avg', + 'output_current_max' + + ] + + headers = [ + 'PSU', + 'Output Power (W)', + 'Min', + 'Avg', + 'Max', + 'Output Current (A)', + 'Min', + 'Avg', + 'Max' + ] + + self.my_output.my_table( + power['Data']['PSU'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassiz_psu(self, chassiz): + order = [ + 'chassis_rn', + 'name', + 'output_power', + 'output_power_min', + 'output_power_avg', + 'output_power_max', + 'output_current', + 'output_current_min', + 'output_current_avg', + 'output_current_max' + + ] + + headers = [ + 'Chassis', + 'PSU', + 'Output Power (W)', + 'Min', + 'Avg', + 'Max', + 'Output Current (A)', + 'Min', + 'Avg', + 'Max' + ] + + data = [] + for chassis in chassiz: + data = data + chassis['power_stats']['Data']['PSU'] + + self.my_output.my_table( + data, + order=order, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/ucsm/power_modules/fi.py b/lib/ucsm/power_modules/fi.py new file mode 100644 index 00000000..bb723450 --- /dev/null +++ b/lib/ucsm/power_modules/fi.py @@ -0,0 +1,45 @@ +class FiPower(): + def __init__(self, log_id=None): + self.mo_equipment_psu_input_stats = None + + def get_equipment_psu_input_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'input_status', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['switch_name'] = info['dn'].split('/')[1] + info['psu_name'] = info['dn'].split('/')[2] + + for suffix in ['', '_avg', '_min', '_max']: + info['current%s' % (suffix)] = getattr(managed_object, 'current%s' % (suffix)) + info['power%s' % (suffix)] = getattr(managed_object, 'power%s' % (suffix)) + info['voltage%s' % (suffix)] = getattr(managed_object, 'voltage%s' % (suffix)) + + return info + + def get_equipment_psu_input_stats(self): + if self.mo_equipment_psu_input_stats is None: + managed_objects = self.query_classid( + 'EquipmentPsuInputStats' + ) + if managed_objects is None: + return None + + self.mo_equipment_psu_input_stats = managed_objects + + psu_stats = [] + + for managed_object in self.mo_equipment_psu_input_stats: + psu_stats.append( + self.get_equipment_psu_input_stats_info( + managed_object + ) + ) + + return psu_stats diff --git a/lib/ucsm/power_modules/server.py b/lib/ucsm/power_modules/server.py new file mode 100644 index 00000000..fa73d266 --- /dev/null +++ b/lib/ucsm/power_modules/server.py @@ -0,0 +1,183 @@ +from lib import output_helper + + +class ServerPower(): + def __init__(self, log_id=None): + self.mo_compute_stats = None + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def get_compute_power_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['blade_rn'] = info['dn'].split('/')[2] + + for suffix in ['', '_avg', '_min', '_max']: + info['consumed_power%s' % (suffix)] = round( + float( + getattr(managed_object, 'consumed_power%s' % (suffix)) + ), + 2 + ) + info['input_current%s' % (suffix)] = round( + float( + getattr(managed_object, 'input_current%s' % (suffix)) + ), + 2 + ) + info['input_voltage%s' % (suffix)] = round( + float( + getattr(managed_object, 'input_voltage%s' % (suffix)) + ), + 2 + ) + + return info + + def get_compute_power_stats(self, chassis_rn=None, blade_rn=None): + if self.mo_compute_stats is None: + managed_objects = self.query_classid( + 'ComputeMbPowerStats' + ) + if managed_objects is None: + return None + + self.mo_compute_stats = managed_objects + + power_stats = {} + power_stats['Data'] = [] + + for managed_object in self.mo_compute_stats: + power_info = self.get_compute_power_stats_info( + managed_object + ) + if chassis_rn is None and blade_rn is None: + power_stats['Data'].append( + power_info + ) + continue + + if chassis_rn is not None and blade_rn is None: + if power_info['chassis_rn'] == chassis_rn: + power_stats['Data'] = power_info + continue + + if power_info['chassis_rn'] == chassis_rn and power_info['blade_rn'] == blade_rn: + power_stats['Data'] = power_info + + power_stats['Summary'] = {} + power_stats['Summary']['Source'] = 'UCSM' + power_stats['Summary']['PowerNow'] = power_info['consumed_power'] + power_stats['Summary']['PowerMin'] = power_info['consumed_power_min'] + power_stats['Summary']['PowerAvg'] = power_info['consumed_power_avg'] + power_stats['Summary']['PowerMax'] = power_info['consumed_power_max'] + continue + + return power_stats + + def print_blades_power(self, blades, include_chassis_id=True): + order = [ + 'chassis_rn', + 'rn', + 'power.Data.consumed_power', + 'power.Data.consumed_power_min', + 'power.Data.consumed_power_avg', + 'power.Data.consumed_power_max', + 'power.Data.input_current', + 'power.Data.input_current_min', + 'power.Data.input_current_avg', + 'power.Data.input_current_max', + 'power.Data.input_voltage', + 'power.Data.input_voltage_min', + 'power.Data.input_voltage_avg', + 'power.Data.input_voltage_max' + ] + + headers = [ + 'Chassis', + 'Name', + 'Power', + 'Min', + 'Avg', + 'Max', + 'Current', + 'Min', + 'Avg', + 'Max', + 'Voltage', + 'Min', + 'Avg', + 'Max' + ] + + if not include_chassis_id: + order.remove('chassis_rn') + headers.remove('Chassis') + + self.my_output.my_table( + blades, + order=order, + allow_order_subkeys=True, + headers=headers, + underline=True, + table=True + ) + + def print_blade_power(self, power): + headers = [ + 'Power Statistics', + 'Value', + 'Min', + 'Avg', + 'Max' + ] + + order = [ + 'Type', + 'Value', + 'Min', + 'Avg', + 'Max' + ] + + info = [] + + entry = {} + entry['Type'] = 'Consumed Power (W)' + entry['Value'] = power['Data']['consumed_power'] + entry['Min'] = power['Data']['consumed_power_min'] + entry['Avg'] = power['Data']['consumed_power_avg'] + entry['Max'] = power['Data']['consumed_power_max'] + info.append(entry) + + entry = {} + entry['Type'] = 'Input Current (A)' + entry['Value'] = power['Data']['input_current'] + entry['Min'] = power['Data']['input_current_min'] + entry['Avg'] = power['Data']['input_current_avg'] + entry['Max'] = power['Data']['input_current_max'] + info.append(entry) + + entry = {} + entry['Type'] = 'Input Voltage (V)' + entry['Value'] = power['Data']['input_voltage'] + entry['Min'] = power['Data']['input_voltage_min'] + entry['Avg'] = power['Data']['input_voltage_avg'] + entry['Max'] = power['Data']['input_voltage_max'] + info.append(entry) + + self.my_output.my_table( + info, + order=order, + allow_order_subkeys=True, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/ucsm/settings.py b/lib/ucsm/settings.py new file mode 100644 index 00000000..79e6686c --- /dev/null +++ b/lib/ucsm/settings.py @@ -0,0 +1,153 @@ +import os +import json +import traceback + +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class UcsmSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log = log_helper.Log(log_id=log_id) + self.log_id = log_id + self.my_output = None + + self.ucsm_settings_filename = os.path.join( + self.settings_dir, + 'ucsm' + ) + + if not self.initialize_ucsm_settings(): + raise ValueError('Ucsm settings initialization failed') + + def get_ucsm_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Managers'] = [] + return settings + + def initialize_ucsm_settings(self): + if not os.path.isfile(self.ucsm_settings_filename): + settings = self.get_ucsm_default_settings() + if not self.set_ucsm_settings(settings): + return False + return True + + def get_ucsm_settings(self): + if not os.path.isfile(self.ucsm_settings_filename): + return None + + try: + with open(self.ucsm_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_ucsm_settings', traceback.format_exc()) + return None + + return settings + + def set_ucsm_settings(self, settings): + try: + with open(self.ucsm_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_ucsm_settings', traceback.format_exc()) + return False + + return True + + def get_ucsm_managers(self): + settings = self.get_ucsm_settings() + if settings is None: + return None + + return settings['Managers'] + + def get_ucsm_manager(self, ucsm_name): + managers = self.get_ucsm_managers() + if managers is None: + return None + + for manager in managers: + if manager['name'] == ucsm_name: + return manager + + return None + + def set_ucsm_managers(self, managers): + settings = self.get_ucsm_settings() + if settings is None: + return False + + settings['Managers'] = managers + return self.set_ucsm_settings(settings) + + def set_ucsm_manager(self, ucsm_name, ucsm_ip, ucsm_username, ucsm_password): + managers = self.get_ucsm_managers() + if managers is None: + return False + + new_managers = [] + for manager in managers: + if manager['name'] != ucsm_name: + new_managers.append(manager) + + new_manager = {} + new_manager['name'] = ucsm_name + new_manager['ip'] = ucsm_ip + new_manager['username'] = ucsm_username + new_manager['password'] = ucsm_password + new_managers.append(new_manager) + + return self.set_ucsm_managers(new_managers) + + def delete_ucsm_manager(self, ucsm_name): + managers = self.get_ucsm_managers() + if managers is None: + return False + + new_managers = [] + for manager in managers: + if manager['name'] != ucsm_name: + new_managers.append(manager) + + return self.set_ucsm_managers(new_managers) + + def print_ucsm_managers(self, managers, show_password=True): + if self.my_output is None: + self.my_output = output_helper.OutputHelper( + log_id=self.log_id, + verbose=False, + debug=False + ) + + managers = sorted(managers, key=lambda i: i['name']) + if not show_password: + for manager in managers: + manager['password'] = '******' + + order = [ + 'name', + 'ip', + 'username', + 'password' + ] + + headers = [ + 'Name', + 'IP', + 'Username', + 'Password' + ] + + self.my_output.my_table( + managers, + order=order, + headers=headers, + table=True + ) diff --git a/lib/ucsm/thermal.py b/lib/ucsm/thermal.py new file mode 100644 index 00000000..af418064 --- /dev/null +++ b/lib/ucsm/thermal.py @@ -0,0 +1,10 @@ +from lib.ucsm.thermal_modules.chassis import ChassisThermal +from lib.ucsm.thermal_modules.server import ServerThermal +from lib.ucsm.thermal_modules.fi import FiThermal + + +class Thermal(ChassisThermal, ServerThermal, FiThermal): + def __init__(self, log_id=None): + ChassisThermal.__init__(self, log_id=log_id) + ServerThermal.__init__(self, log_id=log_id) + FiThermal.__init__(self, log_id=log_id) diff --git a/lib/ucsm/thermal_modules/__init__.py b/lib/ucsm/thermal_modules/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/ucsm/thermal_modules/__pycache__/__init__.cpython-310.pyc b/lib/ucsm/thermal_modules/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..62589211 Binary files /dev/null and b/lib/ucsm/thermal_modules/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/ucsm/thermal_modules/__pycache__/chassis.cpython-310.pyc b/lib/ucsm/thermal_modules/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..aec1a87b Binary files /dev/null and b/lib/ucsm/thermal_modules/__pycache__/chassis.cpython-310.pyc differ diff --git a/lib/ucsm/thermal_modules/__pycache__/fi.cpython-310.pyc b/lib/ucsm/thermal_modules/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..75c3e42f Binary files /dev/null and b/lib/ucsm/thermal_modules/__pycache__/fi.cpython-310.pyc differ diff --git a/lib/ucsm/thermal_modules/__pycache__/server.cpython-310.pyc b/lib/ucsm/thermal_modules/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..c823fe35 Binary files /dev/null and b/lib/ucsm/thermal_modules/__pycache__/server.cpython-310.pyc differ diff --git a/lib/ucsm/thermal_modules/chassis.py b/lib/ucsm/thermal_modules/chassis.py new file mode 100644 index 00000000..e992c629 --- /dev/null +++ b/lib/ucsm/thermal_modules/chassis.py @@ -0,0 +1,463 @@ +import json +from lib import output_helper + + +class ChassisThermal(): + def __init__(self, log_id=None): + self.mo_equipment_fan_stats = None + self.mo_equipment_fan_module_stats = None + self.mo_equipment_psu_stats = None + self.mo_equipment_io_card_stats = None + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def get_chassis_thermal_data(self): + if self.mo_equipment_fan_stats is None: + managed_objects = self.query_classid( + 'EquipmentFanStats' + ) + self.mo_equipment_fan_stats = managed_objects + + if self.mo_equipment_fan_module_stats is None: + managed_objects = self.query_classid( + 'EquipmentFanModuleStats' + ) + self.mo_equipment_fan_module_stats = managed_objects + + if self.mo_equipment_psu_stats is None: + managed_objects = self.query_classid( + 'EquipmentPsuStats' + ) + self.mo_equipment_psu_stats = managed_objects + + if self.mo_equipment_io_card_stats is None: + managed_objects = self.query_classid( + 'EquipmentIOCardStats' + ) + self.mo_equipment_io_card_stats = managed_objects + + def get_equipment_fan_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['fan_module_rn'] = info['dn'].split('/')[2] + info['fan_module_id'] = info['fan_module_rn'].split('-')[-1] + info['fan_rn'] = info['dn'].split('/')[3] + info['fan_id'] = info['fan_rn'].split('-')[-1] + info['name'] = 'Fan Module %s - Fan %s' % ( + info['fan_module_id'], + info['fan_id'] + ) + + for suffix in ['', '_avg', '_min', '_max']: + info['speed%s' % (suffix)] = getattr(managed_object, 'speed%s' % (suffix)) + + return info + + def get_equipment_fan_stats(self, chassis_rn=None): + self.get_chassis_thermal_data() + if self.mo_equipment_fan_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_equipment_fan_stats: + thermal_info = self.get_equipment_fan_stats_info( + managed_object + ) + if chassis_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + return thermal_stats + + def get_equipment_fan_module_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['fan_module_rn'] = info['dn'].split('/')[2] + info['fan_module_id'] = info['fan_module_rn'].split('-')[-1] + info['name'] = 'Fan Module %s' % ( + info['fan_module_id'] + ) + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'ambient_temp%s' % (suffix)) + ), + 2 + ) + + return info + + def get_equipment_fan_module_stats(self, chassis_rn=None): + self.get_chassis_thermal_data() + if self.mo_equipment_fan_module_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_equipment_fan_module_stats: + thermal_info = self.get_equipment_fan_module_stats_info( + managed_object + ) + if chassis_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + return thermal_stats + + def get_equipment_psu_temp_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['psu_rn'] = info['dn'].split('/')[2] + info['psu_id'] = info['psu_rn'].split('-')[-1] + info['name'] = 'PSU %s' % ( + info['psu_id'] + ) + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'ambient_temp%s' % (suffix)) + ), + 2 + ) + + return info + + def get_equipment_psu_temp(self, chassis_rn=None): + self.get_chassis_thermal_data() + if self.mo_equipment_psu_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_equipment_psu_stats: + thermal_info = self.get_equipment_psu_temp_info( + managed_object + ) + if chassis_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + return thermal_stats + + def get_equipment_io_ambient_temp_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['slot_rn'] = info['dn'].split('/')[2] + info['slot_id'] = info['slot_rn'].split('-')[-1] + info['name'] = 'IO Module %s - Ambient' % ( + info['slot_id'] + ) + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'ambient_temp%s' % (suffix)) + ), + 2 + ) + + return info + + def get_equipment_io_asic_temp_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['slot_rn'] = info['dn'].split('/')[2] + info['slot_id'] = info['slot_rn'].split('-')[-1] + info['name'] = 'IO Module %s - ASIC' % ( + info['slot_id'] + ) + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'temp%s' % (suffix)) + ), + 2 + ) + + return info + + def get_equipment_io_thermal_stats(self, chassis_rn=None): + self.get_chassis_thermal_data() + if self.mo_equipment_io_card_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_equipment_io_card_stats: + thermal_info = self.get_equipment_io_ambient_temp_info( + managed_object + ) + if chassis_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + for managed_object in self.mo_equipment_io_card_stats: + thermal_info = self.get_equipment_io_asic_temp_info( + managed_object + ) + if chassis_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + return thermal_stats + + def get_chassis_thermal_stats(self, chassis_rn=None): + self.get_chassis_thermal_data() + + thermal_stats = {} + thermal_stats['Data'] = {} + thermal_stats['Data']['Fan'] = [] + thermal_stats['Data']['Temperature'] = [] + + thermal_stats_fan = self.get_equipment_fan_stats( + chassis_rn=chassis_rn + ) + if thermal_stats_fan is not None: + thermal_stats['Data']['Fan'] = thermal_stats_fan + + thermal_stats_fan_module = self.get_equipment_fan_module_stats( + chassis_rn=chassis_rn + ) + if thermal_stats_fan_module is not None: + thermal_stats['Data']['Temperature'] = thermal_stats['Data']['Temperature'] + thermal_stats_fan_module + + thermal_stats_psu = self.get_equipment_psu_temp( + chassis_rn=chassis_rn + ) + if thermal_stats_psu is not None: + thermal_stats['Data']['Temperature'] = thermal_stats['Data']['Temperature'] + thermal_stats_psu + + thermal_stats_io = self.get_equipment_io_thermal_stats( + chassis_rn=chassis_rn + ) + if thermal_stats_io is not None: + thermal_stats['Data']['Temperature'] = thermal_stats['Data']['Temperature'] + thermal_stats_io + + thermal_stats['Summary'] = {} + thermal_stats['Summary']['Source'] = 'UCSM' + thermal_stats['Summary']['HighestTemperature'] = None + + for item in thermal_stats['Data']['Temperature']: + if 'temperature' in item: + if thermal_stats['Summary']['HighestTemperature'] is None: + thermal_stats['Summary']['HighestTemperature'] = item['temperature'] + continue + + thermal_stats['Summary']['HighestTemperature'] = max( + thermal_stats['Summary']['HighestTemperature'], + item['temperature'] + ) + + return thermal_stats + + def print_chassis_fans(self, thermal): + order = [ + 'name', + 'speed', + 'speed_min', + 'speed_avg', + 'speed_max' + + ] + + headers = [ + 'Fan', + 'Speed (RPM)', + 'Min', + 'Avg', + 'Max' + ] + + self.my_output.my_table( + thermal['Data']['Fan'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassis_sensors(self, thermal): + order = [ + 'name', + 'temperature', + 'temperature_min', + 'temperature_avg', + 'temperature_max' + + ] + + headers = [ + 'Sensor', + 'Temperature (C)', + 'Min', + 'Avg', + 'Max' + ] + + self.my_output.my_table( + thermal['Data']['Temperature'], + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassis_thermal(self, data): + self.print_chassis_fans(data) + self.print_chassis_sensors(data) + + def print_chassiz_fans(self, chassiz): + order = [ + 'chassis_rn', + 'name', + 'speed', + 'speed_min', + 'speed_avg', + 'speed_max' + + ] + + headers = [ + 'Chassis', + 'Fan', + 'Speed (RPM)', + 'Min', + 'Avg', + 'Max' + ] + + data = [] + for chassis in chassiz: + data = data + chassis['thermal_stats']['Data']['Fan'] + + self.my_output.my_table( + data, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassiz_sensors(self, chassiz): + order = [ + 'chassis_rn', + 'name', + 'temperature', + 'temperature_min', + 'temperature_avg', + 'temperature_max' + + ] + + headers = [ + 'Chassis', + 'Sensor', + 'Temperature (C)', + 'Min', + 'Avg', + 'Max' + ] + + data = [] + for chassis in chassiz: + data = data + chassis['thermal_stats']['Data']['Temperature'] + + self.my_output.my_table( + data, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_chassiz_thermal(self, chassiz): + self.print_chassiz_fans(chassiz) + self.print_chassiz_sensors(chassiz) diff --git a/lib/ucsm/thermal_modules/fi.py b/lib/ucsm/thermal_modules/fi.py new file mode 100644 index 00000000..893bd409 --- /dev/null +++ b/lib/ucsm/thermal_modules/fi.py @@ -0,0 +1,24 @@ +class FiThermal(): + def __init__(self, log_id=None): + self.mo_equipment_psu_input_stats = None + + def get_equipment_psu_input_stats(self): + if self.mo_equipment_psu_input_stats is None: + managed_objects = self.query_classid( + 'EquipmentPsuInputStats' + ) + if managed_objects is None: + return None + + self.mo_equipment_psu_input_stats = managed_objects + + psu_stats = [] + + for managed_object in self.mo_equipment_psu_input_stats: + psu_stats.append( + self.get_equipment_psu_input_stats_info( + managed_object + ) + ) + + return psu_stats diff --git a/lib/ucsm/thermal_modules/server.py b/lib/ucsm/thermal_modules/server.py new file mode 100644 index 00000000..e87db1ad --- /dev/null +++ b/lib/ucsm/thermal_modules/server.py @@ -0,0 +1,351 @@ +from lib import output_helper + + +class ServerThermal(): + def __init__(self, log_id=None): + self.mo_compute_motherboard_stats = None + self.mo_compute_cpu_stats = None + self.mo_compute_memory_stats = None + self.my_output = output_helper.OutputHelper(log_id=log_id) + + def get_compute_thermal_data(self): + if self.mo_compute_motherboard_stats is None: + managed_objects = self.query_classid( + 'ComputeMbTempStats' + ) + self.mo_compute_motherboard_stats = managed_objects + + if self.mo_compute_cpu_stats is None: + managed_objects = self.query_classid( + 'ProcessorEnvStats' + ) + self.mo_compute_cpu_stats = managed_objects + + if self.mo_compute_memory_stats is None: + managed_objects = self.query_classid( + 'MemoryUnitEnvStats' + ) + self.mo_compute_memory_stats = managed_objects + + def get_compute_thermal_motherboard_front_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['blade_rn'] = info['dn'].split('/')[2] + info['name'] = 'Motherboard Front' + info['type'] = 'motherboard' + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'fm_temp_sen_io%s' % (suffix)) + ), + 2 + ) + info['fm_temp_sen_rear%s' % (suffix)] = round( + float( + getattr(managed_object, 'fm_temp_sen_rear%s' % (suffix)) + ), + 2 + ) + + return info + + def get_compute_thermal_motherboard_rear_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['blade_rn'] = info['dn'].split('/')[2] + info['name'] = 'Motherboard Rear' + info['type'] = 'motherboard' + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'fm_temp_sen_rear%s' % (suffix)) + ), + 2 + ) + + return info + + def get_compute_thermal_motherboard_stats(self, chassis_rn=None, blade_rn=None): + self.get_compute_thermal_data() + if self.mo_compute_motherboard_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_compute_motherboard_stats: + thermal_info = self.get_compute_thermal_motherboard_front_stats_info( + managed_object + ) + if chassis_rn is None and blade_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None and blade_rn is None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + if thermal_info['chassis_rn'] == chassis_rn and thermal_info['blade_rn'] == blade_rn: + thermal_stats.append( + thermal_info + ) + + for managed_object in self.mo_compute_motherboard_stats: + thermal_info = self.get_compute_thermal_motherboard_rear_stats_info( + managed_object + ) + if chassis_rn is None and blade_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None and blade_rn is None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + if thermal_info['chassis_rn'] == chassis_rn and thermal_info['blade_rn'] == blade_rn: + thermal_stats.append( + thermal_info + ) + + return thermal_stats + + def get_compute_thermal_cpu_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['blade_rn'] = info['dn'].split('/')[2] + info['cpu_rn'] = info['dn'].split('/')[4] + info['name'] = info['cpu_rn'].upper() + info['type'] = 'cpu' + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'temperature%s' % (suffix)) + ), + 2 + ) + + return info + + def get_compute_thermal_cpu_stats(self, chassis_rn=None, blade_rn=None): + self.get_compute_thermal_data() + if self.mo_compute_cpu_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_compute_cpu_stats: + thermal_info = self.get_compute_thermal_cpu_stats_info( + managed_object + ) + if chassis_rn is None and blade_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None and blade_rn is None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + if thermal_info['chassis_rn'] == chassis_rn and thermal_info['blade_rn'] == blade_rn: + thermal_stats.append(thermal_info) + + return thermal_stats + + def get_compute_thermal_memory_stats_info(self, managed_object): + info = {} + + keys = [ + 'dn', + 'time_collected' + ] + for key in keys: + info[key] = getattr(managed_object, key) + + info['chassis_rn'] = info['dn'].split('/')[1] + info['blade_rn'] = info['dn'].split('/')[2] + info['array_rn'] = info['dn'].split('/')[4] + info['dimm_rn'] = info['dn'].split('/')[5] + info['name'] = info['dimm_rn'].upper() + info['type'] = 'memory' + + for suffix in ['', '_avg', '_min', '_max']: + info['temperature%s' % (suffix)] = round( + float( + getattr(managed_object, 'temperature%s' % (suffix)) + ), + 2 + ) + + return info + + def get_compute_thermal_memory_stats(self, chassis_rn=None, blade_rn=None): + self.get_compute_thermal_data() + if self.mo_compute_memory_stats is None: + return None + + thermal_stats = [] + + for managed_object in self.mo_compute_memory_stats: + thermal_info = self.get_compute_thermal_memory_stats_info( + managed_object + ) + if chassis_rn is None and blade_rn is None: + thermal_stats.append( + thermal_info + ) + continue + + if chassis_rn is not None and blade_rn is None: + if thermal_info['chassis_rn'] == chassis_rn: + thermal_stats.append( + thermal_info + ) + continue + + if thermal_info['chassis_rn'] == chassis_rn and thermal_info['blade_rn'] == blade_rn: + thermal_stats.append(thermal_info) + + thermal_stats = sorted(thermal_stats, key=lambda i: i['name']) + + return thermal_stats + + def get_compute_thermal_stats(self, chassis_rn=None, blade_rn=None): + self.get_compute_thermal_data() + + thermal_stats = {} + thermal_stats['Data'] = [] + thermal_stats_motherboard = self.get_compute_thermal_motherboard_stats( + chassis_rn=chassis_rn, + blade_rn=blade_rn + ) + if thermal_stats_motherboard is not None: + thermal_stats['Data'] = thermal_stats['Data'] + thermal_stats_motherboard + + thermal_stats_cpu = self.get_compute_thermal_cpu_stats( + chassis_rn=chassis_rn, + blade_rn=blade_rn + ) + if thermal_stats_cpu is not None: + thermal_stats['Data'] = thermal_stats['Data'] + thermal_stats_cpu + + thermal_stats_memory = self.get_compute_thermal_memory_stats( + chassis_rn=chassis_rn, + blade_rn=blade_rn + ) + if thermal_stats_memory is not None: + thermal_stats['Data'] = thermal_stats['Data'] + thermal_stats_memory + + thermal_stats['Summary'] = {} + thermal_stats['Summary']['Source'] = 'UCSM' + thermal_stats['Summary']['FanHealth'] = 'N/A' + thermal_stats['Summary']['SensorHealth'] = True + thermal_stats['Summary']['HighestTemperature'] = None + thermal_stats['Summary']['SmallestGap'] = 'N/A' + thermal_stats['Summary']['OverThreshold'] = 'N/A' + + for item in thermal_stats['Data']: + if 'temperature' in item: + if thermal_stats['Summary']['HighestTemperature'] is None: + thermal_stats['Summary']['HighestTemperature'] = item['temperature'] + continue + + thermal_stats['Summary']['HighestTemperature'] = max( + thermal_stats['Summary']['HighestTemperature'], + item['temperature'] + ) + + return thermal_stats + + def print_blades_thermal(self, blades, include_chassis_id=True): + order = [ + 'chassis_rn', + 'rn', + 'thermal.Summary.SensorHealth', + 'thermal.Summary.HighestTemperature' + ] + + headers = [ + 'Chassis', + 'Name', + 'Sensor Health', + 'Highest Temperature' + ] + + if not include_chassis_id: + order.remove('chassis_rn') + headers.remove('Chassis') + + self.my_output.my_table( + blades, + order=order, + allow_order_subkeys=True, + headers=headers, + underline=True, + table=True + ) + + def print_blade_thermal(self, thermal): + headers = [ + 'Thermal Statistics', + 'Value', + 'Min', + 'Avg', + 'Max' + ] + + order = [ + 'name', + 'temperature', + 'temperature_min', + 'temperature_avg', + 'temperature_max' + ] + + self.my_output.my_table( + thermal['Data'], + order=order, + allow_order_subkeys=True, + headers=headers, + underline=True, + table=True + ) diff --git a/lib/vc/__init__.py b/lib/vc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/vc/common.py b/lib/vc/common.py new file mode 100644 index 00000000..d5794a6c --- /dev/null +++ b/lib/vc/common.py @@ -0,0 +1,82 @@ +# pylint: disable=no-name-in-module +from pyVmomi import vim +# pylint: disable=no-name-in-module +from pyVmomi import vmodl + + +class VcCommon(): + def __init__(self): + pass + + def get_filter_spec(self, container_view, obj_type, path): + traverse_spec = vmodl.query.PropertyCollector.TraversalSpec() + traverse_spec.name = 'traverse' + traverse_spec.path = 'view' + traverse_spec.skip = False + traverse_spec.type = vim.view.ContainerView + + obj_spec = vmodl.query.PropertyCollector.ObjectSpec() + obj_spec.obj = container_view + obj_spec.skip = True + obj_spec.selectSet.append(traverse_spec) + + prop_spec = vmodl.query.PropertyCollector.PropertySpec() + prop_spec.type = obj_type + prop_spec.pathSet = path + + return vmodl.query.PropertyCollector.FilterSpec(propSet=[prop_spec], objectSet=[obj_spec]) + + def get_filemanager_handler(self): + if self.is_vc_connected(): + return self.vc_service_instance.RetrieveServiceContent().fileManager + return None + + def wait_for_tasks(self, tasks, exception_on_task_failure=True): + """ + Given the service instance and tasks, it returns after all the + tasks are complete + """ + if self.vc_service_instance is None: + return False + + property_collector = self.vc_service_instance.content.propertyCollector + task_list = [str(task) for task in tasks] + # Create filter + obj_specs = [vmodl.query.PropertyCollector.ObjectSpec(obj=task) for task in tasks] + property_spec = vmodl.query.PropertyCollector.PropertySpec(type=vim.Task, pathSet=[], all=True) + filter_spec = vmodl.query.PropertyCollector.FilterSpec() + filter_spec.objectSet = obj_specs + filter_spec.propSet = [property_spec] + pcfilter = property_collector.CreateFilter(filter_spec, True) + try: + version, state = None, None + # Loop looking for updates till the state moves to a completed state. + while task_list: + update = property_collector.WaitForUpdates(version) + for filter_set in update.filterSet: + for obj_set in filter_set.objectSet: + task = obj_set.obj + for change in obj_set.changeSet: + if change.name == 'info': + state = change.val.state + elif change.name == 'info.state': + state = change.val + else: + continue + + if not str(task) in task_list: + continue + + if state == vim.TaskInfo.State.success: + # Remove task from taskList + task_list.remove(str(task)) + elif state == vim.TaskInfo.State.error: + if exception_on_task_failure: + raise task.info.error + task_list.remove(str(task)) + + # Move to next version + version = update.version + finally: + if pcfilter: + pcfilter.Destroy() diff --git a/lib/vc/connect.py b/lib/vc/connect.py new file mode 100644 index 00000000..c2938378 --- /dev/null +++ b/lib/vc/connect.py @@ -0,0 +1,62 @@ +import time +import atexit +import traceback + +from pyVim.connect import SmartConnect, Disconnect + + +class VcConnect(): + def __init__(self, vcenter_ip, vcenter_port, vcenter_username, vcenter_password, disable_ssl_verification=True): + self.vcenter_ip = vcenter_ip + self.vcenter_port = vcenter_port + self.vcenter_username = vcenter_username + self.vcenter_password = vcenter_password + self.vc_disable_ssl_verification = disable_ssl_verification + + self.vc_service_instance = None + + def is_vc_connected(self): + if self.vc_service_instance is None: + return False + return True + + def vc_connect(self): + if self.vc_service_instance is not None: + return True + + start_time = int(time.time() * 1000) + try: + self.vc_service_instance = SmartConnect( + host=self.vcenter_ip, + user=self.vcenter_username, + pwd=self.vcenter_password, + port=self.vcenter_port, + disableSslCertValidation=self.vc_disable_ssl_verification + ) + + # doing this means you don't need to remember to disconnect your script/objects + atexit.register(Disconnect, self.vc_service_instance) + + except IOError as io_error: + self.my_output.error('Failed to connect to vcenter instance') + self.my_output.default(io_error) + return False + + except BaseException: + self.my_output.error('Failed to connect to vcenter instance') + self.my_output.default(traceback.format_exc()) + return False + + if self.vc_service_instance is None: + self.my_output.error('Failed to connect to vcenter instance with supplied credentials') + return False + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'connect', + self.vcenter_ip, + True, + duration + ) + + return True diff --git a/lib/vc/datacenter.py b/lib/vc/datacenter.py new file mode 100644 index 00000000..b15973d7 --- /dev/null +++ b/lib/vc/datacenter.py @@ -0,0 +1,59 @@ +# pylint: disable=no-name-in-module +from pyVmomi import vim + + +class VcDatacenter(): + def __init__(self): + pass + + def is_datacenter(self, datacenter_name): + datacenters = self.get_datacenters() + if datacenters is None: + return False + + for datacenter in datacenters: + if datacenter['name'] == datacenter_name: + return True + + return False + + def get_datacenters(self): + if not self.vc_connect(): + return None + + datacenters = [] + content = self.vc_service_instance.RetrieveContent() + + # Get the list of all datacenters we have available to us + datacenters_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Datacenter], + True + ) + + for dc_obj in datacenters_object_view.view: + datacenter = {} + datacenter['name'] = dc_obj.name + datacenters.append(datacenter) + + return datacenters + + def get_datacenter_object(self, datacenter_name): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + datacenters_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Datacenter], + True + ) + + for dc_obj in datacenters_object_view.view: + if dc_obj.name == datacenter_name: + datacenters_object_view.Destroy() + return dc_obj + + datacenters_object_view.Destroy() + + return None diff --git a/lib/vc/datastore.py b/lib/vc/datastore.py new file mode 100644 index 00000000..ce8cb9e0 --- /dev/null +++ b/lib/vc/datastore.py @@ -0,0 +1,476 @@ +import os +import traceback +import requests + +# pylint: disable=no-name-in-module +from pyVmomi import vim + +# mypy: ignore-errors +requests.packages.urllib3.disable_warnings() + + +class VcDatastore(): + def __init__(self): + self.datastore_info_cache = {} + + def is_datastore(self, datacenter_name, datastore_name): + datastores = self.get_datastores() + if datastores is None: + return False + + for datastore in datastores: + if datastore['dc'] == datacenter_name: + if datastore['name'] == datastore_name: + return True + + return False + + def get_datastore_info(self, datastore_obj): + if datastore_obj in self.datastore_info_cache: + return self.datastore_info_cache[datastore_obj] + + info = {} + try: + info['name'] = datastore_obj.name + if getattr(datastore_obj.info, 'nas', None) is not None: + info['type'] = datastore_obj.info.nas.type + info['capacity'] = datastore_obj.info.nas.capacity + info['capacity_unit'] = self.convert_storage(datastore_obj.info.nas.capacity) + if getattr(datastore_obj.info, 'vmfs', None) is not None: + info['type'] = datastore_obj.info.vmfs.type + info['capacity'] = datastore_obj.info.vmfs.capacity + info['capacity_unit'] = self.convert_storage(datastore_obj.info.vmfs.capacity) + info['free'] = datastore_obj.info.freeSpace + info['free_unit'] = self.convert_storage(datastore_obj.info.freeSpace) + info['used'] = info['capacity'] - info['free'] + info['usage_pct'] = round( + info['used'] * 100 / info['capacity'], + 2 + ) + info['usage_unit'] = self.convert_pct(info['usage_pct']) + except BaseException: + info = None + + self.datastore_info_cache[datastore_obj] = info + return info + + def get_datastore_object(self, datacenter_name, datastore_name): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + datacenters_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Datacenter], + True + ) + + for dc_obj in datacenters_object_view.view: + if dc_obj.name == datacenter_name: + datastores_object_view = content.viewManager.CreateContainerView( + dc_obj, + [vim.Datastore], + True + ) + + for ds_obj in datastores_object_view.view: + if ds_obj.info.name == datastore_name: + datacenters_object_view.Destroy() + datastores_object_view.Destroy() + return ds_obj + + datastores_object_view.Destroy() + + datacenters_object_view.Destroy() + + return None + + def get_datastores(self, datacenter_name=None): + if not self.vc_connect(): + return None + + datastores = [] + content = self.vc_service_instance.RetrieveContent() + + # Get the list of all datacenters we have available to us + datacenters_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Datacenter], + True + ) + + for dc_obj in datacenters_object_view.view: + if datacenter_name is not None and dc_obj.name != datacenter_name: + continue + + datastores_object_view = content.viewManager.CreateContainerView( + dc_obj, + [vim.Datastore], + True + ) + + for ds_obj in datastores_object_view.view: + datastore = self.get_datastore_info(ds_obj) + datastore['dc'] = dc_obj.name + datastores.append(datastore) + + datastores_object_view.Destroy() + + datacenters_object_view.Destroy() + + return datastores + + def print_datastores(self, datastores): + if datastores is None or len(datastores) == 0: + self.my_output.default('No datastores found') + return + + self.my_output.my_table( + datastores, + order=[ + 'dc', + 'name', + 'type', + 'capacity_unit', + 'free_unit', + 'usage_unit' + ], + headers=[ + 'Datacenter', + 'Datastore', + 'Type', + 'Capacity', + 'Free', + 'Usage' + ], + table=True + ) + + def get_datastore_folders(self, datacenter_name, datastore_name, folder_name): + ds_obj = self.get_datastore_object(datacenter_name, datastore_name) + if ds_obj is None: + return None + + spec = vim.host.DatastoreBrowser.SearchSpec(query=[vim.host.DatastoreBrowser.FolderQuery()]) + spec.details = vim.host.DatastoreBrowser.FileInfo.Details( + fileOwner=True, fileSize=True, fileType=True, modification=True + ) + search_path = '[%s] %s' % (datastore_name, folder_name) + + task = ds_obj.browser.SearchDatastoreSubFolders_Task( + search_path, + spec + ) + self.wait_for_tasks([task]) + search_results = task.info.result + + folders = [] + for search_result in search_results: + folder_path = self.fixup_datastore_path( + search_result.folderPath + ) + if folder_path != search_path: + continue + + for folder_info in search_result.file: + folder_details = {} + folder_details['type'] = 'Folder' + folder_details['datastore'] = datastore_name + folder_details['folder'] = folder_name + folder_details['filename'] = folder_info.path + folder_details['path'] = '[%s] %s%s' % ( + datastore_name, + folder_name, + folder_details['filename'] + ) + folder_details['size'] = folder_info.fileSize + folder_details['size_unit'] = self.convert_storage(folder_details['size']) + folder_details['owner'] = folder_info.owner + folder_details['modification'] = folder_info.modification + folders.append(folder_details) + + return folders + + def get_datastore_folder(self, datacenter_name, datastore_name, folder_name): + folders = self.get_datastore_folders(datacenter_name, datastore_name, folder_name) + if folders is None: + return None + + files = self.get_datastore_files(datacenter_name, datastore_name, folder_name) + if files is None: + return None + + result = folders + for file in files: + found = False + for folder in folders: + if file['path'] == folder['path']: + found = True + break + + if found: + continue + + result.append(file) + + return result + + def print_datastore_files(self, files): + self.my_output.my_table( + files, + order=[ + 'path', + 'type', + 'size_unit', + 'owner', + 'modification' + ], + headers=[ + 'Path', + 'Type', + 'Size', + 'Owner', + 'Modification' + ], + table=True + ) + + def is_datastore_folder(self, datacenter_name, datastore_name, folder_name): + ds_obj = self.get_datastore_object(datacenter_name, datastore_name) + if ds_obj is None: + return False + + spec = vim.host.DatastoreBrowser.SearchSpec(query=[vim.host.DatastoreBrowser.FolderQuery()]) + search_path = '[%s] %s' % (datastore_name, folder_name) + task = ds_obj.browser.SearchDatastoreSubFolders_Task( + search_path, + spec + ) + self.wait_for_tasks([task], exception_on_task_failure=False) + if task.info.state == 'error': + return False + + return True + + def create_datastore_folder(self, datacenter_name, datastore_name, folder_name, nested=True): + if not self.vc_connect(): + print('[ERROR] Failed to connect to virtual center') + return False + + # https://vdc-download.vmware.com/vmwb-repository/dcr-public/fa5d1ee7-fad5-4ebf-b150-bdcef1d38d35/a5e46da1-9b96-4f0c-a1d0-7b8f3ebfd4f5/doc/vim.FileManager.html + dc_obj = self.get_datacenter_object(datacenter_name) + + file_manager_handler = self.get_filemanager_handler() + if file_manager_handler is None: + print('[ERROR] Failed to get file manager handler') + return False + + name = '[%s] %s' % (datastore_name, folder_name) + try: + file_manager_handler.MakeDirectory( + name=name, + datacenter=dc_obj, + createParentDirectories=nested + ) + except BaseException: + print(traceback.format_exc()) + return False + + return self.is_datastore_folder(datacenter_name, datastore_name, folder_name) + + def delete_datastore_folder(self, datacenter_name, datastore_name, folder_name, nested=True): + if not self.vc_connect(): + print('[ERROR] Failed to connect to virtual center') + return False + + # https://vdc-download.vmware.com/vmwb-repository/dcr-public/fa5d1ee7-fad5-4ebf-b150-bdcef1d38d35/a5e46da1-9b96-4f0c-a1d0-7b8f3ebfd4f5/doc/vim.FileManager.html + dc_obj = self.get_datacenter_object(datacenter_name) + + file_manager_handler = self.get_filemanager_handler() + if file_manager_handler is None: + print('[ERROR] Failed to get file manager handler') + return False + + name = '[%s] %s' % (datastore_name, folder_name) + try: + file_manager_handler.DeleteFile( + name=name, + datacenter=dc_obj + ) + except BaseException: + print(traceback.format_exc()) + return False + + return True + + def get_datastore_files(self, datacenter_name, datastore_name, folder_name): + ds_obj = self.get_datastore_object(datacenter_name, datastore_name) + if ds_obj is None: + return None + + spec = vim.host.DatastoreBrowser.SearchSpec(query=[vim.host.DatastoreBrowser.Query()]) + spec.details = vim.host.DatastoreBrowser.FileInfo.Details( + fileOwner=True, fileSize=True, fileType=True, modification=True + ) + search_path = '[%s] %s' % (datastore_name, folder_name) + task = ds_obj.browser.SearchDatastoreSubFolders_Task( + search_path, + spec + ) + self.wait_for_tasks([task]) + search_results = task.info.result + + files = [] + for search_result in search_results: + # + + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # datastore = 'vim.Datastore:datastore-1013', + # folderPath = '[datastore1] catalog/tidy/', + # file = (vim.host.DatastoreBrowser.FileInfo) [ + # (vim.host.DatastoreBrowser.FolderInfo) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # path = 'v1', + # friendlyName = , + # fileSize = , + # modification = , + # owner = + # } + # ] + for file_info in search_result.file: + file_folder = self.fixup_datastore_path( + search_result.folderPath + ) + if file_folder != search_path: + continue + + file_details = {} + file_details['type'] = 'File' + file_details['datastore'] = datastore_name + file_details['folder'] = folder_name + file_details['filename'] = file_info.path + file_details['path'] = '[%s] %s%s' % ( + datastore_name, + folder_name, + file_details['filename'] + ) + file_details['size'] = file_info.fileSize + file_details['size_unit'] = self.convert_storage(file_details['size']) + file_details['owner'] = file_info.owner + file_details['modification'] = file_info.modification + files.append(file_details) + + return files + + def is_datastore_file(self, datacenter_name, datastore_name, folder_name, file_name): + if not self.is_datastore_folder(datacenter_name, datastore_name, folder_name): + return False + + files = self.get_datastore_files(datacenter_name, datastore_name, folder_name) + if files is None: + return False + + for folder_file_info in files: + if folder_file_info['filename'] == file_name: + return True + + return False + + def create_datastore_file(self, datacenter_name, datastore_name, source_filename, target_folder_name, target_filename): + if not os.path.isfile(source_filename): + self.my_output.error('File not found: %s' % (source_filename)) + return False + + if not self.vc_connect(): + return None + + target_filename = '/folder%s%s' % (target_folder_name, target_filename) + params = {} + params["dsName"] = datastore_name + params["dcPath"] = datacenter_name + http_url = "https://%s:%s%s" % ( + self.vcenter_ip, + self.vcenter_port, + target_filename + ) + + # Get the cookie built from the current session + + # pylint: disable=protected-access + client_cookie = self.vc_service_instance._stub.cookie + + # Break apart the cookie into it's component parts - This is more than + # is needed, but a good example of how to break apart the cookie + # anyways. The verbosity makes it clear what is happening. + cookie_name = client_cookie.split("=", 1)[0] + cookie_value = client_cookie.split("=", 1)[1].split(";", 1)[0] + cookie_path = client_cookie.split("=", 1)[1].split(";", 1)[1].split( + ";", 1)[0].lstrip() + cookie_text = " " + cookie_value + "; $" + cookie_path + + # Make a cookie + cookie = {} + cookie[cookie_name] = cookie_text + + # Get the request headers set up + headers = {'Content-Type': 'application/octet-stream'} + + try: + self.my_output.debug(http_url) + + with open(source_filename, "rb") as file_data: + # Connect and upload the file + response = requests.put( + http_url, + params=params, + data=file_data, + headers=headers, + cookies=cookie, + verify=False, + timeout=3600 + ) + + response_code = response.status_code + self.my_output.debug('Reponse code: %s' % (response_code)) + if response_code >= 300: + self.my_output.error('File upload failed with response code %s' % (response_code)) + try: + self.my_output.default(response.content) + except BaseException: + pass + + return False + + except BaseException: + self.my_output.error('Exception in file upload') + self.my_output.default(traceback.format_exc()) + return False + + return True + + def delete_datastore_file(self, datacenter_name, datastore_name, file_path): + if not self.vc_connect(): + print('[ERROR] Failed to connect to virtual center') + return False + + # https://vdc-download.vmware.com/vmwb-repository/dcr-public/fa5d1ee7-fad5-4ebf-b150-bdcef1d38d35/a5e46da1-9b96-4f0c-a1d0-7b8f3ebfd4f5/doc/vim.FileManager.html + dc_obj = self.get_datacenter_object(datacenter_name) + + file_manager_handler = self.get_filemanager_handler() + if file_manager_handler is None: + print('[ERROR] Failed to get file manager handler') + return False + + name = '[%s] %s' % (datastore_name, file_path) + try: + file_manager_handler.DeleteFile( + name=name, + datacenter=dc_obj + ) + except BaseException: + print(traceback.format_exc()) + return False + + return True diff --git a/lib/vc/helper.py b/lib/vc/helper.py new file mode 100644 index 00000000..6a038125 --- /dev/null +++ b/lib/vc/helper.py @@ -0,0 +1,160 @@ +class VcHelper(): + def __init__(self): + pass + + def convert_cpu_capacity(self, value, empty_for_zero=False): + try: + if value == 0 and empty_for_zero: + return '' + + unit = ['kHz', 'MHz', 'GHz'] + for index in range(0, 3): + value = value / 1000 + if value < 1000: + break + + if value == 0: + value = '0 [Hz]' + else: + value = '%s [%s]' % ( + round(value, 2), + unit[index] + ) + + except BaseException: + self.log.error('iwe_cluster_info.convert_cpu_capacity', value) + return None + return value + + def convert_cpu_usage(self, value): + try: + value = '%s%%' % (int(value)) + except BaseException: + self.log.error('iwe_cluster_info.convert_cpu_usage', value) + return None + return value + + def convert_pct(self, pct, rounded=2): + try: + if rounded > 0: + value = '%s%%' % (round(pct, rounded)) + else: + value = '%s%%' % (int(pct)) + + except BaseException: + self.log.error('iwe_cluster_info.convert_cpu_capacity', pct) + return None + return value + + def convert_memory(self, value, empty_for_zero=False): + try: + if value == 0 and empty_for_zero: + return '' + + unit = ['KiB', 'MiB', 'GiB', 'TiB'] + for index in range(0, 4): + value = value / 1024 + if value < 1000: + break + + if value == 0: + value = '0 [B]' + else: + value = '%s [%s]' % ( + round(value, 2), + unit[index] + ) + + except BaseException: + self.log.error('iwe_cluster_info.convert_memory', value) + return None + + return value + + def convert_storage(self, value, empty_for_zero=False): + try: + if value == 0 and empty_for_zero: + return '' + + unit = ['KB', 'MB', 'GB', 'TB'] + for index in range(0, 4): + value = value / 1024 + if value < 1024: + break + + if value == 0: + value = '0 [B]' + else: + value = '%s [%s]' % ( + round(value, 2), + unit[index] + ) + + except BaseException: + self.log.error('iwe_cluster_info.convert_storage', value) + return None + + return value + + def convert_speed(self, value, empty_for_zero=False): + try: + if value == 0 and empty_for_zero: + return '' + + unit = ['kbps', 'mbps', 'gbps'] + for index in range(0, 4): + value = value / 1000 + if value < 1000: + break + + if value == 0: + value = '0' + else: + value = '%s [%s]' % ( + round(value, 0), + unit[index] + ) + + except BaseException: + self.log.error('iwe_cluster_info.convert_speed', value) + return None + + return value + + def fixup_datastore_folder_name(self, folder): + if folder == '': + return '/' + + if not folder.startswith('/'): + folder = '/%s' % (folder) + + if not folder.endswith('/'): + folder = '%s/' % (folder) + + return folder + + def fixup_datastore_path(self, path): + path = path.strip() + if len(path.split(' ')) == 1: + return '%s /' % (path) + + items = path.split(' ') + datastore_name = items[0] + file_name = ' '.join(items[1:]) + if not file_name.startswith('/'): + file_name = '/%s' % (file_name) + + return '%s %s' % (datastore_name, file_name) + + def get_parent_folder_name(self, folder_name): + folder_name = self.fixup_datastore_folder_name(folder_name) + + if folder_name == '/': + return folder_name + + subfolders = folder_name.lstrip('/').rstrip('/').split('/')[:-1] + return '/%s/' % ('/'.join(subfolders)) + + def get_datastore_file_path(self, folder_name, file_name): + folder_name = self.fixup_datastore_folder_name(folder_name) + return '%s%s' % (folder_name, file_name.lstrip('/')) diff --git a/lib/vc/host/__init__.py b/lib/vc/host/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/vc/host/__pycache__/__init__.cpython-310.pyc b/lib/vc/host/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..71d07ddc Binary files /dev/null and b/lib/vc/host/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/vc/host/__pycache__/api.cpython-310.pyc b/lib/vc/host/__pycache__/api.cpython-310.pyc new file mode 100644 index 00000000..45772312 Binary files /dev/null and b/lib/vc/host/__pycache__/api.cpython-310.pyc differ diff --git a/lib/vc/host/__pycache__/filtering.cpython-310.pyc b/lib/vc/host/__pycache__/filtering.cpython-310.pyc new file mode 100644 index 00000000..ee3c59da Binary files /dev/null and b/lib/vc/host/__pycache__/filtering.cpython-310.pyc differ diff --git a/lib/vc/host/__pycache__/main.cpython-310.pyc b/lib/vc/host/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..bf77261f Binary files /dev/null and b/lib/vc/host/__pycache__/main.cpython-310.pyc differ diff --git a/lib/vc/host/__pycache__/networking.cpython-310.pyc b/lib/vc/host/__pycache__/networking.cpython-310.pyc new file mode 100644 index 00000000..7f74356d Binary files /dev/null and b/lib/vc/host/__pycache__/networking.cpython-310.pyc differ diff --git a/lib/vc/host/__pycache__/summary.cpython-310.pyc b/lib/vc/host/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..01cb0cb2 Binary files /dev/null and b/lib/vc/host/__pycache__/summary.cpython-310.pyc differ diff --git a/lib/vc/host/api.py b/lib/vc/host/api.py new file mode 100644 index 00000000..207a5f00 --- /dev/null +++ b/lib/vc/host/api.py @@ -0,0 +1,129 @@ +import time + +# pylint: disable=no-name-in-module +from pyVmomi import vim, vmodl + + +class VcHostApi(): + def __init__(self): + self.mo_host = None + self.host_names = {} + + def get_host_name(self, host_obj): + if host_obj is None: + return None + + if host_obj in self.host_names: + return self.host_names[host_obj] + self.host_names[host_obj] = host_obj.name + + return self.host_names[host_obj] + + def get_host_ips(self): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + hosts_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.HostSystem], + True + ) + + if len(hosts_object_view.view) == 0: + self.my_output.error('No available host found') + return None + + host_ips = [] + for host_obj in hosts_object_view.view: + host_ips.append(host_obj.name) + + hosts_object_view.Destroy() + + return host_ips + + def match_host(self, host_info, host_filter): + if host_filter is None or len(host_filter) == 0: + return True + + name_filtering = False + name_match = False + for host_rule in host_filter: + if host_rule.startswith('name:'): + name_filtering = True + name_value = host_rule[5:] + if name_value in host_info['name']: + name_match = True + + if name_filtering and not name_match: + return False + + return True + + def get_hosts_properties(self, properties): + if not self.vc_connect(): + return None + + start_time = int(time.time() * 1000) + + content = self.vc_service_instance.RetrieveContent() + host_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.HostSystem], + True + ) + + filter_spec = self.get_filter_spec( + host_object_view, + vim.HostSystem, + properties + ) + options = vmodl.query.PropertyCollector.RetrieveOptions() + result = self.vc_service_instance.content.propertyCollector.RetrievePropertiesEx([filter_spec], options) + + mo_host = [] + while True: + for oresult in result.objects: + item = {} + for prop in oresult.propSet: + item[prop.name] = prop.val + mo_host.append(item) + + if result.token is None: + break + + result = self.vc_service_instance.content.propertyCollector.ContinueRetrievePropertiesEx(result.token) + + host_object_view.Destroy() + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'vim.HostSystem', + True, + duration + ) + + return mo_host + + def get_host_objects(self): + if self.mo_host is not None: + return self.mo_host + + if not self.vc_connect(): + return None + + self.mo_host = [] + content = self.vc_service_instance.RetrieveContent() + + # Get the list of all datacenters we have available to us + hosts_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.HostSystem], + True + ) + + for host_obj in hosts_object_view.view: + self.mo_host.append(host_obj) + + return self.mo_host diff --git a/lib/vc/host/filtering.py b/lib/vc/host/filtering.py new file mode 100644 index 00000000..ad54a7a8 --- /dev/null +++ b/lib/vc/host/filtering.py @@ -0,0 +1,28 @@ +class VcHostFiltering(): + def __init__(self): + pass + + def get_hosts_by_name(self, name, strict=True): + mo_hosts = self.get_host_objects() + if mo_hosts is None: + return None + + hosts = [] + + for mo_host in mo_hosts: + mo_host_name = getattr(mo_host, 'name', None) + if mo_host_name is None: + continue + + if strict and mo_host_name == name: + hosts.append( + mo_host + ) + continue + + if name in mo_host_name: + hosts.append( + mo_host + ) + + return hosts diff --git a/lib/vc/host/main.py b/lib/vc/host/main.py new file mode 100644 index 00000000..2191e079 --- /dev/null +++ b/lib/vc/host/main.py @@ -0,0 +1,12 @@ +from lib.vc.host.api import VcHostApi +from lib.vc.host.filtering import VcHostFiltering +from lib.vc.host.networking import VcHostNetworking +from lib.vc.host.summary import VcHostSummary + + +class VcHost(VcHostApi, VcHostFiltering, VcHostNetworking, VcHostSummary): + def __init__(self): + VcHostApi.__init__(self) + VcHostFiltering.__init__(self) + VcHostNetworking.__init__(self) + VcHostSummary.__init__(self) diff --git a/lib/vc/host/networking.py b/lib/vc/host/networking.py new file mode 100644 index 00000000..19f58b0d --- /dev/null +++ b/lib/vc/host/networking.py @@ -0,0 +1,736 @@ +import time + +# pylint: disable=no-name-in-module +from pyVmomi import vim + +from lib import ip_helper + + +class VcHostNetworking(): + def __init__(self): + pass + + def get_host_pnic_info(self, pnic_obj): + # (vim.host.PhysicalNic) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # key = 'key-vim.host.PhysicalNic-vmnic0', + # device = 'vmnic0', + # pci = '0000:0c:00.0', + # driver = 'i40en', + # linkSpeed = (vim.host.PhysicalNic.LinkSpeedDuplex) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # speedMb = 10000, + # duplex = true + # }, + + # validLinkSpecification = (vim.host.PhysicalNic.LinkSpeedDuplex) [ + # (vim.host.PhysicalNic.LinkSpeedDuplex) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # speedMb = 10000, + # duplex = true + # } + # ], + # spec = (vim.host.PhysicalNic.Specification) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # ip = (vim.host.IpConfig) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # dhcp = false, + # ipAddress = '', + # subnetMask = '', + # ipV6Config = + # }, + # linkSpeed = , + # enableEnhancedNetworkingStack = false, + # ensInterruptEnabled = false + # }, + # wakeOnLanSupported = false, + # mac = '40:a6:b7:0b:e5:50', + # fcoeConfiguration = (vim.host.FcoeConfig) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # priorityClass = 3, + # sourceMac = '40:a6:b7:0b:e5:50', + # vlanRange = (vim.host.FcoeConfig.VlanRange) [ + # (vim.host.FcoeConfig.VlanRange) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # vlanLow = 0, + # vlanHigh = 0 + # } + # ], + # capabilities = (vim.host.FcoeConfig.FcoeCapabilities) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # priorityClass = false, + # sourceMacAddress = false, + # vlanRange = false + # }, + # fcoeActive = false + # }, + # vmDirectPathGen2Supported = false, + # vmDirectPathGen2SupportedMode = , + # resourcePoolSchedulerAllowed = true, + # resourcePoolSchedulerDisallowedReason = (str) [], + # autoNegotiateSupported = true, + # enhancedNetworkingStackSupported = true, + # ensInterruptSupported = true, + # rdmaDevice = + # }, + + info = {} + + info['key'] = pnic_obj.key + info['device'] = pnic_obj.device + info['pci'] = pnic_obj.pci + info['driver'] = pnic_obj.driver + + link_speed_obj = pnic_obj.linkSpeed + if link_speed_obj is not None: + info['speedMb'] = link_speed_obj.speedMb + info['speedUnit'] = self.convert_speed( + info['speedMb'] * 1000 * 1000 + ) + info['duplex'] = link_speed_obj.duplex + + info['mac'] = pnic_obj.mac + info['wakeOnLanSupported'] = pnic_obj.wakeOnLanSupported + + return info + + def get_host_vnic_info(self, vnic_obj, port_group_info): + # (vim.host.VirtualNic) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # device = 'vmk0', + # key = 'key-vim.host.VirtualNic-vmk0', + # portgroup = 'Management Network', + # spec = (vim.host.VirtualNic.Specification) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # ip = (vim.host.IpConfig) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # dhcp = false, + # ipAddress = '', + # subnetMask = '', + # ipV6Config = + # }, + # mac = '3c:fd:fe:cb:f7:c0', + # distributedVirtualPort = , + # portgroup = 'Management Network', + # mtu = 1500, + # tsoEnabled = true, + # netStackInstanceKey = 'defaultTcpipStack', + # opaqueNetwork = , + # externalId = , + # pinnedPnic = , + # ipRouteSpec = (vim.host.VirtualNic.IpRouteSpec) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # ipRouteConfig = (vim.host.IpRouteConfig) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # defaultGateway = '', + # gatewayDevice = , + # ipV6DefaultGateway = , + # ipV6GatewayDevice = + # } + # }, + # systemOwned = + # }, + # port = 'key-vim.host.PortGroup.Port-234881068' + # }, + + info = {} + info['key'] = vnic_obj.key + info['device'] = vnic_obj.device + info['portgroup'] = vnic_obj.portgroup + info['mac'] = vnic_obj.spec.mac + info['mtu'] = vnic_obj.spec.mtu + info['ip'] = vnic_obj.spec.ip.ipAddress + info['mask'] = vnic_obj.spec.ip.subnetMask + info['prefix'] = ip_helper.netmask_to_prefix(vnic_obj.spec.ip.subnetMask) + info['cidr'] = '%s/%s' % ( + info['ip'], + info['prefix'] + ) + + info['gateway'] = None + ip_route_spec = vnic_obj.spec.ipRouteSpec + if ip_route_spec is not None: + info['gateway'] = ip_route_spec.ipRouteConfig.defaultGateway + + info['port_key'] = vnic_obj.port + info['vswitch'] = None + info['vlan'] = None + for port_group in port_group_info: + for port in port_group['ports']: + if port['key'] == info['port_key']: + info['vswitch'] = port_group['vswitch'] + info['vlan'] = port_group['vlan'] + + return info + + def get_host_vnic_services(self, services_obj): + services = {} + for net_config in services_obj.netConfig: + if len(net_config.selectedVnic) == 0: + continue + + services[net_config.nicType] = [] + for nic_key in net_config.selectedVnic: + for nic_candidate in net_config.candidateVnic: + if nic_candidate.key == nic_key: + services[net_config.nicType].append( + nic_candidate.device + ) + + return services + + def get_host_port_group_config_info(self, port_group_obj): + # (vim.host.PortGroup) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # key = 'key-vim.host.PortGroup-iscsi-B', + # port = (vim.host.PortGroup.Port) [ + # (vim.host.PortGroup.Port) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # key = 'key-vim.host.PortGroup.Port-234881072', + # mac = (str) [ + # '00:50:56:65:15:68' + # ], + # type = 'host' + # } + # ], + # vswitch = 'key-vim.host.VirtualSwitch-vSwitch0', + # computedPolicy = (vim.host.NetworkPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # security = (vim.host.NetworkPolicy.SecurityPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # allowPromiscuous = false, + # macChanges = true, + # forgedTransmits = true + # }, + # nicTeaming = (vim.host.NetworkPolicy.NicTeamingPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # policy = 'loadbalance_srcid', + # reversePolicy = true, + # notifySwitches = true, + # rollingOrder = false, + # failureCriteria = (vim.host.NetworkPolicy.NicFailureCriteria) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # checkSpeed = 'minimum', + # speed = 10, + # checkDuplex = false, + # fullDuplex = false, + # checkErrorPercent = false, + # percentage = 0, + # checkBeacon = false + # }, + # nicOrder = (vim.host.NetworkPolicy.NicOrderPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # activeNic = (str) [ + # 'vmnic1' + # ], + # standbyNic = (str) [] + # } + # }, + # offloadPolicy = (vim.host.NetOffloadCapabilities) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # csumOffload = true, + # tcpSegmentation = true, + # zeroCopyXmit = true + # }, + # shapingPolicy = (vim.host.NetworkPolicy.TrafficShapingPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # enabled = false, + # averageBandwidth = , + # peakBandwidth = , + # burstSize = + # } + # }, + # spec = (vim.host.PortGroup.Specification) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # name = 'iscsi-B', + # vlanId = 19, + # vswitchName = 'vSwitch0', + + # policy = (vim.host.NetworkPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # security = (vim.host.NetworkPolicy.SecurityPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # allowPromiscuous = , + # macChanges = , + # forgedTransmits = + # }, + # nicTeaming = (vim.host.NetworkPolicy.NicTeamingPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # policy = , + # reversePolicy = , + # notifySwitches = , + # rollingOrder = , + # failureCriteria = (vim.host.NetworkPolicy.NicFailureCriteria) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # checkSpeed = , + # speed = , + # checkDuplex = , + # fullDuplex = , + # checkErrorPercent = , + # percentage = , + # checkBeacon = + # }, + # nicOrder = (vim.host.NetworkPolicy.NicOrderPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # activeNic = (str) [ + # 'vmnic1' + # ], + # standbyNic = (str) [] + # } + # }, + # offloadPolicy = (vim.host.NetOffloadCapabilities) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # csumOffload = , + # tcpSegmentation = , + # zeroCopyXmit = + # }, + # shapingPolicy = (vim.host.NetworkPolicy.TrafficShapingPolicy) { + # dynamicType = , + # dynamicProperty = (vmodl.DynamicProperty) [], + # enabled = , + # averageBandwidth = , + # peakBandwidth = , + # burstSize = + # } + # } + # } + # }, + + info = {} + info['key'] = getattr(port_group_obj, 'key') + info['ports'] = [] + port_objs = getattr(port_group_obj, 'port', None) + if port_objs is not None: + for port_obj in port_objs: + port_info = {} + port_info['key'] = getattr(port_obj, 'key') + port_info['type'] = getattr(port_obj, 'type') + port_info['mac'] = [] + macs = getattr(port_obj, 'mac', None) + if macs is not None: + for mac in macs: + port_info['mac'].append(mac) + info['ports'].append(port_info) + + info['vswitch_key'] = getattr(port_group_obj, 'vswitch', None) + + security = getattr( + getattr(port_group_obj, 'computedPolicy'), + 'security' + ) + + info['allowPromiscuous'] = getattr(security, 'allowPromiscuous') + info['macChanges'] = getattr(security, 'macChanges') + info['forgedTransmits'] = getattr(security, 'forgedTransmits') + + spec = getattr(port_group_obj, 'spec') + info['name'] = getattr(spec, 'name') + info['vswitch'] = getattr(spec, 'vswitchName') + info['vlan'] = getattr(spec, 'vlanId') + + return info + + def get_host_vswitch_config_info(self, vswitch_obj): + info = {} + info['name'] = vswitch_obj.name + info['mtu'] = vswitch_obj.mtu + info['portgroup'] = [] + for port_group_key in vswitch_obj.portgroup: + item = {} + item['key'] = port_group_key + info['portgroup'].append(item) + + info['pnic'] = [] + for pnic_key in vswitch_obj.pnic: + item = {} + item['key'] = pnic_key + info['pnic'].append(item) + + spec = getattr(vswitch_obj, 'spec') + info['discoveryProtocol'] = spec.bridge.linkDiscoveryProtocolConfig.protocol + + return info + + def get_host_dvswitch_config_info(self, dvswitch_obj): + info = {} + info['name'] = dvswitch_obj.dvsName + info['mtu'] = dvswitch_obj.mtu + + info['pnic'] = [] + for pnic_key in dvswitch_obj.spec.backing.pnicSpec: + item = {} + item['device'] = pnic_key.pnicDevice + item['uplink'] = pnic_key.uplinkPortKey + info['pnic'].append(item) + + return info + + def get_host_pci_pt(self, pci_pt_obj): + info = [] + + for pci_pt_device in pci_pt_obj: + if isinstance(pci_pt_device, vim.Host.PciPassthruInfo): + keys = [ + 'id', + 'passthruEnabled', + 'passthruCapable', + 'passthruActive' + ] + item = {} + for key in keys: + item[key] = getattr(pci_pt_device, key) + info.append(item) + + return info + + def get_host_sriov(self, pci_pt_obj): + info = [] + + if pci_pt_obj is None: + return info + + for pci_pt_device in pci_pt_obj: + if isinstance(pci_pt_device, vim.host.SriovInfo): + keys = [ + 'id', + 'passthruEnabled', + 'passthruCapable', + 'passthruActive', + 'sriovEnabled', + 'sriovCapable', + 'sriovActive', + 'numVirtualFunctionRequested', + 'numVirtualFunction', + 'maxVirtualFunctionSupported' + ] + item = {} + for key in keys: + item[key] = getattr(pci_pt_device, key) + + item['vf'] = '%s/%s/%s' % ( + item['numVirtualFunctionRequested'], + item['numVirtualFunction'], + item['maxVirtualFunctionSupported'] + ) + info.append(item) + + return info + + def get_host_networking_hint_cdp_info(self, cdp_obj): + info = {} + info['switch_device_id'] = cdp_obj.devId + info['switch_system_name'] = cdp_obj.systemName + info['switch_hw'] = cdp_obj.hardwarePlatform + info['switch_sw'] = cdp_obj.softwareVersion + info['switch_mgmt_ip'] = cdp_obj.mgmtAddr + info['switch_port'] = cdp_obj.portId + return info + + def get_host_networking_hint_lldp_info(self, lldp_obj): + info = {} + for paremeter_obj in lldp_obj.parameter: + if paremeter_obj.key == 'Management Address': + info['switch_mgmt_ip'] = paremeter_obj.value + + if paremeter_obj.key == 'System Name': + info['switch_system_name'] = paremeter_obj.value + + if paremeter_obj.key == 'System Description': + info['switch_device_id'] = paremeter_obj.value + + info['switch_hw'] = '' + info['switch_sw'] = '' + info['switch_port'] = lldp_obj.portId + + return info + + def get_host_networking_hint_info(self, hint_obj): + info = {} + info['device'] = hint_obj.device + + cdp_obj = getattr(hint_obj, 'connectedSwitchPort', None) + lldp_obj = getattr(hint_obj, 'lldpInfo', None) + + nei_info = None + info['switch_source'] = None + + if cdp_obj is not None: + info['switch_source'] = 'cdp' + nei_info = self.get_host_networking_hint_cdp_info(cdp_obj) + + if lldp_obj is not None: + info['switch_source'] = 'lldp' + nei_info = self.get_host_networking_hint_lldp_info(lldp_obj) + + if nei_info is not None: + for key in nei_info: + info[key] = nei_info[key] + + return info + + def get_host_networking_hints(self, host_obj): + hints = [] + network_system = host_obj.configManager.networkSystem + if network_system is not None: + if network_system.capabilities.supportsNetworkHints: + for hint_obj in network_system.QueryNetworkHint(): + hints.append( + self.get_host_networking_hint_info( + hint_obj + ) + ) + + return hints + + def get_host_networking(self, host_obj): + network_config = host_obj.config.network + + start_time = int(time.time() * 1000) + + info = {} + + info['vswitch'] = [] + for vswitch_obj in network_config.vswitch: + info['vswitch'].append( + self.get_host_vswitch_config_info( + vswitch_obj + ) + ) + + info['dvswitch'] = [] + for dvswitch_obj in network_config.proxySwitch: + info['dvswitch'].append( + self.get_host_dvswitch_config_info( + dvswitch_obj + ) + ) + + info['port_group'] = [] + for port_group_obj in network_config.portgroup: + info['port_group'].append( + self.get_host_port_group_config_info( + port_group_obj + ) + ) + + info['pnic'] = [] + for pnic_obj in network_config.pnic: + info['pnic'].append( + self.get_host_pnic_info( + pnic_obj + ) + ) + + info['pnic'] = sorted( + info['pnic'], + key=lambda i: i['device'] + ) + + sriovs = self.get_host_sriov( + host_obj.config.pciPassthruInfo + ) + + hints = self.get_host_networking_hints( + host_obj + ) + + for pnic in info['pnic']: + pnic['sriov'] = {} + pnic['sriov']['sriovCapable'] = False + for sriov in sriovs: + if pnic['pci'] == sriov['id']: + pnic['sriov'] = sriov + + pnic['uplink'] = None + for vswitch in info['vswitch']: + for vswitch_pnic in vswitch['pnic']: + if vswitch_pnic['key'] == pnic['key']: + pnic['uplink'] = vswitch['name'] + + for dvswitch in info['dvswitch']: + for dvswitch_pnic in dvswitch['pnic']: + if dvswitch_pnic['device'] == pnic['device']: + pnic['uplink'] = dvswitch['name'] + + for hint in hints: + if hint['device'] == pnic['device']: + for key in hint: + if key != 'device': + pnic[key] = hint[key] + + info['vnic'] = [] + for vnic_obj in network_config.vnic: + info['vnic'].append( + self.get_host_vnic_info( + vnic_obj, + info['port_group'] + ) + ) + + info['vnic'] = sorted( + info['vnic'], + key=lambda i: i['device'] + ) + + info['vnic_services'] = self.get_host_vnic_services( + host_obj.config.virtualNicManagerInfo + ) + for vnic in info['vnic']: + vnic['services'] = [] + for vnic_service in info['vnic_services']: + for vnic_device in info['vnic_services'][vnic_service]: + if vnic['device'] == vnic_device: + vnic['services'].append(vnic_service) + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'get_host_net', + True, + duration + ) + + return info + + def print_host_networking_vmkernel(self, info): + order = [ + 'device', + 'portgroup', + 'vswitch', + 'vlan', + 'cidr', + 'gateway', + 'services' + ] + + headers = [ + 'VMkernel Adapter Device', + 'Network Label', + 'Switch', + 'VLAN', + 'IP', + 'Gateway', + 'Services' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + info['vnic'], + order, + ['services'] + ), + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_host_networking_pnic(self, info): + order = [ + 'device', + 'pci', + 'driver', + 'speedUnit', + 'duplex', + 'mac', + 'wakeOnLanSupported', + 'sriov.sriovCapable', + 'sriov.sriovActive', + 'sriov.vf', + 'uplink' + ] + + headers = [ + 'Physical Adapter', + 'PCI', + 'Driver', + 'Speed', + 'Duplex', + 'MAC', + 'Wake On LAN', + 'SRIOV Capable', + 'SRIOV Active', + 'VF (req/act/max)', + 'vSwitch Uplink' + ] + + self.my_output.my_table( + info['pnic'], + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_host_networking_pnic_switch(self, info): + order = [ + 'device', + 'switch_source', + 'switch_system_name', + 'switch_port', + 'switch_hw', + 'switch_sw', + 'switch_mgmt_ip' + ] + + headers = [ + 'Physical Adapter', + 'Source', + 'Switch Name', + 'Port', + 'Hardware', + 'Software', + 'Management IP' + ] + + self.my_output.my_table( + info['pnic'], + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) + + def print_host_networking(self, info): + self.print_host_networking_vmkernel(info) + self.print_host_networking_pnic(info) + self.print_host_networking_pnic_switch(info) + + def print_host_phy_networking(self, info): + self.print_host_networking_pnic(info) + self.print_host_networking_pnic_switch(info) diff --git a/lib/vc/host/summary.py b/lib/vc/host/summary.py new file mode 100644 index 00000000..76e9092f --- /dev/null +++ b/lib/vc/host/summary.py @@ -0,0 +1,194 @@ +import time + + +class VcHostSummary(): + def __init__(self): + pass + + def add_host_summary_state_flag(self, host_info): + color = ':' + if host_info['runtime']['powerState'] == 'poweredOn': + state = 'P+' + color = '%sGG' % (color) + else: + state = 'P-' + color = '%sRR' % (color) + + if host_info['runtime']['connectionState'] == 'connected': + state = '%s C' % (state) + color = '%s.G' % (color) + else: + state = '%s C' % (state) + color = '%s.R' % (color) + + host_info['flagState'] = state + host_info['__Output']['flagState'] = color + + return host_info + + def get_host_summary_info(self, mo_host, host_filter=None): + info = {} + info['__Output'] = {} + + info['name'] = mo_host['summary'].config.name + if host_filter is not None: + if not self.match_host(info, host_filter): + return None + + hardware = mo_host['summary'].hardware + info['serial'] = None + for hardware_id in hardware.otherIdentifyingInfo: + if hardware_id.identifierType.key == 'SerialNumberTag': + info['serial'] = hardware_id.identifierValue + + info['hypervisor'] = mo_host['summary'].config.product.fullName + + keys = [ + 'vendor', + 'model', + 'memorySize', + 'cpuModel', + 'cpuMhz', + 'numCpuPkgs', + 'numCpuCores', + 'numCpuThreads', + 'numNics', + 'numHBAs' + ] + for key in keys: + info[key] = getattr(hardware, key) + + info['cpuSummary'] = '%s/%s/%s' % ( + info['numCpuPkgs'], + info['numCpuCores'], + info['numCpuThreads'] + ) + + info['cpuCapacity'] = info['cpuMhz'] * info['numCpuCores'] + + info['memoryUnit'] = self.convert_memory( + info['memorySize'] + ) + + runtime = mo_host['summary'].runtime + keys = [ + 'connectionState', + 'powerState', + 'standbyMode' + ] + info['runtime'] = {} + for key in keys: + info['runtime'][key] = getattr(runtime, key) + + stats = mo_host['summary'].quickStats + keys = [ + 'overallCpuUsage', + 'overallMemoryUsage', + 'distributedCpuFairness', + 'distributedMemoryFairness', + 'availablePMemCapacity', + 'uptime' + ] + info['stats'] = {} + for key in keys: + info['stats'][key] = getattr(stats, key) + + if info['stats']['overallCpuUsage'] is None: + info['stats']['overallCpuUsagePct'] = '0%' + else: + info['stats']['overallCpuUsagePct'] = self.convert_pct( + info['stats']['overallCpuUsage'] * 100 / info['cpuCapacity'], + rounded=0 + ) + + if info['stats']['overallMemoryUsage'] is None: + info['stats']['overallMemoryUsagePct'] = '0%' + else: + info['stats']['overallMemoryUsagePct'] = self.convert_pct( + info['stats']['overallMemoryUsage'] * 1024 * 1024 * 100 / info['memorySize'], + rounded=0 + ) + + info['overallStatus'] = mo_host['summary'].overallStatus + + info = self.add_host_summary_state_flag(info) + + return info + + def get_hosts_summary(self, host_filter=None): + mo_hosts = self.get_hosts_properties(['summary']) + if mo_hosts is None: + return None + + start_time = int(time.time() * 1000) + + hosts = [] + for mo_host in mo_hosts: + host_info = self.get_host_summary_info(mo_host, host_filter=host_filter) + if host_info is not None: + hosts.append(host_info) + + hosts = sorted( + hosts, + key=lambda i: i['name'].lower() + ) + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'get_hosts_summary', + True, + duration + ) + + return hosts + + def print_hosts_summary(self, info, title=False): + if title: + self.my_output.default( + 'Host [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'flagState', + 'name', + 'hypervisor', + 'serial', + 'model', + 'cpuSummary', + 'stats.overallCpuUsagePct', + 'memoryUnit', + 'stats.overallMemoryUsagePct', + 'numNics', + 'numHBAs' + ] + + headers = [ + 'SF', + 'Name', + 'Hypervisor', + 'Serial', + 'Model', + 'CPU', + 'Usage', + 'Memory', + 'Usage', + 'NICs', + 'HBAs' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + remove_empty_columns=True, + underline=True, + table=True + ) diff --git a/lib/vc/network.py b/lib/vc/network.py new file mode 100644 index 00000000..1e7c748c --- /dev/null +++ b/lib/vc/network.py @@ -0,0 +1,183 @@ +import time + +# pylint: disable=no-name-in-module +from pyVmomi import vim, vmodl + + +class VcNetwork(): + def __init__(self): + self.distributed_network_objects = None + self.distributed_network_names = {} + + self.network_objects = None + self.network_names = {} + + def get_distributed_network_name_by_key(self, key): + if key in self.distributed_network_names: + return self.distributed_network_names[key] + + network_objs = self.get_distributed_network_objects() + if network_objs is None: + return None + + network_name = None + for network_obj in network_objs: + if network_obj['key'] == key: + self.distributed_network_names[key] = network_obj['name'] + network_name = self.distributed_network_names[key] + break + + return network_name + + def is_network_distributed(self, network_obj): + return isinstance(network_obj, vim.dvs.DistributedVirtualPortgroup) + + def get_distributed_network_objects(self): + if self.distributed_network_objects is not None: + return self.distributed_network_objects + + if not self.vc_connect(): + return None + + start_time = int(time.time() * 1000) + + content = self.vc_service_instance.RetrieveContent() + networks_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.dvs.DistributedVirtualPortgroup], + True + ) + + filter_spec = self.get_filter_spec( + networks_object_view, + vim.dvs.DistributedVirtualPortgroup, + ['name', 'key', 'config'] + ) + options = vmodl.query.PropertyCollector.RetrieveOptions() + result = self.vc_service_instance.content.propertyCollector.RetrievePropertiesEx([filter_spec], options) + + self.distributed_network_objects = [] + while True: + for oresult in result.objects: + item = {} + for prop in oresult.propSet: + item[prop.name] = prop.val + self.distributed_network_objects.append(item) + + if result.token is None: + break + + result = self.vc_service_instance.content.propertyCollector.ContinueRetrievePropertiesEx(result.token) + + networks_object_view.Destroy() + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'vim.dvs.DistributedVirtualPortgroup', + True, + duration + ) + + return self.distributed_network_objects + + def get_distributed_network_object(self, network_name): + network_objs = self.get_distributed_network_objects() + if network_objs is None: + return None + + for network_obj in network_objs: + if network_obj['name'] == network_name: + return network_obj + + return None + + def get_network_info(self, network_obj): + info = {} + info['name'] = network_obj.name + # info['objects'] = dir(network_obj) + # info['host'] = dir(network_obj.host) + # info['summary'] = dir(network_obj.summary) + # info['vm'] = dir(network_obj.vm) + return info + + def is_network(self, network_name): + network_obj = self.get_network_object(network_name) + if network_obj is None: + return False + return True + + def get_network_objects(self): + if self.network_objects is not None: + return self.network_objects + + if not self.vc_connect(): + return None + + start_time = int(time.time() * 1000) + + content = self.vc_service_instance.RetrieveContent() + networks_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Network], + True + ) + + self.network_objects = [] + for network_obj in networks_object_view.view: + self.network_objects.append(network_obj) + + networks_object_view.Destroy() + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'vim.Network', + True, + duration + ) + + return self.network_objects + + def get_network_object(self, network_name): + network_objs = self.get_network_objects() + if network_objs is None: + return None + + for network_obj in network_objs: + if network_obj.name == network_name: + return network_obj + + return None + + def get_network_name(self, network_obj): + if network_obj in self.network_names: + return self.network_names[network_obj] + + self.network_names[network_obj] = network_obj.name + return self.network_names[network_obj] + + def get_network_names(self): + network_objs = self.get_network_objects() + if network_objs is None: + return None + + network_names = [] + for network_obj in network_objs: + network_names.append( + network_obj.name + ) + + return sorted(network_names) + + def print_network_names(self, title=None): + if title is not None: + self.my_output.default(title) + + network_names = self.get_network_names() + if network_names is None: + self.my_output.error('No network found') + return + + for network_name in network_names: + self.my_output.default('- %s' % (network_name)) diff --git a/lib/vc/settings.py b/lib/vc/settings.py new file mode 100644 index 00000000..553b826a --- /dev/null +++ b/lib/vc/settings.py @@ -0,0 +1,177 @@ +import os +import json +import traceback + +from lib import log_helper +from lib import output_helper +from lib.settings_helper import Settings + + +class VcSettings(Settings): + def __init__(self, log_id=None): + Settings.__init__(self, log_id=log_id) + + self.log = log_helper.Log(log_id=log_id) + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=False, + debug=False + ) + + self.vc_settings_filename = os.path.join( + self.settings_dir, + 'vc' + ) + + if not self.initialize_vc_settings(): + raise ValueError('vSphere Client settings initialization failed') + + def get_vc_default_settings(self): + settings = {} + settings['Enabled'] = True + settings['Defaults'] = {} + settings['Defaults']['Instance'] = None + settings['Instances'] = [] + return settings + + def initialize_vc_settings(self): + if not os.path.isfile(self.vc_settings_filename): + settings = self.get_vc_default_settings() + if not self.set_vc_settings(settings): + return False + return True + + def get_vc_settings(self): + if not os.path.isfile(self.vc_settings_filename): + return None + + try: + with open(self.vc_settings_filename, 'r', encoding='utf-8') as file_handler: + settings = json.loads(file_handler.read()) + + except BaseException: + self.log.error('get_vc_settings', traceback.format_exc()) + return None + + return settings + + def set_vc_settings(self, settings): + try: + with open(self.vc_settings_filename, 'w', encoding='utf-8') as file_handler: + file_handler.write(json.dumps(settings, indent=4)) + + except BaseException: + self.log.error('set_vc_settings', traceback.format_exc()) + return False + + return True + + def get_default_instance(self): + settings = self.get_vc_settings() + if settings is None: + return None + + try: + default_instance_name = settings['Defaults']['Instance'] + except BaseException: + default_instance_name = None + + return default_instance_name + + def set_default_instance(self, name): + settings = self.get_vc_settings() + if settings is None: + return False + + if 'Defaults' not in settings: + settings['Defaults'] = {} + + settings['Defaults']['Instance'] = name + return self.set_vc_settings(settings) + + def get_vc_instances(self): + settings = self.get_vc_settings() + if settings is None: + return None + + return settings['Instances'] + + def get_vc_instance(self, vc_name): + instances = self.get_vc_instances() + if instances is None: + return None + + for instance in instances: + if instance['name'] == vc_name: + return instance + + return None + + def set_vc_instances(self, instances): + settings = self.get_vc_settings() + if settings is None: + return False + + settings['Instances'] = instances + return self.set_vc_settings(settings) + + def set_vc_instance(self, vc_name, vc_ip, vc_port, vc_username, vc_password): + instances = self.get_vc_instances() + if instances is None: + return False + + new_instances = [] + for instance in instances: + if instance['name'] != vc_name: + new_instances.append(instance) + + new_instance = {} + new_instance['name'] = vc_name + new_instance['ip'] = vc_ip + new_instance['port'] = vc_port + new_instance['username'] = vc_username + new_instance['password'] = vc_password + new_instances.append(new_instance) + + return self.set_vc_instances(new_instances) + + def delete_vc_instance(self, vc_name): + instances = self.get_vc_instances() + if instances is None: + return False + + new_instances = [] + for instance in instances: + if instance['name'] != vc_name: + new_instances.append(instance) + + return self.set_vc_instances(new_instances) + + def print_vc_instances(self, instances, show_password=True): + instances = sorted(instances, key=lambda i: i['name']) + if not show_password: + for instance in instances: + instance['password'] = '******' + + order = [ + 'name', + 'ip', + 'port', + 'username', + 'password' + ] + + headers = [ + 'Name', + 'IP', + 'Port', + 'Username', + 'Password' + ] + + self.my_output.my_table( + instances, + order=order, + headers=headers, + table=True + ) diff --git a/lib/vc/vcenter.py b/lib/vc/vcenter.py new file mode 100644 index 00000000..2fea9602 --- /dev/null +++ b/lib/vc/vcenter.py @@ -0,0 +1,60 @@ +from lib.vc.common import VcCommon +from lib.vc.connect import VcConnect +from lib.vc.datacenter import VcDatacenter +from lib.vc.datastore import VcDatastore +from lib.vc.helper import VcHelper +from lib.vc.host.main import VcHost +from lib.vc.network import VcNetwork +from lib.vc.virtual_machine import VcVirtualMachine +from lib.vc.virtual_machine_deployment_lcm import VcVirtualMachineDeploymentLcm +from lib.vc.virtual_machine_lcm import VcVirtualMachineLcm +from lib.vc.vm_cluster import VcVmCluster +from lib.vc.vm_folder import VcVmFolder + +from lib import log_helper +from lib import output_helper + + +class Vcenter( + VcCommon, + VcConnect, + VcDatacenter, + VcDatastore, + VcHost, + VcHelper, + VcNetwork, + VcVirtualMachine, + VcVirtualMachineDeploymentLcm, + VcVirtualMachineLcm, + VcVmCluster, + VcVmFolder + ): + def __init__(self, vcenter_ip, vcenter_username, vcenter_password, port=443, disable_ssl_verification=True, verbose=False, debug=False, log_id=None): + VcCommon.__init__(self) + VcHelper.__init__(self) + VcConnect.__init__( + self, + vcenter_ip, + port, + vcenter_username, + vcenter_password, + disable_ssl_verification=disable_ssl_verification + ) + VcDatacenter.__init__(self) + VcDatastore.__init__(self) + VcHost.__init__(self) + VcNetwork.__init__(self) + VcVirtualMachine.__init__(self) + VcVirtualMachineLcm.__init__(self) + VcVirtualMachineDeploymentLcm.__init__(self, log_id=log_id, verbose=verbose, debug=debug) + VcVmCluster.__init__(self) + VcVmFolder.__init__(self) + + self.my_output = output_helper.OutputHelper( + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.log = log_helper.Log(log_id=log_id) + + self.vc_connect() diff --git a/lib/vc/virtual_machine.py b/lib/vc/virtual_machine.py new file mode 100644 index 00000000..ea6550e1 --- /dev/null +++ b/lib/vc/virtual_machine.py @@ -0,0 +1,843 @@ +import time +import traceback +import requests + +# pylint: disable=no-name-in-module +from pyVmomi import vim, vmodl + + +class VcVirtualMachine(): + def __init__(self): + self.mo_virtual_machine = None + + def get_host_object_info(self, host_obj): + info = {} + info['name'] = host_obj.summary.config.name + info['ip'] = host_obj.summary.managementServerIp + info['status'] = host_obj.summary.overallStatus + info['esxi_version'] = host_obj.summary.config.product.version + info['server_vendor'] = host_obj.summary.hardware.vendor + info['server_model'] = host_obj.summary.hardware.model + info['server_uuid'] = host_obj.summary.hardware.uuid + info['server_serial'] = None + for other_identifying_info in host_obj.summary.hardware.otherIdentifyingInfo: + if other_identifying_info.identifierType.key == 'SerialNumberTag': + info['server_serial'] = other_identifying_info.identifierValue + + return info + + def get_device_class_name(self, device): + try: + class_name = device.__class__.__name__ + return class_name.split('.')[-1] + except BaseException: + return None + + def get_cdrom_device_objects(self, vm_obj): + cdrom_objs = [] + for device in vm_obj.config.hardware.device: + if self.get_device_class_name(device) == 'VirtualCdrom': + cdrom_objs.append(device) + return cdrom_objs + + def get_cdrom_devices(self, devices): + cdrom_devices = [] + for device in devices: + if self.get_device_class_name(device) == 'VirtualCdrom': + cdrom_device = {} + cdrom_device['label'] = device.deviceInfo.label + cdrom_device['summary'] = device.deviceInfo.summary + cdrom_device['backing'] = device.backing.fileName + cdrom_device['connected'] = device.connectable.connected + cdrom_device['key'] = device.key + cdrom_device['controllerKey'] = device.controllerKey + cdrom_device['unitNumber'] = device.unitNumber + cdrom_devices.append(cdrom_device) + + return cdrom_devices + + def get_network_devices(self, devices): + network_devices = [] + for device in devices: + if self.get_device_class_name(device) == 'VirtualVmxnet3': + network_device = {} + network_device['type'] = 'vmxnet3' + network_device['label'] = device.deviceInfo.label + network_device['summary'] = device.deviceInfo.summary + try: + network_device['backing'] = device.backing.deviceName + except BaseException: + network_device['backing'] = None + + network_device['connected'] = device.connectable.connected + network_device['key'] = device.key + network_device['controllerKey'] = device.controllerKey + network_device['unitNumber'] = device.unitNumber + network_device['mac'] = device.macAddress + network_devices.append(network_device) + + return network_devices + + def get_disk_devices(self, devices): + disk_devices = [] + for device in devices: + if self.get_device_class_name(device) == 'VirtualDisk': + disk_device = {} + disk_device['label'] = device.deviceInfo.label + disk_device['summary'] = device.deviceInfo.summary + disk_device['backing'] = device.backing.fileName + disk_device['mode'] = device.backing.diskMode + disk_device['writeThrough'] = device.backing.writeThrough + disk_device['thinProvisioned'] = device.backing.thinProvisioned + disk_device['key'] = device.key + disk_device['controllerKey'] = device.controllerKey + disk_device['unitNumber'] = device.unitNumber + disk_device['capacity'] = device.capacityInBytes + disk_device['capacity_unit'] = self.convert_storage(device.capacityInBytes) + disk_devices.append(disk_device) + + return disk_devices + + def get_vm_nestedhv(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.log.error( + 'vc.get_vm_nestedhv', + 'virtual machine not found: %s' % (vm_name) + ) + return False + + vm_config = vm_obj.config + return vm_config.nestedHVEnabled + + def set_vm_nestedhv(self, vm_name, enabled=True): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.log.error( + 'vc.get_vm_nestedhv', + 'virtual machine not found: %s' % (vm_name) + ) + return False + + vm_config_spec = vim.vm.ConfigSpec() + vm_config_spec.nestedHVEnabled = enabled + task = vm_obj.Reconfigure(vm_config_spec) + self.wait_for_tasks([task], exception_on_task_failure=True) + + return True + + def get_vm_power_state(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.log.error( + 'vc.get_vm_power_state', + 'virtual machine not found: %s' % (vm_name) + ) + return False + + vm_runtime = vm_obj.summary.runtime + return vm_runtime.powerState + + def is_vm_powered_on(self, vm_name): + power_state = self.get_vm_power_state(vm_name) + if power_state == 'poweredOn': + return True + return False + + def is_vm_powered_off(self, vm_name): + return not self.is_vm_powered_on(vm_name) + + def is_vm(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + return False + return True + + def get_vm_config_device_virtual_vmxnet3_info(self, device): + info = {} + info['label'] = device.deviceInfo.label + info['type'] = 'VMXNET 3' + if isinstance(device.backing, vim.vm.device.VirtualEthernetCard.NetworkBackingInfo): + info['networkName'] = self.get_network_name( + device.backing.network + ) + + if isinstance(device.backing, vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo): + info['networkName'] = self.get_distributed_network_name_by_key( + device.backing.port.portgroupKey + ) + info['macAddress'] = device.macAddress + return info + + def get_vm_config_device_virtual_disk_info(self, device): + info = {} + info['label'] = device.deviceInfo.label + info['backingFilename'] = device.backing.fileName + info['backingDatastore'] = self.get_datastore_info( + device.backing.datastore + ) + info['thin'] = False + if not isinstance(device.backing, vim.vm.device.VirtualDisk.SparseVer2BackingInfo): + info['thin'] = device.backing.thinProvisioned + info['capacity'] = device.capacityInBytes + info['capacityUnit'] = self.convert_storage(info['capacity']) + return info + + def get_vm_config_info(self, vm_config): + # 'alternateGuestName', 'annotation', 'bootOptions', 'changeTrackingEnabled', 'changeVersion', 'consolePreferences', 'contentLibItemInfo', 'cpuAffinity', 'cpuAllocation', + # 'cpuFeatureMask', 'cpuHotAddEnabled', 'cpuHotRemoveEnabled', 'createDate', 'datastoreUrl', 'defaultPowerOps', 'dynamicProperty', 'dynamicType', 'extraConfig', + # 'files', 'firmware', 'flags', 'forkConfigInfo', 'ftEncryptionMode', 'ftInfo', 'guestAutoLockEnabled', 'guestFullName', 'guestId', 'guestIntegrityInfo', + # 'guestMonitoringModeInfo', 'hardware', 'hotPlugMemoryIncrementSize', 'hotPlugMemoryLimit', 'initialOverhead', 'instanceUuid', 'keyId', 'latencySensitivity', 'locationId', + # 'managedBy', 'maxMksConnections', 'memoryAffinity', 'memoryAllocation', 'memoryHotAddEnabled', 'memoryReservationLockedToMax', 'messageBusTunnelEnabled', 'migrateEncryption', + # 'modified', 'name', 'nestedHVEnabled', 'networkShaper', 'npivDesiredNodeWwns', 'npivDesiredPortWwns', 'npivNodeWorldWideName', 'npivOnNonRdmDisks', 'npivPortWorldWideName', + # 'npivTemporaryDisabled', 'npivWorldWideNameType', 'pmem', 'pmemFailoverEnabled', 'repConfig', 'scheduledHardwareUpgradeInfo', 'sevEnabled', 'sgxInfo', 'swapPlacement', + # 'swapStorageObjectId', 'template', 'tools', 'uuid', 'vAppConfig', 'vAssertsEnabled', 'vFlashCacheReservation', 'vPMCEnabled', 'vcpuConfig', 'version', + # 'vmOpNotificationToAppEnabled', 'vmStorageObjectId', 'vmxConfigChecksum'] + info = {} + info['uuid'] = vm_config.uuid + info['guestFullName'] = vm_config.guestFullName + info['version'] = vm_config.version + info['instanceUuid'] = vm_config.instanceUuid + info['template'] = vm_config.template + info['guestId'] = vm_config.guestId + info['annotation'] = vm_config.annotation + info['template'] = vm_config.template + + info['cpu'] = {} + info['cpu']['flags'] = '' + info['cpu']['count'] = vm_config.hardware.numCPU + info['cpu']['coresPerSocket'] = vm_config.hardware.numCoresPerSocket + info['cpu']['reservation'] = vm_config.cpuAllocation.reservation + if info['cpu']['reservation'] > 0: + info['cpu']['flags'] = '%sR' % (info['cpu']['flags']) + info['cpu']['limit'] = vm_config.cpuAllocation.limit + if info['cpu']['limit'] > 0: + info['cpu']['flags'] = '%sL' % (info['cpu']['flags']) + info['cpu']['cpuHotAddEnabled'] = vm_config.cpuHotAddEnabled + info['cpu']['cpuHotRemoveEnabled'] = vm_config.cpuHotRemoveEnabled + if info['cpu']['cpuHotAddEnabled'] or info['cpu']['cpuHotRemoveEnabled']: + info['cpu']['flags'] = '%sH' % (info['cpu']['flags']) + info['cpu']['cpuAffinity'] = vm_config.cpuAffinity + if info['cpu']['cpuAffinity'] is not None: + info['cpu']['flags'] = '%sA' % (info['cpu']['flags']) + info['cpu']['virtualization'] = vm_config.nestedHVEnabled + if info['cpu']['virtualization']: + info['cpu']['flags'] = '%sV' % (info['cpu']['flags']) + + info['cpu']['info'] = info['cpu']['count'] + if len(info['cpu']['flags']) > 0: + info['cpu']['info'] = '%s %s' % ( + info['cpu']['info'], + info['cpu']['flags'] + ) + + info['memory'] = {} + info['memory']['memory'] = vm_config.hardware.memoryMB * 1024 * 1024 + info['memory']['memoryUnit'] = self.convert_memory( + info['memory']['memory'] + ) + info['memory']['reservation'] = vm_config.memoryAllocation.reservation + info['memory']['limit'] = vm_config.memoryAllocation.limit + info['memory']['memoryHotAddEnabled'] = vm_config.memoryHotAddEnabled + info['memory']['hotPlugMemoryLimit'] = vm_config.hotPlugMemoryLimit + info['memory']['hotPlugMemoryIncrementSize'] = vm_config.hotPlugMemoryIncrementSize + info['memory']['memoryAffinity'] = vm_config.memoryAffinity + + info['nic'] = [] + info['disk'] = [] + for device in vm_config.hardware.device: + if isinstance(device, vim.vm.device.VirtualVmxnet3): + info['nic'].append( + self.get_vm_config_device_virtual_vmxnet3_info(device) + ) + + if isinstance(device, vim.vm.device.VirtualDisk): + info['disk'].append( + self.get_vm_config_device_virtual_disk_info(device) + ) + + return info + + def get_vm_summary_info(self, vm_object, vm_filter=None): + info = {} + info['__Output'] = {} + + vm_config = vm_object['summary'].config + + info['name'] = vm_config.name + if vm_filter is not None: + if not self.match_vm(info, vm_filter): + return None + + info['uuid'] = vm_config.uuid + info['guestId'] = vm_config.guestId + info['guestFullName'] = vm_config.guestFullName + info['annotation'] = vm_config.annotation + + info['template'] = vm_config.template + info['vmPathName'] = vm_config.vmPathName + + info['cpu'] = vm_config.numCpu + if vm_config.cpuReservation is None: + info['cpuReservation'] = None + info['cpuReservationUnit'] = None + else: + info['cpuReservation'] = vm_config.cpuReservation * 1000 * 1000 + info['cpuReservationUnit'] = self.convert_cpu_capacity( + info['cpuReservation'], + empty_for_zero=True + ) + + if vm_config.memorySizeMB is None: + info['memory'] = None + info['memoryUnit'] = None + else: + info['memory'] = vm_config.memorySizeMB * 1024 * 1024 + info['memoryUnit'] = self.convert_memory( + info['memory'] + ) + + if vm_config.memoryReservation is None: + info['memoryReservation'] = None + info['memoryReservationUnit'] = None + else: + info['memoryReservation'] = vm_config.memoryReservation * 1024 * 1024 + info['memoryReservationUnit'] = self.convert_memory( + info['memoryReservation'], + empty_for_zero=True + ) + + info['numEthernetCards'] = vm_config.numEthernetCards + info['numVirtualDisks'] = vm_config.numVirtualDisks + + vm_runtime = vm_object['summary'].runtime + info['host'] = self.get_host_name( + vm_runtime.host + ) + if vm_filter is not None: + if not self.match_vm(info, vm_filter): + return None + + info['connectionState'] = vm_runtime.connectionState + info['powerState'] = vm_runtime.powerState + + storage = vm_object['summary'].storage + if storage is None or storage.uncommitted is None and storage.committed is None: + info['provisionedStorage'] = None + info['provisionedStorageUnit'] = None + info['usedStorage'] = None + info['usedStorageUnit'] = None + info['usedStoragePct'] = None + else: + info['provisionedStorage'] = storage.uncommitted + storage.committed + info['provisionedStorageUnit'] = self.convert_storage( + info['provisionedStorage'] + ) + info['usedStorage'] = storage.committed + info['usedStorageUnit'] = self.convert_storage( + info['usedStorage'] + ) + usage = info['usedStorage'] * 100 / info['provisionedStorage'] + info['usedStoragePct'] = self.convert_pct( + usage, + rounded=0 + ) + if 50 < usage <= 75: + info['__Output']['usedStoragePct'] = 'Yellow' + if usage > 75: + info['__Output']['usedStoragePct'] = 'Red' + + stats = vm_object['summary'].quickStats + info['cpuUsage'] = stats.overallCpuUsage * 1000 * 1000 + info['cpuUsageUnit'] = self.convert_cpu_capacity( + info['cpuUsage'] + ) + + info['guestMemoryUsage'] = stats.guestMemoryUsage + info['hostMemoryUsage'] = stats.hostMemoryUsage * 1024 * 1024 + info['hostMemoryUsageUnit'] = self.convert_memory( + info['hostMemoryUsage'] + ) + info['guestMemoryUsage'] = stats.guestMemoryUsage * 1024 * 1024 + info['guestMemoryUsageUnit'] = self.convert_memory( + info['guestMemoryUsage'] + ) + + if info['memory'] is None: + info['guestMemoryUsagePct'] = None + else: + usage = info['guestMemoryUsage'] * 100 / int(info['memory']) + info['guestMemoryUsagePct'] = self.convert_pct( + usage, + rounded=0 + ) + if 50 < usage <= 75: + info['__Output']['guestMemoryUsagePct'] = 'Yellow' + if usage > 75: + info['__Output']['guestMemoryUsagePct'] = 'Red' + + info['status'] = vm_object['summary'].overallStatus + + color = ':' + if info['powerState'] == 'poweredOn': + state = 'P+' + color = '%sGG' % (color) + else: + state = 'P-' + color = '%sRR' % (color) + + if info['status'] == 'green': + state = '%s H' % (state) + color = '%s.G' % (color) + else: + state = '%s W' % (state) + color = '%s.R' % (color) + + info['stateFlag'] = state + info['__Output']['stateFlag'] = color + + return info + + def get_vm_info(self, vm_object, vm_filter=None): + info = self.get_vm_summary_info(vm_object, vm_filter=vm_filter) + if info is None: + return None + + if 'config' in vm_object: + config = self.get_vm_config_info(vm_object['config']) + for key in config: + info[key] = config[key] + + return info + + def get_vm_objects(self): + if self.mo_virtual_machine is not None: + return self.mo_virtual_machine + + if not self.vc_connect(): + return None + + start_time = int(time.time() * 1000) + + content = self.vc_service_instance.RetrieveContent() + vm_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.VirtualMachine], + True + ) + + filter_spec = self.get_filter_spec( + vm_object_view, + vim.VirtualMachine, + ['config', 'summary'] + ) + options = vmodl.query.PropertyCollector.RetrieveOptions() + result = self.vc_service_instance.content.propertyCollector.RetrievePropertiesEx([filter_spec], options) + + self.mo_virtual_machine = [] + while True: + for oresult in result.objects: + item = {} + for prop in oresult.propSet: + item[prop.name] = prop.val + self.mo_virtual_machine.append(item) + + if result.token is None: + break + + result = self.vc_service_instance.content.propertyCollector.ContinueRetrievePropertiesEx(result.token) + + vm_object_view.Destroy() + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'vim.VirtualMachine', + True, + duration + ) + + return self.mo_virtual_machine + + def match_vm(self, vm_info, vm_filter): + if vm_filter is None or len(vm_filter) == 0: + return True + + name_filtering = False + name_match = False + for vm_rule in vm_filter: + if vm_rule.startswith('name:'): + name_filtering = True + name_value = vm_rule[5:] + if name_value in vm_info['name']: + name_match = True + + if name_filtering and not name_match: + return False + + for vm_rule in vm_filter: + if vm_rule.startswith('host:'): + if 'host' in vm_info: + host_value = vm_rule[5:] + if host_value not in vm_info['host']: + return False + + return True + + def get_vms(self, vm_filter=None): + vm_objects = self.get_vm_objects() + if vm_objects is None: + return None + + start_time = int(time.time() * 1000) + + vms = [] + for vm_object in vm_objects: + vm_info = self.get_vm_info(vm_object, vm_filter=vm_filter) + if vm_info is not None: + vms.append(vm_info) + + vms = sorted( + vms, + key=lambda i: i['name'].lower() + ) + + duration = int(time.time() * 1000) - start_time + self.log.vcenter( + 'get', + 'get_vm_info', + True, + duration + ) + + return vms + + def get_vm_object(self, vm_name): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + vm_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.VirtualMachine], + True + ) + + obj = None + for vm_obj in vm_object_view.view: + try: + if vm_obj.name == vm_name: + obj = vm_obj + break + except BaseException: + pass + + vm_object_view.Destroy() + + return obj + + def get_host_object(self, host_ip): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + hosts_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.HostSystem], + True + ) + + if len(hosts_object_view.view) == 0: + self.my_output.error('No available host found') + return None + + if host_ip is None: + obj = hosts_object_view.view[0] + self.my_output.default('Selecting the first available host: %s' % (obj.name)) + return obj + + obj = None + for host_obj in hosts_object_view.view: + if host_ip is not None: + if host_obj.name == host_ip: + obj = host_obj + break + + hosts_object_view.Destroy() + + if obj is None: + self.my_output.error('Host %s not found' % (host_ip)) + return None + + return obj + + def is_network_devices_connected(self, vm_name): + network_devices = self.get_network_devices_info(vm_name) + if network_devices is None: + return False + + for network_device in network_devices: + if not network_device['connected']: + return False + + return True + + def get_network_device_obj(self, vm_name, device_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + return None + + for dev in vm_obj.config.hardware.device: + if isinstance(dev, vim.vm.device.VirtualVmxnet3): + if dev.deviceInfo.label == device_name: + return dev + + return None + + def get_network_devices_info(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + return None + + devices = [] + + for dev in vm_obj.config.hardware.device: + if isinstance(dev, vim.vm.device.VirtualVmxnet3): + device_info = {} + device_info['nic_name'] = dev.deviceInfo.label + device_info['mac'] = dev.macAddress + + is_connected = False + if isinstance(dev.connectable.connected, bool) and dev.connectable.connected: + is_connected = True + if isinstance(dev.connectable.connected, str) and dev.connectable.connected == 'True': + is_connected = True + + if is_connected: + device_info['connected'] = True + device_info['network_name'] = dev.backing.port.portgroupKey + else: + device_info['connected'] = False + device_info['network_name'] = dev.backing.deviceName + + devices.append( + device_info + ) + + return devices + + def get_screen(self, url, username, password, filename, timeout=30): + try: + with open(filename, "wb") as file_handler: + response = requests.get( + url, + auth=(username, password), + verify=False, + timeout=timeout + ) + file_handler.write(response.content) + except BaseException: + self.my_output.error('Screen download failed') + self.my_output.default(traceback.format_exc()) + + + def get_state(self, vm_name, screen_filename=None): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.my_output.error('Virtual machine not found: %s' % (vm_name)) + return None + + vm_state = {} + vm_state['name'] = vm_obj.summary.config.name + # pylint: disable=protected-access + vm_state['moid'] = vm_obj.summary.vm._moId + + vm_state['screen'] = {} + vm_state['screen']['url'] = 'https://%s/screen?id=%s' % ( + self.vcenter_ip, + vm_state['moid'] + ) + vm_state['screen']['username'] = self.vcenter_username + vm_state['screen']['password'] = self.vcenter_password + vm_state['screen']['filename'] = screen_filename + if screen_filename is not None: + self.get_screen( + vm_state['screen']['url'], + vm_state['screen']['username'], + vm_state['screen']['password'], + screen_filename + ) + + vm_state['vmPathName'] = vm_obj.summary.config.vmPathName + vm_state['memorySizeMB'] = vm_obj.summary.config.memorySizeMB + vm_state['memorySizeUnit'] = self.convert_memory( + vm_obj.summary.config.memorySizeMB * 1024 * 1024 + ) + vm_state['numCpu'] = vm_obj.summary.config.numCpu + vm_state['numEthernetCards'] = vm_obj.summary.config.numEthernetCards + vm_state['numVirtualDisks'] = vm_obj.summary.config.numVirtualDisks + vm_state['overallStatus'] = vm_obj.summary.overallStatus + vm_state['connectionState'] = vm_obj.summary.runtime.connectionState + vm_state['powerState'] = vm_obj.summary.runtime.powerState + vm_state['bootTime'] = str(vm_obj.summary.runtime.bootTime) + vm_state['cdrom'] = self.get_cdrom_devices(vm_obj.config.hardware.device) + vm_state['numCdrom'] = len(vm_state['cdrom']) + vm_state['disk'] = self.get_disk_devices(vm_obj.config.hardware.device) + vm_state['network'] = self.get_network_devices(vm_obj.config.hardware.device) + vm_state['host'] = self.get_host_object_info(vm_obj.summary.runtime.host) + + return vm_state + + def print_network_devices(self, info): + order = [ + 'nic_name', + 'network_name', + 'mac', + 'connected' + ] + + headers = [ + 'Name', + 'Network', + 'MAC Address', + 'Connected' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + underline=True, + table=True + ) + + def print_vms(self, info, title=False): + if title: + self.my_output.default( + 'Virtual Machine [#%s]' % (len(info)), + underline=True, + before_newline=True + ) + + if len(info) == 0: + self.my_output.default('None') + return + + order = [ + 'stateFlag', + 'name', + 'host', + 'cpu.count', + 'cpuUsageUnit', + 'cpuReservationUnit', + 'memoryUnit', + 'guestMemoryUsageUnit', + 'guestMemoryUsagePct', + 'memoryReservationUnit', + 'numEthernetCards', + 'numVirtualDisks', + 'provisionedStorageUnit', + 'usedStorageUnit', + 'usedStoragePct' + ] + + headers = [ + 'SF', + 'Name', + 'Host', + 'CPU', + 'Usage', + 'Rsvd', + 'Memory', + 'Usage', + '[%]', + 'Rsvd', + 'NIC', + 'Disks', + 'Storage', + 'Usage', + '[%]' + ] + + self.my_output.my_table( + info, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + table=True + ) + + def print_vms_net(self, vms): + order = [ + 'stateFlag', + 'name', + 'host', + 'nic.label', + 'nic.type', + 'nic.networkName', + 'nic.macAddress' + ] + + headers = [ + 'SF', + 'Name', + 'Host', + 'Label', + 'Type', + 'Network', + 'MAC' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + vms, + order, + ['nic'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + table=True + ) + + def print_vms_fabric(self, vms): + order = [ + 'stateFlag', + 'name', + 'host', + 'nic.label', + 'nic.type', + 'nic.networkName', + 'nic.macAddress', + 'nic.fabric', + 'nic.port' + ] + + headers = [ + 'SF', + 'Name', + 'Host', + 'Label', + 'Type', + 'Network', + 'MAC', + 'Fabric', + 'Port' + ] + + self.my_output.my_table( + self.my_output.expand_lists( + vms, + order, + ['nic'] + ), + order=order, + headers=headers, + underline=True, + allow_order_subkeys=True, + row_separator=True, + table=True + ) diff --git a/lib/vc/virtual_machine_deployment_lcm.py b/lib/vc/virtual_machine_deployment_lcm.py new file mode 100644 index 00000000..ea77e194 --- /dev/null +++ b/lib/vc/virtual_machine_deployment_lcm.py @@ -0,0 +1,596 @@ +import os +import time +import json +import traceback +import uuid + +from lib import ssh +from lib import ip_helper +from lib import template +from lib.iso import kickstart +from lib.iso import autoinstall + + +class VcVirtualMachineDeploymentLcm(): + def __init__(self, log_id=None, verbose=False, debug=False): + self.template_handler = template.Template(verbose=verbose, debug=debug) + self.iso_kickstart_handler = kickstart.IsoKickstart() + self.iso_autoinstall_handler = autoinstall.IsoAutoinstall( + 'ubuntu', + log_id=log_id, + verbose=verbose, + debug=debug + ) + self.vm_parameters = None + self.dry_run = False + + def set_vm_parameters(self, vm_parameters): + self.vm_parameters = vm_parameters + + def is_iso_preparation_required(self): + self.my_output.debug( + 'ISO parameters: %s' % ( + json.dumps(self.vm_parameters['iso'], indent=4) + ) + ) + + if not self.vm_parameters['iso']['enabled']: + return False + + if self.vm_parameters['iso']['is_file'] and not self.vm_parameters['iso']['overwrite']: + return False + + return True + + def prepare_iso(self): + if not self.is_iso_preparation_required(): + self.my_output.info('ISO preparation not required') + return True + + if not self.vm_parameters['iso']['is_folder']: + self.my_output.default('Create data store folder: %s' % (self.vm_parameters['iso']['folder_name'])) + success = self.create_datastore_folder( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['iso']['folder_name'] + ) + if not success: + self.my_output.error('Folder %s create failed' % (self.vm_parameters['iso']['folder_name'])) + return False + self.my_output.default('Folder created: %s' % (self.vm_parameters['iso']['folder_name'])) + + self.my_output.default('Upload iso: %s => [%s] %s/%s' % ( + self.vm_parameters['iso']['source'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['iso']['folder_name'], + self.vm_parameters['iso']['file_name'] + )) + success = self.create_datastore_file( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['iso']['source'], + self.vm_parameters['iso']['folder_name'], + self.vm_parameters['iso']['file_name'] + ) + if not success: + self.my_output.error('Failed to create file: %s' % (self.vm_parameters['iso']['destination'])) + return False + + self.my_output.default('ISO ready: %s' % (self.vm_parameters['iso']['destination'])) + + return True + + def is_ks_preparation_required(self): + self.my_output.debug( + 'Kickstart parameters: %s' % ( + json.dumps(self.vm_parameters['ks'], indent=4) + ) + ) + + if not self.vm_parameters['ks']['enabled']: + return False + + if self.vm_parameters['ks']['is_file'] and not self.vm_parameters['ks']['overwrite']: + return False + + return True + + def prepare_kickstart(self): + if self.vm_parameters['vm']['distribution'] not in ['centos', 'fedora', 'rhel']: + return True + + if not self.is_ks_preparation_required(): + self.my_output.info('Kickstart iso preparation not required') + return True + + if self.vm_parameters['ks']['generate']: + success = self.iso_kickstart_handler.generate_iso( + self.vm_parameters['ks']['template'], + self.vm_parameters['variables'], + self.vm_parameters['ks']['source'], + self.vm_parameters['jump'] + ) + if not success: + self.my_output.error('Kickstart iso generation failed') + return None + self.my_output.info('Kickstart iso generated: %s' % (self.vm_parameters['ks']['source'])) + + if not self.vm_parameters['ks']['is_folder']: + success = self.create_datastore_folder( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['ks']['folder_name'] + ) + if not success: + self.my_output.error('Folder %s create failed' % (self.vm_parameters['ks']['folder_name'])) + return False + self.my_output.default('Folder created: %s' % (self.vm_parameters['ks']['folder_name'])) + + success = self.create_datastore_file( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['ks']['source'], + self.vm_parameters['ks']['folder_name'], + self.vm_parameters['ks']['file_name'] + ) + if not success: + self.my_output.error('Failed to create file: %s' % (self.vm_parameters['ks']['destination'])) + return False + + self.my_output.default('Kickstart ready: %s' % (self.vm_parameters['ks']['destination'])) + + return True + + def is_autoinstall_preparation_required(self): + self.my_output.debug( + 'Kickstart parameters: %s' % ( + json.dumps(self.vm_parameters['ks'], indent=4) + ) + ) + + if not self.vm_parameters['ks']['enabled']: + return False + + return True + + def prepare_autoinstall(self): + if self.vm_parameters['vm']['distribution'] not in ['ubuntu']: + return True + + if not self.is_autoinstall_preparation_required(): + self.my_output.info('Autoinstall iso preparation not required') + return True + + if self.vm_parameters['ks']['is_file']: + self.my_output.error('Autoinstall iso already exists...') + return False + + self.my_output.default('Prepare autoinstall iso...') + + if not self.vm_parameters['ks']['is_folder']: + success = self.create_datastore_folder( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['ks']['folder_name'] + ) + if not success: + self.my_output.error('Folder %s create failed' % (self.vm_parameters['ks']['folder_name'])) + return False + self.my_output.default('Folder created: %s' % (self.vm_parameters['ks']['folder_name'])) + + success = self.iso_autoinstall_handler.generate_iso( + self.vm_parameters['ks']['template'], + self.vm_parameters['variables'], + self.vm_parameters['jump'], + replace_variables_enabled=self.vm_parameters['settings']['kickstart_template_variable_replacement_enabled'] + ) + if not success: + self.my_output.error('Autoinstall iso generation failed') + return False + + self.my_output.default('Autoinstall iso prepared: %s' % (self.vm_parameters['ks']['destination'])) + self.vm_parameters['ks']['is_file'] = True + + return True + + def create_vm_deployment(self, vm_parameters, screen_base_directory=None, dry_run=False): + self.vm_parameters = vm_parameters + self.dry_run = dry_run + + vm_name = self.vm_parameters['vm']['name'] + if self.is_vm(vm_name): + self.my_output.info('VM already created: %s' % (vm_name)) + else: + if not self.prepare_iso(): + return False + + if not self.prepare_kickstart(): + return False + + if not self.prepare_autoinstall(): + return False + + success = self.create_vm(self.vm_parameters['vm'], dry_run=self.dry_run) + if not success: + return False + + if self.dry_run: + return True + + if self.is_vm_powered_on(vm_name): + self.my_output.default('Virtual machine already powered on') + else: + success = self.power_on_vm(vm_name) + if not success: + return False + + if screen_base_directory is not None: + self.my_output.default('Get initial screenshot...') + screen_filename = '%s/initial.png' % (screen_base_directory) + self.get_state( + vm_name, + screen_filename=screen_filename + ) + + if 'settings' in self.vm_parameters: + if self.vm_parameters['settings']['sleep_after_vm_connected'] > 0: + self.my_output.default('Extra wait time after connected state reached of %s seconds...' % (self.vm_parameters['settings']['sleep_after_vm_connected'])) + time.sleep( + self.vm_parameters['settings']['sleep_after_vm_connected'] + ) + + if screen_base_directory is not None: + self.my_output.default('Get installation screenshot...') + screen_filename = '%s/install.png' % (screen_base_directory) + self.get_state( + vm_name, + screen_filename=screen_filename + ) + + if self.vm_parameters['vm']['ssh']['enabled']: + if not self.wait_ssh(): + return False + + if not self.run_tasks(): + return False + + if screen_base_directory is not None: + self.my_output.default('Get final screenshot...') + screen_filename = '%s/final.png' % (screen_base_directory) + + vm_state = self.get_state( + vm_name, + screen_filename=screen_filename + ) + + return True + + def wait_ssh(self, timeout=3600): + self.my_output.default( + 'Wait for SSH access %s using (%s, %s) credentials with %s seconds timeout' % ( + self.vm_parameters['vm']['ssh']['ip'], + self.vm_parameters['vm']['ssh']['username'], + self.vm_parameters['vm']['ssh']['password'], + timeout + ) + ) + + ssh_handler = ssh.Ssh( + self.vm_parameters['vm']['ssh']['ip'], + self.vm_parameters['vm']['ssh']['username'], + password=self.vm_parameters['vm']['ssh']['password'] + ) + + if not ssh_handler.wait_ssh(timeout): + self.my_output.error('SSH timed out') + return False + + return True + + def wait_connected(self, timeout=120, extra_wait=30): + if self.vm_parameters['settings']['wait_vm_connected']: + self.my_output.default('Wait for VM connected state with %s seconds timeout...' % (timeout)) + start_time = int(time.time()) + while True: + vm_state = self.get_state(self.vm_parameters['vm']['name']) + if vm_state['connectionState'] == 'connected': + break + + if int(time.time()) - start_time > timeout: + self.my_output.error('VM connection state did not reach connected in time') + return False + + time.sleep(5) + + time.sleep(extra_wait) + return True + + def run_task_script(self, script_filename, live_output=False): + ssh_handler = ssh.Ssh( + self.vm_parameters['vm']['ssh']['ip'], + self.vm_parameters['vm']['ssh']['username'], + password=self.vm_parameters['vm']['ssh']['password'] + ) + + self.my_output.default('Run script', underline=True, before_newline=True, after_newline=True) + self.my_output.default('Script filename: %s\n' % (script_filename)) + + content = self.template_handler.get_template( + script_filename, + self.vm_parameters['variables'] + ) + if content is None: + return False + + self.my_output.debug('~~~ script content ~~~') + self.my_output.debug(content) + self.my_output.debug('~~~~~~~~~~~~~~~~~~~~~~') + + source_filename = '/tmp/%s' % (str(uuid.uuid4())) + try: + with open(source_filename, 'wb') as file_handler: + file_handler.write(content.encode('utf-8')) + except BaseException: + self.my_output.error( + 'Preparation of script file for upload failed' + ) + self.my_output.default(traceback.format_exc()) + return False + + self.my_output.debug('Local script prepared: %s' % (source_filename)) + + destination_filename = str(uuid.uuid4()) + if not ssh_handler.scp_file(source_filename, destination_filename): + self.my_output.error( + 'Script upload failed: %s => %s' % ( + source_filename, + destination_filename + ) + ) + return False + self.my_output.debug('Script uploaded: %s' % (destination_filename)) + + if not ssh_handler.set_file_chmod(destination_filename, '755'): + self.my_output.error( + 'Script chmod failed: %s' % ( + destination_filename + ) + ) + return False + self.my_output.debug('Chmod set to 755') + + if live_output: + self.my_output.debug('Run script with live output...') + else: + self.my_output.debug('Run script and wait for completion...') + + success, output, error = ssh_handler.run_cmd( + './%s' % (destination_filename), + live_output=live_output + ) + + if success: + self.my_output.debug('Remote script execution finished') + + if not live_output: + self.my_output.debug('~~~ script output ~~~') + self.my_output.debug(output) + self.my_output.debug('~~~~~~~~~~~~~~~~~~~~~') + + if not ssh_handler.delete_file(destination_filename): + self.my_output.error( + 'Remote script delete failed: %s' % ( + destination_filename + ) + ) + return False + + self.my_output.debug('Remote script deleted') + + if not success: + self.my_output.error('Remote script execution failed') + self.my_output.default('~~~ script error ~~~') + self.my_output.default(error) + self.my_output.default('~~~~~~~~~~~~~~~~~~~~~') + self.my_output.default('Remote script not deleted for further troubleshooting: %s' % (destination_filename)) + + return success + + def run_task_file(self, file_info, create_directory=False): + ssh_handler = ssh.Ssh( + self.vm_parameters['vm']['ssh']['ip'], + self.vm_parameters['vm']['ssh']['username'], + password=self.vm_parameters['vm']['ssh']['password'] + ) + + self.my_output.default('Copy file', underline=True, before_newline=True, after_newline=True) + source_filename = file_info['source'] + destination_filename = file_info['destination'] + destination_directory = os.path.dirname(destination_filename) + destination_chmod = file_info['chmod'] + self.my_output.debug('Source: %s' % (source_filename)) + self.my_output.debug('Destination: %s' % (destination_filename)) + self.my_output.debug('Template: %s' % (file_info['template'])) + self.my_output.debug('Target chmod: %s\n' % (destination_chmod)) + + if file_info['template']: + content = self.template_handler.get_template( + source_filename, + self.vm_parameters['variables'] + ) + if content is None: + return False + + self.my_output.debug('~~~ file content ~~~') + self.my_output.debug(content) + self.my_output.debug('~~~~~~~~~~~~~~~~~~~~') + + source_filename = '/tmp/%s' % (str(uuid.uuid4())) + try: + with open(source_filename, 'wb') as file_handler: + file_handler.write(content.encode('utf-8')) + except BaseException: + self.my_output.error( + 'Preparation of script file for upload failed' + ) + self.my_output.default(traceback.format_exc()) + return False + + self.my_output.debug('Local file prepared with variables replaced: %s' % (source_filename)) + + self.my_output.default('Copy file: %s => %s' % (source_filename, destination_filename)) + + if not os.path.isfile(source_filename): + self.my_output.error('Local file not found: %s' % (source_filename)) + return False + self.my_output.info('Local file found: %s' % (source_filename)) + + source_md5 = ip_helper.get_file_md5(source_filename) + self.my_output.debug('Local file checksum: %s' % (source_md5)) + destination_md5 = ssh_handler.get_file_md5(destination_filename) + self.my_output.debug('Remote file checksum: %s' % (destination_md5)) + if source_md5 == destination_md5: + self.my_output.default('Checksum (md5) match and upload skipped') + else: + if create_directory: + if not ssh_handler.create_directory(destination_directory): + self.my_output.error('Directory create failed: %s' % (destination_directory)) + return False + self.my_output.debug('File upload...') + if not ssh_handler.scp_file(source_filename, destination_filename): + self.my_output.error('File upload failed') + return False + self.my_output.debug('File upload completed') + + if not ssh_handler.set_file_chmod(destination_filename, destination_chmod): + self.my_output.error('File chmod failed: %s' % (destination_filename)) + return False + + self.my_output.debug('File chmod set to %s' % (destination_chmod)) + self.my_output.debug('Task file copy completed') + + return True + + def run_task_command(self, command): + self.my_output.default('Run command', underline=True, before_newline=True) + self.my_output.default('Command: %s' % (command)) + + ssh_handler = ssh.Ssh( + self.vm_parameters['vm']['ssh']['ip'], + self.vm_parameters['vm']['ssh']['username'], + password=self.vm_parameters['vm']['ssh']['password'] + ) + + success, output, error = ssh_handler.run_cmd(command) + if success: + self.my_output.default('Command successful') + if output is not None and len(output) > 0: + self.my_output.debug('~~~ command output ~~~') + self.my_output.debug(output) + self.my_output.debug('~~~~~~~~~~~~~~~~~~~~~') + + if not success: + self.my_output.error('Command failed') + self.my_output.default('~~~ command output ~~~') + self.my_output.default(error) + self.my_output.default('~~~~~~~~~~~~~~~~~~~~~') + + return success + + def run_task(self, task_filename): + self.my_output.default('Task: %s' % (task_filename), underline=True) + + task_definition = self.template_handler.get_template( + task_filename, + self.vm_parameters['variables'], + yaml_conversion=True + ) + + if task_definition is None: + return False + + for task in task_definition['tasks']: + for key in task: + if key == 'scripts': + for script_name in task[key]: + script_filename = os.path.join( + os.path.dirname(task_filename), + script_name + ) + if not self.run_task_script(script_filename): + return False + + if key == 'files': + for file_info in task[key]: + if '/' in file_info['source'] or '\\' in file_info['source']: + pass + else: + file_info['source'] = os.path.join( + os.path.dirname(task_filename), + file_info['source'] + ) + if not self.run_task_file(file_info): + return False + + if key == 'commands': + for item in task[key]: + if not self.run_task_command(item): + return False + + return True + + def run_tasks(self): + if 'tasks' not in self.vm_parameters or len(self.vm_parameters['tasks']) == 0: + return True + + if not self.vm_parameters['vm']['ssh']['enabled']: + self.my_output.error('Tasks configured but ssh not enabled') + return False + + for task_filename in self.vm_parameters['tasks']: + if not self.run_task(task_filename): + return False + + return True + + def check_vm_network_devices(self): + vm_name = self.vm_parameters['vm']['name'] + network_devices = self.get_network_devices_info(vm_name) + if network_devices is None: + self.my_output.error('No network device found') + return False + + if not self.is_network_devices_connected(vm_name): + network_devices = self.get_network_devices_info(vm_name) + self.print_network_devices(network_devices) + + return True + + def delete_vm_deployment(self, parameters): + name = parameters['vm']['name'] + + if not self.is_vm(name): + self.my_output.default('Virtual machine does not exist: %s' % (name)) + else: + if not self.power_off_vm(name): + return False + + if not self.destroy_vm(name): + return False + + if 'ks' in parameters and parameters['ks']['enabled']: + datacenter_name = parameters['vcenter']['datacenter'] + datastore_name = parameters['vcenter']['datastore'] + kickstart_folder = parameters['ks']['folder_name'] + kickstart_filename = parameters['ks']['file_name'] + kickstart_path = parameters['ks']['destination'] + if not self.is_datastore_file(datacenter_name, datastore_name, kickstart_folder, kickstart_filename): + self.my_output.default('Kickstart does not exist: %s @ %s' % (kickstart_path, datastore_name)) + else: + if not self.delete_datastore_file(datacenter_name, datastore_name, kickstart_path): + self.my_output.error('Kickstart delete failed: %s' % (kickstart_path)) + return False + + self.my_output.default('Kickstart deleted: %s' % (kickstart_path)) + + return True diff --git a/lib/vc/virtual_machine_deployment_validator.py b/lib/vc/virtual_machine_deployment_validator.py new file mode 100644 index 00000000..3acce9fb --- /dev/null +++ b/lib/vc/virtual_machine_deployment_validator.py @@ -0,0 +1,890 @@ +import os +import json +import uuid +import datetime +import bcrypt + +from lib.input_validator import InputValidator + +from lib import file_helper +from lib import ip_helper +from lib import log_helper +from lib import output_helper + +from lib.vc import helper +from lib.vc import vcenter +from lib import ssh +from lib import template + + +class VcVirtualMachineDeploymentValidator(InputValidator): + def __init__(self, log_id=None, verbose=False, debug=False): + InputValidator.__init__(self, log_id=log_id) + + self.log_id = log_id + self.log_handler = log_helper.Log(log_id=log_id) + + self.my_output = output_helper.OutputHelper(log_id=log_id, verbose=verbose, debug=debug) + self.template_handler = template.Template(debug=debug, log_id=log_id) + self.template_category = 'vc' + self.vc_helper_handler = helper.VcHelper() + self.vcenter_handler = None + self.user_input = None + self.vm_parameters = {} + + def validate_settings(self): + self.my_output.debug('Validate settings section', underline=True, before_newline=True) + + self.vm_parameters['settings'] = {} + for key in self.user_input['settings']: + self.vm_parameters['settings'][key] = self.user_input['settings'][key] + + self.my_output.debug('Completed') + return True + + def validate_datacenter_name(self): + datacenters = self.vcenter_handler.get_datacenters() + if datacenters is None: + self.my_output.error('No datacenters found') + return False + + datacenter_name = self.vm_parameters['vcenter']['datacenter'] + for datacenter in datacenters: + if datacenter['name'] == datacenter_name: + self.my_output.debug('Datacenter found: %s' % (datacenter_name)) + return True + + self.my_output.error('Datacenter not found: %s' % (datacenter_name)) + return False + + def validate_datastore_name(self): + datacenter_name = self.vm_parameters['vcenter']['datacenter'] + datastores = self.vcenter_handler.get_datastores(datacenter_name=datacenter_name) + + if datastores is None: + self.my_output.error('No datastores found') + return False + + datastore_name = self.vm_parameters['vcenter']['datastore'] + for datastore in datastores: + if datastore['name'] == datastore_name: + self.my_output.debug('Datastore found: %s' % (datastore_name)) + return datastore_name + + self.my_output.error('Datastore not found: %s' % (datastore_name)) + return True + + def validate_vm_folder_name(self): + if self.vm_parameters['vcenter']['vm_folder'] is not None: + folder_name = self.vm_parameters['vcenter']['vm_folder'] + if not self.vcenter_handler.is_vm_folder(folder_name): + self.my_output.error('Folder not found: %s' % (folder_name)) + return False + + self.my_output.debug('Folder found: %s' % (folder_name)) + + return True + + def validate_vcenter_parameters(self, location): + self.my_output.debug('Validate vcenter section', underline=True, before_newline=True) + + self.vm_parameters['vcenter'] = {} + for key in self.user_input['vcenter']: + self.vm_parameters['vcenter'][key] = self.user_input['vcenter'][key] + + vcenter_filename = os.path.join(location, 'secret') + vcenter_filename = os.path.join(vcenter_filename, 'vcenter.yaml') + if not os.path.isfile(vcenter_filename): + self.my_output.error('Specify valid vcenter credentials file: %s' % (vcenter_filename)) + return False + + vcenter_credentials = file_helper.get_file_yaml(vcenter_filename) + if vcenter_credentials is None: + self.my_output.error('Specify valid vcenter credentials file: %s' % (vcenter_filename)) + return False + + if 'username' not in vcenter_credentials or 'password' not in vcenter_credentials: + self.my_output.error('Specify valid vcenter credentials file: %s' % (vcenter_filename)) + return False + + self.vm_parameters['vcenter']['username'] = vcenter_credentials['username'] + self.vm_parameters['vcenter']['password'] = vcenter_credentials['password'] + + self.vcenter_handler = vcenter.Vcenter( + self.vm_parameters['vcenter']['ip'], + self.vm_parameters['vcenter']['username'], + self.vm_parameters['vcenter']['password'], + port=self.vm_parameters['vcenter']['port'], + log_id=self.log_id + ) + if not self.validate_datacenter_name(): + return False + + if not self.validate_datastore_name(): + return False + + if not self.validate_vm_folder_name(): + return False + + host_ips = self.vcenter_handler.get_host_ips() + if host_ips is None: + self.my_output.error('No host IP found in datacenter') + return False + + self.my_output.debug('vcenter hosts: %s' % (','.join(host_ips))) + self.vm_parameters['vcenter']['host_ips'] = host_ips + self.my_output.debug('Completed') + + return True + + def validate_jump_parameters(self): + ''' + Optional section in user input. Required if machine is Windows and KS template is used + Then ISO needs to be generated and this code works on Linux only + Jump is the optional definition of Linux-based machine + + jump: + ip: + username: **** + password: **** + + if used, then all attributes required. + + SSH access check included unless syntax_only + ''' + self.my_output.debug('Validate jump section', underline=True, before_newline=True) + self.vm_parameters['jump'] = {} + + if 'jump' not in self.user_input: + self.vm_parameters['jump']['enabled'] = False + self.my_output.debug('Jump disabled') + return True + + self.vm_parameters['jump']['enabled'] = True + for key in ['ip', 'username', 'password']: + self.vm_parameters['jump'][key] = self.user_input['jump'][key] + + ssh_handler = ssh.Ssh( + self.vm_parameters['jump']['ip'], + self.vm_parameters['jump']['username'], + port=22, + password=self.vm_parameters['jump']['password'] + ) + success = ssh_handler.is_ssh() + if not success: + self.my_output.error( + 'Jump access fails: %s@%s with %s' % ( + self.vm_parameters['jump']['username'], + self.vm_parameters['jump']['ip'], + self.vm_parameters['jump']['password'] + ) + ) + return False + + self.my_output.debug('jump ssh access verified') + self.my_output.debug('Completed') + return True + + def validate_iso_parameters(self, check_source=True): + self.my_output.debug('Validate linux.iso section', underline=True, before_newline=True) + + iso_section = self.user_input['linux']['iso'] + + self.vm_parameters['iso'] = {} + self.vm_parameters['iso']['enabled'] = True + self.vm_parameters['iso']['source'] = iso_section['source'] + self.vm_parameters['iso']['delete_source'] = False + self.vm_parameters['iso']['overwrite'] = False + self.vm_parameters['iso']['delete_destination'] = False + + # destination syntax + # - if linux.iso.filename contains '/' then it is considerd as full path name + # - otherwise destination is based on vcenter.iso_folder and linux.iso.filename + + if '/' in iso_section['filename']: + self.vm_parameters['iso']['folder_name'] = self.vc_helper_handler.get_parent_folder_name( + iso_section['filename'] + ) + self.vm_parameters['iso']['file_name'] = iso_section['filename'].split('/')[-1] + self.vm_parameters['iso']['destination'] = '%s%s' % (self.vm_parameters['iso']['folder_name'], self.vm_parameters['iso']['file_name']) + self.my_output.debug('iso destination verified: %s' % (self.vm_parameters['iso']['destination'])) + else: + self.vm_parameters['iso']['folder_name'] = self.vc_helper_handler.fixup_datastore_folder_name( + self.vm_parameters['vcenter']['iso_folder'] + ) + self.vm_parameters['iso']['file_name'] = iso_section['filename'] + self.vm_parameters['iso']['destination'] = '%s%s' % (self.vm_parameters['iso']['folder_name'], self.vm_parameters['iso']['file_name']) + self.my_output.debug('iso destination verified: %s' % (self.vm_parameters['iso']['destination'])) + + # verify destination folder + + self.vm_parameters['iso']['is_folder'] = self.vcenter_handler.is_datastore_folder( + self.user_input['vcenter']['datacenter'], + self.user_input['vcenter']['datastore'], + self.vm_parameters['iso']['folder_name'] + ) + if self.vm_parameters['iso']['is_folder']: + self.my_output.debug('datastore folder found: %s' % (self.vm_parameters['iso']['folder_name'])) + else: + self.my_output.debug('datastore folder not found: %s' % (self.vm_parameters['iso']['folder_name'])) + + # verify destination file + + self.vm_parameters['iso']['is_file'] = False + if self.vm_parameters['iso']['is_folder']: + files = self.vcenter_handler.get_datastore_files( + self.user_input['vcenter']['datacenter'], + self.user_input['vcenter']['datastore'], + self.vm_parameters['iso']['folder_name'] + ) + if files is not None: + for file_info in files: + if file_info['filename'] == self.vm_parameters['iso']['file_name']: + self.vm_parameters['iso']['is_file'] = True + break + + if self.vm_parameters['iso']['is_file']: + self.my_output.debug('datastore file found: %s' % (self.vm_parameters['iso']['file_name'])) + else: + self.my_output.debug('datastore file not found: %s' % (self.vm_parameters['iso']['file_name'])) + + if check_source: + # Source verification + # - source is optional if destination exists (is_file) and overwrite is False + # - must be local filesystem name + # - must be present + if self.vm_parameters['iso']['is_file'] and not self.vm_parameters['iso']['overwrite']: + if self.vm_parameters['iso']['source'] is not None: + self.my_output.debug('linux.iso.source attribute value is not checked as linux.iso.filename exists') + else: + if self.vm_parameters['iso']['source'] is None: + self.my_output.error('linux.iso.source attribute value required since linux.iso.destination does not exist') + return False + + if self.vm_parameters['iso']['source'].startswith('http'): + self.my_output.error('linux.iso.source attribute value must be local filename') + return False + + if not os.path.isfile(self.vm_parameters['iso']['source']): + self.my_output.error('linux.iso.source file not found: %s' % (self.vm_parameters['iso']['source'])) + return False + + self.my_output.debug('iso source verified: %s' % (self.vm_parameters['iso']['source'])) + + self.my_output.debug('Completed') + + return True + + def generate_variables(self): + self.my_output.debug('Variables generation', underline=True, before_newline=True) + + self.vm_parameters['variables'] = {} + + # User defined variables + + if 'variables' in self.user_input: + for name in self.user_input['variables']: + self.vm_parameters['variables'][name] = self.user_input['variables'][name] + + # Proxy based variables + + if 'proxy' in self.user_input: + self.vm_parameters['variables']['HTTP_PROXY_ENABLED'] = str(self.user_input['proxy']['enabled']) + self.vm_parameters['variables']['HTTP_PROXY'] = self.user_input['proxy']['http'] + self.vm_parameters['variables']['HTTPS_PROXY'] = self.user_input['proxy']['https'] + else: + self.vm_parameters['variables']['HTTP_PROXY_ENABLED'] = str(False) + self.vm_parameters['variables']['HTTP_PROXY'] = 'undefined' + self.vm_parameters['variables']['HTTPS_PROXY'] = 'undefined' + + # vcenter based variables + + vcenter_section = self.vm_parameters['vcenter'] + self.vm_parameters['variables']['VCENTER_NAME'] = vcenter_section['name'] + self.vm_parameters['variables']['VCENTER_IP'] = vcenter_section['ip'] + self.vm_parameters['variables']['VCENTER_PORT'] = vcenter_section['port'] + self.vm_parameters['variables']['VCENTER_USERNAME'] = vcenter_section['username'] + self.vm_parameters['variables']['VCENTER_PASSWORD'] = vcenter_section['password'] + self.vm_parameters['variables']['VCENTER_DATACENTER'] = vcenter_section['datacenter'] + self.vm_parameters['variables']['VCENTER_DATASTORE'] = vcenter_section['datastore'] + self.vm_parameters['variables']['VCENTER_CLUSTER'] = vcenter_section['cluster'] + self.vm_parameters['variables']['VCENTER_VM_FOLDER'] = vcenter_section['vm_folder'] + self.vm_parameters['variables']['VCENTER_ISO_FOLDER'] = vcenter_section['iso_folder'] + self.vm_parameters['variables']['VCENTER_KS_FOLDER'] = vcenter_section['ks_folder'] + self.vm_parameters['variables']['VCENTER_CLUSTER_HOST_IPS'] = ','.join(self.vm_parameters['vcenter']['host_ips']) + self.vm_parameters['variables']['ISO_FILENAME'] = self.vm_parameters['iso']['destination'] + + # Linux VM based variables + + linux_section = self.user_input['linux'] + self.vm_parameters['variables']['LINUX_DISTRIBUTION'] = linux_section['distribution'] + self.vm_parameters['variables']['LINUX_VERSION'] = linux_section['version'] + self.vm_parameters['variables']['VM_NAME'] = linux_section['vm']['name'] + self.vm_parameters['variables']['HOSTNAME'] = linux_section['vm']['name'] + self.vm_parameters['variables']['PASSWORD'] = linux_section['vm']['password'] + if self.vm_parameters['variables']['PASSWORD'] is not None: + self.vm_parameters['variables']['ENCRYPTED_PASSWORD'] = bcrypt.hashpw( + linux_section['vm']['password'].encode('utf-8'), + bcrypt.gensalt() + ).decode('utf-8') + + if linux_section['vm']['dns']['servers'] is not None: + self.vm_parameters['variables']['DNS_NAMESERVER'] = linux_section['vm']['dns']['servers'].split(',')[0] + if linux_section['vm']['dns']['domain'] is not None: + self.vm_parameters['variables']['DNS_DOMAIN'] = linux_section['vm']['dns']['domain'] + + if linux_section['vm']['ntp']['servers'] is not None: + self.vm_parameters['variables']['NTP_SERVER'] = linux_section['vm']['ntp']['servers'].split(',')[0] + + if linux_section['vm']['ntp']['timezone'] is not None: + self.vm_parameters['variables']['TIMEZONE'] = linux_section['vm']['ntp']['timezone'] + + network_id = 0 + self.vm_parameters['variables']['INTERFACE_%s_VC_NETWORK_NAME' % (network_id)] = linux_section['vm']['interface']['network'] + self.vm_parameters['variables']['INTERFACE_%s_NAME' % (network_id)] = linux_section['vm']['interface']['device'] + if linux_section['vm']['ip'] is not None: + self.vm_parameters['variables']['INTERFACE_%s_IP' % (network_id)] = linux_section['vm']['ip'].split('/')[0] + self.vm_parameters['variables']['INTERFACE_%s_NETMASK' % (network_id)] = ip_helper.prefix_to_netmask( + int(linux_section['vm']['ip'].split('/')[1]) + ) + self.vm_parameters['variables']['INTERFACE_%s_PREFIX' % (network_id)] = linux_section['vm']['ip'].split('/')[1] + self.vm_parameters['variables']['INTERFACE_%s_CIDR' % (network_id)] = linux_section['vm']['ip'] + self.vm_parameters['variables']['INTERFACE_%s_NETWORK' % (network_id)] = ip_helper.get_network_ipv4_in_cidr( + linux_section['vm']['ip'] + ) + self.vm_parameters['variables']['INTERFACE_%s_GATEWAY' % (network_id)] = linux_section['vm']['gateway'] + self.vm_parameters['variables']['INTERFACE_%s_REVDNS' % (network_id)] = '%s.%s.%s' % ( + self.vm_parameters['variables']['INTERFACE_%s_NETWORK' % (network_id)].split('.')[2], + self.vm_parameters['variables']['INTERFACE_%s_NETWORK' % (network_id)].split('.')[1], + self.vm_parameters['variables']['INTERFACE_%s_NETWORK' % (network_id)].split('.')[0] + ) + + # Non-user input related variables + + self.vm_parameters['variables']['DNS_SERIAL'] = '%s01' % (datetime.date.today().strftime("%Y%m%d")) + + # IP address octets variables + + new_attributes = {} + for key in self.vm_parameters['variables']: + if ip_helper.is_valid_ipv4_address(self.vm_parameters['variables'][key]): + index = 1 + for octet in self.vm_parameters['variables'][key].split('.'): + new_attributes['%s_OCTET_%s' % (key, index)] = octet + index = index + 1 + + for key in new_attributes: + if key not in self.vm_parameters['variables']: + self.vm_parameters['variables'][key] = new_attributes[key] + + for key in self.vm_parameters['variables']: + self.my_output.debug( + '%s => %s' % ( + key, + self.vm_parameters['variables'][key] + ) + ) + + self.my_output.debug('Completed') + return True + + def get_kickstart_default_filename(self): + kickstart_filename = None + + if self.vm_parameters['variables']['LINUX_DISTRIBUTION'] in ['centos', 'fedora', 'rhel']: + kickstart_filename = self.get_template_definition_key_value( + self.vm_parameters['template_name'], + 'default_kickstart', + template_category=self.template_category + ) + + if self.vm_parameters['variables']['LINUX_DISTRIBUTION'] in ['ubuntu']: + if self.vm_parameters['variables']['HTTP_PROXY_ENABLED'] == 'True': + kickstart_filename = self.get_template_definition_key_value( + self.vm_parameters['template_name'], + 'default_user_data_proxy', + template_category=self.template_category + ) + else: + kickstart_filename = self.get_template_definition_key_value( + self.vm_parameters['template_name'], + 'default_user_data_no_proxy', + template_category=self.template_category + ) + + if kickstart_filename is None: + self.my_output.error('No default kickstart defined for template: %s' % (self.vm_parameters['template_name'])) + return None + + kickstart_path = self.get_template_filename( + self.vm_parameters['template_name'], + kickstart_filename, + template_category=self.template_category + ) + + return kickstart_path + + def validate_ks_parameters(self, check_source=True): + self.my_output.debug('Validate linux.ks section', underline=True, before_newline=True) + ks_section = self.user_input['linux']['ks'] + + self.vm_parameters['ks'] = {} + self.vm_parameters['ks']['enabled'] = ks_section['enabled'] + + # Auto-fix ks.enabled in case ks.template or ks.iso is defined + if ks_section['template'] is not None or ks_section['iso'] is not None: + self.vm_parameters['ks']['enabled'] = True + + # ks.template and ks.iso cannot be used at the same time + if ks_section['template'] is not None and ks_section['iso'] is not None: + self.my_output.error('Define linux.ks.template or linux.ks.source') + return False + + # if ks is disabled, exit early + if not self.vm_parameters['ks']['enabled']: + self.my_output.debug('Kickstart disabled') + return True + + # Kickstart destination related parameters + + self.vm_parameters['ks']['folder_name'] = self.vc_helper_handler.fixup_datastore_folder_name( + self.vm_parameters['vcenter']['ks_folder'] + ) + self.vm_parameters['ks']['file_name'] = '%s-ks.iso' % ( + self.vm_parameters['variables']['VM_NAME'] + ) + self.vm_parameters['ks']['destination'] = '%s%s' % ( + self.vm_parameters['ks']['folder_name'], + self.vm_parameters['ks']['file_name'] + ) + self.vm_parameters['ks']['overwrite'] = True + self.vm_parameters['ks']['delete_destination'] = True + + self.vm_parameters['variables']['KS_FILENAME'] = self.vm_parameters['ks']['destination'] + + # Check destination folder + + success = self.vcenter_handler.is_datastore_folder( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['ks']['folder_name'] + ) + if success: + self.my_output.debug('datastore folder found: %s' % (self.vm_parameters['ks']['folder_name'])) + self.vm_parameters['ks']['is_folder'] = True + else: + self.my_output.debug('datastore folder not found: %s' % (self.vm_parameters['ks']['folder_name'])) + self.vm_parameters['ks']['is_folder'] = False + + # Check destination file + + success = self.vcenter_handler.is_datastore_file( + self.vm_parameters['vcenter']['datacenter'], + self.vm_parameters['vcenter']['datastore'], + self.vm_parameters['ks']['folder_name'], + self.vm_parameters['ks']['file_name'] + ) + if success: + self.vm_parameters['ks']['is_file'] = True + self.my_output.debug('kickstart iso file already defined: %s' % (self.vm_parameters['ks']['destination'])) + else: + self.vm_parameters['ks']['is_file'] = False + self.my_output.debug('datastore file not found: %s' % (self.vm_parameters['ks']['destination'])) + + # check_source code runs for create operation + # delete operation only cares about kickstart location that is based on vcenter.ks_folder and linux.vm.name + if check_source: + + # Option: ks.iso defined (only for centos/fedora/rhel) + if ks_section['iso'] is not None: + self.vm_parameters['ks']['generate'] = False + self.vm_parameters['ks']['template'] = None + self.vm_parameters['ks']['delete_source'] = False + + # ks.iso can be relative or absolute path + self.vm_parameters['ks']['source'] = ks_section['iso'] + if not os.path.isabs(ks_section['iso']): + self.vm_parameters['ks']['source'] = os.path.join( + self.user_input['base_directory'], + ks_section['iso'] + ) + + # ks.iso must exist + if not os.path.isfile(self.vm_parameters['ks']['source']): + self.my_output.error( + 'linux.ks.iso must be valid kickstart iso file location: %s' % + (self.vm_parameters['ks']['source']) + ) + return False + + if ks_section['iso'] is None: + # Option: ks.template is not defined and default template should be used + if ks_section['template'] is None: + self.vm_parameters['ks']['generate'] = True + + self.vm_parameters['ks']['template'] = self.get_kickstart_default_filename() + if self.vm_parameters['ks']['template'] is None: + return False + + # Option: ks.template is defined + if ks_section['template'] is not None: + self.vm_parameters['ks']['generate'] = True + self.vm_parameters['ks']['source'] = '/tmp/%s.iso' % (str(uuid.uuid4())) + self.vm_parameters['ks']['delete_source'] = True + + # ks.template can be relative or absolute path + self.vm_parameters['ks']['template'] = ks_section['template'] + if not os.path.isabs(ks_section['template']): + self.vm_parameters['ks']['template'] = os.path.join( + self.user_input['base_directory'], + ks_section['template'] + ) + + # ks.template must exist + if not os.path.isfile(self.vm_parameters['ks']['template']): + self.my_output.error('linux.ks.template file not found: %s' % (self.vm_parameters['ks']['template'])) + return False + + # check template content with conditional variable replacement + content = self.template_handler.get_template( + self.vm_parameters['ks']['template'], + self.vm_parameters['variables'], + replace_variables_enabled=self.vm_parameters['settings']['kickstart_template_variable_replacement_enabled'] + ) + if content is None: + return False + + self.vm_parameters['ks']['delete_source'] = True + self.vm_parameters['ks']['source'] = '/tmp/%s.iso' % (str(uuid.uuid4())) + + self.my_output.debug('Kickstart template verified: %s' % (self.vm_parameters['ks']['template'])) + self.my_output.debug('Generated kickstart iso target location: %s' % (self.vm_parameters['ks']['source'])) + + self.my_output.debug('Completed') + return True + + def validate_vm_get_parameters(self): + self.my_output.debug('Validate linux vm section', underline=True, before_newline=True) + + linux_section = self.user_input['linux'] + + self.vm_parameters['vm'] = {} + self.vm_parameters['vm']['distribution'] = linux_section['distribution'] + self.vm_parameters['vm']['datacenter_name'] = self.vm_parameters['vcenter']['datacenter'] + self.vm_parameters['vm']['datastore_name'] = self.vm_parameters['vcenter']['datastore'] + self.vm_parameters['vm']['host_ip'] = self.vm_parameters['vcenter']['host_ip'] + self.vm_parameters['vm']['name'] = linux_section['vm']['name'] + + self.vm_parameters['vm']['management_ip'] = None + self.vm_parameters['vm']['ssh'] = {} + self.vm_parameters['vm']['ssh']['enabled'] = False + self.vm_parameters['vm']['ssh']['username'] = None + self.vm_parameters['vm']['ssh']['password'] = None + self.vm_parameters['vm']['ssh']['ip'] = None + + if linux_section['vm']['username'] is not None: + self.vm_parameters['vm']['ssh']['username'] = linux_section['vm']['username'] + if linux_section['vm']['password'] is not None: + self.vm_parameters['vm']['ssh']['password'] = linux_section['vm']['password'] + if linux_section['vm']['ip'] is not None: + self.vm_parameters['vm']['ssh']['ip'] = linux_section['vm']['ip'].split('/')[0] + self.vm_parameters['vm']['management_ip'] = linux_section['vm']['ip'].split('/')[0] + + if self.vm_parameters['vm']['ssh']['username'] is not None: + if self.vm_parameters['vm']['ssh']['password'] is not None: + if self.vm_parameters['vm']['ssh']['ip'] is not None: + self.vm_parameters['vm']['ssh']['enabled'] = True + + self.my_output.debug('Completed') + return True + + def validate_vm_create_parameters(self): + self.my_output.debug('Validate linux vm section', underline=True, before_newline=True) + + kickstart = self.vm_parameters['ks'] + linux_section = self.user_input['linux'] + + self.vm_parameters['vm'] = {} + self.vm_parameters['vm']['distribution'] = linux_section['distribution'] + self.vm_parameters['vm']['datacenter_name'] = self.vm_parameters['vcenter']['datacenter'] + self.vm_parameters['vm']['datastore_name'] = self.vm_parameters['vcenter']['datastore'] + self.vm_parameters['vm']['host_ip'] = self.vm_parameters['vcenter']['host_ip'] + + for key in ['name', 'cpu', 'memory']: + self.vm_parameters['vm'][key] = linux_section['vm'][key] + + self.vm_parameters['vm']['disk'] = [] + new_disk = {} + new_disk['size'] = linux_section['vm']['disk']['size'] + new_disk['thin'] = False + if linux_section['vm']['disk']['type'] == 'thin': + new_disk['thin'] = True + self.vm_parameters['vm']['disk'].append(new_disk) + + self.vm_parameters['vm']['network'] = [] + new_network = {} + new_network['device'] = linux_section['vm']['interface']['device'] + new_network['name'] = linux_section['vm']['interface']['network'] + new_network['type'] = linux_section['vm']['interface']['type'] + self.vm_parameters['vm']['network'].append(new_network) + + self.vm_parameters['vm']['cdrom'] = [] + + if self.vm_parameters['iso']['enabled']: + if linux_section['distribution'] in ['centos', 'fedora', 'rhel']: + new_cdrom = {} + new_cdrom['datastore_name'] = self.vm_parameters['vcenter']['datastore'] + new_cdrom['iso'] = self.vm_parameters['iso']['destination'] + self.vm_parameters['vm']['cdrom'].append(new_cdrom) + + if linux_section['distribution'] in ['ubuntu'] and not kickstart['enabled']: + new_cdrom = {} + new_cdrom['datastore_name'] = self.vm_parameters['vcenter']['datastore'] + new_cdrom['iso'] = self.vm_parameters['iso']['destination'] + self.vm_parameters['vm']['cdrom'].append(new_cdrom) + + if kickstart['enabled']: + new_cdrom = {} + new_cdrom['datastore_name'] = self.vm_parameters['vcenter']['datastore'] + new_cdrom['iso'] = kickstart['destination'] + self.vm_parameters['vm']['cdrom'].append(new_cdrom) + + self.vm_parameters['vm']['created'] = self.vcenter_handler.is_vm(linux_section['vm']['name']) + if not self.vm_parameters['vm']['created']: + if kickstart['enabled'] and kickstart['is_file']: + self.my_output.error('Kickstart file already defined: %s' % (kickstart['destination'])) + return None + + net_obj = self.vcenter_handler.get_network_object(linux_section['vm']['interface']['network']) + if net_obj is None: + self.my_output.error('Network %s not found' % (linux_section['vm']['interface']['network'])) + return None + + self.vm_parameters['vm']['management_ip'] = None + self.vm_parameters['vm']['ssh'] = {} + self.vm_parameters['vm']['ssh']['enabled'] = False + self.vm_parameters['vm']['ssh']['username'] = None + self.vm_parameters['vm']['ssh']['password'] = None + self.vm_parameters['vm']['ssh']['ip'] = None + + if linux_section['vm']['username'] is not None: + self.vm_parameters['vm']['ssh']['username'] = linux_section['vm']['username'] + if linux_section['vm']['password'] is not None: + self.vm_parameters['vm']['ssh']['password'] = linux_section['vm']['password'] + if linux_section['vm']['ip'] is not None: + self.vm_parameters['vm']['ssh']['ip'] = linux_section['vm']['ip'].split('/')[0] + self.vm_parameters['vm']['management_ip'] = linux_section['vm']['ip'].split('/')[0] + + if self.vm_parameters['vm']['ssh']['username'] is not None: + if self.vm_parameters['vm']['ssh']['password'] is not None: + if self.vm_parameters['vm']['ssh']['ip'] is not None: + self.vm_parameters['vm']['ssh']['enabled'] = True + + self.my_output.debug('Completed') + return True + + def validate_vm_delete_parameters(self): + self.my_output.debug('Validate linux vm section', underline=True, before_newline=True) + + linux_section = self.user_input['linux'] + + self.vm_parameters['vm'] = {} + self.vm_parameters['vm']['distribution'] = linux_section['distribution'] + self.vm_parameters['vm']['datacenter_name'] = self.vm_parameters['vcenter']['datacenter'] + self.vm_parameters['vm']['datastore_name'] = self.vm_parameters['vcenter']['datastore'] + self.vm_parameters['vm']['host_ip'] = self.vm_parameters['vcenter']['host_ip'] + self.vm_parameters['vm']['name'] = linux_section['vm']['name'] + + self.vm_parameters['vm']['management_ip'] = None + self.vm_parameters['vm']['ssh'] = {} + self.vm_parameters['vm']['ssh']['enabled'] = False + self.vm_parameters['vm']['ssh']['username'] = None + self.vm_parameters['vm']['ssh']['password'] = None + self.vm_parameters['vm']['ssh']['ip'] = None + + if linux_section['vm']['username'] is not None: + self.vm_parameters['vm']['ssh']['username'] = linux_section['vm']['username'] + if linux_section['vm']['password'] is not None: + self.vm_parameters['vm']['ssh']['password'] = linux_section['vm']['password'] + if linux_section['vm']['ip'] is not None: + self.vm_parameters['vm']['ssh']['ip'] = linux_section['vm']['ip'].split('/')[0] + self.vm_parameters['vm']['management_ip'] = linux_section['vm']['ip'].split('/')[0] + + if self.vm_parameters['vm']['ssh']['username'] is not None: + if self.vm_parameters['vm']['ssh']['password'] is not None: + if self.vm_parameters['vm']['ssh']['ip'] is not None: + self.vm_parameters['vm']['ssh']['enabled'] = True + + self.my_output.debug('Completed') + return True + + def load_task(self, filename): + content = self.template_handler.get_template( + filename, + self.vm_parameters['variables'], + yaml_conversion=True + ) + + if content is None: + return None + + return content + + def validate_task(self, task_filename): + task_definition = self.load_task(task_filename) + if task_definition is None: + return False + + if 'tasks' not in task_definition: + self.my_output.error('tasks list required') + return False + + task_directory = os.path.dirname(task_filename) + for task in task_definition['tasks']: + for key in task: + if key not in ['scripts', 'files', 'commands']: + self.my_output.error('Unsupported task key: %s' % (key)) + return False + + if key == 'scripts': + for item in task[key]: + filename = os.path.join(task_directory, item) + self.my_output.debug('\nScript: %s' % (filename)) + + content = self.template_handler.get_template(filename, self.vm_parameters['variables']) + if content is None: + return False + + self.my_output.debug('Verified') + self.my_output.debug(content) + + if key == 'files': + for item in task[key]: + for attribute in ['source', 'template', 'destination', 'chmod']: + if attribute not in item: + self.my_output.error('File requires attribute %s' % (attribute)) + return False + + if '/' in item['source'] or '\\' in item['source']: + filename = item['source'] + else: + filename = os.path.join(task_directory, item['source']) + self.my_output.debug('\nFile: %s' % (filename)) + + if item['template']: + content = self.template_handler.get_template(filename, self.vm_parameters['variables']) + if content is None: + return False + self.my_output.debug(content) + + self.my_output.debug('Verifed') + + return True + + def validate_tasks(self, task_type): + self.vm_parameters['tasks'] = [] + if task_type in self.user_input: + for task_filename in self.user_input[task_type]: + self.my_output.debug('Validate task: %s' % (task_filename), underline=True, before_newline=True) + if not self.validate_task(task_filename): + return False + self.vm_parameters['tasks'].append(task_filename) + + return True + + def validate_get(self, location): + if not self.validate_syntax(location, 'get'): + return None + + if not self.validate_vcenter_parameters(location): + return None + + if not self.validate_vm_get_parameters(): + return None + + self.vm_parameters['state'] = {} + for key in self.user_input['state']: + self.vm_parameters['state'][key] = self.user_input['state'][key] + + self.my_output.debug('\nValidated vm get parameters: %s' % (json.dumps(self.vm_parameters, indent=4))) + return self.vm_parameters + + def validate_syntax(self, location, operation): + self.log_handler.debug('validate_syntax', 'Operation: %s, Location: %s' % (operation, location)) + self.user_input = self.validate( + location, + operation, + template_reference='linux.template', + template_category=self.template_category + ) + if self.user_input is None: + self.log_handler.error('validate_syntax', 'Validation failed') + return False + + self.log_handler.debug('validate_syntax', 'self.user_input: %s' % (json.dumps(self.user_input, indent=4))) + + self.vm_parameters['template_name'] = self.user_input['template_name'] + self.log_handler.debug('validate_syntax', 'self.vm_parameters: %s' % (json.dumps(self.vm_parameters, indent=4))) + + return True + + def validate_create(self, location): + self.log_handler.debug('validate_create', location) + if not self.validate_syntax(location, 'create'): + return None + + if not self.validate_settings(): + return None + + if not self.validate_vcenter_parameters(location): + return None + + if not self.validate_jump_parameters(): + return None + + if not self.validate_iso_parameters(check_source=True): + return None + + if not self.generate_variables(): + return None + + if not self.validate_ks_parameters(check_source=True): + return None + + if not self.validate_vm_create_parameters(): + return None + + if not self.validate_tasks('create_tasks'): + return None + + self.vm_parameters['state'] = {} + for key in self.user_input['state']: + self.vm_parameters['state'][key] = self.user_input['state'][key] + + self.my_output.debug('\nValidated vm create parameters: %s' % (json.dumps(self.vm_parameters, indent=4))) + return self.vm_parameters + + def validate_delete(self, location): + if not self.validate_syntax(location, 'delete'): + return None + + if not self.validate_vcenter_parameters(location): + return None + + if not self.validate_iso_parameters(check_source=False): + return None + + if not self.generate_variables(): + return None + + if not self.validate_ks_parameters(check_source=False): + return None + + if not self.validate_vm_delete_parameters(): + return None + + if not self.validate_tasks('delete_tasks'): + return None + + self.my_output.debug('\nValidated vm delete parameters: %s' % (json.dumps(self.vm_parameters, indent=4))) + return self.vm_parameters diff --git a/lib/vc/virtual_machine_lcm.py b/lib/vc/virtual_machine_lcm.py new file mode 100644 index 00000000..e7acc58b --- /dev/null +++ b/lib/vc/virtual_machine_lcm.py @@ -0,0 +1,428 @@ +# pylint: disable=no-name-in-module +from pyVmomi import vim + + +class VcVirtualMachineLcm(): + def __init__(self): + pass + + def create_vm_config_spec(self, vm_definition, devices): + config = vim.vm.ConfigSpec() + config.name = vm_definition['name'] + config.numCPUs = int(vm_definition['cpu']) + config.memoryMB = int(vm_definition['memory']) + config.guestId = 'otherGuest' + + files = vim.vm.FileInfo() + files.vmPathName = '[%s]' % (vm_definition['datastore_name']) + config.files = files + + config.deviceChange = devices + + return config + + def update_network_device(self, vm_name, device_name, target_network): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + return False + + device_obj = self.get_network_device_obj( + vm_name, + device_name + ) + if device_obj is None: + return False + + nicspec = vim.vm.device.VirtualDeviceSpec() + nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit + nicspec.device = device_obj + nicspec.device.key = device_obj.key + nicspec.device.macAddress = device_obj.macAddress + nicspec.device.backing = device_obj.backing + nicspec.device.backing.deviceName = target_network + + connectable = vim.vm.device.VirtualDevice.ConnectInfo() + connectable.connected = True + connectable.startConnected = True + nicspec.device.connectable = connectable + + config_spec = vim.vm.ConfigSpec(deviceChange=[nicspec]) + task = vm_obj.Reconfigure(config_spec) + self.wait_for_tasks([task], exception_on_task_failure=False) + + self.my_output.info('VM %s network device %s connected to network %s' % (vm_name, device_name, target_network)) + + return True + + def create_network_devices(self, vm_definition): + devices = [] + + for network in vm_definition['network']: + net_obj = self.get_network_object(network['name']) + if net_obj is None: + self.my_output.error('Network %s not found' % (network['name'])) + self.print_network_names( + title='Available networks' + ) + return None + + if network['type'] not in ['vmxnet3']: + self.my_output.error('Unsupported network type: %s' % (network['type'])) + return None + + nicspec = vim.vm.device.VirtualDeviceSpec() + nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add + + if network['type'] == 'vmxnet3': + nic_type = vim.vm.device.VirtualVmxnet3() + + nicspec.device = nic_type + nicspec.device.deviceInfo = vim.Description() + nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() + nicspec.device.connectable.startConnected = True + nicspec.device.connectable.allowGuestControl = True + + if self.is_network_distributed(net_obj): + dv_net_obj = self.get_distributed_network_object(network['name']) + if dv_net_obj is None: + self.my_output.error('DV Network %s not found' % (network['name'])) + return False + + dswitch_port_connection = vim.dvs.PortConnection( + portgroupKey=dv_net_obj['key'], + switchUuid=dv_net_obj['config'].distributedVirtualSwitch.uuid + ) + + nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo() + nicspec.device.backing.port = dswitch_port_connection + else: + nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo() + nicspec.device.backing.network = net_obj + nicspec.device.backing.deviceName = net_obj.name + + devices.append(nicspec) + + return devices + + def add_network_devices(self, vm_obj, vm_definition): + if len(vm_definition['network']) == 0: + return True + + for network in vm_definition['network']: + net_obj = self.get_network_object(network['name']) + if net_obj is None: + self.my_output.error('Network %s not found' % (network['name'])) + self.print_network_names( + title='Available networks' + ) + return False + + if network['type'] not in ['vmxnet3']: + self.my_output.error('Unsupported network type: %s' % (network['type'])) + return False + + nicspec = vim.vm.device.VirtualDeviceSpec() + nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add + + if network['type'] == 'vmxnet3': + nic_type = vim.vm.device.VirtualVmxnet3() + + nicspec.device = nic_type + nicspec.device.deviceInfo = vim.Description() + nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() + nicspec.device.connectable.startConnected = True + nicspec.device.connectable.allowGuestControl = True + + if self.is_network_distributed(net_obj): + dv_net_obj = self.get_distributed_network_object(network['name']) + if dv_net_obj is None: + self.my_output.error('DV Network %s not found' % (network['name'])) + return False + + dswitch_port_connection = vim.dvs.PortConnection( + portgroupKey=dv_net_obj.key, + switchUuid=dv_net_obj.config.distributedVirtualSwitch.uuid + ) + + nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo() + nicspec.device.backing.port = dswitch_port_connection + else: + nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo() + nicspec.device.backing.network = net_obj + nicspec.device.backing.deviceName = net_obj.name + + config_spec = vim.vm.ConfigSpec(deviceChange=[nicspec]) + task = vm_obj.Reconfigure(config_spec) + self.wait_for_tasks([task], exception_on_task_failure=False) + + if task.info.state == 'error': + self.my_output.error('Virtual Machine update with network devices failed') + self.my_output.default(task.info.error) + return False + + self.my_output.default('Network device added to virtual machine') + + return True + + def create_cdrom_devices(self, vm_definition): + devices = [] + if len(vm_definition['cdrom']) == 0: + return devices + + cdrom_id = 0 + for cdrom in vm_definition['cdrom']: + cdrom_spec = vim.vm.device.VirtualDeviceSpec() + cdrom_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add + cdrom_spec.device = vim.vm.device.VirtualCdrom() + cdrom_spec.device.backing = vim.vm.device.VirtualCdrom.IsoBackingInfo() + cdrom_spec.device.backing.fileName = '[%s] %s' % (cdrom['datastore_name'], cdrom['iso']) + + connectable = vim.vm.device.VirtualDevice.ConnectInfo() + connectable.allowGuestControl = True + connectable.startConnected = True + cdrom_spec.device.connectable = connectable + + # I have no clue how to programmatically get the IDE controller value... + # https://stackoverflow.com/questions/33223262/listing-valid-controllerkey-values-with-pyvmomi + cdrom_spec.device.controllerKey = 200 + + devices.append(cdrom_spec) + + cdrom_id = cdrom_id + 1 + + return devices + + def add_cdrom_devices(self, vm_obj, controller, vm_definition): + if len(vm_definition['cdrom']) == 0: + self.my_output.default('No cdrom device defined') + return True + + for cdrom in vm_definition['cdrom']: + cdrom_spec = vim.vm.device.VirtualDeviceSpec() + cdrom_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add + cdrom_spec.device = vim.vm.device.VirtualCdrom() + cdrom_spec.device.backing = vim.vm.device.VirtualCdrom.IsoBackingInfo() + cdrom_spec.device.backing.fileName = '[%s] %s' % (cdrom['datastore_name'], cdrom['iso']) + + connectable = vim.vm.device.VirtualDevice.ConnectInfo() + connectable.allowGuestControl = True + connectable.startConnected = True + cdrom_spec.device.connectable = connectable + + cdrom_spec.device.controllerKey = controller.key + + config_spec = vim.vm.ConfigSpec(deviceChange=[cdrom_spec]) + task = vm_obj.Reconfigure(config_spec) + self.wait_for_tasks([task], exception_on_task_failure=False) + + if task.info.state == 'error': + self.my_output.error('Virtual Machine update with cdrom devices failed') + self.my_output.default(task.info.error) + return False + + self.my_output.default('Cdrom added to virtual machine') + + return True + + def create_disk_devices(self, vm_definition): + devices = [] + + scsi_ctr = vim.vm.device.VirtualDeviceSpec() + scsi_ctr.operation = vim.vm.device.VirtualDeviceSpec.Operation.add + scsi_ctr.device = vim.vm.device.ParaVirtualSCSIController() + scsi_ctr.device.deviceInfo = vim.Description() + scsi_ctr.device.slotInfo = vim.vm.device.VirtualDevice.PciBusSlotInfo() + scsi_ctr.device.slotInfo.pciSlotNumber = 16 + scsi_ctr.device.controllerKey = 100 + scsi_ctr.device.unitNumber = 3 + scsi_ctr.device.busNumber = 0 + scsi_ctr.device.hotAddRemove = True + scsi_ctr.device.sharedBus = 'noSharing' + scsi_ctr.device.scsiCtlrUnitNumber = 7 + devices.append(scsi_ctr) + + disk_id = 0 + for disk in vm_definition['disk']: + disk_spec = vim.vm.device.VirtualDeviceSpec() + disk_spec.fileOperation = "create" + disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add + disk_spec.device = vim.vm.device.VirtualDisk() + disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo() + disk_spec.device.backing.diskMode = 'persistent' + disk_spec.device.backing.fileName = '[%s] %s/%s-disk%s.vmdk' % ( + vm_definition['datastore_name'], + vm_definition['name'], + vm_definition['name'], + disk_id + ) + disk_spec.device.backing.thinProvisioned = True + disk_spec.device.unitNumber = disk_id + disk_spec.device.capacityInKB = disk['size'] * 1024 * 1024 + disk_spec.device.controllerKey = scsi_ctr.device.key + devices.append(disk_spec) + + disk_id = disk_id + 1 + + return devices + + def create_vm(self, vm_definition, dry_run=False): + if not self.vc_connect(): + self.my_output.error('VM folder not found') + return False + + devices = [] + + new_device = self.create_disk_devices(vm_definition) + if new_device is None: + return False + + devices = devices + new_device + + new_device = self.create_network_devices(vm_definition) + if new_device is None: + return False + + devices = devices + new_device + + vm_config_spec = self.create_vm_config_spec(vm_definition, devices) + + content = self.vc_service_instance.RetrieveContent() + vm_folder = None + for child in content.rootFolder.childEntity: + if child.name == vm_definition['datacenter_name']: + vm_folder = child.vmFolder + break + + if vm_folder is None: + self.my_output.error('VM folder not found') + return False + + host_obj = self.get_host_object(vm_definition['host_ip']) + if host_obj is None: + return False + + source_pool = host_obj.parent.resourcePool + + if dry_run: + self.my_output.default(vm_config_spec) + return True + + task = vm_folder.CreateVm( + vm_config_spec, + pool=source_pool, + host=host_obj + ) + self.wait_for_tasks([task], exception_on_task_failure=False) + + if task.info.state == 'error': + self.my_output.error('Virtual Machine create failed') + self.my_output.default(task.info.error) + return False + + self.my_output.default('Virtual Machine created: %s' % (vm_definition['name'])) + + vm_obj = self.get_vm_object(vm_definition['name']) + if vm_obj is None: + self.my_output.error('Virtual Machine not found: %s' % (vm_definition['name'])) + return False + + controller = None + for dev in vm_obj.config.hardware.device: + if isinstance(dev, vim.vm.device.VirtualIDEController): + # If there are less than 2 devices attached, we can use it. + if len(dev.device) < 2: + controller = dev + + if controller is None: + self.my_output.error('Virtual IDE controller not found') + return False + + if not self.add_cdrom_devices(vm_obj, controller, vm_definition): + return False + + return True + + def power_on_vm(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.my_output.error('Virtual Machine not found: %s' % (vm_name)) + return False + + current_power_state = vm_obj.runtime.powerState + if current_power_state == 'poweredOn': + self.my_output.default('Virtual Machine already powered on: %s' % (vm_name)) + return True + self.my_output.default('The current powerState is: %s' % (current_power_state)) + + task = vm_obj.PowerOnVM_Task() + self.wait_for_tasks([task], exception_on_task_failure=False) + + if task.info.state == 'error': + self.my_output.error('Virtual Machine power on failed') + self.my_output.default(task.info.error) + return False + + self.my_output.default('Virtual Machine powered on: %s' % (vm_name)) + + return True + + def power_off_vm(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.my_output.error('Virtual Machine not found: %s' % (vm_name)) + return False + + current_power_state = vm_obj.runtime.powerState + if current_power_state == 'poweredOff': + self.my_output.default('Virtual Machine already powered off: %s' % (vm_name)) + return True + self.my_output.default('The current powerState is: %s' % (current_power_state)) + + task = vm_obj.PowerOffVM_Task() + self.wait_for_tasks([task], exception_on_task_failure=False) + + if task.info.state == 'error': + self.my_output.error('Virtual Machine power off failed') + self.my_output.default(task.info.error) + return False + + self.my_output.default('Virtual Machine powered off: %s' % (vm_name)) + + return True + + def destroy_vm(self, vm_name): + vm_obj = self.get_vm_object(vm_name) + if vm_obj is None: + self.my_output.error('Virtual Machine not found: %s' % (vm_name)) + return False + + current_power_state = vm_obj.runtime.powerState + if current_power_state != 'poweredOff': + self.my_output.default('Virtual Machine must be powered off: %s' % (vm_name)) + return True + self.my_output.default('The current powerState is: %s' % (current_power_state)) + + task = vm_obj.Destroy_Task() + self.wait_for_tasks([task], exception_on_task_failure=False) + + if task.info.state == 'error': + self.my_output.error('Virtual Machine destroy failed') + self.my_output.default(task.info.error) + return False + + self.my_output.default('Virtual Machine destroyed: %s' % (vm_name)) + + return True + + def delete_vm(self, name): + if not self.is_vm(name): + self.my_output.default('Virtual machine does not exist: %s' % (name)) + return True + + if not self.power_off_vm(name): + return False + + if not self.destroy_vm(name): + return False + + return True diff --git a/lib/vc/vm_cluster.py b/lib/vc/vm_cluster.py new file mode 100644 index 00000000..83a2e866 --- /dev/null +++ b/lib/vc/vm_cluster.py @@ -0,0 +1,80 @@ +# pylint: disable=no-name-in-module +from pyVmomi import vim + + +class VcVmCluster(): + def __init__(self): + pass + + def is_vm_cluster(self, cluster_name): + cluster_obj = self.get_vm_cluster_object(cluster_name) + if cluster_obj is None: + return False + + return True + + def get_vm_clusters(self): + if not self.vc_connect(): + return None + + clusters = [] + content = self.vc_service_instance.RetrieveContent() + + # Get the list of all datacenters we have available to us + clusters_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.ClusterComputeResource], + True + ) + + for cluster_obj in clusters_object_view.view: + cluster = {} + cluster['name'] = cluster_obj.name + clusters.append(cluster) + + return clusters + + def get_vm_cluster_object(self, cluster_name): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + clusters_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.ClusterComputeResource], + True + ) + + # ['AbandonHciWorkflow', 'AddHost', 'AddHost_Task', 'ApplyRecommendation', 'Array', 'CancelRecommendation', 'ClusterEnterMaintenanceMode', 'ConfigureHCI', 'ConfigureHCI_Task', + # 'Destroy', 'Destroy_Task', 'EnterMaintenanceMode', 'EvcManager', 'ExtendHCI', 'ExtendHCI_Task', 'FindRulesForVm', 'GetResourceUsage', 'GetSystemVMsRestrictedDatastores', + # 'MoveHostInto', 'MoveHostInto_Task', 'MoveInto', 'MoveInto_Task', 'PlaceVm', 'RecommendHostsForVm', 'Reconfigure', 'ReconfigureCluster_Task', 'ReconfigureComputeResource_Task', + # 'ReconfigureEx', 'RefreshRecommendation', 'Reload', 'Rename', 'Rename_Task', 'RetrieveDasAdvancedRuntimeInfo', 'SetCryptoMode', 'SetCustomValue', 'StampAllRulesWithUuid', + # 'StampAllRulesWithUuid_Task', 'Summary', 'ValidateHCIConfiguration', '_GetMethodInfo', '_GetMethodList', '_GetMoId', '_GetPropertyInfo', '_GetPropertyList', '_GetServerGuid', + # '_GetStub', '_InvokeAccessor', '_InvokeMethod', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', + # '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', + # '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_methodInfo', '_moId', '_propInfo', '_propList', '_serverGuid', '_stub', '_version', '_wsdlName', 'actionHistory', + # 'alarmActionsEnabled', 'availableField', 'configIssue', 'configStatus', 'configuration', 'configurationEx', 'customValue', + # 'datastore', 'declaredAlarmState', 'disabledMethod', 'drsFault', 'drsRecommendation', 'effectiveRole', 'environmentBrowser', 'hciConfig', 'host', 'lifecycleManaged', 'migrationHistory', + # 'name', 'network', 'overallStatus', 'parent', 'permission', 'recentTask', 'recommendation', 'resourcePool', 'setCustomValue', 'summary', 'summaryEx', 'tag', 'triggeredAlarmState', 'value'] + + for cluster_obj in clusters_object_view.view: + if cluster_obj.name == cluster_name: + clusters_object_view.Destroy() + return cluster_obj + + clusters_object_view.Destroy() + + return None + + def get_vm_cluster_hosts(self, cluster_name): + cluster_obj = self.get_vm_cluster_object(cluster_name) + if cluster_obj is None: + return None + + cluster_hosts = [] + for cluster_host in cluster_obj.host: + cluster_hosts.append( + cluster_host.name + ) + + return cluster_hosts diff --git a/lib/vc/vm_folder.py b/lib/vc/vm_folder.py new file mode 100644 index 00000000..de6952d7 --- /dev/null +++ b/lib/vc/vm_folder.py @@ -0,0 +1,59 @@ +# pylint: disable=no-name-in-module +from pyVmomi import vim + + +class VcVmFolder(): + def __init__(self): + pass + + def is_vm_folder(self, folder_name): + folders = self.get_folders() + if folders is None: + return False + + for folder in folders: + if folder['name'] == folder_name: + return True + + return False + + def get_folders(self): + if not self.vc_connect(): + return None + + folders = [] + content = self.vc_service_instance.RetrieveContent() + + # Get the list of all datacenters we have available to us + folders_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Folder], + True + ) + + for folder_obj in folders_object_view.view: + folder = {} + folder['name'] = folder_obj.name + folders.append(folder) + + return folders + + def get_folder_object(self, folder_name): + if not self.vc_connect(): + return None + + content = self.vc_service_instance.RetrieveContent() + folders_object_view = content.viewManager.CreateContainerView( + content.rootFolder, + [vim.Folder], + True + ) + + for folder_obj in folders_object_view.view: + if folder_obj.name == folder_name: + folders_object_view.Destroy() + return folder_obj + + folders_object_view.Destroy() + + return None diff --git a/lib/webex_bot/__init__.py b/lib/webex_bot/__init__.py new file mode 100644 index 00000000..2eef1dc7 --- /dev/null +++ b/lib/webex_bot/__init__.py @@ -0,0 +1,4 @@ +"""Top-level package for Webex Bot.""" + +__author__ = """Finbarr Brady""" +__version__ = '0.4.1' diff --git a/lib/webex_bot/api.py b/lib/webex_bot/api.py new file mode 100644 index 00000000..2ce86e94 --- /dev/null +++ b/lib/webex_bot/api.py @@ -0,0 +1,48 @@ +import time +from webexteamssdk import WebexTeamsAPI + + +class MyWebexApi(): + def __init__(self, bot_token, proxies=None): + self.webex_api_handler = None + self.bot_token = bot_token + self.proxies = proxies + + def create_message(self, room_id=None, text=None, markdown=None, parent_id=None, files=None, max_attempts=3): + try: + if len(self.proxies) == 0: + self.webex_api_handler = WebexTeamsAPI( + access_token=self.bot_token + ) + else: + self.webex_api_handler = WebexTeamsAPI( + access_token=self.bot_token, + proxies=self.proxies + ) + + except BaseException: + return False + + attempt = 1 + while True: + try: + success = True + self.webex_api_handler.messages.create( + roomId=room_id, + markdown=markdown, + text=text, + parentId=parent_id, + files=files + ) + except BaseException: + success = False + + if success: + break + + attempt = attempt + 1 + time.sleep(.5) + if attempt > max_attempts: + return False + + return True diff --git a/lib/webex_bot/cards/__init__.py b/lib/webex_bot/cards/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/webex_bot/commands/__init__.py b/lib/webex_bot/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/webex_bot/commands/aci.py b/lib/webex_bot/commands/aci.py new file mode 100644 index 00000000..586647ae --- /dev/null +++ b/lib/webex_bot/commands/aci.py @@ -0,0 +1,467 @@ +import os +import uuid +import time +import json +import traceback +import logging + +from lib.webex_bot.models.command import Command +from lib.aci import settings as aci_settings +from lib.aci import bot_output +from lib.aci import apic +from lib import log_helper +from lib import ip_helper +from lib import file_helper + +logger = logging.getLogger(__name__) + + +class GetAciCommand(Command): + def __init__(self, my_webex_api_handler, url): + super().__init__( + command_keyword="get aci", + help_message="get aci", + card=None, + ) + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + self.link = 'https://wwwin-github.cisco.com/emear-telcocloud/iserver/blob/master/doc/bot/GetAci.md' + self.url = url + logger.info('Command initialized: get aci [%s]', self.run_id[4:]) + + self.my_webex_api_handler = my_webex_api_handler + + def help(self): + output = 'Supported commands followed by controller names, device names and filtering options

' + output = '%s- get aci apic
' % (output) + output = '%s- get aci ep
' % (output) + output = '%s- get aci lacp
' % (output) + output = '%s- get aci lldp
' % (output) + output = '%s- get aci node
' % (output) + output = '%s
Find more examples and documentation here' % (output, self.link) + return output + + def doc(self, activity): + files = [] + files.append( + os.path.join( + os.path.join( + os.path.join( + file_helper.get_main_dir(), + 'doc' + ), + 'bot' + ), + 'GetAci.md' + ) + ) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files + ) + + def parse_command(self, message, command_run_id): + options = {} + options['success'] = True + options['error'] = '' + options['view'] = [] + options['apic'] = [] + options['filter'] = {} + options['cache'] = None + + words = message.split(' ') + if len(words) == 0: + options['success'] = False + options['error'] = 'Cannot parse the command. Check documnetation.' % (self.link) + return options + + # View + + for view_name in words: + if view_name in ['apic', 'ep', 'node', 'lacp', 'lldp', 'cache']: + if view_name not in options['view']: + options['view'].append(view_name) + + # Controller + + aci_settings_handler = aci_settings.ApicSettings(log_id=command_run_id) + controller_names = [] + for controller_name in words: + if controller_name not in ['apic', 'ep', 'node', 'lacp', 'lldp', 'cache', 'cache:on', 'cache:off']: + if controller_name in controller_names: + continue + + if controller_name == 'apic:all': + controller_names = aci_settings_handler.get_apic_controller_names() + options['apic'] = aci_settings_handler.get_apic_controllers() + + if controller_name != 'dev:all': + if len(controller_name.split(':')) > 1: + continue + + controller_names.append(controller_name) + controller_settings = aci_settings_handler.get_apic_controller(controller_name) + if controller_settings is None: + options['success'] = False + options['error'] = 'Unknown controller: %s' % (controller_name) + return options + + options['apic'].append( + controller_settings + ) + + if len(controller_names) == 0: + if len(options['view']) == 1 and 'apic' in options['view']: + options['apic'] = aci_settings_handler.get_apic_controllers() + else: + controller_names = aci_settings_handler.get_apic_controller_names() + options['success'] = False + options['error'] = 'Select at least one controller: %s' % (','.join(controller_names)) + return options + + # Filter + + for item in words: + if item in controller_names: + continue + + if item in options['view']: + continue + + if item in ['cache:on', 'cache:off', 'apic:all']: + continue + + if len(item.split(':')) == 1: + options['success'] = False + options['error'] = 'Filtering options should follow key:value format: %s. Check documnetation.' % (item, self.link) + return options + + key = item.split(':')[0] + value = ':'.join(item.split(':')[1:]) + + if len(value) == 0: + options['success'] = False + options['error'] = 'Filtering options should follow key:value format: %s. Check documnetation.' % (item, self.link) + return options + + if ip_helper.is_valid_ipv4_address(value) or ip_helper.is_valid_ipv4_cidr(value): + options['filter'][key] = value + else: + items = value.split('/') + new_items = [] + for item in items: + if item == '*': + new_items.append(item) + continue + + item = '*%s*' % (item.replace('*', '')) + new_items.append(item) + + options['filter'][key] = '/'.join(new_items) + + for key in options['filter']: + if key not in ['ap', 'bd', 'epg', 'mac', 'ip', 'subnet', 'tenant', 'vrf']: + options['success'] = False + options['error'] = 'Unsupported filter key: %s. Check documnetation.' % (key, self.link) + return options + + if key == 'ip': + if not ip_helper.is_valid_ipv4_address(options['filter'][key]): + options['success'] = False + options['error'] = 'Invalid ip value: %s. Check documnetation.' % (options['filter'][key], self.link) + return options + + if key == 'subnet': + if not ip_helper.is_valid_ipv4_cidr(options['filter'][key]): + options['success'] = False + options['error'] = 'Invalid subnet value: %s. Check documnetation.' % (options['filter'][key], self.link) + return options + + # Cache + + for flag in words: + if flag == 'cache:on': + options['cache'] = True + if flag == 'cache:off': + options['cache'] = False + + return options + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: get aci [%s]', command_run_id[4:]) + + try: + message = message.strip().lower() + logger.info('Message: [%s]', message) + if len(message) == 0 or message in ['help', '?', '--help']: + if activity['verb'] == 'cardAction': + return self.help() + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=self.help(), + parent_id=activity['id'] + ) + self.doc(activity) + return + + options = self.parse_command(message, command_run_id) + logger.info(options) + if not options['success']: + logger.info(options['error']) + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=options['error'], + parent_id=activity['id'] + ) + self.doc(activity) + return + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + text='Processing request...', + parent_id=activity['id'] + ) + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + return output + + logger.info(json.dumps(options, indent=4)) + + try: + start_time = int(time.time() * 1000) + + bot_output_handler = bot_output.ApicBotOutput(log_id=command_run_id) + + # Bot should always have cache enabled but can be per-command disabled by user + no_cache = False + if options['cache'] is not None and not options['cache']: + no_cache = True + + apic_handlers = [] + for controller in options['apic']: + apic_handlers.append( + apic.Apic( + controller['ip'], + controller['port'], + controller['username'], + controller['password'], + apic_name=controller['name'], + log_id=command_run_id, + debug=False, + no_cache=no_cache + ) + ) + + output = '' + output_html = '' + output_view_html = {} + + if 'apic' in options['view']: + view_output, view_output_html = bot_output_handler.print_apic_controllers(options['apic']) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['apic'] = view_output_html + + if 'ep' in options['view']: + endpoints = [] + endpoint_filter = [] + for key in ['bd', 'epg', 'mac', 'ip', 'subnet', 'tenant', 'vrf']: + if key in options['filter']: + endpoint_filter.append( + '%s:%s' % ( + key, + options['filter'][key] + ) + ) + + for apic_handler in apic_handlers: + apic_endpoints = apic_handler.get_endpoints( + endpoint_filter + ) + if apic_endpoints is not None: + endpoints = endpoints + apic_endpoints + + view_output, view_output_html = bot_output_handler.print_endpoints(endpoints, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['ep'] = view_output_html + + if 'node' in options['view']: + nodes = [] + for apic_handler in apic_handlers: + apic_nodes = apic_handler.get_nodes() + if apic_nodes is not None: + nodes = nodes + apic_nodes + + view_output, view_output_html = bot_output_handler.print_nodes(nodes, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['node'] = view_output_html + + if 'lacp' in options['view']: + instance = [] + interface = [] + for apic_handler in apic_handlers: + apic_nodes = apic_handler.get_nodes() + if apic_nodes is None: + continue + + for apic_node in apic_nodes: + if apic_node['role'] == 'controller': + continue + + proto_info = apic_handler.get_protocol_lacp( + apic_node['podId'], + apic_node['id'], + instance_info=True, + interface_info=True, + interface_filter=[] + ) + if proto_info is None: + continue + + instance.append(proto_info['instance']) + if 'interfaces' in proto_info and proto_info['interfaces'] is not None: + interface = interface + proto_info['interfaces'] + + view_output, view_output_html = bot_output_handler.print_proto_lacp_instances(instance, title=True) + if view_output_html is not None: + output_view_html['lacp instance'] = view_output_html + + view_output, view_output_html = bot_output_handler.print_proto_lacp_interfaces(interface, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['lacp'] = view_output_html + + view_output, view_output_html = bot_output_handler.print_proto_lacp_interfaces_stats(interface, title=True) + if view_output_html is not None: + output_view_html['lacp stats'] = view_output_html + + if 'lldp' in options['view']: + instance = [] + stats = [] + adjacency = [] + for apic_handler in apic_handlers: + apic_nodes = apic_handler.get_nodes() + if apic_nodes is None: + continue + + for apic_node in apic_nodes: + if apic_node['role'] == 'controller': + continue + + proto_info = apic_handler.get_protocol_lldp( + apic_node['podId'], + apic_node['id'], + adjacency_filter=[], + instance_info=True, + stats_info=True, + adjacency_info=True + ) + if proto_info is None: + continue + + if 'instance' in proto_info and proto_info['instance'] is not None: + instance.append(proto_info['instance']) + + if 'stats' in proto_info and proto_info['stats'] is not None: + stats.append( + proto_info['stats'] + ) + + if 'adjacency' in proto_info and proto_info['adjacency'] is not None: + adjacency = adjacency + proto_info['adjacency'] + + view_output, view_output_html = bot_output_handler.print_proto_lldp_instances(instance, title=True) + if view_output_html is not None: + output_view_html['lldp instance'] = view_output_html + + view_output, view_output_html = bot_output_handler.print_proto_lldp_adjacency(adjacency, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['lldp'] = view_output_html + + view_output, view_output_html = bot_output_handler.print_proto_lldp_interfaces_stats(stats, title=True) + if view_output_html is not None: + output_view_html['lldp stats'] = view_output_html + + logger.info('Commands executed') + + execution_time = int(time.time() * 1000) - start_time + + files = None + filename = self.log_handler.bot_output(output, log_id=command_run_id) + if filename is not None: + files = [filename] + + output = bot_output_handler.my_output.sanitize_bot_output( + output, + output_html, + self.url, + execution_time=execution_time + ) + + if len(output_html) > 0: + self.log_handler.output_html( + bot_output_handler.my_output.wrap_bot_html_output( + output_view_html[options['view'][0]], + command='get aci %s' % (message), + view=output_view_html, + exclude_view=[options['view'][0]] + ) + ) + + for key in output_view_html: + self.log_handler.output_html( + bot_output_handler.my_output.wrap_bot_html_output( + output_view_html[key], + command='get aci %s' % (message), + view=output_view_html, + exclude_view=[key] + ), + filename='%s.html' % (key) + ) + + logger.info('Output prepared') + + except BaseException: + files = None + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=output, + parent_id=activity['id'] + ) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files + ) + + return diff --git a/lib/webex_bot/commands/echo.py b/lib/webex_bot/commands/echo.py new file mode 100644 index 00000000..37ddf683 --- /dev/null +++ b/lib/webex_bot/commands/echo.py @@ -0,0 +1,86 @@ +import logging + +from webexteamssdk.models.cards import Colors, TextBlock, FontWeight, FontSize, Column, AdaptiveCard, ColumnSet, \ + Text, Image, HorizontalAlignment +from webexteamssdk.models.cards.actions import Submit + +from lib.webex_bot.formatting import quote_info +from lib.webex_bot.models.command import Command +from lib.webex_bot.models.response import response_from_adaptive_card + +log = logging.getLogger(__name__) + + +class EchoCommand(Command): + + def __init__(self): + super().__init__( + command_keyword="echo", + help_message="Echo Words Back to You!", + chained_commands=[EchoCallback()]) + + def pre_execute(self, message, attachment_actions, activity): + """ + (optional function). + Reply before running the execute function. + + Useful to indicate the bot is handling it if it is a long running task. + + :return: a string or Response object (or a list of either). Use Response if you want to return another card. + """ + + image = Image(url="https://i.postimg.cc/2jMv5kqt/AS89975.jpg") + text1 = TextBlock("Working on it....", weight=FontWeight.BOLDER, wrap=True, size=FontSize.DEFAULT, + horizontalAlignment=HorizontalAlignment.CENTER, color=Colors.DARK) + text2 = TextBlock("I am busy working on your request. Please continue to look busy while I do your work.", + wrap=True, color=Colors.DARK) + card = AdaptiveCard( + body=[ColumnSet(columns=[Column(items=[image], width=2)]), + ColumnSet(columns=[Column(items=[text1, text2])]), + ]) + + return response_from_adaptive_card(card) + + def execute(self, message, attachment_actions, activity): + """ + If you want to respond to a submit operation on the card, you + would write code here! + + You can return text string here or even another card (Response). + + This sample command function simply echos back the sent message. + + :param message: message with command already stripped + :param attachment_actions: attachment_actions object + :param activity: activity object + + :return: a string or Response object (or a list of either). Use Response if you want to return another card. + """ + + text1 = TextBlock("Echo", weight=FontWeight.BOLDER, size=FontSize.MEDIUM) + text2 = TextBlock("Type in something here and it will be echo'd back to you. How useful is that!", + wrap=True, isSubtle=True) + input_text = Text(id="message_typed", placeholder="Type something here", maxLength=30) + input_column = Column(items=[input_text], width=2) + + submit = Submit(title="Submit", + data={ + "callback_keyword": "echo_callback"}) + + card = AdaptiveCard( + body=[ColumnSet(columns=[Column(items=[text1, text2], width=2)]), + ColumnSet(columns=[input_column]), + ], actions=[submit]) + + return response_from_adaptive_card(card) + + +class EchoCallback(Command): + + def __init__(self): + super().__init__( + card_callback_keyword="echo_callback", + delete_previous_message=True) + + def execute(self, message, attachment_actions, activity): + return quote_info(attachment_actions.inputs.get("message_typed")) diff --git a/lib/webex_bot/commands/help.py b/lib/webex_bot/commands/help.py new file mode 100644 index 00000000..7f055ed3 --- /dev/null +++ b/lib/webex_bot/commands/help.py @@ -0,0 +1,91 @@ +import logging + +from webexteamssdk.models.cards import Colors, TextBlock, FontWeight, FontSize, Column, AdaptiveCard, ColumnSet, \ + ImageSize, Image, Fact +from webexteamssdk.models.cards.actions import Submit + +from lib.webex_bot.models.command import Command, COMMAND_KEYWORD_KEY +from lib.webex_bot.models.response import response_from_adaptive_card + +log = logging.getLogger(__name__) + +HELP_COMMAND_KEYWORD = "help" + + +class HelpCommand(Command): + + def __init__(self, bot_name, bot_help_subtitle, bot_help_image): + self.commands = None + super().__init__( + command_keyword=HELP_COMMAND_KEYWORD, + help_message="Get Help", + card=None) + self.card_callback = self.build_card + self.card_populated = False + self.bot_name = bot_name + self.bot_help_subtitle = bot_help_subtitle + self.bot_help_image = bot_help_image + + def execute(self, message, attachment_actions, activity): + pass + + def build_card(self, message, attachment_actions, activity): + """ + Construct a help message for users. + :param message: message with command already stripped + :param attachment_actions: attachment_actions object + :param activity: activity object + :return: + """ + heading = TextBlock(self.bot_name, weight=FontWeight.BOLDER, wrap=True, size=FontSize.LARGE) + subtitle = TextBlock(self.bot_help_subtitle, wrap=True, size=FontSize.SMALL, color=Colors.LIGHT) + + image = Image( + url=self.bot_help_image, + size=ImageSize.SMALL) + + header_column = Column(items=[heading, subtitle], width=2) + header_image_column = Column( + items=[image], + width=1, + ) + + log.info('build help card activity: %s', activity) + thread_parent_id = None + if 'parent' not in activity: + thread_parent_id = activity['id'] + + actions, hint_texts = self.build_actions_and_hints(thread_parent_id) + + card = AdaptiveCard( + body=[ColumnSet(columns=[header_column, header_image_column]), + # ColumnSet(columns=[Column(items=[subtitle])]), + # FactSet(facts=hint_texts), + ], + actions=actions) + + return response_from_adaptive_card(adaptive_card=card) + + def build_actions_and_hints(self, thread_parent_id): + # help_card = HELP_CARD_CONTENT + help_actions = [] + hint_texts = [] + + if self.commands is not None: + # Sort list by keyword + sorted_commands_list = sorted(self.commands, key=lambda command: ( + command.command_keyword is not None, command.command_keyword)) + for command in sorted_commands_list: + if command.help_message and command.command_keyword != HELP_COMMAND_KEYWORD: + action = Submit( + title=f"{command.help_message}", + data={COMMAND_KEYWORD_KEY: command.command_keyword, + 'thread_parent_id': thread_parent_id}, + ) + help_actions.append(action) + + hint = Fact(title=command.command_keyword, + value=command.help_message) + + hint_texts.append(hint) + return help_actions, hint_texts diff --git a/lib/webex_bot/commands/info.py b/lib/webex_bot/commands/info.py new file mode 100644 index 00000000..874fb180 --- /dev/null +++ b/lib/webex_bot/commands/info.py @@ -0,0 +1,44 @@ +import uuid +import traceback +import logging + +from lib import log_helper +from lib.webex_bot.models.command import Command + +logger = logging.getLogger(__name__) + + +class InfoCommand(Command): + def __init__(self): + super().__init__( + command_keyword="info", + help_message="info", + card=None, + ) + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + logger.info('Command initialized: info [%s]', self.run_id[4:]) + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: get info [%s]', command_run_id[4:]) + + try: + output = 'Welcome to iserver-bot for Vimercate lab

' + output = '%sUseful Links
' % (output) + output = '%s- Lab sharepoint
' % (output) + output = '%s- Lab calendar
' % (output) + output = '%s- Wiring diagrams
' % (output) + output = '%s- Netbox
' % (output) + output = '%s
Notes
' % (output) + output = '%s- only for authorized users
' % (output) + output = '%s- join iserver-bot space to provide feedback and send requests
' % (output) + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + return output diff --git a/lib/webex_bot/commands/nx.py b/lib/webex_bot/commands/nx.py new file mode 100644 index 00000000..27462865 --- /dev/null +++ b/lib/webex_bot/commands/nx.py @@ -0,0 +1,358 @@ +import os +import uuid +import time +import json +import traceback +import logging + +from lib import log_helper +from lib import file_helper +from lib.webex_bot.models.command import Command +from lib.nexus import settings as nexus_settings +from lib.nexus import bot_output +from lib.nexus import nxapi + +logger = logging.getLogger(__name__) + + +class GetNexusCommand(Command): + def __init__(self, my_webex_api_handler, url): + super().__init__( + command_keyword="get nx", + help_message="get nx", + card=None, + ) + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + self.link = 'https://wwwin-github.cisco.com/emear-telcocloud/iserver/blob/master/doc/bot/GetNexus.md' + self.url = url + logger.info('Command initialized: get nexus [%s]', self.run_id[4:]) + + self.my_webex_api_handler = my_webex_api_handler + + def help(self): + output = 'Command syntax: get nx <option> <device>

' + output = '%s- option: dev, cache, lacp, lldp, mac, version
' % (output) + output = '%s- define multiple options or opt:all
' % (output) + output = '%s- define multiple device names or dev:all
' % (output) + output = '%s
Find more examples and documentation here' % (output, self.link) + return output + + def doc(self, activity): + files = [] + files.append( + os.path.join( + os.path.join( + os.path.join( + file_helper.get_main_dir(), + 'doc' + ), + 'bot' + ), + 'GetNexus.md' + ) + ) + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files + ) + + def parse_command(self, message, command_run_id): + nexus_settings_handler = nexus_settings.NexusSettings(log_id=command_run_id) + + options = {} + options['success'] = True + options['error'] = '' + options['view'] = [] + options['device'] = [] + options['cache'] = None + + words = message.split(' ') + if len(words) == 0: + options['success'] = False + options['error'] = 'Cannot parse the command' + return options + + # View + + for view_name in words: + if view_name in ['dev', 'cache', 'lacp', 'lldp', 'mac', 'version', 'opt:all']: + if view_name == 'opt:all': + for item in ['cache', 'lacp', 'lldp', 'mac', 'version']: + if item not in options['view']: + options['view'].append(item) + + if view_name != 'opt:all': + if view_name not in options['view']: + options['view'].append(view_name) + + if len(options['view']) == 1 and 'dev' in options['view']: + options['device'] = nexus_settings_handler.get_nexus_devices() + return options + + # Device + + device_names = [] + for device_name in words: + if device_name not in ['dev', 'cache', 'lacp', 'lldp', 'mac', 'version', 'cache:on', 'cache:off', 'opt:all']: + if device_name in device_names: + continue + + if device_name == 'dev:all': + device_names = nexus_settings_handler.get_nexus_device_names() + options['device'] = nexus_settings_handler.get_nexus_devices() + + if device_name != 'dev:all': + device_names.append(device_name) + device_settings = nexus_settings_handler.get_nexus_device(device_name) + if device_settings is None: + options['success'] = False + options['error'] = 'Unknown device: %s' % (device_name) + return options + + options['device'].append( + device_settings + ) + + if len(device_names) == 0: + options['success'] = False + options['error'] = 'Select at least one device' + return options + + # Cache + + for flag in words: + if flag == 'cache:on': + options['cache'] = True + if flag == 'cache:off': + options['cache'] = False + + return options + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: get nx [%s]', command_run_id[4:]) + + try: + message = message.strip().lower() + if len(message) == 0 or message in ['help', '?', '--help']: + if activity['verb'] == 'cardAction': + return self.help() + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=self.help(), + parent_id=activity['id'] + ) + self.doc(activity) + return + + options = self.parse_command(message, command_run_id) + logger.info(options) + if not options['success']: + logger.info(options['error']) + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=options['error'], + parent_id=activity['id'] + ) + self.doc(activity) + return + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + text='Processing request...', + parent_id=activity['id'] + ) + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + return output + + logger.info(json.dumps(options, indent=4)) + + try: + start_time = int(time.time() * 1000) + + nexus_settings_handler = nexus_settings.NexusSettings(log_id=command_run_id) + bot_output_handler = bot_output.NexusBotOutput(log_id=command_run_id) + + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + if options['cache'] is not None: + cache_enabled = options['cache'] + + device_handlers = [] + for device in options['device']: + device_handler = nxapi.NxApi( + device['ip'], + device['username'], + device['password'], + name=device['name'], + log_id=command_run_id, + debug=False, + cache_enabled=cache_enabled + ) + + device_handlers.append( + device_handler + ) + + device_cache = device_handler.get_cache_commands_timestamp() + device['cache_command'] = device_cache['command'] + device['cache_valid'] = device_cache['valid'] + + output = '' + output_html = '' + output_view_html = {} + + view_output, view_output_html = bot_output_handler.print_devices(options['device'], title=True) + if 'dev' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['dev'] = view_output_html + + if options['cache'] is None or options['cache']: + view_output, view_output_html = bot_output_handler.print_devices_cache(options['device'], title=True) + if 'cache' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['cache'] = view_output_html + + if 'version' in options['view']: + neighbors = [] + for device_handler in device_handlers: + device_neighbors = device_handler.get_versions() + if device_neighbors is not None: + neighbors = neighbors + device_neighbors + + view_output, view_output_html = bot_output_handler.print_versions(neighbors, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['version'] = view_output_html + + if 'lldp' in options['view']: + neighbors = [] + for device_handler in device_handlers: + device_neighbors = device_handler.get_lldps() + if device_neighbors is not None: + neighbors = neighbors + device_neighbors + + view_output, view_output_html = bot_output_handler.print_lldps(neighbors, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['lldp'] = view_output_html + + if 'lacp' in options['view']: + neighbors = [] + for device_handler in device_handlers: + device_neighbors = device_handler.get_lacps() + if device_neighbors is not None: + neighbors = neighbors + device_neighbors + + view_output, view_output_html = bot_output_handler.print_lacps(neighbors, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['lacp'] = view_output_html + + if 'mac' in options['view']: + neighbors = [] + for device_handler in device_handlers: + device_neighbors = device_handler.get_macs() + if device_neighbors is not None: + neighbors = neighbors + device_neighbors + + view_output, view_output_html = bot_output_handler.print_macs(neighbors, title=True) + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['mac'] = view_output_html + + logger.info('Commands executed') + + execution_time = int(time.time() * 1000) - start_time + + files = None + filename = self.log_handler.bot_output(output, log_id=command_run_id) + if filename is not None: + files = [filename] + + output = bot_output_handler.my_output.sanitize_bot_output( + output, + output_html, + self.url, + execution_time=execution_time + ) + + if len(output_html) > 0: + if len(options['view']) == 1: + self.log_handler.output_html( + bot_output_handler.my_output.wrap_bot_html_output( + output_view_html[options['view'][0]], + command='get nx %s' % (message), + view=output_view_html, + exclude_view=[options['view'][0]] + ) + ) + + if len(options['view']) > 1: + self.log_handler.output_html( + bot_output_handler.my_output.wrap_bot_html_output( + output_view_html['dev'], + command='get nx %s' % (message), + view=output_view_html, + exclude_view=['dev'] + ) + ) + + for key in output_view_html: + self.log_handler.output_html( + bot_output_handler.my_output.wrap_bot_html_output( + output_view_html[key], + command='get nx %s' % (message), + view=output_view_html, + exclude_view=[key] + ), + filename='%s.html' % (key) + ) + + logger.info('Output prepared') + + except BaseException: + files = None + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=output, + parent_id=activity['id'] + ) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files + ) + + return diff --git a/lib/webex_bot/commands/server.py b/lib/webex_bot/commands/server.py new file mode 100644 index 00000000..7f6a203a --- /dev/null +++ b/lib/webex_bot/commands/server.py @@ -0,0 +1,1079 @@ +import os +import uuid +import time +import json +import traceback +import logging + +from lib.webex_bot.commands import validations +from lib.webex_bot.models.command import Command +from lib.intersight import compute +from lib.intersight import bot_output +from lib.intersight import validations as intersight_validations +from lib.nexus import settings as nexus_settings +from lib.nexus import nxapi +from lib.aci import settings as aci_settings +from lib.aci import apic +from lib import log_helper +from lib import ip_helper +from lib import filter_helper +from lib import file_helper + +logger = logging.getLogger(__name__) + + +class GetServerCommand(Command): + def __init__(self, my_webex_api_handler, url): + super().__init__( + command_keyword="get server", + help_message="get server", + card=None, + ) + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + self.link = 'https://wwwin-github.cisco.com/emear-telcocloud/iserver/blob/master/doc/bot/GetServer.md' + self.url = url + logger.info('Command initialized: get server [%s]', self.run_id[4:]) + + self.my_webex_api_handler = my_webex_api_handler + + def help(self): + output = 'Get state and inventory information about the Intersight managed servers.

' + output = '%s- get server all
' % (output) + output = '%s- get server name:p2b
' % (output) + output = '%s- get server ip:10.1.1.1
' % (output) + output = '%s- get server serial:WZP666666
' % (output) + output = '%s- get server model:m5sn
' % (output) + output = '%s- get server cpu-vendor:amd view:cpu
' % (output) + output = '%s- get server gpu-slot:gt0 view:gpu
' % (output) + output = '%s- get server pci-model:xxv710 view:pci
' % (output) + output = '%s- get server mac:85ab view:net
' % (output) + output = '%s- get server tag:uc:ocp
' % (output) + output = '%s- get server view:tag
' % (output) + output = '%s
Find more examples and documentation here' % (output, self.link) + return output + + def doc(self, activity): + files = [] + files.append( + os.path.join( + os.path.join( + os.path.join( + file_helper.get_main_dir(), + 'doc' + ), + 'bot' + ), + 'GetServer.md' + ) + ) + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files + ) + + def parse_command(self, message): + options = {} + options['success'] = True + options['error'] = '' + options['include_rack'] = True + options['include_blade'] = True + options['name'] = [] + options['serial'] = [] + options['model'] = [] + options['ip'] = [] + options['tag'] = [] + options['alarm_filter'] = 'any' + options['mode_filter'] = 'any' + options['locator_filter'] = 'any' + options['power_filter'] = 'any' + options['cpu_filter'] = [] + options['gpu_filter'] = [] + options['memory_filter'] = [] + options['pci_filter'] = [] + options['sc_filter'] = [] + options['pd_filter'] = [] + options['vd_filter'] = [] + options['mac_filter'] = [] + options['fan_filter'] = [] + options['psu_filter'] = [] + + words = message.split(' ') + requested_view = [] + if 'all' not in words: + for word in words: + if len(word) == 0: + continue + + if len(word.split(':')) == 1: + options['success'] = False + options['error'] = 'Error

Command options must follow type:value syntax.

Check documentation' % (self.link) + return options + + key = word.split(':')[0] + value = ':'.join(word.split(':')[1:]) + + if key == 'type': + if value not in ['rack', 'blade']: + options['success'] = False + options['error'] = 'Error

Unsupported type value %s.

Check documentation' % (value, self.link) + return options + + if value == 'rack': + options['include_blade'] = False + + if value == 'blade': + options['include_rack'] = False + + if key == 'serial': + options['serial'].append('*%s*' % (value)) + + if key == 'model': + options['model'].append('*%s*' % (value)) + + if key == 'tag': + options['tag'].append(value) + + if key == 'name': + options['name'].append('*%s*' % (value)) + + if key == 'ip': + if not ip_helper.is_valid_ipv4_cidr(value) and not ip_helper.is_valid_ipv4_address(value): + options['success'] = False + options['error'] = 'Error

Provide value ip or subnet value.

Check documentation' % (self.link) + return options + + options['ip'].append(value) + + if key == 'led': + if value.lower() not in ['on', 'off']: + options['success'] = False + options['error'] = 'Error

Unsupported led value %s.

Check documentation' % (value, self.link) + return options + + options['locator_filter'] = value.lower() + + if key == 'power': + if value.lower() not in ['on', 'off']: + options['success'] = False + options['error'] = 'Error

Unsupported power value %s.

Check documentation' % (value, self.link) + return options + + options['power_filter'] = value.lower() + + if key == 'mode': + if value.lower() not in ['imm', 'ucsm']: + options['success'] = False + options['error'] = 'Error

Unsupported mode value %s.

Check documentation' % (value, self.link) + return options + + options['mode_filter'] = value.lower() + + if key == 'alarm': + if value.lower() not in ['info', 'warn', 'crit']: + options['success'] = False + options['error'] = 'Error

Unsupported alarm value %s.

Check documentation' % (value, self.link) + return options + + options['alarm_filter'] = value.lower() + + if key.startswith('cpu-'): + options['cpu_filter'].append(word[4:]) + + if key.startswith('gpu-'): + options['gpu_filter'].append(word[4:]) + + if key.startswith('mem-'): + options['memory_filter'].append(word[4:]) + + if key.startswith('pci-'): + options['pci_filter'].append(word[4:]) + + if key.startswith('sc-'): + options['sc_filter'].append(word[3:]) + + if key.startswith('pd-'): + options['pd_filter'].append(word[3:]) + + if key.startswith('vd-'): + options['vd_filter'].append(word[3:]) + + if key == 'mac': + options['mac_filter'].append(value) + + if key.startswith('fan-'): + options['fan_filter'].append(word[4:]) + + if key.startswith('psu-'): + options['psu_filter'].append(word[4:]) + + if key == 'view': + requested_view.append(value) + + if len(requested_view) == 0: + options['view'] = ['list'] + else: + options['view'] = validations.validate_view( + requested_view, + 'list|adv|alarm|board|boot|connector|contract|cpu|green|fan|fw|gpu|hcl|hw|state|kvm|lic|mem|net|pci|power|profile|psu|sc|pd|vd|storage|thermal|sw|tpm|tag', + 'list', + [ + 'hw:board,cpu,fan,gpu,mem,pci,net,psu,storage,tpm', + 'green:power,thermal', + 'sw:fw,boot,kvm', + 'state:adv,alarm,connector,contract,hcl,lic,profile,workflow' + ] + ) + + if options['view'] is None: + options['success'] = False + options['error'] = 'Error

Unsupported view.

Check documentation' % (self.link) + return options + + settings = {} + settings['alarm'] = 'alarm' in options['view'] or options['alarm_filter'] != 'any' + settings['advisory'] = 'adv' in options['view'] + settings['board'] = 'board' in options['view'] or 'tpm' in options['view'] + settings['boot'] = 'boot' in options['view'] + settings['connector'] = 'connector' in options['view'] or 'list' in options['view'] + settings['contract'] = 'contract' in options['view'] + settings['cpu'] = 'cpu' in options['view'] or len(options['cpu_filter']) > 0 + settings['fan'] = 'fan' in options['view'] or 'fanm' in options['view'] or len(options['fan_filter']) + settings['fw'] = 'fw' in options['view'] + settings['gpu'] = 'gpu' in options['view'] or len(options['gpu_filter']) + settings['hcl'] = 'hcl' in options['view'] + settings['inventory'] = 'inventory' in options['view'] + settings['locator'] = 'list' in options['view'] or options['locator_filter'] != 'any' + settings['memory'] = 'mem' in options['view'] or len(options['memory_filter']) > 0 + settings['net'] = 'net' in options['view'] or len(options['mac_filter']) > 0 + settings['pci'] = 'pci' in options['view'] or 'gpu' in options['view'] or len(options['pci_filter']) > 0 or len(options['gpu_filter']) > 0 + settings['power'] = 'power' in options['view'] + settings['profile'] = 'profile' in options['view'] + settings['psu'] = 'psu' in options['view'] or len(options['psu_filter']) > 0 + settings['state'] = 'list' in options['view'] or options['locator_filter'] != 'any' or options['power_filter'] != 'any' + settings['storage'] = 'storage' in options['view'] or 'sc' in options['view'] or 'pd' in options['view'] or 'vd' in options['view'] or len(options['sc_filter']) > 0 or len(options['pd_filter']) > 0 or len(options['vd_filter']) > 0 + settings['thermal'] = 'thermal' in options['view'] + settings['tpm'] = 'tpm' in options['view'] + + options['settings'] = settings + + match_rules = {} + match_rules['locator'] = options['locator_filter'] + match_rules['power'] = options['power_filter'] + match_rules['alarms'] = options['alarm_filter'] + match_rules['ucsm'] = False + if options['mode_filter'] == 'ucsm': + match_rules['ucsm'] = True + match_rules['imm'] = False + if options['mode_filter'] == 'imm': + match_rules['imm'] = True + match_rules['disconnected'] = False + + match_rules['cpu'] = intersight_validations.bot_cpu_filter(options['cpu_filter']) + if match_rules['cpu'] is None: + options['success'] = False + options['error'] = 'unsupported cpu filtering options' + return options + + match_rules['gpu'] = intersight_validations.bot_gpu_filter(options['gpu_filter']) + if match_rules['gpu'] is None: + options['success'] = False + options['error'] = 'unsupported gpu filtering options' + return options + + match_rules['memory'] = intersight_validations.bot_memory_filter(options['memory_filter']) + if match_rules['memory'] is None: + options['success'] = False + options['error'] = 'unsupported memory filtering options' + return options + + match_rules['pci'] = intersight_validations.bot_pci_filter(options['pci_filter']) + if match_rules['pci'] is None: + options['success'] = False + options['error'] = 'unsupported pci filtering options' + return options + + match_rules['mac'] = options['mac_filter'] + + match_rules['sc'] = intersight_validations.bot_sc_filter(options['sc_filter']) + if match_rules['sc'] is None: + options['success'] = False + options['error'] = 'unsupported sc filtering options' + return options + + match_rules['pd'] = intersight_validations.bot_pd_filter(options['pd_filter']) + if match_rules['pd'] is None: + options['success'] = False + options['error'] = 'unsupported pd filtering options' + return options + + match_rules['vd'] = intersight_validations.bot_vd_filter(options['vd_filter']) + if match_rules['vd'] is None: + options['success'] = False + options['error'] = 'unsupported vd filtering options' + return options + + match_rules['fan'] = intersight_validations.bot_fan_filter(options['fan_filter']) + if match_rules['fan'] is None: + options['success'] = False + options['error'] = 'unsupported fan filtering options' + return options + + match_rules['psu'] = intersight_validations.bot_psu_filter(options['psu_filter']) + if match_rules['psu'] is None: + options['success'] = False + options['error'] = 'unsupported psu filtering options' + return options + + match_rules['ancestor'] = [] + + options['match_rules'] = match_rules + + return options + + def add_fabric_info(self, servers_info, command_run_id): + for server_info in servers_info: + for cimc_info in server_info['CimcInfo']: + cimc_info['FabricDomain'] = '' + cimc_info['FabricDevice'] = '' + cimc_info['FabricSource'] = '' + cimc_info['FabricInterface'] = '' + + for ext_eth_info in server_info['ExtEthInfo']: + ext_eth_info['FabricDomain'] = '' + ext_eth_info['FabricDevice'] = '' + ext_eth_info['FabricSource'] = '' + ext_eth_info['FabricInterface'] = '' + + for host_eth_info in server_info['HostEthInfo']: + host_eth_info['FabricDomain'] = '' + host_eth_info['FabricDevice'] = '' + host_eth_info['FabricSource'] = '' + host_eth_info['FabricInterface'] = '' + + servers_info = self.add_aci_info( + servers_info, + command_run_id + ) + + servers_info = self.add_nexus_info( + servers_info, + command_run_id + ) + + return servers_info + + def add_aci_info(self, servers_info, command_run_id): + aci_settings_handler = aci_settings.ApicSettings(log_id=command_run_id) + controllers = aci_settings_handler.get_apic_controllers() + if controllers is not None: + for controller in controllers: + if not aci_settings_handler.is_cache_enabled(controller['name']): + continue + + apic_handler = apic.Apic( + controller['ip'], + controller['port'], + controller['username'], + controller['password'], + apic_name=controller['name'], + log_id=command_run_id, + debug=False, + no_cache=False + ) + + apic_nodes = apic_handler.get_nodes() + if apic_nodes is None: + continue + + for apic_node in apic_nodes: + if apic_node['role'] == 'controller': + continue + + proto_info = apic_handler.get_protocol_lacp( + apic_node['podId'], + apic_node['id'], + instance_info=True, + interface_info=True, + interface_filter=[] + ) + if proto_info is None: + continue + + if 'interfaces' in proto_info and proto_info['interfaces'] is not None: + for interface_info in proto_info['interfaces']: + for lacp_interface_info in interface_info['lacp']: + for server_info in servers_info: + for ext_eth_info in server_info['ExtEthInfo']: + if filter_helper.match_mac(lacp_interface_info['adjacency']['sysId'], ext_eth_info['MacAddress']): + ext_eth_info['FabricDomain'] = 'ACI' + ext_eth_info['FabricDevice'] = apic_node['name'] + ext_eth_info['FabricSource'] = 'LACP' + ext_eth_info['FabricInterface'] = interface_info['id'] + + for host_eth_info in server_info['HostEthInfo']: + if filter_helper.match_mac(lacp_interface_info['adjacency']['sysId'], host_eth_info['MacAddress']): + host_eth_info['FabricDomain'] = 'ACI' + host_eth_info['FabricDevice'] = apic_node['name'] + host_eth_info['FabricSource'] = 'LACP' + host_eth_info['FabricInterface'] = interface_info['id'] + + for cimc_info in server_info['CimcInfo']: + if filter_helper.match_mac(lacp_interface_info['adjacency']['sysId'], cimc_info['MacAddress']): + cimc_info['FabricDomain'] = 'ACI' + cimc_info['FabricDevice'] = apic_node['name'] + cimc_info['FabricSource'] = 'LACP' + cimc_info['FabricInterface'] = interface_info['id'] + + proto_info = apic_handler.get_protocol_lldp( + apic_node['podId'], + apic_node['id'], + adjacency_filter=[], + instance_info=True, + stats_info=True, + adjacency_info=True + ) + if proto_info is None: + continue + + if 'adjacency' in proto_info and proto_info['adjacency'] is not None: + for adjacency_info in proto_info['adjacency']: + for server_info in servers_info: + for ext_eth_info in server_info['ExtEthInfo']: + if filter_helper.match_mac(adjacency_info['mac'], ext_eth_info['MacAddress']): + ext_eth_info['FabricDomain'] = 'ACI' + ext_eth_info['FabricDevice'] = apic_node['name'] + ext_eth_info['FabricSource'] = 'LLDP' + ext_eth_info['FabricInterface'] = adjacency_info['interface_id'] + + for host_eth_info in server_info['HostEthInfo']: + if filter_helper.match_mac(adjacency_info['mac'], host_eth_info['MacAddress']): + host_eth_info['FabricDomain'] = 'ACI' + host_eth_info['FabricDevice'] = apic_node['name'] + host_eth_info['FabricSource'] = 'LLDP' + host_eth_info['FabricInterface'] = adjacency_info['interface_id'] + + for cimc_info in server_info['HostEthInfo']: + if filter_helper.match_mac(adjacency_info['mac'], cimc_info['MacAddress']): + cimc_info['FabricDomain'] = 'ACI' + cimc_info['FabricDevice'] = apic_node['name'] + cimc_info['FabricSource'] = 'LLDP' + cimc_info['FabricInterface'] = adjacency_info['interface_id'] + + return servers_info + + def add_nexus_info(self, servers_info, command_run_id): + nexus_settings_handler = nexus_settings.NexusSettings(log_id=command_run_id) + if nexus_settings_handler.is_nexus_cache_enabled(): + devices = nexus_settings_handler.get_nexus_devices() + if devices is not None: + for device in devices: + device_handler = nxapi.NxApi( + device['ip'], + device['username'], + device['password'], + name=device['name'], + log_id=command_run_id, + debug=False, + cache_enabled=True + ) + + device_mac_addresses = device_handler.get_macs() + if device_mac_addresses is not None: + for device_mac_address in device_mac_addresses: + for server_info in servers_info: + for ext_eth_info in server_info['ExtEthInfo']: + if filter_helper.match_mac(ext_eth_info['MacAddress'], device_mac_address['mac_addr']): + ext_eth_info['FabricDomain'] = 'Nexus' + ext_eth_info['FabricDevice'] = device_mac_address['nexus_name'] + ext_eth_info['FabricSource'] = 'MAC' + ext_eth_info['FabricInterface'] = device_mac_address['port'] + + for host_eth_info in server_info['HostEthInfo']: + if filter_helper.match_mac(host_eth_info['MacAddress'], device_mac_address['mac_addr']): + host_eth_info['FabricDomain'] = 'Nexus' + host_eth_info['FabricDevice'] = device_mac_address['nexus_name'] + host_eth_info['FabricSource'] = 'MAC' + host_eth_info['FabricInterface'] = device_mac_address['port'] + + for cimc_info in server_info['CimcInfo']: + if filter_helper.match_mac(cimc_info['MacAddress'], device_mac_address['mac_addr']): + cimc_info['FabricDomain'] = 'Nexus' + cimc_info['FabricDevice'] = device_mac_address['nexus_name'] + cimc_info['FabricSource'] = 'MAC' + cimc_info['FabricInterface'] = device_mac_address['port'] + + device_neighbors = device_handler.get_lacps() + if device_neighbors is not None: + for device_neighbor in device_neighbors: + for port_info in device_neighbor['port']: + if ip_helper.is_mac_address(port_info['partner_mac']): + for server_info in servers_info: + for ext_eth_info in server_info['ExtEthInfo']: + if filter_helper.match_mac(ext_eth_info['MacAddress'], port_info['partner_mac']): + ext_eth_info['FabricDomain'] = 'Nexus' + ext_eth_info['FabricDevice'] = device_neighbor['nexus_name'] + ext_eth_info['FabricSource'] = 'LACP' + ext_eth_info['FabricInterface'] = port_info['port'] + + for host_eth_info in server_info['HostEthInfo']: + if filter_helper.match_mac(host_eth_info['MacAddress'], port_info['partner_mac']): + host_eth_info['FabricDomain'] = 'Nexus' + host_eth_info['FabricDevice'] = device_neighbor['nexus_name'] + host_eth_info['FabricSource'] = 'LACP' + host_eth_info['FabricInterface'] = port_info['port'] + + for cimc_info in server_info['CimcInfo']: + if filter_helper.match_mac(cimc_info['MacAddress'], port_info['partner_mac']): + cimc_info['FabricDomain'] = 'Nexus' + cimc_info['FabricDevice'] = device_neighbor['nexus_name'] + cimc_info['FabricSource'] = 'LACP' + cimc_info['FabricInterface'] = port_info['port'] + + device_neighbors = device_handler.get_lldps() + if device_neighbors is not None: + for device_neighbor in device_neighbors: + if ip_helper.is_mac_address(device_neighbor['port_id']): + for server_info in servers_info: + for ext_eth_info in server_info['ExtEthInfo']: + if filter_helper.match_mac(ext_eth_info['MacAddress'], device_neighbor['port_id']): + ext_eth_info['FabricDomain'] = 'Nexus' + ext_eth_info['FabricDevice'] = device_neighbor['nexus_name'] + ext_eth_info['FabricSource'] = 'LLDP' + ext_eth_info['FabricInterface'] = device_neighbor['l_port_id'] + + for host_eth_info in server_info['HostEthInfo']: + if filter_helper.match_mac(host_eth_info['MacAddress'], port_info['partner_mac']): + host_eth_info['FabricDomain'] = 'Nexus' + host_eth_info['FabricDevice'] = device_neighbor['nexus_name'] + host_eth_info['FabricSource'] = 'LLDP' + host_eth_info['FabricInterface'] = device_neighbor['l_port_id'] + + for cimc_info in server_info['CimcInfo']: + if filter_helper.match_mac(cimc_info['MacAddress'], port_info['partner_mac']): + cimc_info['FabricDomain'] = 'Nexus' + cimc_info['FabricDevice'] = device_neighbor['nexus_name'] + cimc_info['FabricSource'] = 'LLDP' + cimc_info['FabricInterface'] = device_neighbor['l_port_id'] + + return servers_info + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: get server [%s]', command_run_id[4:]) + + try: + message = message.strip().lower() + if len(message) == 0 or message in ['help', '?', '--help']: + if activity['verb'] == 'cardAction': + return self.help() + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=self.help(), + parent_id=activity['id'] + ) + self.doc(activity) + return + + options = self.parse_command(message) + if not options['success']: + logger.info(options['error']) + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=options['error'], + parent_id=activity['id'] + ) + self.doc(activity) + return + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + text='Processing request...', + parent_id=activity['id'] + ) + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + return output + + logger.info(json.dumps(options, indent=4)) + + try: + start_time = int(time.time() * 1000) + + # Hardcode + cache_ttl = 1800 + mo_cache_ttl = 180 + + compute_handler = compute.Compute('isctl', log_id=command_run_id) + compute_output_handler = bot_output.ComputeBotOutput(log_id=command_run_id) + + mo_match_rules = compute_handler.get_mo_match_rules( + ip_filter=options['ip'], + name_filter=options['name'], + serial_filter=options['serial'], + model_filter=options['model'], + tag_filter=options['tag'] + ) + logger.info(mo_match_rules) + + rack_expand = [] + blade_expand = [] + + if options['settings']['pci']: + rack_expand.append('PciDevices') + blade_expand.append('PciDevices') + if options['settings']['psu']: + rack_expand.append('Psus') + if options['settings']['fan']: + rack_expand.append('Fanmodules') + if options['settings']['locator']: + rack_expand.append('LocatorLed') + blade_expand.append('LocatorLed') + if options['settings']['state']: + rack_expand.append('RegisteredDevice') + blade_expand.append('RegisteredDevice') + + # Bot is supported with crontab task that runs every minute + # cache_ttl of 180 should be good compromise between accuracy and efficiency + + servers_mo = compute_handler.get_mo( + match_rules=mo_match_rules, + include_rack=options['include_rack'], + rack_expand=rack_expand, + include_blade=options['include_blade'], + blade_expand=blade_expand, + cache_ttl=mo_cache_ttl + ) + logger.info('Selected %s servers', len(servers_mo)) + + compute_handler.set_cache( + servers_mo, + options['settings'], + cache_ttl, + ctx=None + ) + + logger.info('Cache populated') + + servers_info = compute_handler.get_info( + servers_mo, + options['settings'], + options['match_rules'], + cache_ttl, + prepare_cache=False, + bar_handler=None + ) + + logger.info('Servers info collected') + + output = '' + output_file = '' + output_html = '' + output_view_html = {} + output_csvs = [] + + if servers_info is None or len(servers_info) == 0: + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + text='No servers found', + parent_id=activity['id'] + ) + return + + view_output, view_output_html = compute_output_handler.print_summary_table(servers_info, title=True) + output_csvs.append('Server') + if 'list' in options['view']: + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if view_output_html is not None: + output_view_html['list'] = view_output_html + + # hw + + if 'board' in options['view'] or options['settings']['board']: + view_output, view_output_html = compute_output_handler.print_board(servers_info, title=True) + output_csvs.append('Board') + output_file = output_file + view_output + if 'board' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['board']: + if view_output_html is not None: + output_view_html['board'] = view_output_html + + if 'cpu' in options['view'] or options['settings']['cpu']: + view_output, view_output_html = compute_output_handler.print_cpu(servers_info, title=True) + output_csvs.append('CPU') + output_file = output_file + view_output + if 'cpu' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['cpu']: + if view_output_html is not None: + output_view_html['cpu'] = view_output_html + + if 'gpu' in options['view'] or options['settings']['gpu']: + view_output, view_output_html = compute_output_handler.print_gpu(servers_info, title=True) + output_csvs.append('GPU') + output_file = output_file + view_output + if 'gpu' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['gpu']: + if view_output_html is not None: + output_view_html['gpu'] = view_output_html + + if 'mem' in options['view'] or options['settings']['memory']: + view_output, view_output_html = compute_output_handler.print_memory(servers_info, title=True) + output_csvs.append('Memory') + output_file = output_file + view_output + if 'mem' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['memory']: + if view_output_html is not None: + output_view_html['mem'] = view_output_html + + if 'storage' in options['view'] or 'sc' in options['view'] or options['settings']['storage']: + view_output, view_output_html = compute_output_handler.print_storage_controllers(servers_info, title=True) + output_csvs.append('StorageController') + output_file = output_file + view_output + output_file = output_file + view_output + if 'storage' in options['view'] or 'sc' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['storage']: + if view_output_html is not None: + output_view_html['storage controller'] = view_output_html + + if 'storage' in options['view'] or 'pd' in options['view'] or options['settings']['storage']: + state_view_output, state_view_output_html = compute_output_handler.print_physical_disks_state(servers_info, title=True) + output_csvs.append('PhysicalDisk') + output_file = output_file + state_view_output + inv_view_output, inv_view_output_html = compute_output_handler.print_physical_disks_inventory(servers_info, title=True) + + if 'storage' in options['view'] or 'pd' in options['view']: + output = output + state_view_output + if state_view_output_html is not None: + output_html = output_html + state_view_output_html + + output = output + inv_view_output + if inv_view_output_html is not None: + output_html = output_html + inv_view_output_html + + if options['settings']['storage']: + output_view_html['physical disk'] = '' + if state_view_output_html is not None: + output_view_html['physical disk'] = output_view_html['physical disk'] + state_view_output_html + + if inv_view_output_html is not None: + output_view_html['physical disk'] = output_view_html['physical disk'] + inv_view_output_html + + if 'storage' in options['view'] or 'vd' in options['view'] or options['settings']['storage']: + view_output, view_output_html = compute_output_handler.print_virtual_drives(servers_info, title=True) + output_csvs.append('VirtualDrive') + output_file = output_file + view_output + if 'storage' in options['view'] or 'vd' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['storage']: + if view_output_html is not None: + output_view_html['virtual drive'] = view_output_html + + if 'net' in options['view'] or options['settings']['net']: + servers_info = self.add_fabric_info(servers_info, command_run_id) + + cimc_view_output, cimc_view_output_html = compute_output_handler.print_cimc(servers_info, title=True) + output_csvs.append('IMC') + output_file = output_file + cimc_view_output + adapter_view_output, adapter_view_output_html = compute_output_handler.print_adapters(servers_info, title=True) + output_csvs.append('NetworkAdapter') + output_file = output_file + adapter_view_output + ext_view_output, ext_view_output_html = compute_output_handler.print_ext_eth(servers_info, title=True) + output_csvs.append('MLOM') + output_file = output_file + ext_view_output + eth_view_output, eth_view_output_html = compute_output_handler.print_host_eth(servers_info, title=True) + output_csvs.append('HostEthernet') + output_file = output_file + eth_view_output + fc_view_output, fc_view_output_html = compute_output_handler.print_host_fc(servers_info, title=True) + output_csvs.append('HostFc') + output_file = output_file + fc_view_output + + if 'net' in options['view']: + output = output + cimc_view_output + if cimc_view_output_html is not None: + output_html = output_html + cimc_view_output_html + + output = output + adapter_view_output + if adapter_view_output_html is not None: + output_html = output_html + adapter_view_output_html + + output = output + ext_view_output + if ext_view_output_html is not None: + output_html = output_html + ext_view_output_html + + output = output + eth_view_output + if eth_view_output_html is not None: + output_html = output_html + eth_view_output_html + + output = output + fc_view_output + if fc_view_output_html is not None: + output_html = output_html + fc_view_output_html + + if options['settings']['net']: + if cimc_view_output_html is not None: + output_view_html['cimc'] = cimc_view_output_html + + if adapter_view_output_html is not None: + output_view_html['net adapter'] = adapter_view_output_html + + if ext_view_output_html is not None: + output_view_html['mlom'] = ext_view_output_html + + if eth_view_output_html is not None: + output_view_html['host eth'] = eth_view_output_html + + if fc_view_output_html is not None: + output_view_html['host fc'] = fc_view_output_html + + if 'pci' in options['view'] or options['settings']['pci']: + view_output, view_output_html = compute_output_handler.print_pci(servers_info, title=True) + output_csvs.append('PCI') + output_file = output_file + view_output + if 'pci' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['pci']: + if view_output_html is not None: + output_view_html['pci'] = view_output_html + + if 'fan' in options['view'] or options['settings']['fan']: + view_output, view_output_html = compute_output_handler.print_fan(servers_info, title=True) + output_csvs.append('FanModule') + output_csvs.append('Fan') + output_file = output_file + view_output + if 'fan' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['fan']: + if view_output_html is not None: + output_view_html['fan'] = view_output_html + + if 'psu' in options['view'] or options['settings']['psu']: + view_output, view_output_html = compute_output_handler.print_psu(servers_info, title=True) + output_csvs.append('PSU') + output_file = output_file + view_output + if 'psu' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['psu']: + if view_output_html is not None: + output_view_html['psu'] = view_output_html + + if 'tpm' in options['view'] or options['settings']['tpm']: + view_output, view_output_html = compute_output_handler.print_tpm(servers_info, title=True) + output_csvs.append('TPM') + output_file = output_file + view_output + if 'tpm' in options['view']: + output = output + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if options['settings']['tpm']: + if view_output_html is not None: + output_view_html['tpm'] = view_output_html + + # sw:fw,boot,kvm + + if 'fw' in options['view']: + view_output, view_output_html = compute_output_handler.print_firmware(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'boot' in options['view']: + view_output, view_output_html = compute_output_handler.print_boot(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'kvm' in options['view']: + view_output, view_output_html = compute_output_handler.print_kvm(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + # state:adv,alarm,connector,contract,hcl,lic,profile,workflow + + if 'adv' in options['view']: + view_output, view_output_html = compute_output_handler.print_advisory(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'alarm' in options['view']: + view_output, view_output_html = compute_output_handler.print_server_alarm(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'connector' in options['view']: + view_output, view_output_html = compute_output_handler.print_connector(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'contract' in options['view']: + view_output, view_output_html = compute_output_handler.print_contract(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'hcl' in options['view']: + view_output, view_output_html = compute_output_handler.print_hcl_summary(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + view_output, view_output_html = compute_output_handler.print_hcl_hardware(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + view_output, view_output_html = compute_output_handler.print_hcl_software(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + view_output, view_output_html = compute_output_handler.print_hcl_component(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'lic' in options['view']: + view_output, view_output_html = compute_output_handler.print_license(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'profile' in options['view']: + view_output, view_output_html = compute_output_handler.print_profile(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + if 'tag' in options['view']: + view_output, view_output_html = compute_output_handler.print_tag(servers_info, title=True) + output = output + view_output + output_file = output_file + view_output + if view_output_html is not None: + output_html = output_html + view_output_html + + logger.info('Commands executed') + + execution_time = int(time.time() * 1000) - start_time + + files = None + filename = self.log_handler.bot_output(output_file, log_id=command_run_id) + if filename is not None: + files = [filename] + + files_xls = None + filename = self.log_handler.bot_xls(output_csvs, log_id=command_run_id) + if filename is not None: + files_xls = [filename] + + output = compute_output_handler.my_output.sanitize_bot_output( + output, + output_html, + self.url, + execution_time=execution_time + ) + + if len(output_html) > 0: + self.log_handler.output_html( + compute_output_handler.my_output.wrap_bot_html_output( + output_view_html['list'], + command='get server %s' % (message), + view=output_view_html, + exclude_view=['list'] + ) + ) + + for key in output_view_html: + self.log_handler.output_html( + compute_output_handler.my_output.wrap_bot_html_output( + output_view_html[key], + command='get server %s [view:%s]' % (message, key), + view=output_view_html, + exclude_view=[key] + ), + filename='%s.html' % (key) + ) + + logger.info('Output prepared') + + except BaseException: + files = None + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + markdown=output, + parent_id=activity['id'] + ) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files + ) + + self.my_webex_api_handler.create_message( + room_id=activity['target']['globalId'], + parent_id=activity['id'], + files=files_xls + ) + + return diff --git a/lib/webex_bot/commands/settings.py b/lib/webex_bot/commands/settings.py new file mode 100644 index 00000000..316e4ee2 --- /dev/null +++ b/lib/webex_bot/commands/settings.py @@ -0,0 +1,135 @@ +import uuid +import traceback +import logging + +from lib import log_helper +from lib import output_helper +from lib import iaccount_helper +from lib.intersight import settings as intersight_settings +from lib.nexus import settings as nexus_settings +from lib.nexus import bot_output as nexus_bot_output +from lib.aci import settings as aci_settings +from lib.aci import bot_output as aci_bot_output +from lib.webex_bot.models.command import Command + +logger = logging.getLogger(__name__) + + +class SettingsCommand(Command): + def __init__(self, url): + super().__init__( + command_keyword="settings", + help_message="settings", + card=None, + ) + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + self.url = url + logger.info('Command initialized: settings [%s]', self.run_id[4:]) + + def print_intersight_settings(self, command_run_id): + my_output = output_helper.OutputHelper( + log_id=command_run_id + ) + + output = '' + output_html = '' + + intersight_settings_handler = intersight_settings.IntersightSettings(log_id=command_run_id) + settings = intersight_settings_handler.get_intersight_settings() + logger.info(settings) + + iaccount_handler = iaccount_helper.IntersightAccount() + accounts = iaccount_handler.get_iaccounts() + + if len(accounts) == 0: + return output, output_html + + for account in accounts: + account['cache_enabled'] = settings['CacheEnabled'] + account['ttl'] = settings['CacheTtl'] + + my_output.clear_output() + + my_output.my_print( + 'Intersight', + underline=True, + before_newline=True + ) + + order = [ + 'name', + 'account', + 'role', + 'cache_enabled', + 'ttl' + ] + + headers = [ + 'Name', + 'Account', + 'Role', + 'Cache', + 'TTL' + ] + + my_output.my_table( + accounts, + order=order, + headers=headers, + allow_order_subkeys=True, + table=True, + stream='output' + ) + + output = my_output.get_output() + + return output, None + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: get settings [%s]', command_run_id[4:]) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=command_run_id) + nexus_bot_output_handler = nexus_bot_output.NexusBotOutput(log_id=command_run_id) + + aci_settings_handler = aci_settings.ApicSettings(log_id=command_run_id) + aci_bot_output_handler = aci_bot_output.ApicBotOutput(log_id=command_run_id) + + output = '' + output_html = '' + + view_output, view_output_html = self.print_intersight_settings( + command_run_id + ) + output = output + view_output + + view_output, view_output_html = aci_bot_output_handler.print_apic_controllers( + aci_settings_handler.get_apic_controllers(), + title=True + ) + output = output + view_output + + view_output, view_output_html = nexus_bot_output_handler.print_devices( + nexus_settings_handler.get_nexus_devices(), + title=True + ) + output = output + view_output + + output = aci_bot_output_handler.my_output.sanitize_bot_output( + output, + output_html, + self.url + ) + + logger.info('Output prepared') + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + return output diff --git a/lib/webex_bot/commands/template.py b/lib/webex_bot/commands/template.py new file mode 100644 index 00000000..1cf22685 --- /dev/null +++ b/lib/webex_bot/commands/template.py @@ -0,0 +1,56 @@ +import uuid +import traceback +import logging + +from lib.webex_bot.models.command import Command +from lib import log_helper + +logger = logging.getLogger(__name__) + + +class GetXxxCommand(Command): + def __init__(self): + super().__init__( + command_keyword="get xxx", + help_message="Get xxx state", + card=None, + ) + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + self.link = 'https://wwwin-github.cisco.com/emear-telcocloud/iserver' + logger.info('Command initialized: get xxx [%s]', self.run_id[4:]) + + def help(self): + output = 'Get state of xxx' + return output + + def parse(self, message): + parse = {} + parse['success'] = True + parse['error'] = '' + + return parse + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: get nx [%s]', command_run_id[4:]) + + if message.strip().lower() in ['help', '?', '--help']: + return self.help() + + parsed = self.parse(message) + if not parsed['success']: + logger.info(parsed['error']) + return parsed['error'] + + try: + output = 'command response' + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + return output diff --git a/lib/webex_bot/commands/validations.py b/lib/webex_bot/commands/validations.py new file mode 100644 index 00000000..1c381e51 --- /dev/null +++ b/lib/webex_bot/commands/validations.py @@ -0,0 +1,44 @@ +def validate_view(user_input, all_views, default, resolve): + views = [] + + if len(user_input) == 0: + view = [default] + return view + + user_views = [] + for item in user_input: + user_views = user_views + item.split(',') + + defined_views = all_views.split('|') + resolve_views = {} + for item in resolve: + (resolve_name, resolve_view) = item.split(':') + resolve_views[resolve_name] = resolve_view + + for user_view in user_views: + if user_view not in defined_views: + return None + + if user_view == 'all': + for defined_view in defined_views: + if defined_view not in ['all', 'verbose'] and defined_view not in views and defined_view not in resolve_views: + views.append( + defined_view + ) + continue + + if user_view in resolve_views: + for resolve_view in resolve_views[user_view].split(','): + if resolve_view not in views: + views.append( + resolve_view + ) + + continue + + if user_view not in views: + views.append( + user_view + ) + + return views \ No newline at end of file diff --git a/lib/webex_bot/commands/whoami.py b/lib/webex_bot/commands/whoami.py new file mode 100644 index 00000000..d529c594 --- /dev/null +++ b/lib/webex_bot/commands/whoami.py @@ -0,0 +1,47 @@ +import uuid +import traceback +import logging + +from lib import log_helper +from lib.webex_bot.models.command import Command + +logger = logging.getLogger(__name__) + + +class WhoamiCommand(Command): + def __init__(self, approved_users): + super().__init__( + command_keyword="whoami", + help_message="whoami", + card=None, + ) + self.approved_users = approved_users + self.run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(self.run_id) + self.log_handler.initialize() + logger.info('Command initialized: whoami [%s]', self.run_id[4:]) + + def execute(self, message, attachment_actions, activity): + command_run_id = 'bot.%s' % (str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1]) + self.log_handler = log_helper.Log(command_run_id) + self.log_handler.initialize() + + logger.info('Command execution: whoami [%s]', command_run_id[4:]) + + try: + output = '' + + output = '%sWebex
' % (output) + output = '%s- id: %s
' % (output, activity['actor']['id']) + output = '%s- name: %s
' % (output, activity['actor']['displayName']) + output = '%s- email: %s
' % (output, activity['actor']['emailAddress']) + + for user in self.approved_users: + if user['username'] == activity['actor']['emailAddress']: + output = '%s
Bot
' % (output) + output = '%s- role: %s
' % (output, user['role']) + + except BaseException: + output = 'Command execution failed [%s]\n\n%s' % (command_run_id, traceback.format_exc()) + + return output diff --git a/lib/webex_bot/exceptions.py b/lib/webex_bot/exceptions.py new file mode 100644 index 00000000..8656b8e1 --- /dev/null +++ b/lib/webex_bot/exceptions.py @@ -0,0 +1,16 @@ +class BotException(Exception): + """Exception which we want to reply to the user about in the bot.""" + + def __init__(self, debug_message, reply_message, reply_one_to_one=False): + """ + Generic exception for handling issues which require a custom message back to the user. + :param debug_message: Message to log + :param reply_message: Message to send back to the bot user + :param reply_one_to_one: Some replies should be private. e.g. auth info. If you + don't want to the reply to be to a space, set this to True. + """ + self.debug_message = debug_message + self.reply_message = reply_message + self.reply_one_to_one = reply_one_to_one + + pass diff --git a/lib/webex_bot/formatting.py b/lib/webex_bot/formatting.py new file mode 100644 index 00000000..b0ad5131 --- /dev/null +++ b/lib/webex_bot/formatting.py @@ -0,0 +1,18 @@ +def quote_info(text): + return f"
{text}
" + + +def quote_warning(text): + return f"
{text}
" + + +def quote_danger(text): + return f"
{text}
" + + +def code(text): + return f"{text}" + + +def html_link(link_text, url): + return f"{link_text}" diff --git a/lib/webex_bot/mode/__init__.py b/lib/webex_bot/mode/__init__.py new file mode 100644 index 00000000..2eef1dc7 --- /dev/null +++ b/lib/webex_bot/mode/__init__.py @@ -0,0 +1,4 @@ +"""Top-level package for Webex Bot.""" + +__author__ = """Finbarr Brady""" +__version__ = '0.4.1' diff --git a/lib/webex_bot/mode/backend.py b/lib/webex_bot/mode/backend.py new file mode 100644 index 00000000..4b50bf9e --- /dev/null +++ b/lib/webex_bot/mode/backend.py @@ -0,0 +1,58 @@ +import time +import traceback + +from lib.webex_bot.commands.aci import GetAciCommand +from lib.webex_bot.commands.nx import GetNexusCommand +from lib.webex_bot.commands.server import GetServerCommand +from lib.webex_bot.commands.info import InfoCommand +from lib.webex_bot.commands.whoami import WhoamiCommand +from lib.webex_bot.commands.settings import SettingsCommand + +from lib.webex_bot.webex_bot import MyWebexBot +from lib.webex_bot import api + +def run(bot_settings, bot_modules): + approved_users = [] + for user in bot_settings['users']: + approved_users.append( + user['username'] + ) + + backend_url = None + if 'backend' in bot_settings: + backend_url = bot_settings['backend'] + + bot = MyWebexBot( + bot_settings['token'], + bot_settings['email'], + approved_users=approved_users, + bot_name=bot_settings['name'], + url=backend_url, + include_demo_commands=False + ) + + my_webex_api_handler = api.MyWebexApi( + bot_settings['token'], + proxies=bot_settings['proxies'] + ) + + # Add new commands for the bot to listen out for. + bot.add_command(InfoCommand()) + bot.add_command(WhoamiCommand(bot_settings['users'])) + bot.add_command(SettingsCommand(backend_url)) + + if 'aci' in bot_modules.split(','): + bot.add_command(GetAciCommand(my_webex_api_handler, backend_url)) + if 'nexus' in bot_modules.split(','): + bot.add_command(GetNexusCommand(my_webex_api_handler, backend_url)) + if 'intersight' in bot_modules.split(','): + bot.add_command(GetServerCommand(my_webex_api_handler, backend_url)) + + # Call `run` for the bot to wait for incoming messages. + while True: + try: + bot.run() + except BaseException: + print(traceback.format_exc()) + + time.sleep(3) diff --git a/lib/webex_bot/mode/members.py b/lib/webex_bot/mode/members.py new file mode 100644 index 00000000..7c4b0b09 --- /dev/null +++ b/lib/webex_bot/mode/members.py @@ -0,0 +1,13 @@ +from webexteamssdk import WebexTeamsAPI + + +def run(bot_settings): + # https://webexteamssdk.readthedocs.io/en/latest/user/api.html#memberships + webex_api_handler = WebexTeamsAPI( + access_token=bot_settings['token'], + proxies=bot_settings['proxies'] + ) + + memberships = webex_api_handler.memberships.list() + for membership in memberships: + print(membership) diff --git a/lib/webex_bot/models/__init__.py b/lib/webex_bot/models/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/webex_bot/models/command.py b/lib/webex_bot/models/command.py new file mode 100644 index 00000000..1d100d31 --- /dev/null +++ b/lib/webex_bot/models/command.py @@ -0,0 +1,97 @@ +import logging +from abc import ABC, abstractmethod + +log = logging.getLogger(__name__) + +CALLBACK_KEYWORD_KEY = 'callback_keyword' +COMMAND_KEYWORD_KEY = "command_keyword" + + +class Command(ABC): + + def __init__(self, command_keyword=None, chained_commands=[], card=None, help_message=None, + delete_previous_message=False, + card_callback_keyword=None, approved_rooms=None): + """ + Create a new bot command. + + If the command has a simple string keyword, it can be invoked by the user when they type that word. + + Alternatively, if `card_callback_keyword` is defined, the command can be invoked from the 'callback_keyword' + data from the Submit action of a previous card. E.g. + + Submit(title="Submit", data={ + "callback_keyword": "echo_callback"} + ) + + @param command_keyword: (optional) Text indicating a phrase to invoke this card. + @param chained_commands: (optional) List of other commands related + to this command. This allows multiple related cards to be added at once. + @param card: (deprecated) A dict representation of the JSON card. + Prefer to use cards built in code using the webexteamssdk.models.cards classes + (see https://github.com/fbradyirl/webex_bot/blob/main/webex_bot/commands/echo.py for example) + @param help_message: Short description of this command. + @param delete_previous_message: If True, the card which invoked this command will be deleted. (default False) + @param card_callback_keyword: (optional) this command can be invoked from the 'callback_keyword' + text in the data from the Submit action of a previous card. + @param approved_rooms: If defined, only members of these spaces will be allowed to run this command. Default: None (everyone) + """ + self.command_keyword = command_keyword + self.help_message = help_message + self.card = card + self.pre_card_callback = self.execute + self.card_callback = self.execute + self.card_callback_keyword = card_callback_keyword + self.delete_previous_message = delete_previous_message + self.approved_rooms = approved_rooms + self.chained_commands = chained_commands + + # Now, if this card has a Action.Submit action, let's read the callback keyword, + # or if it doesnt exist, add it. + # Only work from the first action for now. Maybe in future support multiple actions. + if card is not None: + log.warning(f"[{command_keyword}]. Using a card dict is now deprecated. " + f"Switch to use adaptive cards built in code " + "using the webexteamssdk.models.cards classes (see " + "https://github.com/fbradyirl/webex_bot/blob/main/webex_bot/commands/echo.py for example)") + if 'actions' in card: + if len(card['actions']) > 0: + first_action = card['actions'][0] + if 'type' in first_action and first_action['type'] == 'Action.Submit': + if 'data' in first_action and len(first_action['data']) > 0: + data = first_action['data'] + if CALLBACK_KEYWORD_KEY in data: + self.card_callback_keyword = first_action['data'][CALLBACK_KEYWORD_KEY] + elif COMMAND_KEYWORD_KEY in data: + self.command_keyword = first_action['data'][COMMAND_KEYWORD_KEY] + else: + log.warning( + f"card actions data but no entry for '{CALLBACK_KEYWORD_KEY}' for {command_keyword}") + self.set_default_card_callback_keyword() + else: + log.warning( + f"no card actions data so no entry for '{CALLBACK_KEYWORD_KEY}' for {command_keyword}") + self.set_default_card_callback_keyword() + else: + log.info(f"No actions defined in this card. command_keyword={command_keyword}") + + def set_default_card_callback_keyword(self): + if self.card_callback_keyword is None: + if 'data' not in self.card['actions'][0]: + self.card['actions'][0]['data'] = {} + + self.card_callback_keyword = f"callback___{self.command_keyword}" + self.card['actions'][0]['data'][CALLBACK_KEYWORD_KEY] = self.card_callback_keyword + + log.info( + f"Added default action for '{self.command_keyword}' {CALLBACK_KEYWORD_KEY}={self.card_callback_keyword}") + + def pre_card_load_reply(self, message, attachment_actions, activity): + pass + + def pre_execute(self, message, attachment_actions, activity): + pass + + @abstractmethod + def execute(self, message, attachment_actions, activity): + pass diff --git a/lib/webex_bot/models/response.py b/lib/webex_bot/models/response.py new file mode 100644 index 00000000..170d5573 --- /dev/null +++ b/lib/webex_bot/models/response.py @@ -0,0 +1,103 @@ +import json + +from webexteamssdk.models.cards import AdaptiveCard + + +def response_from_adaptive_card(adaptive_card: AdaptiveCard): + """ + Convenience method for generating a Response from an AdaptiveCard. + + @param adaptive_card: AdaptiveCard object + @return: Response object + """ + + response = Response() + response.text = "This bot requires a client which can render cards." + response.markdown = "This bot requires a client which can render cards." + response.attachments = { + "contentType": "application/vnd.microsoft.card.adaptive", + "content": adaptive_card.to_dict() + } + + return response + + +class Response(object): + def __init__(self, attributes=None): + if attributes: + self.attributes = attributes + else: + self.attributes = dict() + self.attributes["text"] = None + self.attributes["roomId"] = None + self.attributes["parentId"] = None + self.attributes["markdown"] = None + self.attributes["html"] = None + self.attributes["files"] = list() + self.attributes["attachments"] = list() + + @property + def text(self): + return self.attributes["text"] + + @text.setter + def text(self, val): + self.attributes["text"] = val + + @property + def files(self): + return self.attributes["files"] + + @files.setter + def files(self, val): + self.attributes["files"].append(val) + + @property + def attachments(self): + return self.attributes["attachments"] + + @attachments.setter + def attachments(self, val): + self.attributes["attachments"].append(val) + + @property + def roomId(self): + return self.attributes["roomId"] + + @roomId.setter + def roomId(self, val): + self.attributes["roomId"] = val + + @property + def parentId(self): + return self.attributes["parentId"] + + @parentId.setter + def parentId(self, val): + self.attributes["parentId"] = val + + @property + def markdown(self): + return self.attributes["markdown"] + + @markdown.setter + def markdown(self, val): + self.attributes["markdown"] = val + + @property + def html(self): + return self.attributes["html"] + + @html.setter + def html(self, val): + self.attributes["html"] = val + + def as_dict(self): + ret = dict() + for k, v in self.attributes.items(): + if v: + ret[k] = v + return ret + + def json(self): + return json.dumps(self.attributes) diff --git a/lib/webex_bot/webex_bot.py b/lib/webex_bot/webex_bot.py new file mode 100644 index 00000000..2c3c45b5 --- /dev/null +++ b/lib/webex_bot/webex_bot.py @@ -0,0 +1,406 @@ +"""Main module.""" +import logging +import os + +import backoff +import coloredlogs +import requests +import webexteamssdk + +from lib.webex_bot.commands.echo import EchoCommand +from lib.webex_bot.commands.help import HelpCommand +from lib.webex_bot.exceptions import BotException +from lib.webex_bot.formatting import quote_info +from lib.webex_bot.models.command import CALLBACK_KEYWORD_KEY, Command, COMMAND_KEYWORD_KEY +from lib.webex_bot.models.response import Response +from lib.webex_bot.websockets.webex_websocket_client import MyWebexWebsocketClient, DEFAULT_DEVICE_URL + +log = logging.getLogger(__name__) +coloredlogs.install(level=os.getenv("LOG_LEVEL", "INFO"), + fmt='%(asctime)s [%(levelname)s] ' + '[%(module)s.%(name)s.%(funcName)' + 's]:%(lineno)s %(message)s') + +# pylint: disable=logging-fstring-interpolation + +class MyWebexBot(MyWebexWebsocketClient): + + def __init__(self, + teams_bot_token, + teams_bot_email, + approved_users=[], + approved_domains=[], + approved_rooms=[], + device_url=DEFAULT_DEVICE_URL, + include_demo_commands=False, + bot_name="Webex Bot", + bot_help_subtitle="Here are my available commands. Click one to begin.", + url=None): + """ + Initialise MyWebexBot. + + @param teams_bot_token: Your token. + @param approved_users: List of email address who are allowed to chat to this bot. + @param approved_domains: List of domains which are allowed to chat to this bot. + @param approved_rooms: List of rooms whose members are allowed to chat to this bot. + @param device_url: WDM Url + @param include_demo_commands: If True, any demo commands will be included. + @param bot_name: Your custom name for the bot. + @param bot_help_subtitle: Text to show in the help card. + """ + + log.info("Registering bot with Webex cloud") + MyWebexWebsocketClient.__init__(self, + teams_bot_token, + teams_bot_email, + on_message=self.process_incoming_message, + on_card_action=self.process_incoming_card_action, + device_url=device_url) + + # A dictionary of commands this bot listens to + # Each key in the dictionary is a command, with associated help + # text and callback function + # By default supports 2 command, echo and help + + self.help_command = HelpCommand( + bot_name=bot_name, + bot_help_subtitle=bot_help_subtitle, + bot_help_image=self.teams.people.me().avatar) + self.commands = { + self.help_command + } + if include_demo_commands: + self.add_command(EchoCommand()) + + self.help_command.commands = self.commands + + self.card_callback_commands = {} + self.approved_users = approved_users + self.approved_domains = approved_domains + self.approved_rooms = approved_rooms + # Set default help message + self.help_message = "Hello! I understand the following commands: \n" + self.approval_parameters_check() + self.bot_display_name = "" + self.get_me_info() + + @backoff.on_exception(backoff.expo, requests.exceptions.ConnectionError) + def get_me_info(self): + """ + Fetch me info from webexteamssdk + """ + me = self.teams.people.me() + self.bot_display_name = me.displayName + log.info(f"Running as {me.type} '{me.displayName}' with email {me.emails}") + log.debug(f"Running as bot '{me}'") + + def add_command(self, command_class: Command): + """ + Add a new command to the bot + @param command_class: Command Class to add + """ + + for c in self.commands: + log.debug(f"Checking command '{c}' against {command_class}") + new_callback_keyword = command_class.card_callback_keyword + if new_callback_keyword and c.card_callback_keyword == new_callback_keyword: + raise BaseException(f"Error adding new command: '{command_class.command_keyword}'. " + f"Duplicate callback_keyword found: " + f"'{new_callback_keyword}'. Use a unique keyword in your " + f"'{command_class.command_keyword}' adaptive card JSON.") + + self.commands.add(command_class) + for chained_command in command_class.chained_commands: + self.commands.add(chained_command) + + def approval_parameters_check(self): + """ + Simply logs a warning if no approved users, domains or rooms are set. + """ + if len(self.approved_users) == 0 and len(self.approved_domains) == 0 and len(self.approved_rooms) == 0: + log.warning("Your bot is open to anyone on Webex Teams. " + "Consider limiting this to specific users, domains or room members via the " + "MyWebexBot(approved_domains=['example.com'], approved_users=['user@company.com'], " + "approved_rooms=['Y2lzY29zcGFyazovL3VzL1JPT00vZDUwMDE2ZWEtNmQ5My00MTY1LTg0ZWEtOGNmNTNhYjA3YzA5']) " + "bot parameters.") + + def check_user_approved(self, user_email, approved_rooms): + """ + A user is approved if they are in an approved domain or the approved_users list. + + * If both those lists are empty, the user is approved. + + Throws BotException if user is not approved. + + @param approved_rooms: list of spaces the user needs to be in to use this command. + @param user_email: The email from the user of the incoming message. + """ + user_approved = False + self.approval_parameters_check() + + if len(self.approved_users) == 0 and len(self.approved_domains) == 0 and len(approved_rooms) == 0: + user_approved = True + elif len(self.approved_domains) > 0 and user_email.split('@')[1] in self.approved_domains: + user_approved = True + elif len(self.approved_users) > 0 and user_email in self.approved_users: + user_approved = True + elif len(approved_rooms) > 0 and self.is_user_member_of_room(user_email, approved_rooms): + user_approved = True + + if not user_approved: + log.warning(f"{user_email} is not approved to interact at this time. Ignoring.") + return user_approved + + def is_user_member_of_room(self, user_email, approved_rooms): + is_user_member = False + + for approved_room in approved_rooms: + try: + room_members = self.teams.memberships.list(roomId=approved_room, personEmail=user_email) + for member in room_members: + if member.personEmail == user_email: + is_user_member = True + except webexteamssdk.exceptions.ApiError as apie: + log.warn(f"API error: {apie}") + return is_user_member + + def process_incoming_card_action(self, attachment_actions, activity): + """ + Process an incoming card action, determine the command and action, + and determine reply. + :param attachment_actions: The attachment_actions object + :param activity: The websocket activity object + :return: + """ + callback_keyword = attachment_actions.inputs.get(CALLBACK_KEYWORD_KEY) + command_keyword = attachment_actions.inputs.get(COMMAND_KEYWORD_KEY) + is_card_callback_command = callback_keyword is not None + raw_message = callback_keyword if callback_keyword else command_keyword + log.debug(f"raw_message (callback) ='{raw_message}' is_card_callback_command={is_card_callback_command}") + + self.process_raw_command(raw_message, + attachment_actions, activity['actor']['emailAddress'], activity, + is_card_callback_command=is_card_callback_command) + + def process_incoming_message(self, teams_message, activity): + """ + Process an incoming message, determine the command and action, + and determine reply. + :param teams_message: The teams_message object + :param activity: The websocket activity object + :return: + """ + user_email = teams_message.personEmail + raw_message = teams_message.text + is_one_on_one_space = 'ONE_ON_ONE' in activity['target']['tags'] + + if activity['actor']['type'] != 'PERSON': + log.debug('message is from a bot, ignoring') + return + + # Log details on message + log.info(f"Message from {user_email}: {teams_message}") + + if not self.check_user_approved(user_email=user_email, approved_rooms=self.approved_rooms): + return + + # Remove the Bots display name from the message if this is not a 1-1 + if not is_one_on_one_space: + raw_message = raw_message.replace(self.bot_display_name, '').strip() + + self.process_raw_command(raw_message, teams_message, user_email, activity) + + def process_raw_command(self, raw_message, teams_message, user_email, activity, is_card_callback_command=False): + room_id = teams_message.roomId + is_one_on_one_space = 'ONE_ON_ONE' in activity['target']['tags'] + + # Find the command that was sent, if any + command = None + user_command = raw_message.lower() + log.info(f"New user_command: {user_command}") + log.info(f"is_card_callback_command: {is_card_callback_command}") + + for c in self.commands: + log.debug("--------") + log.debug(f"Checking c.command_keyword: {c.command_keyword}") + + if not is_card_callback_command and c.command_keyword: + log.debug(f"c.command_keyword: {c.command_keyword}") + if user_command.find(c.command_keyword) != -1: + command = c + # If a command was found, stop looking for others + break + else: + log.debug(f"card_callback_keyword: {c.card_callback_keyword}") + if user_command == c.command_keyword or user_command == c.card_callback_keyword: + command = c + break + + if not command: + log.warning(f"Did not find command for {user_command}. Default to help card.") + command = self.help_command + else: + log.info(f"Found command: {command.command_keyword}") + + if command.approved_rooms: + if not self.check_user_approved(user_email=user_email, approved_rooms=command.approved_rooms): + log.info(f"{user_email} is not allowed to run command: '{command.command_keyword}'") + return + + # Build the reply to the user + reply = "" + reply_one_to_one = False + message_without_command = MyWebexBot.get_message_passed_to_command(command.command_keyword, raw_message) + thread_parent_id = None + + if hasattr(teams_message, "inputs") and teams_message.inputs.get("thread_parent_id"): + thread_parent_id = teams_message.inputs.get("thread_parent_id") + elif 'parent' in activity: + log.info(f"activity: {activity}") + + if activity['parent']['type'] == 'reply': + thread_parent_id = activity['parent']['id'] + else: + # Some bug where message cannot be sent back in response to cardAction in thread. + # Must reply outside of the thread in this case. + log.warning(f"There is a server side bug where message cannot be sent back in " + f"response to cardAction inside a thread. " + f"Must reply outside of the thread in this case.: {activity}") + thread_parent_id = None + elif 'id' in activity: + thread_parent_id = activity['id'] + else: + log.info("There is no activity id (thread ID) for this request.") + + if command.delete_previous_message and hasattr(teams_message, 'messageId'): + previous_message_id = teams_message.messageId + log.info(f"delete_previous_message is True. Deleting message with ID: {previous_message_id}") + self.teams.messages.delete(previous_message_id) + + if not is_card_callback_command and command.card is not None: + response = Response() + response.text = "This bot requires a client which can render cards." + response.attachments = { + "contentType": "application/vnd.microsoft.card.adaptive", + "content": command.card + } + + pre_card_load_reply, pre_card_load_reply_one_to_one = self.run_pre_card_load_reply(command=command, + message=message_without_command, + teams_message=teams_message, + activity=activity) + self.do_reply(pre_card_load_reply, room_id, user_email, pre_card_load_reply_one_to_one, is_one_on_one_space, thread_parent_id) + reply = response + else: + log.debug(f"Going to run command: '{command}' with input: '{message_without_command}'") + pre_execute_reply, pre_execute_reply_one_to_one = self.run_pre_execute(command=command, + message=message_without_command, + teams_message=teams_message, + activity=activity) + self.do_reply(pre_execute_reply, room_id, user_email, pre_execute_reply_one_to_one, is_one_on_one_space, thread_parent_id) + reply, reply_one_to_one = self.run_command_and_handle_bot_exceptions(command=command, + message=message_without_command, + teams_message=teams_message, + activity=activity) + log.info(f"Using thread id={thread_parent_id}") + return self.do_reply(reply, room_id, user_email, reply_one_to_one, is_one_on_one_space, thread_parent_id) + + def do_reply(self, reply, room_id, user_email, reply_one_to_one, is_one_on_one_space, conv_target_id): + # allow command handlers to craft their own Teams message + if reply and isinstance(reply, Response): + # If the Response lacks a roomId, set it to the incoming room + if not reply.roomId: + reply.roomId = room_id + if not reply.parentId and conv_target_id: + reply.parentId = conv_target_id + reply = reply.as_dict() + self.teams.messages.create(**reply) + reply = "ok" + # Support returning a list of Responses + elif reply and isinstance(reply, list): + for response in reply: + # Make sure is a Response + if isinstance(response, Response): + if not response.roomId: + response.roomId = room_id + if not response.parentId and conv_target_id: + response.parentId = conv_target_id + self.teams.messages.create(**response.as_dict()) + else: + # Just a plain message + self.send_message_to_room_or_person(user_email, + room_id, + reply_one_to_one, + is_one_on_one_space, + response, + conv_target_id) + reply = "ok" + elif reply: + self.send_message_to_room_or_person(user_email, + room_id, + reply_one_to_one, + is_one_on_one_space, + reply, + conv_target_id) + return reply + + def send_message_to_room_or_person(self, + user_email, + room_id, + reply_one_to_one, + is_one_on_one_space, + reply, + conv_target_id): + default_move_to_one_to_one_heads_up = \ + quote_info(f"{user_email} I've messaged you 1-1. Please reply to me there.") + if reply_one_to_one: + if not is_one_on_one_space: + self.teams.messages.create(roomId=room_id, + markdown=default_move_to_one_to_one_heads_up, + parentId=conv_target_id) + self.teams.messages.create(toPersonEmail=user_email, + markdown=reply, + parentId=conv_target_id) + else: + self.teams.messages.create(roomId=room_id, markdown=reply, parentId=conv_target_id) + + def run_pre_card_load_reply(self, command, message, teams_message, activity): + """ + This allows a reply to be sent back before the command/card function is called. Useful if it takes a while for the card to generate. + """ + try: + return command.pre_card_load_reply(message, teams_message, activity), False + except BotException as e: + log.warn(f"BotException: {e.debug_message}") + return e.reply_message, e.reply_one_to_one + + def run_pre_execute(self, command, message, teams_message, activity): + """ + This allows a reply to be sent back before the execute function is called. Useful if it takes a while to run. + """ + try: + return command.pre_execute(message, teams_message, activity), False + except BotException as e: + log.warn(f"BotException: {e.debug_message}") + return e.reply_message, e.reply_one_to_one + + def run_command_and_handle_bot_exceptions(self, command, message, teams_message, activity): + try: + return command.card_callback(message, teams_message, activity), False + except BotException as e: + log.warn(f"BotException: {e.debug_message}") + return e.reply_message, e.reply_one_to_one + + @staticmethod + def get_message_passed_to_command(command, message): + """ + Remove the command from the start of the message + + :param command: command string + :param message: message string + :return: message without command prefix + """ + + if command and message.lower().startswith(command.lower()): + return message[len(command):] + return message diff --git a/lib/webex_bot/websockets/__init__.py b/lib/webex_bot/websockets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/webex_bot/websockets/webex_websocket_client.py b/lib/webex_bot/websockets/webex_websocket_client.py new file mode 100644 index 00000000..16b6f4a2 --- /dev/null +++ b/lib/webex_bot/websockets/webex_websocket_client.py @@ -0,0 +1,218 @@ +import asyncio +import json +import logging +import socket +import ssl +import uuid + +import backoff +import certifi +import requests +import websockets +import websocket +from webexteamssdk import WebexTeamsAPI +#from commands import command + +# pylint: disable=logging-fstring-interpolation + +logger = logging.getLogger(__name__) + +DEFAULT_DEVICE_URL = "https://wdm-a.wbx2.com/wdm/api/v1" + +DEVICE_DATA = { + "deviceName": "pywebsocket-client", + "deviceType": "DESKTOP", + "localizedModel": "python", + "model": "python", + "name": "python-spark-client", + "systemName": "python-spark-client", + "systemVersion": "0.1" +} + +ssl_context = ssl.create_default_context() +ssl_context.load_verify_locations(certifi.where()) + + +class MyWebexWebsocketClient(): + def __init__(self, + teams_bot_token, + teams_bot_email, + device_url=DEFAULT_DEVICE_URL, + on_message=None, + on_card_action=None): + + self.access_token = teams_bot_token + self.teams_bot_email = teams_bot_email + + self.headers = {} + self.headers['Authorization'] = 'Bearer %s' % (teams_bot_token) + self.headers['Content-Type'] = 'application/json' + + self.teams = WebexTeamsAPI(access_token=teams_bot_token) + self.device_url = device_url + self.device_info = None + self.on_message = on_message + self.on_card_action = on_card_action + self.websocket = None + + self.get_message_timeout = 5 + + def _process_incoming_websocket_message(self, msg): + """ + Handle websocket data. + :param msg: The raw websocket message + """ + + if msg['data']['eventType'] == 'conversation.activity': + activity = msg['data']['activity'] + logger.info(f"This is the activity: {activity}") + if activity['verb'] == 'post': + logger.debug('activity=%s', activity) + message_base_64_id = self._get_base64_message_id(activity) + webex_message = self.teams.messages.get(message_base_64_id) + if webex_message.personEmail == self.teams_bot_email: + self._ack_message(message_base_64_id) + return + + logger.info('activity=%s', webex_message) + if self.on_message: + logger.info('reaction') + self.on_message(teams_message=webex_message, activity=activity) + + elif activity['verb'] == 'cardAction': + logger.debug('activity=%s', activity) + + message_base_64_id = self._get_base64_message_id(activity) + attachment_actions = self.teams.attachment_actions.get(message_base_64_id) + logger.info('attachment_actions from message_base_64_id: %s', attachment_actions) + if self.on_card_action: + # Now process it with the handler + logger.info('process card action with handler') + self.on_card_action(attachment_actions=attachment_actions, activity=activity) + # ack message first + logger.info('ack message') + self._ack_message(message_base_64_id) + + else: + logger.debug('activity verb is: %s', activity['verb']) + + def _get_base64_message_id(self, activity): + """ + In order to geo-locate the correct DC to fetch the message from, you need to use the base64 Id of the + message. + @param activity: incoming websocket data + @return: base 64 message id + """ + activity_id = activity['id'] + logger.debug(f"activity verb=post. message id={activity_id}") + conversation_url = activity['target']['url'] + conv_target_id = activity['target']['id'] + verb = "messages" if activity['verb'] == "post" else "attachment/actions" + conversation_message_url = conversation_url.replace(f"conversations/{conv_target_id}", + f"{verb}/{activity_id}") + conversation_message = requests.get( + conversation_message_url, + headers=self.headers, + timeout=self.get_message_timeout + ).json() + logger.debug(f"conversation_message={conversation_message}") + return conversation_message['id'] + + def _ack_message(self, message_id): + """ + Ack that this message has been processed. This will prevent the + message coming again. + @param message_id: activity message 'id' + """ + logger.debug(f"WebSocket ack message with id={message_id}") + logger.info("reached ack message") + + ack_message = {'type': 'ack', + 'messageId': message_id} + asyncio.run(self.websocket.send(json.dumps(ack_message))) + + logger.info(f"WebSocket ack message with id={message_id}. Complete.") + + def _get_device_info(self, check_existing=True): + """ + Get device info from Webex Cloud. + + If it doesn't exist, one will be created. + """ + if check_existing: + logger.debug('Getting device list') + try: + resp = self.teams._session.get(f"{self.device_url}/devices") + for device in resp['devices']: + if device['name'] == DEVICE_DATA['name']: + self.device_info = device + logger.debug(f"device_info: {self.device_info}") + return device + except Exception as WdmException: + logger.warning('wdmException: %s', WdmException) + + logger.info('Device does not exist, creating') + + resp = self.teams._session.post(f"{self.device_url}/devices", json=DEVICE_DATA) + if resp is None: + raise Exception("could not create WDM device") + self.device_info = resp + logger.debug(f"self.device_info: {self.device_info}") + return resp + + def run(self): + if self.device_info is None: + if self._get_device_info() is None: + logger.error('could not get/create device info') + raise Exception("No WDM device info") + + async def _websocket_recv(): + #logger.info("Entered into received func") + message = self.websocket.recv() + + #logger.debug("WebSocket Received Message(raw): %s\n" % message) + try: + msg = json.loads(message) +# logger.info(f"message: {msg}") + loop = asyncio.get_event_loop() + loop.run_in_executor(None, self._process_incoming_websocket_message, msg) + except Exception as messageProcessingException: + logger.warning( + f"An exception occurred while processing message. Ignoring. {messageProcessingException}") + + @backoff.on_exception(backoff.expo, websockets.ConnectionClosedError) + @backoff.on_exception(backoff.expo, websockets.ConnectionClosedOK) + @backoff.on_exception(backoff.expo, websockets.ConnectionClosed) + @backoff.on_exception(backoff.expo, socket.gaierror) + async def _connect_and_listen(): + ws_url = self.device_info['webSocketUrl'] + logger.info(f"Opening websocket connection to {ws_url}") + + ws = websocket.WebSocket() + ws.connect(ws_url, http_proxy_host="72.163.217.102", http_proxy_port="80", proxy_type="http") + self.websocket = ws + logger.info("MyWebSocket Opened.") + + msg = {'id': str(uuid.uuid4()), + 'type': 'authorization', + 'data': {'token': 'Bearer ' + self.access_token}} + #log.info(f'UUID of message is: {msg}') + #text1 = await asyncio.to_thread(self.websocket.send, json.dumps(msg)) + text = await asyncio.to_thread(self.websocket.send, json.dumps(msg)) + + #logger.info(f' response of send {text1}') + + while True: + await _websocket_recv() + + + try: + asyncio.get_event_loop().run_until_complete(_connect_and_listen()) + except Exception as runException: + logger.error(f"runException: {runException}") + if self._get_device_info(check_existing=False) is None: + logger.error('could not create device info') + raise Exception("No WDM device info") + # trigger re-connect + asyncio.get_event_loop().run_until_complete(_connect_and_listen()) + diff --git a/lib/workflow/__init__.py b/lib/workflow/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/workflow/ocp_bm_install.py b/lib/workflow/ocp_bm_install.py new file mode 100644 index 00000000..05c37886 --- /dev/null +++ b/lib/workflow/ocp_bm_install.py @@ -0,0 +1,1065 @@ +# Useful links +# https://cloudcult.dev/creating-openshift-clusters-with-the-assisted-service-api/ +# https://cloudcult.dev/static-networking-with-assisted-installer/ +# https://cloudcult.dev/calico-installation-openshift-assisted-installer/ +# https://cloudcult.dev/cilium-installation-openshift-assisted-installer/ +# https://api.openshift.com/?urls.primaryName=assisted-service%20service#/ + +import os +import json +import time +import uuid +import base64 +from progress.bar import Bar + +from lib import file_helper +from lib import ip_helper +from lib import log_helper +from lib import output_helper +from lib import ssh +from lib import template +from lib.openshift import console +from lib.openshift import output as openshift_output +from lib.ocp import settings as ocp_settings +from lib.redfish import endpoint as redfish_endpoint +from lib.imc.cli import endpoint as imc_endpoint + +from menu import common + + +def get_data(user_settings, my_output): + data = {} + + mandatory_keys = [ + 'name', + 'openshift_version', + 'base_dns_domain', + 'ssh_public_key' + ] + for key in mandatory_keys: + if key not in user_settings: + my_output.error('Key %s missing' % (key)) + return None, None + + data['name'] = '%s-%s' % ( + user_settings['name'], + str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1] + ) + + data['openshift_version'] = user_settings['openshift_version'] + data['base_dns_domain'] = user_settings['base_dns_domain'] + data['ssh_public_key'] = user_settings['ssh_public_key'] + + if 'cpu_architecture' in user_settings: + data['cpu_architecture'] = user_settings['cpu_architecture'] + else: + data['cpu_architecture'] = 'x86_64' + + if 'cpu_architecture' in user_settings: + data['cluster_network_cidr'] = user_settings['cluster_network_cidr'] + else: + data['cluster_network_cidr'] = '10.128.0.0/14' + + if 'cluster_network_host_prefix' in user_settings: + data['cluster_network_host_prefix'] = user_settings['cluster_network_host_prefix'] + else: + data['cluster_network_host_prefix'] = 23 + + if 'service_network_cidr' in user_settings: + data['service_network_cidr'] = user_settings['service_network_cidr'] + else: + data['service_network_cidr'] = '172.30.0.0/16' + + if 'server' not in user_settings or len(user_settings['server']) == 0: + my_output.error('Servers key missing or empty') + return None, None + + if len(user_settings['server']) == 2: + my_output.error('Invalid server count') + return None, None + + if len(user_settings['server']) == 1: + data['high_availability_mode'] = "None" + user_settings['api'] = user_settings['server'][0]['ssh']['ip'] + user_settings['ingress'] = user_settings['server'][0]['ssh']['ip'] + else: + data['high_availability_mode'] = "Full" + for key in ['api', 'ingress']: + if key not in user_settings: + my_output.error('Key %s missing' % (key)) + return None, None + + if 'http_proxy' in user_settings: + data['http_proxy'] = user_settings['http_proxy'] + else: + data['http_proxy'] = None + + if 'https_proxy' in user_settings: + data['https_proxy'] = user_settings['https_proxy'] + else: + data['https_proxy'] = None + + if 'no_proxy' in user_settings: + data['no_proxy'] = user_settings['no_proxy'] + else: + data['no_proxy'] = None + + if 'olm_operators' in user_settings: + data['olm_operators'] = user_settings['olm_operators'] + else: + data['olm_operators'] = [] + + if 'network_type' in user_settings: + data['network_type'] = user_settings['network_type'] + else: + data['network_type'] = 'OVNKubernetes' + + return user_settings, data + +def get_infra(user_settings, data, directory, my_output, log_id): + template_handler = template.Template(log_id=log_id) + infra = {} + + infra['cpu_architecture'] = data['cpu_architecture'] + infra['openshift_version'] = data['openshift_version'] + infra['proxy'] = {} + infra['proxy']['http_proxy'] = data['http_proxy'] + infra['proxy']['https_proxy'] = data['https_proxy'] + infra['proxy']['no_proxy'] = data['no_proxy'] + infra['ssh_authorized_key'] = data['ssh_public_key'] + + infra['static_network_config'] = [] + for server in user_settings['server']: + network_config = {} + network_config['mac_interface_map'] = [] + for interface in server['interface']: + mac_interface_map = {} + mac_interface_map['logical_nic_name'] = interface['name'] + mac_interface_map['mac_address'] = interface['mac'] + network_config['mac_interface_map'].append( + mac_interface_map + ) + + nmstate_filename = os.path.join( + directory, + server['nmstate'] + ) + if not os.path.isfile(nmstate_filename): + my_output.error('nmstate file not found: %s' % (nmstate_filename)) + return None + + content = file_helper.get_file_text( + nmstate_filename + ) + if content is None: + my_output.error('nmstate file read failed: %s' % (nmstate_filename)) + return None + + if 'variables' in server and len(server['variables']) > 0: + content = template_handler.replace_attributes( + content, + server['variables'] + ) + if content is None: + my_output.error('nmstate variables replacemet failed for server %s' % (server['redfish']['endpoint_ip'])) + return None + + if template_handler.is_template_attributes(content): + my_output.error('nmstate variables replacemet missing for server %s' % (server['redfish']['endpoint_ip'])) + return None + + network_config['network_yaml'] = '\r\n'.join(content.split('\n')) + + infra['static_network_config'].append( + network_config + ) + + infra['additional_trust_bundle'] = '' + infra['image_type'] = 'minimal-iso' + + return infra + +def get_manifests(user_settings, directory, my_output, log_id): + manifests = {} + manifests_directory = os.path.join(directory, 'manifests') + if os.path.isdir(manifests_directory): + template_handler = template.Template(log_id=log_id) + for file_basename in os.listdir(manifests_directory): + filename = os.path.join( + manifests_directory, + file_basename + ) + content = file_helper.get_file_text( + filename + ) + if content is None: + my_output.error('manifest file read failed: %s' % (filename)) + return None + + if 'variables' in user_settings and len(user_settings['variables']) > 0: + content = template_handler.replace_attributes( + content, + user_settings['variables'] + ) + if content is None: + my_output.error('manifest variables replacemet failed for file %s' % (filename)) + return None + + if template_handler.is_template_attributes(content): + my_output.error('manifest variables replacemet missing for file %s' % (filename)) + return None + + encoded_content = base64.b64encode( + content.encode('utf-8') + ).decode('utf-8') + + manifests[file_basename] = encoded_content + + return manifests + +def get_input_files(directory, log_id=None): + console_handler = console.Console(log_id=log_id) + my_output = output_helper.OutputHelper(log_id=log_id) + log = log_helper.Log(log_id=log_id) + + my_output.default('Checking openshift API...') + if not console_handler.is_ready(): + my_output.error('OpenShift API not configured') + return False, None, None, None, None + + if len(directory) == 0: + my_output.error('Cluster definition directory required') + return False, None, None, None, None + + my_output.default('Checking user input...') + + filename = os.path.join(directory, 'cluster.json') + user_settings = file_helper.get_file_json(filename) + if user_settings is None: + my_output.error('Failed to read cluster.json') + return False, None, None, None, None + + user_settings, data = get_data(user_settings, my_output) + if data is None: + return False, None, None, None, None + + data['pull_secret'] = console_handler.get_pull_secret() + log.debug( + 'workflow_ocp_bm_installation', + json.dumps( + data, + indent=4 + ) + ) + + infra = get_infra(user_settings, data, directory, my_output, log_id) + if infra is None: + return False, None, None, None, None + + infra['name'] = '%s_infra-env' % (data['name']) + infra['pull_secret'] = console_handler.get_pull_secret() + + log.debug( + 'workflow_ocp_bm_installation', + json.dumps( + infra, + indent=4 + ) + ) + + manifests = get_manifests(user_settings, directory, my_output, log_id) + if manifests is None: + return False, None, None, None, None + + log.debug( + 'workflow_ocp_bm_installation', + json.dumps( + manifests, + indent=4 + ) + ) + + return True, user_settings, data, infra, manifests + +def create_cluster(data, infra, manifests, console_handler, my_output, log): + if data['network_type'] in ['OpenShiftSDN', 'OVNKubernetes']: + cluster_id = console_handler.create_assisted_install_cluster(data) + if cluster_id is None: + my_output.error('Cluster create failed') + return None, None + + my_output.default('Cluster created: %s [%s]' % (data['name'], cluster_id)) + else: + target_cni = data['network_type'] + data['network_type'] = 'OVNKubernetes' + + cluster_id = console_handler.create_assisted_install_cluster(data) + if cluster_id is None: + my_output.error('Cluster create failed') + return None, None + + my_output.default('Cluster created: %s [%s]' % (data['name'], cluster_id)) + + patch_data_text = '"{\\\"networking\\\":{\\\"networkType\\\":\\\"%s\\\"}}"' % (target_cni) + response = console_handler.patch_assisted_install_cluster_install_config(cluster_id, patch_data_text) + if response is None: + my_output.error('Cluster install config patch with target cni failed') + return None, None + + my_output.default('Cluster install config cni patched: %s' % (target_cni)) + + infra['cluster_id'] = cluster_id + infra_id = console_handler.create_assisted_install_infra(infra) + if infra_id is None: + my_output.error('Infra create failed') + return None, None + + my_output.default('Infra created: %s' % (infra_id)) + + if len(manifests) > 0: + for manifest in manifests: + success = console_handler.create_assisted_install_manifest( + cluster_id, + manifest, + manifests[manifest] + ) + if not success: + my_output.error('Manifest create failed') + return None, None + + my_output.default('Manifest created: %s' % (manifest)) + + cluster_info = console_handler.get_assisted_install_cluster( + cluster_id=cluster_id, + config_info=True, + credentials_info=True, + infra_info=True, + manifest_info=True, + kubeconfig_info=True, + cache_enabled=False + ) + if cluster_info is None: + my_output.error('Failed to get newly created cluster information') + return None, None + + log.debug( + 'workflow_ocp_bm_installation', + json.dumps( + cluster_info, + indent=4 + ) + ) + + return cluster_id, cluster_info + +def boot_from_iso(user_settings, cluster_id, cluster_info, console_handler, my_output, log, log_id): + if cluster_info['iso_url'] is None: + my_output.error('ISO URL not found...') + return False + + iso_filename = '/tmp/%s.iso' % (cluster_id) + my_output.default('Download ISO...') + log.debug( + 'workflow_ocp_bm_installation', + 'Downloading %s to %s' % (cluster_info['iso_url'], iso_filename) + ) + if not ip_helper.download_url(cluster_info['iso_url'], iso_filename): + my_output.error('ISO download failed') + return False, False + + web_server_supported = True + if user_settings['web_server']['ssh_public_key'] is None: + ssh_handler = ssh.Ssh( + user_settings['web_server']['ip'], + user_settings['web_server']['username'], + password=user_settings['web_server']['password'] + ) + else: + key_filename = file_helper.set_tmp_file( + user_settings['web_server']['ssh_public_key'] + ) + ssh_handler = ssh.Ssh( + user_settings['web_server']['ip'], + user_settings['web_server']['username'], + key_filename=key_filename + ) + + if not ssh_handler.is_ssh(): + my_output.error('SSH access to web server failed') + web_server_supported = False + else: + my_output.default('Upload iso to web server...') + target_iso_filename = '%s/%s.iso' % ( + user_settings['web_server']['image_upload_directory'], + cluster_id + ) + success = ssh_handler.scp_file( + iso_filename, + target_iso_filename + ) + log.debug( + 'workflow_ocp_bm_installation', + 'ISO upload: %s => %s' % ( + iso_filename, + target_iso_filename + ) + ) + + if success: + my_output.default('ISO uploaded') + else: + my_output.error('ISO upload failed') + web_server_supported = False + + if not web_server_supported: + my_output.default('Continue with manual mount and boot from iso: %s' % (iso_filename)) + if not common.get_confirmation(): + return False, False + + if web_server_supported: + for server in user_settings['server']: + redfish_handler = redfish_endpoint.RedfishEndpoint( + server['redfish']['endpoint_type'], + server['redfish']['endpoint_ip'], + server['redfish']['endpoint_port'], + server['redfish']['username'], + server['redfish']['password'], + auto_connect=True, + ssl_verify=False, + log_id=log_id + ) + + if not redfish_handler.is_connected(): + my_output.error('Redfish connection to server failed: %s' % (server['redfish']['endpoint_ip'])) + return False, False + + success = redfish_handler.endpoint_handler.insert_media_http('%s/%s.iso' % (user_settings['web_server']['image_base_url'], cluster_id)) + if not success: + my_output.error('Redfish vmedia insert failed: %s' % (server['redfish']['endpoint_ip'])) + return False, False + + success = redfish_handler.endpoint_handler.wait_virtual_media_inserted() + if not success: + my_output.error('Redfish vmedia mapping failed: %s' % (server['redfish']['endpoint_ip'])) + return False, False + + my_output.default('Redfish vmedia mapping created successfuly: %s' % (server['redfish']['endpoint_ip'])) + + success = redfish_handler.endpoint_handler.set_one_time_boot_source('Cd') + if not success: + my_output.error('Redfish boot source set to cd failed: %s' % (server['redfish']['endpoint_ip'])) + return False, False + + my_output.default('Redfish boot source set to cd successful: %s' % (server['redfish']['endpoint_ip'])) + + success = redfish_handler.endpoint_handler.power_cycle() + if not success: + my_output.error('Server power cycle failed: %s' % (server['redfish']['endpoint_ip'])) + return False, False + + my_output.default('Server booted: %s' % (server['redfish']['endpoint_ip'])) + + my_output.default('Wait for all the servers discovered...') + + bmc_addresses = [] + for server in user_settings['server']: + bmc_addresses.append( + server['redfish']['endpoint_ip'] + ) + + success = console_handler.wait_assisted_install_cluster_hosts_discovered( + cluster_id, + bmc_addresses + ) + if not success: + my_output.error('Servers discovery failed') + return False + + return True, web_server_supported + +def update_cluster_settings(user_settings, cluster_id, console_handler, my_output): + my_output.default('Change hostnames...') + + server_hostname = {} + for server in user_settings['server']: + server_hostname[server['redfish']['endpoint_ip']] = server['hostname'] + + success = console_handler.update_assisted_install_cluster_hosts_hostname( + cluster_id, + server_hostname + ) + if not success: + my_output.error('Hostname update failed') + return False + + if 'ntp' in user_settings and user_settings['ntp'] is not None: + ntp_data = {} + ntp_data['additional_ntp_source'] = user_settings['ntp'] + + my_output.default('Update ntp with %s...' % (ntp_data['additional_ntp_source'])) + response = console_handler.patch_assisted_install_cluster(cluster_id, ntp_data) + if response is None: + my_output.error('NTP source update failed') + return False + + if len(user_settings['server']) > 1: + # 'api_vips': [{'cluster_id': '7200331f-ff22-467b-861f-f7a84dc77483', 'ip': ''}] + api_vip = {} + api_vip['cluster_id'] = cluster_id + api_vip['ip'] = user_settings['api'] + api_vips = [] + api_vips.append( + api_vip + ) + + # 'ingress_vips': [{'cluster_id': '7200331f-ff22-467b-861f-f7a84dc77483', 'ip': ''}] + ingress_vip = {} + ingress_vip['cluster_id'] = cluster_id + ingress_vip['ip'] = user_settings['ingress'] + ingress_vips = [] + ingress_vips.append( + ingress_vip + ) + + data = {} + data['api_vips'] = api_vips + data['ingress_vips'] = ingress_vips + + my_output.default('Update api %s and ingress vip %s' % (user_settings['api'], user_settings['ingress'])) + response = console_handler.patch_assisted_install_cluster(cluster_id, data) + if response is None: + my_output.error('API/Ingress VIP update failed') + return False + + my_output.default('Wait for cluster ready to be installed...') + + return True + +def wait_installation_started(cluster_id, console_handler, my_output): + success = console_handler.wait_assisted_install_cluster_status( + cluster_id, + 'ready' + ) + if not success: + my_output.error('Cluster has not reached ready state') + return False + + my_output.default('Start installation request...') + + success = console_handler.action_assisted_install_cluster_install( + cluster_id + ) + if not success: + my_output.error('Cluster installation start request failed') + return False + + my_output.default('Wait for installation started...') + + success = console_handler.wait_assisted_install_cluster_status( + cluster_id, + 'installing' + ) + if not success: + my_output.error('Cluster has not reached installation in progress state') + return False + + return True + +def boot_from_hdd(user_settings, my_output, log_id): + for server in user_settings['server']: + redfish_handler = redfish_endpoint.RedfishEndpoint( + server['redfish']['endpoint_type'], + server['redfish']['endpoint_ip'], + server['redfish']['endpoint_port'], + server['redfish']['username'], + server['redfish']['password'], + auto_connect=True, + ssl_verify=False, + log_id=log_id + ) + + if not redfish_handler.is_connected(): + my_output.error('Redfish connection to server failed: %s' % (server['redfish']['endpoint_ip'])) + return False + + success = redfish_handler.endpoint_handler.eject_media() + if not success: + my_output.error('Redfish vmedia eject failed: %s' % (server['redfish']['endpoint_ip'])) + else: + my_output.default('Redfish vmedia eject successful: %s' % (server['redfish']['endpoint_ip'])) + + imc_handler = imc_endpoint.ImcCliEndpoint( + server['redfish']['endpoint_ip'], + 22, + server['redfish']['username'], + server['redfish']['password'] + ) + success = imc_handler.set_boot_order(['hdd']) + if not success: + my_output.error('Imc boot source set to hdd failed: %s' % (server['redfish']['endpoint_ip'])) + return False + + my_output.default('Imc boot source set to hdd successful: %s' % (server['redfish']['endpoint_ip'])) + + return True + +def host_pending_user_action_fixup(host_ip, user_settings, my_output): + for server in user_settings['server']: + if server['redfish']['endpoint_ip'] == host_ip: + imc_handler = imc_endpoint.ImcCliEndpoint( + server['redfish']['endpoint_ip'], + 22, + server['redfish']['username'], + server['redfish']['password'] + ) + + if not imc_handler.is_boot_device_type('LOCALHDD'): + my_output.default( + 'Creating hdd boot device type: %s' % (host_ip) + ) + success = imc_handler.create_boot_device('hdd', 'LOCALHDD', device_order=1) + if not success: + my_output.error( + 'Failed to create localhdd boot device type: %s' % (host_ip) + ) + return + + if imc_handler.is_top_boot_order_from_device_type('HDD'): + my_output.default('HDD already top priority for boot order: %s' % (host_ip)) + else: + success = imc_handler.set_boot_order(['hdd']) + if not success: + my_output.error( + 'Failed to set boot order to hdd: %s' % (host_ip) + ) + return + + my_output.default('Boot order set to hdd: %s' % (server['redfish']['endpoint_ip'])) + + if not imc_handler.power_cycle(): + my_output.error('Imc power cycle failed: %s' % (server['redfish']['endpoint_ip'])) + return + + my_output.default('Power cycle successful: %s' % (server['redfish']['endpoint_ip'])) + +def wait_installation_finished(user_settings, cluster_id, console_handler, my_output, log): + last_hosts_status = {} + pending_fixup = {} + for server in user_settings['server']: + last_hosts_status[server['redfish']['endpoint_ip']] = None + pending_fixup[server['redfish']['endpoint_ip']] = False + + bar_handler = Bar('Progress', max=100) + bar_handler.goto(0) + while True: + progress = console_handler.get_assisted_install_cluster_progress( + cluster_id + ) + if progress is None: + time.sleep(10) + continue + + bar_handler.goto(progress) + + if progress == 100: + break + + hosts_status = console_handler.get_assisted_install_cluster_host_status( + cluster_id + ) + if hosts_status is not None: + for host_ip in last_hosts_status: + if host_ip in hosts_status: + if hosts_status[host_ip] is not None: + if last_hosts_status[host_ip] is None or last_hosts_status[host_ip] != hosts_status[host_ip]: + last_hosts_status[host_ip] = hosts_status[host_ip] + log.debug( + 'workflow_ocp_bm_installation', + 'Host %s status changed to %s' % ( + host_ip, + last_hosts_status[host_ip] + ) + ) + my_output.default( + 'Host %s status changed to %s' % ( + host_ip, + last_hosts_status[host_ip] + ), + before_newline=True + ) + + if last_hosts_status[host_ip] == 'error': + return False + + if last_hosts_status[host_ip] == 'installing-pending-user-action': + if not pending_fixup[host_ip]: + host_pending_user_action_fixup(host_ip, user_settings, my_output) + pending_fixup[host_ip] = True + + time.sleep(10) + + my_output.default('Installation finished...', before_newline=True) + return True + +def delete_iso(user_settings, cluster_id, my_output): + if user_settings['web_server']['ssh_public_key'] is None: + ssh_handler = ssh.Ssh( + user_settings['web_server']['ip'], + user_settings['web_server']['username'], + password=user_settings['web_server']['password'] + ) + else: + key_filename = file_helper.set_tmp_file( + user_settings['web_server']['ssh_public_key'] + ) + ssh_handler = ssh.Ssh( + user_settings['web_server']['ip'], + user_settings['web_server']['username'], + key_filename=key_filename + ) + + if not ssh_handler.is_ssh(): + my_output.error('SSH access to web server failed') + return False + + my_output.default('Delete iso from web server...') + success = ssh_handler.delete_file( + '%s/%s.iso' % (user_settings['web_server']['image_upload_directory'], cluster_id) + ) + if not success: + my_output.error('Delete failed') + + return True + +def create_connector(user_settings, cluster_info, my_output, log_id): + if 'connector' not in user_settings: + return None + + connector_name = user_settings['connector'] + ocp_settings_handler = ocp_settings.OcpSettings(log_id=log_id) + if ocp_settings_handler.is_ocp_cluster(connector_name): + success = ocp_settings_handler.delete_ocp_cluster( + connector_name + ) + if not success: + my_output.default('Existing ocp connector delete failed: %s' % (connector_name)) + return None + + my_output.default('Create ocp connector: %s' % (connector_name)) + success = ocp_settings_handler.create_ocp_cluster( + connector_name, + cluster_info['kubeconfig'] + ) + if not success: + my_output.error('Ocp connector create failed') + return None + + my_output.default('Ocp connector created') + + success = ocp_settings_handler.set_ocp_cluster_kubeadmin( + connector_name, + cluster_info['credentials']['password'] + ) + if not success: + my_output.error('Kubeadmin updated failed') + return None + + my_output.default('Kubeadmin updated') + + success = ocp_settings_handler.set_ocp_cluster_file( + connector_name, + 'ssh.pub', + user_settings['ssh_public_key'] + ) + if not success: + my_output.error('SSH public key update failed') + return None + + my_output.default('SSH public key updated') + + ssh_settings = {} + ssh_settings['username'] = 'core' + ssh_settings['password'] = None + ssh_settings['key_filename'] = os.path.join( + ocp_settings_handler.get_ocp_cluster_directory(connector_name), + 'ssh.pub' + ) + ocp_settings_handler.set_ocp_cluster_parameter( + connector_name, + 'ssh', + ssh_settings + ) + + my_output.default('SSH access configured in connector') + + server_ip = None + for server in user_settings['server']: + if server['kube']: + server_ip = server['ssh']['ip'] + + if server_ip is not None: + server_settings = {} + server_settings['ip'] = server_ip + server_settings['username'] = 'core' + server_settings['password'] = None + server_settings['key_filename'] = os.path.join( + ocp_settings_handler.get_ocp_cluster_directory(connector_name), + 'ssh.pub' + ) + ocp_settings_handler.set_ocp_cluster_parameter( + connector_name, + 'helm', + ssh_settings + ) + ocp_settings_handler.set_ocp_cluster_parameter( + connector_name, + 'virtctl', + ssh_settings + ) + my_output.default('Helm and virtcl access configured in connector') + + # api.ocp-bm3-cilium-8858d4f50002.ocp.lan + # oauth-openshift.apps.ocp-bm3-cilium-8858d4f50002.ocp.lan + # console-openshift-console.apps.ocp-bm3-cilium-8858d4f50002.ocp.lan + # grafana-openshift-monitoring.apps.ocp-bm3-cilium-8858d4f50002.ocp.lan + # thanos-querier-openshift-monitoring.apps.ocp-bm3-cilium-8858d4f50002.ocp.lan + # prometheus-k8s-openshift-monitoring.apps.ocp-bm3-cilium-8858d4f50002.ocp.lan + # alertmanager-main-openshift-monitoring.apps.ocp-bm3-cilium-8858d4f50002.ocp.lan + + etc_hosts = [] + etc_hosts.append( + '%s\tapi.%s.%s' % ( + user_settings['api'], + cluster_info['name'], + cluster_info['base_dns_domain'] + ) + ) + apps = [ + 'oauth-openshift', + 'console-openshift-console', + 'grafana-openshift-monitoring', + 'thanos-querier-openshift-monitoring', + 'prometheus-k8s-openshift-monitoring', + 'alertmanager-main-openshift-monitoring' + ] + for app in apps: + etc_hosts.append( + '%s\t%s.apps.%s.%s' % ( + user_settings['ingress'], + app, + cluster_info['name'], + cluster_info['base_dns_domain'] + ) + ) + + my_output.default('Required /etc/hosts entries') + for entry in etc_hosts: + my_output.default(entry) + + success = ocp_settings_handler.set_ocp_cluster_file( + connector_name, + 'etc_hosts', + '\n'.join(etc_hosts) + ) + if not success: + my_output.error('etc_hosts update failed') + + return connector_name + +def check_ssh_acccess(user_settings, my_output): + my_output.default('Check ssh access...') + + for server in user_settings['server']: + key_filename = file_helper.set_tmp_file( + user_settings['ssh_public_key'] + ) + ssh_handler = ssh.Ssh( + server['ssh']['ip'], + server['ssh']['username'], + key_filename=key_filename + ) + if not ssh_handler.is_ssh(): + my_output.error('SSH access to cluster node failed: %s' % (server['ssh']['ip'])) + return False + + return True + +def prepare_kubeconfig(user_settings, cluster_info, my_output): + my_output.default('Prepare kubeconfig...') + for server in user_settings['server']: + if server['kube']: + key_filename = file_helper.set_tmp_file( + user_settings['ssh_public_key'] + ) + ssh_handler = ssh.Ssh( + server['ssh']['ip'], + server['ssh']['username'], + key_filename=key_filename + ) + + success = ssh_handler.create_directory('.kube') + if not success: + my_output.error('Directory .kube create failed') + return False + + success = ssh_handler.scp_file( + cluster_info['kubeconfig'], + '.kube/config' + ) + if not success: + my_output.error('Kubeconfig upload failed') + return False + + my_output.default('Kubeconfig upload successful') + + success = ssh_handler.set_file_chmod( + '.kube/config', + '600' + ) + if not success: + my_output.error('Kubeconfig chmod failed') + return False + + my_output.default('Kubeconfig chmod successful') + + return True + +def run_tasks(user_settings, my_output): + my_output.default('Run tasks...') + for server in user_settings['server']: + if server['kube']: + key_filename = file_helper.set_tmp_file( + user_settings['ssh_public_key'] + ) + ssh_handler = ssh.Ssh( + server['ssh']['ip'], + server['ssh']['username'], + key_filename=key_filename + ) + + if 'tasks' in user_settings: + for task in user_settings['tasks']: + if 'command' in task: + for command in task['command']: + my_output.default('Run command: %s' % command, before_newline=True) + success, output, error = ssh_handler.run_cmd(command) + if not success: + my_output.error('Failed') + else: + my_output.default(output) + + return True + +def post_install(user_settings, cluster_info, my_output, log_id): + success = False + connector_name = create_connector(user_settings, cluster_info, my_output, log_id) + if check_ssh_acccess(user_settings, my_output): + if prepare_kubeconfig(user_settings, cluster_info, my_output): + if run_tasks(user_settings, my_output): + success = True + return success + +def run(user_settings, data, infra, manifests, log_id=None): + my_output = output_helper.OutputHelper(log_id=log_id) + log = log_helper.Log(log_id=log_id) + + openshift_output_handler = openshift_output.OpenshiftOutput(log_id=log_id) + console_handler = console.Console(log_id=log_id) + + cluster_id, cluster_info = create_cluster( + data, + infra, + manifests, + console_handler, + my_output, + log + ) + if cluster_info is None: + return False + + success, web_server_supported = boot_from_iso( + user_settings, + cluster_id, + cluster_info, + console_handler, + my_output, + log, + log_id + ) + if not success: + return False + + success = update_cluster_settings( + user_settings, + cluster_id, + console_handler, + my_output + ) + if not success: + return False + + success = wait_installation_started( + cluster_id, + console_handler, + my_output + ) + + if web_server_supported: + success = boot_from_hdd( + user_settings, + my_output, + log_id + ) + if not success: + return False + + success = wait_installation_finished( + user_settings, + cluster_id, + console_handler, + my_output, + log + ) + + if web_server_supported: + delete_iso( + user_settings, + cluster_id, + my_output + ) + + if not success: + my_output.error('Installation failed') + return False + + my_output.default('Collecting cluster information...') + + cluster_info = console_handler.get_assisted_install_cluster( + cluster_id=cluster_id, + credentials_info=True, + kubeconfig_info=True, + cache_enabled=False + ) + if cluster_info is None: + my_output.error('Failed to get newly installed cluster information') + return False + + openshift_output_handler.print_assisted_install_cluster_credentials( + cluster_info + ) + openshift_output_handler.print_assisted_install_cluster_kubeconfig( + cluster_info + ) + + success = post_install( + user_settings, + cluster_info, + my_output, + log_id + ) + if not success: + return False + + my_output.default('OpenShift bare metal installation completed successfully') + + return True diff --git a/lib/workflow/osp_ocp_migration.py b/lib/workflow/osp_ocp_migration.py new file mode 100644 index 00000000..1a90def5 --- /dev/null +++ b/lib/workflow/osp_ocp_migration.py @@ -0,0 +1,412 @@ +import os +import math +import time +import uuid + +from lib import file_helper +from lib import template +from lib import ssh +from lib.k8s import output as k8s_output +from lib.osp import output as osp_output + +from menu import common + + +def run(ctx, osp_handlers, osp_virtual_machine_info, k8s_handlers, namespace, vmi, settings, deployment_directory,confirmation_mode=False): + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + + vmi_filename = os.path.join(deployment_directory, 'vmi.yaml') + rules_filename = os.path.join(deployment_directory, 'rules.yaml') + migration_rules = file_helper.get_file_yaml(rules_filename) + + migration_tag = str(uuid.uuid4()).split('-')[-1] + ctx.my_output.default('Migation tag: %s' % (migration_tag)) + + vm_stopped = False + if osp_handlers.is_virtual_machine_up(osp_virtual_machine_info['id']): + ctx.my_output.default('Stopping virtual machine') + if not osp_handlers.stop_virtual_machine(osp_virtual_machine_info['id'], wait=True): + ctx.my_output.error('Virtual machine stop failed') + return False + + vm_stopped = True + + ctx.my_output.default('Virtual machine stopped') + + ctx.my_output.default('Create image snapshot of virtual machine') + + osp_virtual_machine_snapshot_image_name = 'migrate-%s' % (migration_tag) + osp_virtual_machine_snapshot_image_id = osp_handlers.create_image_from_virtual_machine( + osp_virtual_machine_info['id'], + osp_virtual_machine_snapshot_image_name + ) + if osp_virtual_machine_snapshot_image_id is None: + ctx.my_output.error( + 'Failed to create image snapshot from virtual machine' + ) + return False + + ctx.my_output.default( + 'Virtual machine image snapshot started: %s' % ( + osp_virtual_machine_snapshot_image_name + ) + ) + + if not osp_handlers.wait_for_image_active(osp_virtual_machine_snapshot_image_id, timeout=600): + ctx.my_output.error( + 'Wait for image active timed out' + ) + return False + + time.sleep(10) + + ctx.my_output.default( + 'Virtual machine image snapshot completed: %s' % ( + osp_virtual_machine_snapshot_image_name + ) + ) + + if vm_stopped: + if confirmation_mode: + ctx.my_output.default('Start virtual machine in openstack?') + if not common.get_confirmation(): + return False + + if not osp_handlers.start_virtual_machine(osp_virtual_machine_info['id'], wait=True): + ctx.my_output.error('Virtual machine start failed') + return False + + ctx.my_output.default('Virtual machine started') + + osp_virtual_machine_snapshot_image_info = osp_handlers.get_image(image_id=osp_virtual_machine_snapshot_image_id, cache_enabled=False) + if osp_virtual_machine_snapshot_image_info is None: + ctx.my_output.error( + 'Failed to find image: %s' % (osp_virtual_machine_snapshot_image_id) + ) + return False + + osp_virtual_machine_image_filename = '/tmp/migrate-%s' % (migration_tag) + ctx.my_output.default( + 'Download image %s to local filename %s' % ( + osp_virtual_machine_snapshot_image_name, + osp_virtual_machine_image_filename + ) + ) + + if not osp_handlers.download_image(osp_virtual_machine_snapshot_image_id, osp_virtual_machine_image_filename): + ctx.my_output.error( + 'Image download failed' + ) + return False + + if osp_virtual_machine_snapshot_image_info['checksum'] is None: + ctx.my_output.default('OSP image checksum unknown. Skipping checksum verification') + else: + ctx.my_output.default('Verify checksum') + local_file_checksum = file_helper.get_md5(osp_virtual_machine_image_filename) + if local_file_checksum is None: + ctx.my_output.error( + 'MD5 checksum failed: %s' % (osp_virtual_machine_image_filename) + ) + return False + + if local_file_checksum != osp_virtual_machine_snapshot_image_info['checksum']: + ctx.my_output.error( + 'Image checksum does not match' + ) + ctx.my_output.default( + 'Image %s: %s' % ( + osp_virtual_machine_snapshot_image_name, + osp_virtual_machine_snapshot_image_info['checksum'] + ) + ) + ctx.my_output.default( + 'File %s: %s' % ( + osp_virtual_machine_image_filename, + local_file_checksum + ) + ) + return False + + ctx.my_output.default('Delete snapshot image: %s' % (osp_virtual_machine_snapshot_image_name)) + if not osp_handlers.delete_image(osp_virtual_machine_snapshot_image_id): + ctx.my_output.error( + 'Image delete failed' + ) + return False + + pvc_namespace = namespace + pvc_name = 'migrate-%s' % (migration_tag) + if osp_virtual_machine_info['flavor_info']['disk'] == 0: + ctx.my_output.default( + 'No OSP flavor info. Fallback to default 30Gi pvc size' + ) + pvc_size = '30Gi' + else: + pvc_size = '%sGi' % (math.ceil(osp_virtual_machine_info['flavor_info']['disk'] * 1.05)) + + if k8s_handlers.is_pvc(pvc_namespace, pvc_name, cache_enabled=False): + if k8s_handlers.is_pvc_used(pvc_namespace, pvc_name): + ctx.my_output.default('PVC %s/%s already exists and is used. It cannot be overwritten.' % (pvc_namespace, pvc_name)) + return False + + if confirmation_mode: + ctx.my_output.default('PVC %s/%s already exists. Remove it?' % (pvc_namespace, pvc_name)) + if not common.get_confirmation(): + return + + if not k8s_handlers.delete_namespaced_pvc(pvc_namespace, pvc_name): + ctx.my_output.error('PVC delete failed') + return False + + ctx.my_output.default('PVC deleted') + + ctx.my_output.default( + 'Creating PVC %s/%s type file size %s from file %s' % ( + pvc_namespace, + pvc_name, + pvc_size, + osp_virtual_machine_image_filename + ) + ) + + success = k8s_handlers.create_pvc_via_data_volume_upload( + pvc_namespace, + pvc_name, + settings['tools'], + settings['virtctl'], + source_filename=osp_virtual_machine_image_filename, + file_type='file', + size=pvc_size + ) + if not success: + ctx.my_output.error('PVC creation failed') + return False + + ctx.my_output.default('PVC created') + + pvcs = k8s_handlers.get_pvcs( + object_filter=['namespace:%s' % (pvc_namespace), 'name:%s' % (pvc_name)], + usage_info=False, + pv_info=True, + cache_enabled=False + ) + k8s_output_handler.print_pvcs( + pvcs, + title=False + ) + + remove_file = True + if confirmation_mode: + ctx.my_output.default('Remove local image file?') + if not common.get_confirmation(): + remove_file = False + + if remove_file: + try: + os.remove(osp_virtual_machine_image_filename) + ctx.my_output.default( + 'Local file removed: %s' % (osp_virtual_machine_image_filename) + ) + except BaseException: + ctx.my_output.error( + 'Local file remove failed: %s' % (osp_virtual_machine_image_filename) + ) + + ctx.my_output.default('Preparing virtual machine deployment files') + variables = {} + variables['NAMESPACE'] = namespace + variables['NAME'] = vmi + variables['CORES'] = osp_virtual_machine_info['flavor_info']['vcpus'] + variables['SOCKETS'] = 1 + variables['THREADS'] = 1 + variables['MEMORY'] = '%sM' % (osp_virtual_machine_info['flavor_info']['ram']) + variables['PVC_NAMESPACE'] = pvc_namespace + variables['PVC_NAME'] = pvc_name + + interface_index = 1 + for interface_info in osp_virtual_machine_info['interface']: + variables['INTERFACE_%s_MAC' % (interface_index)] = interface_info['mac'] + interface_index = interface_index + 1 + + if 'variables' in migration_rules: + for key in migration_rules['variables']: + variables[key] = migration_rules['variables'][key] + + template_handler = template.Template( + log_id=ctx.run_id + ) + + if 'sriov_network' in migration_rules: + network_content = {} + for network_name in migration_rules['sriov_network']: + network_filename = os.path.join(deployment_directory, '%s.yaml' % (network_name)) + network_content[network_name] = template_handler.get_template( + network_filename, + variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_conversion=True + ) + if network_content[network_name] is None: + ctx.my_output.error( + 'Failed to generate network definition: %s' % (network_name) + ) + return False + + ctx.my_output.default( + 'Preparing sriov network %s/%s' % ( + network_content[network_name]['metadata']['namespace'], + network_content[network_name]['metadata']['name'] + ) + ) + + network_mo = k8s_handlers.get_sriov_network( + network_content[network_name]['metadata']['name'], + cache_enabled=False, + return_mo=True + ) + if network_mo is not None: + ctx.my_output.error('SRIOV network already exists') + return False + + if not k8s_handlers.create_sriov_network(network_content[network_name]): + ctx.my_output.error('SRIOV network create failed') + return False + + ctx.my_output.default( + 'Network %s/%s created' % ( + network_content[network_name]['metadata']['namespace'], + network_content[network_name]['metadata']['name'] + ) + ) + + vmi_content = template_handler.get_template( + vmi_filename, + variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_conversion=True + ) + if vmi_content is None: + ctx.my_output.error( + 'Failed to generate virtual machine instance definition' + ) + return False + + ctx.my_output.default('Starting virtual machine instance') + if not k8s_handlers.create_virtual_machine_instance_mo(vmi_content): + ctx.my_output.error( + 'Create virtual machine instance request failed' + ) + return False + + ctx.my_output.default( + 'Virtual machine %s/%s created' % ( + vmi_content['metadata']['namespace'], + vmi_content['metadata']['name'] + ) + ) + + if 'service' in migration_rules: + service_content = {} + for service_name in migration_rules['service']: + service_filename = os.path.join(deployment_directory, '%s.yaml' % (service_name)) + service_content[service_name] = template_handler.get_template( + service_filename, + variables, + replace_variables_enabled=True, + check_remaining_variables=True, + yaml_conversion=True + ) + if service_content[service_name] is None: + ctx.my_output.error( + 'Failed to generate service definition: %s' % (service_name) + ) + return False + + ctx.my_output.default( + 'Preparing service %s: %s/%s' % ( + service_name, + service_content[service_name]['metadata']['namespace'], + service_content[service_name]['metadata']['name'] + ) + ) + + service_mo = k8s_handlers.get_service( + service_content[service_name]['metadata']['namespace'], + service_content[service_name]['metadata']['name'], + cache_enabled=False, + return_mo=True + ) + if service_mo is not None: + ctx.my_output.error('Service already exists') + return False + + if not k8s_handlers.create_namespaced_service(service_content[service_name]): + ctx.my_output.error('Service create failed') + return False + + ctx.my_output.default( + 'Serice %s/%s created' % ( + service_content[service_name]['metadata']['namespace'], + service_content[service_name]['metadata']['name'] + ) + ) + + if migration_rules['ssh']['enabled']: + ssh_service_name = migration_rules['ssh']['service'] + service_namespace = service_content[ssh_service_name]['metadata']['namespace'] + service_name = service_content[ssh_service_name]['metadata']['name'] + ctx.my_output.default( + 'Wait ssh service %s/%s using (%s,%s) credentials' % ( + service_namespace, + service_name, + migration_rules['ssh']['username'], + migration_rules['ssh']['password'] + ) + ) + + node_ip, node_port = k8s_handlers.get_service_node_ip_port( + service_namespace, + service_name, + cache_enabled=False + ) + if node_ip is None or node_port is None: + ctx.my_output.error( + 'SSH service information failed' + ) + return False + + ctx.my_output.default( + 'SSH service node port: %s:%s' % ( + node_ip, + node_port + ) + ) + ssh_handler = ssh.Ssh( + node_ip, + migration_rules['ssh']['username'], + port=node_port, + password=migration_rules['ssh']['password'], + endpoint_type=migration_rules['ssh']['type'], + log_id=ctx.run_id + ) + if ssh_handler is None: + ctx.my_output.error( + 'Failed to initialize ssh session' + ) + return False + + if not ssh_handler.wait_ssh(timeout=migration_rules['ssh']['timeout']): + ctx.my_output.error( + 'SSH check timed out' + ) + return False + + ctx.my_output.default( + 'Migration completed' + ) + + return True diff --git a/lib/xd/__init__.py b/lib/xd/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lib/xd/__pycache__/__init__.cpython-310.pyc b/lib/xd/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..da174d1c Binary files /dev/null and b/lib/xd/__pycache__/__init__.cpython-310.pyc differ diff --git a/lib/xd/__pycache__/aci.cpython-310.pyc b/lib/xd/__pycache__/aci.cpython-310.pyc new file mode 100644 index 00000000..1438e99e Binary files /dev/null and b/lib/xd/__pycache__/aci.cpython-310.pyc differ diff --git a/lib/xd/__pycache__/nexus.cpython-310.pyc b/lib/xd/__pycache__/nexus.cpython-310.pyc new file mode 100644 index 00000000..f9a9230d Binary files /dev/null and b/lib/xd/__pycache__/nexus.cpython-310.pyc differ diff --git a/lib/xd/__pycache__/ocp2fabric.cpython-310.pyc b/lib/xd/__pycache__/ocp2fabric.cpython-310.pyc new file mode 100644 index 00000000..1758b010 Binary files /dev/null and b/lib/xd/__pycache__/ocp2fabric.cpython-310.pyc differ diff --git a/lib/xd/__pycache__/server2fabric.cpython-310.pyc b/lib/xd/__pycache__/server2fabric.cpython-310.pyc new file mode 100644 index 00000000..9af4b601 Binary files /dev/null and b/lib/xd/__pycache__/server2fabric.cpython-310.pyc differ diff --git a/lib/xd/__pycache__/vc2fabric.cpython-310.pyc b/lib/xd/__pycache__/vc2fabric.cpython-310.pyc new file mode 100644 index 00000000..3bf1d95f Binary files /dev/null and b/lib/xd/__pycache__/vc2fabric.cpython-310.pyc differ diff --git a/lib/xd/aci.py b/lib/xd/aci.py new file mode 100644 index 00000000..379e57cb --- /dev/null +++ b/lib/xd/aci.py @@ -0,0 +1,148 @@ +from lib.aci import settings as aci_settings +from lib.aci import apic + + +def get_aci_handler(controller_name, log_id=None): + aci_settings_handler = aci_settings.ApicSettings(log_id=log_id) + aci_controllers = aci_settings_handler.get_apic_controllers() + if aci_controllers is not None: + for aci_controller in aci_controllers: + if aci_controller['name'] == controller_name: + apic_handler = apic.Apic( + aci_controller['ip'], + aci_controller['port'], + aci_controller['username'], + aci_controller['password'], + apic_name=aci_controller['name'], + log_id=log_id + ) + return apic_handler + + return None + + +def get_any_aci_handler(log_id=None): + aci_settings_handler = aci_settings.ApicSettings(log_id=log_id) + aci_controllers = aci_settings_handler.get_apic_controllers() + if aci_controllers is not None: + for aci_controller in aci_controllers: + apic_handler = apic.Apic( + aci_controller['ip'], + aci_controller['port'], + aci_controller['username'], + aci_controller['password'], + apic_name=aci_controller['name'], + log_id=log_id + ) + return apic_handler + + return None + + +def get_aci_endpoints(log_id=None, fabric_info=True, macs=None, apic_ips=None): + endpoints = [] + + endpoint_filter = None + if macs is not None: + endpoint_filter = [] + for mac in macs: + endpoint_filter.append('mac:%s' % (mac)) + + aci_settings_handler = aci_settings.ApicSettings(log_id=log_id) + aci_controllers = aci_settings_handler.get_apic_controllers() + if aci_controllers is not None: + for aci_controller in aci_controllers: + if apic_ips is None or aci_controller['ip'] in apic_ips: + apic_handler = apic.Apic( + aci_controller['ip'], + aci_controller['port'], + aci_controller['username'], + aci_controller['password'], + apic_name=aci_controller['name'], + log_id=log_id + ) + + apic_endpoints = apic_handler.get_endpoints( + endpoint_filter=endpoint_filter, + fabric_info=fabric_info + ) + if apic_endpoints is None: + continue + + for apic_endpoint in apic_endpoints: + apic_endpoint['apic'] = aci_controller['name'] + + endpoints = endpoints + apic_endpoints + + return endpoints + + +def get_aci_cdp_info(log_id=None): + aci_cdp_info = [] + + aci_settings_handler = aci_settings.ApicSettings(log_id=log_id) + aci_controllers = aci_settings_handler.get_apic_controllers() + if aci_controllers is not None: + for aci_controller in aci_controllers: + apic_handler = apic.Apic( + aci_controller['ip'], + aci_controller['port'], + aci_controller['username'], + aci_controller['password'], + apic_name=aci_controller['name'], + log_id=log_id + ) + + nodes = apic_handler.get_nodes( + node_filter=['role:leaf'] + ) + + for node in nodes: + node_cdp_info = apic_handler.get_protocol_cdp( + node['podId'], + node['id'], + include_instance=False, + include_interfaces=False + ) + node_cdp_info['apic'] = aci_controller['name'] + aci_cdp_info.append( + node_cdp_info + ) + + return aci_cdp_info + + +def get_aci_lldp_info(log_id=None): + aci_lldp_info = [] + + aci_settings_handler = aci_settings.ApicSettings(log_id=log_id) + aci_controllers = aci_settings_handler.get_apic_controllers() + if aci_controllers is not None: + for aci_controller in aci_controllers: + apic_handler = apic.Apic( + aci_controller['ip'], + aci_controller['port'], + aci_controller['username'], + aci_controller['password'], + apic_name=aci_controller['name'], + log_id=log_id + ) + + nodes = apic_handler.get_nodes( + node_filter=['role:leaf'] + ) + + for node in nodes: + node_lldp_info = apic_handler.get_protocol_lldp( + node['podId'], + node['id'], + instance_info=False, + stats_info=False, + adjacency_info=True + ) + node_lldp_info['apic'] = aci_controller['name'] + aci_lldp_info.append( + node_lldp_info + ) + + return aci_lldp_info diff --git a/lib/xd/nexus.py b/lib/xd/nexus.py new file mode 100644 index 00000000..5728d917 --- /dev/null +++ b/lib/xd/nexus.py @@ -0,0 +1,28 @@ +from lib.nexus import settings as nexus_settings +from lib.nexus import nxapi + + +def get_nexus_lldp_info(log_id=None, verbose=False, cache_enabled=False): + nexus_lldp_info = [] + + nexus_settings_handler = nexus_settings.NexusSettings(log_id=log_id) + nexus_switches = nexus_settings_handler.get_nexus_switches() + if nexus_switches is not None: + for nexus_switch in nexus_switches: + nexus_handler = nxapi.NxApi( + nexus_switch['ip'], + nexus_switch['username'], + nexus_switch['password'], + name=nexus_switch['name'], + log_id=log_id, + cache_enabled=cache_enabled + ) + + info = {} + info['name'] = nexus_switch['name'] + info['neighbors'] = nexus_handler.get_lldp_neighbors() + nexus_lldp_info.append( + info + ) + + return nexus_lldp_info diff --git a/lib/xd/ocp2fabric.py b/lib/xd/ocp2fabric.py new file mode 100644 index 00000000..9cc817fe --- /dev/null +++ b/lib/xd/ocp2fabric.py @@ -0,0 +1,29 @@ +from lib.xd import aci as aci_helper +from lib.aci import output as aci_output + + +def print_ocp_vm_net_fabric_info(interfaces, log_id=None, stream='default'): + if interfaces is None: + return None + + endpoints = [] + for interface in interfaces: + if 'endpoints' in interface: + endpoints = endpoints + interface['endpoints'] + + if len(endpoints) == 0: + return None + + apic_handler = aci_helper.get_any_aci_handler(log_id=log_id) + if apic_handler is None: + return None + + aci_output_handler = aci_output.ApicOutput(log_id=log_id) + aci_output_handler.my_output.clear_output() + aci_output_handler.print_endpoints( + endpoints, + stream=stream, + title=True + ) + + return apic_handler.my_output.get_output() diff --git a/lib/xd/server2fabric.py b/lib/xd/server2fabric.py new file mode 100644 index 00000000..72051d37 --- /dev/null +++ b/lib/xd/server2fabric.py @@ -0,0 +1,119 @@ +from lib import ip_helper +from lib.xd import aci as aci_helper +from lib.xd import nexus as nexus_helper + + +def get_server_macs(server_info): + macs = [] + for mac_address_info in server_info['MacAddressInfo']: + macs.append(mac_address_info['MacAddress']) + return macs + + +def add_server_fabric_aci_lldp_info(server_info, log_id=None): + lldp_info = aci_helper.get_aci_lldp_info( + log_id=log_id + ) + + server_info['lldpSysName'] = None + for mac_address in server_info['MacAddressInfo']: + for node_info in lldp_info: + for adjacency in node_info['adjacency']: + if ip_helper.is_mac_equal(mac_address['MacAddress'], adjacency['portIdV']): + mac_address['Fabric']['Type'] = 'ACI' + mac_address['Fabric']['Controller'] = node_info['apic'] + mac_address['Fabric']['Node'] = '%s/%s' % ( + adjacency['pod_id'], + adjacency['node_id'] + ) + mac_address['Fabric']['Port'] = adjacency['interface_id'] + mac_address['Fabric']['Source'] = 'lldp' + server_info['lldpSysName'] = adjacency['sysName'] + + return server_info + + +def add_server_fabric_aci_cdp_info(server_info, log_id=None): + cdp_info = aci_helper.get_aci_cdp_info( + log_id=log_id + ) + + for mac_address in server_info['MacAddressInfo']: + if len(mac_address['Fabric']) == 0: + for node_info in cdp_info: + for adjacency in node_info['neighbors']: + if adjacency['sysName'] == server_info['lldpSysName']: + mac_address['Fabric']['Type'] = 'ACI' + mac_address['Fabric']['Controller'] = node_info['apic'] + mac_address['Fabric']['Node'] = '%s/%s' % ( + adjacency['dn'].split('/')[1], + adjacency['dn'].split('/')[2] + ) + mac_address['Fabric']['Port'] = adjacency['interfaceId'] + mac_address['Fabric']['Source'] = 'cdp' + + return server_info + + +def add_server_fabric_aci_info(server_info, log_id=None, include_cdp=True): + server_info = add_server_fabric_aci_lldp_info( + server_info, + log_id=log_id + ) + + if include_cdp: + if server_info['lldpSysName'] is not None: + server_info = add_server_fabric_aci_cdp_info( + server_info, + log_id=log_id + ) + + return server_info + + +def add_server_fabric_nexus_lldp_info(server_info, log_id=None): + lldp_info = nexus_helper.get_nexus_lldp_info( + log_id=log_id + ) + + for mac_address in server_info['MacAddressInfo']: + for switch_info in lldp_info: + for adjacency in switch_info['neighbors']: + if ip_helper.is_mac_equal(mac_address['MacAddress'], adjacency['port_id']): + mac_address['Fabric']['Type'] = 'Nexus' + mac_address['Fabric']['Controller'] = '-' + mac_address['Fabric']['Node'] = switch_info['name'] + mac_address['Fabric']['Port'] = adjacency['l_port_id'] + mac_address['Fabric']['Source'] = 'lldp' + + return server_info + + +def add_server_fabric_nexus_info(server_info, log_id=None): + server_info = add_server_fabric_nexus_lldp_info( + server_info, + log_id=log_id + ) + + return server_info + + +def add_server_fabric_info(iaccount, server_info, log_id=None, include_cdp=True): + if 'MacAddressInfo' not in server_info: + return server_info + + for mac_address_info in server_info['MacAddressInfo']: + mac_address_info['Fabric'] = {} + + server_info = add_server_fabric_aci_info( + server_info, + log_id=log_id, + include_cdp=include_cdp + ) + + server_info = add_server_fabric_nexus_info( + server_info, + log_id=log_id + ) + + return server_info diff --git a/lib/xd/vc2fabric.py b/lib/xd/vc2fabric.py new file mode 100644 index 00000000..49bedc1d --- /dev/null +++ b/lib/xd/vc2fabric.py @@ -0,0 +1,53 @@ +import copy + +from lib import ip_helper +from lib.xd import aci as aci_helper + + +def get_vms_macs(virtual_machines): + macs = [] + for virtual_machine in virtual_machines: + for nic in virtual_machine['nic']: + macs.append(nic['macAddress']) + return macs + + +def add_vms_fabric_connections(virtual_machines, log_id=None): + endpoints = aci_helper.get_aci_endpoints( + log_id=log_id, + macs=get_vms_macs(virtual_machines) + ) + + if endpoints is not None: + for virtual_machine in virtual_machines: + expanded_nics = [] + for nic in virtual_machine['nic']: + expanded_nic = copy.deepcopy(nic) + expanded_nic['fabric'] = '' + expanded_nic['node'] = '' + expanded_nic['port'] = '' + + added = False + for endpoint in endpoints: + if ip_helper.is_mac_equal(nic['macAddress'], endpoint['mac']): + if len(endpoint['fabric']) == 0: + expanded_nic['fabric'] = endpoint['apic'] + expanded_nics.append(expanded_nic) + added = True + break + + for fabric_path in endpoint['fabric']: + expanded_nic['fabric'] = endpoint['apic'] + expanded_nic['node'] = fabric_path['node_id'] + expanded_nic['port'] = fabric_path['ep'] + expanded_nics.append(expanded_nic) + + added = True + break + + if not added: + expanded_nics.append(expanded_nic) + + virtual_machine['nic'] = copy.deepcopy(expanded_nics) + + return virtual_machines diff --git a/lib/xmltodict.py b/lib/xmltodict.py new file mode 100644 index 00000000..793b1d28 --- /dev/null +++ b/lib/xmltodict.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python +"Makes working with XML feel like you are working with JSON" + +from xml.parsers import expat +from xml.sax.saxutils import XMLGenerator +from xml.sax.xmlreader import AttributesImpl +try: # pragma no cover + from cStringIO import StringIO +except ImportError: # pragma no cover + try: + from StringIO import StringIO + except ImportError: + from io import StringIO +try: # pragma no cover + from collections import OrderedDict +except ImportError: # pragma no cover + try: + from ordereddict import OrderedDict + except ImportError: + OrderedDict = dict + +try: # pragma no cover + _basestring = basestring +except NameError: # pragma no cover + _basestring = str +try: # pragma no cover + _unicode = unicode +except NameError: # pragma no cover + _unicode = str + +__author__ = 'Martin Blech' +__version__ = '0.9.0' +__license__ = 'MIT' + + +class ParsingInterrupted(Exception): + pass + + +class _DictSAXHandler(object): + def __init__(self, + item_depth=0, + item_callback=lambda *args: True, + xml_attribs=True, + attr_prefix='@', + cdata_key='#text', + force_cdata=False, + cdata_separator='', + postprocessor=None, + dict_constructor=OrderedDict, + strip_whitespace=True, + namespace_separator=':', + namespaces=None): + self.path = [] + self.stack = [] + self.data = None + self.item = None + self.item_depth = item_depth + self.xml_attribs = xml_attribs + self.item_callback = item_callback + self.attr_prefix = attr_prefix + self.cdata_key = cdata_key + self.force_cdata = force_cdata + self.cdata_separator = cdata_separator + self.postprocessor = postprocessor + self.dict_constructor = dict_constructor + self.strip_whitespace = strip_whitespace + self.namespace_separator = namespace_separator + self.namespaces = namespaces + + def _build_name(self, full_name): + if not self.namespaces: + return full_name + i = full_name.rfind(self.namespace_separator) + if i == -1: + return full_name + namespace, name = full_name[:i], full_name[i + 1:] + short_namespace = self.namespaces.get(namespace, namespace) + if not short_namespace: + return name + else: + return self.namespace_separator.join((short_namespace, name)) + + def _attrs_to_dict(self, attrs): + if isinstance(attrs, dict): + return attrs + return self.dict_constructor(zip(attrs[0::2], attrs[1::2])) + + # TODO: Rename method using lower_case. + def startElement(self, full_name, attrs): + name = self._build_name(full_name) + attrs = self._attrs_to_dict(attrs) + self.path.append((name, attrs or None)) + if len(self.path) > self.item_depth: + self.stack.append((self.item, self.data)) + if self.xml_attribs: + attrs = self.dict_constructor( + (self.attr_prefix + key, value) + for (key, value) in attrs.items()) + else: + attrs = None + self.item = attrs or None + self.data = None + + # TODO: Rename method using lower_case. + def endElement(self, full_name): + name = self._build_name(full_name) + if len(self.path) == self.item_depth: + item = self.item + if item is None: + item = self.data + should_continue = self.item_callback(self.path, item) + if not should_continue: + raise ParsingInterrupted() + if len(self.stack): + item, data = self.item, self.data + self.item, self.data = self.stack.pop() + if self.strip_whitespace and data is not None: + data = data.strip() or None + if data and self.force_cdata and item is None: + item = self.dict_constructor() + if item is not None: + if data: + self.push_data(item, self.cdata_key, data) + self.item = self.push_data(self.item, name, item) + else: + self.item = self.push_data(self.item, name, data) + else: + self.item = self.data = None + self.path.pop() + + def characters(self, data): + if not self.data: + self.data = data + else: + self.data += self.cdata_separator + data + + def push_data(self, item, key, data): + if self.postprocessor is not None: + result = self.postprocessor(self.path, key, data) + if result is None: + return item + key, data = result + if item is None: + item = self.dict_constructor() + try: + value = item[key] + if isinstance(value, list): + value.append(data) + else: + item[key] = [value, data] + except KeyError: + item[key] = data + return item + + +def parse(xml_input, encoding=None, expat=expat, process_namespaces=False, + namespace_separator=':', **kwargs): + """Parse the given XML input and convert it into a dictionary. + + `xml_input` can either be a `string` or a file-like object. + + If `xml_attribs` is `True`, element attributes are put in the dictionary + among regular child elements, using `@` as a prefix to avoid collisions. If + set to `False`, they are just ignored. + + Simple example:: + + >>> import xmltodict + >>> doc = xmltodict.parse(\"\"\" + ... + ... 1 + ... 2 + ... + ... \"\"\") + >>> doc['a']['@prop'] + u'x' + >>> doc['a']['b'] + [u'1', u'2'] + + If `item_depth` is `0`, the function returns a dictionary for the root + element (default behavior). Otherwise, it calls `item_callback` every time + an item at the specified depth is found and returns `None` in the end + (streaming mode). + + The callback function receives two parameters: the `path` from the document + root to the item (name-attribs pairs), and the `item` (dict). If the + callback's return value is false-ish, parsing will be stopped with the + :class:`ParsingInterrupted` exception. + + Streaming example:: + + >>> def handle(path, item): + ... print 'path:%s item:%s' % (path, item) + ... return True + ... + >>> xmltodict.parse(\"\"\" + ... + ... 1 + ... 2 + ... \"\"\", item_depth=2, item_callback=handle) + path:[(u'a', {u'prop': u'x'}), (u'b', None)] item:1 + path:[(u'a', {u'prop': u'x'}), (u'b', None)] item:2 + + The optional argument `postprocessor` is a function that takes `path`, + `key` and `value` as positional arguments and returns a new `(key, value)` + pair where both `key` and `value` may have changed. Usage example:: + + >>> def postprocessor(path, key, value): + ... try: + ... return key + ':int', int(value) + ... except (ValueError, TypeError): + ... return key, value + >>> xmltodict.parse('12x', + ... postprocessor=postprocessor) + OrderedDict([(u'a', OrderedDict([(u'b:int', [1, 2]), (u'b', u'x')]))]) + + You can pass an alternate version of `expat` (such as `defusedexpat`) by + using the `expat` parameter. E.g: + + >>> import defusedexpat + >>> xmltodict.parse('hello', expat=defusedexpat.pyexpat) + OrderedDict([(u'a', u'hello')]) + + """ + handler = _DictSAXHandler(namespace_separator=namespace_separator, + **kwargs) + if isinstance(xml_input, _unicode): + if not encoding: + encoding = 'utf-8' + xml_input = xml_input.encode(encoding) + if not process_namespaces: + namespace_separator = None + parser = expat.ParserCreate( + encoding, + namespace_separator + ) + try: + parser.ordered_attributes = True + except AttributeError: + # Jython's expat does not support ordered_attributes + pass + parser.StartElementHandler = handler.startElement + parser.EndElementHandler = handler.endElement + parser.CharacterDataHandler = handler.characters + parser.buffer_text = True + try: + parser.ParseFile(xml_input) + except (TypeError, AttributeError): + parser.Parse(xml_input, True) + return handler.item + + +def _emit(key, value, content_handler, + attr_prefix='@', + cdata_key='#text', + depth=0, + preprocessor=None, + pretty=False, + newl='\n', + indent='\t'): + if preprocessor is not None: + result = preprocessor(key, value) + if result is None: + return + key, value = result + if not isinstance(value, (list, tuple)): + value = [value] + if depth == 0 and len(value) > 1: + raise ValueError('document with multiple roots') + for v in value: + if v is None: + v = OrderedDict() + elif not isinstance(v, dict): + v = _unicode(v) + if isinstance(v, _basestring): + v = OrderedDict(((cdata_key, v),)) + cdata = None + attrs = OrderedDict() + children = [] + for ik, iv in v.items(): + if ik == cdata_key: + cdata = iv + continue + if ik.startswith(attr_prefix): + attrs[ik[len(attr_prefix):]] = iv + continue + children.append((ik, iv)) + if pretty: + content_handler.ignorableWhitespace(depth * indent) + content_handler.startElement(key, AttributesImpl(attrs)) + if pretty and children: + content_handler.ignorableWhitespace(newl) + for child_key, child_value in children: + _emit(child_key, child_value, content_handler, + attr_prefix, cdata_key, depth + 1, preprocessor, + pretty, newl, indent) + if cdata is not None: + content_handler.characters(cdata) + if pretty and children: + content_handler.ignorableWhitespace(depth * indent) + content_handler.endElement(key) + if pretty and depth: + content_handler.ignorableWhitespace(newl) + + +def unparse(input_dict, output=None, encoding='utf-8', full_document=True, + **kwargs): + """Emit an XML document for the given `input_dict` (reverse of `parse`). + + The resulting XML document is returned as a string, but if `output` (a + file-like object) is specified, it is written there instead. + + Dictionary keys prefixed with `attr_prefix` (default=`'@'`) are interpreted + as XML node attributes, whereas keys equal to `cdata_key` + (default=`'#text'`) are treated as character data. + + The `pretty` parameter (default=`False`) enables pretty-printing. In this + mode, lines are terminated with `'\n'` and indented with `'\t'`, but this + can be customized with the `newl` and `indent` parameters. + + """ + ((key, value),) = input_dict.items() + must_return = False + if output is None: + output = StringIO() + must_return = True + content_handler = XMLGenerator(output, encoding) + if full_document: + content_handler.startDocument() + _emit(key, value, content_handler, **kwargs) + if full_document: + content_handler.endDocument() + if must_return: + value = output.getvalue() + try: # pragma no cover + value = value.decode(encoding) + except AttributeError: # pragma no cover + pass + return value + + +if __name__ == '__main__': # pragma: no cover + import sys + import marshal + + (item_depth,) = sys.argv[1:] + item_depth = int(item_depth) + + def handle_item(path, item): + marshal.dump((path, item), sys.stdout) + return True + + try: + root = parse(sys.stdin, + item_depth=item_depth, + item_callback=handle_item, + dict_constructor=dict) + if item_depth == 0: + handle_item([], root) + except KeyboardInterrupt: + pass diff --git a/menu/__init__.py b/menu/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/__pycache__/__init__.cpython-310.pyc b/menu/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a71770b9 Binary files /dev/null and b/menu/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/__pycache__/common.cpython-310.pyc b/menu/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..8343770f Binary files /dev/null and b/menu/__pycache__/common.cpython-310.pyc differ diff --git a/menu/__pycache__/defaults.cpython-310.pyc b/menu/__pycache__/defaults.cpython-310.pyc new file mode 100644 index 00000000..c187c061 Binary files /dev/null and b/menu/__pycache__/defaults.cpython-310.pyc differ diff --git a/menu/__pycache__/main.cpython-310.pyc b/menu/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a6d1b89b Binary files /dev/null and b/menu/__pycache__/main.cpython-310.pyc differ diff --git a/menu/__pycache__/progress.cpython-310.pyc b/menu/__pycache__/progress.cpython-310.pyc new file mode 100644 index 00000000..81df3083 Binary files /dev/null and b/menu/__pycache__/progress.cpython-310.pyc differ diff --git a/menu/__pycache__/user_inputs.cpython-310.pyc b/menu/__pycache__/user_inputs.cpython-310.pyc new file mode 100644 index 00000000..a0af8928 Binary files /dev/null and b/menu/__pycache__/user_inputs.cpython-310.pyc differ diff --git a/menu/__pycache__/validations.cpython-310.pyc b/menu/__pycache__/validations.cpython-310.pyc new file mode 100644 index 00000000..d395a503 Binary files /dev/null and b/menu/__pycache__/validations.cpython-310.pyc differ diff --git a/menu/common.py b/menu/common.py new file mode 100644 index 00000000..134229b4 --- /dev/null +++ b/menu/common.py @@ -0,0 +1,221 @@ +import threading + +from menu import progress +from lib.intersight import compute +from lib.intersight import compute_output + + +def flags_fixup(ctx, silent, verbose, debug): + if silent: + debug = False + verbose = False + + if debug: + verbose = True + + ctx.my_output.set_flags(silent, verbose, debug) + return (silent, verbose, debug) + + +def get_confirmation(title=True, before_newline=False, after_newline=False): + if before_newline: + print('\n') + + answer = "" + while answer not in ["y", "n"]: + if title: + answer = input("Continue [Y/N]? ").lower() + else: + answer = input("[Y/N]? ").lower() + + if after_newline: + print('\n') + + return answer == "y" + + +def get_value_from_list(title, values, before_newline=False, after_newline=False): + if before_newline: + print('\n') + + print(title) + for item in values: + print('- %s' % (item)) + answer = None + while answer not in values: + answer = input('Selected: ') + if len(answer) == 0: + return None + + if after_newline: + print('\n') + + return answer + + +def get_integer(title, before_newline=False, after_newline=False): + if before_newline: + print('\n') + + while True: + answer = input(title) + try: + value = int(answer) + except BaseException: + value = None + if value is not None: + if after_newline: + print('\n') + return value + + +def get_servers_mo( + ctx, + iaccount, + ip_filter=None, + name_filter=None, + model_filter=None, + serial_filter=None, + tag_filter=None, + show_progress=True, + include_rack=True, + include_blade=True, + rack_expand=[], + blade_expand=[] + ): + if show_progress: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + try: + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + match_rules = compute_handler.get_mo_match_rules( + ip_filter=ip_filter, + name_filter=name_filter, + model_filter=model_filter, + serial_filter=serial_filter, + tag_filter=tag_filter + ) + servers_mo = compute_handler.get_mo( + match_rules=match_rules, + include_rack=include_rack, + rack_expand=rack_expand, + include_blade=include_blade, + blade_expand=blade_expand, + ) + except BaseException: + servers_mo = None + + ctx.busy = False + + return servers_mo + + +def get_servers_info(ctx, iaccount, ip_filter=None, name_filter=None, serial_filter=None, show_progress=True, include_rack=True, include_blade=True, settings={}, state=True, cache=True): + if show_progress: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + match_rules = compute_handler.get_mo_match_rules( + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serial_filter + ) + + rack_expand = [] + blade_expand = [] + if state: + rack_expand.append('LocatorLed') + rack_expand.append('RegisteredDevice') + blade_expand.append('LocatorLed') + blade_expand.append('RegisteredDevice') + + servers_mo = compute_handler.get_mo( + match_rules=match_rules, + rack_expand=rack_expand, + blade_expand=blade_expand, + include_rack=include_rack, + include_blade=include_blade + ) + if servers_mo is None or len(servers_mo) == 0: + ctx.busy = False + return servers_mo + + if state: + settings['state'] = True + settings['connector'] = True + settings['locator'] = True + settings['server_setting_id'] = True + settings['workflow'] = 3600 + + if cache: + servers_info = compute_handler.get_info( + servers_mo, + settings, + None, + 0 + ) + else: + servers_info = compute_handler.get_info( + servers_mo, + settings, + None, + 1 + ) + + ctx.busy = False + + return servers_info + + +def print_servers_info(ctx, iaccount, ip_filter=None, name_filter=None, serial_filter=None, show_progress=True, include_rack=True, include_blade=True, settings={}, cache=True): + servers_info = get_servers_info( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serial_filter, + show_progress=show_progress, + include_rack=include_rack, + include_blade=include_blade, + settings=settings, + cache=cache + ) + + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + +def print_servers_mo_info(ctx, iaccount, servers_mo, show_progress=True, settings={}, cache=True, title=True): + if show_progress: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + + if cache: + servers_info = compute_handler.get_info( + servers_mo, + settings, + None, + 0 + ) + else: + servers_info = compute_handler.get_info( + servers_mo, + settings, + None, + 1 + ) + + ctx.busy = False + + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + compute_output_handler.print_summary_table( + servers_info, + title=title + ) diff --git a/menu/create/__init__.py b/menu/create/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/__pycache__/__init__.cpython-310.pyc b/menu/create/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b2c388d0 Binary files /dev/null and b/menu/create/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/create/__pycache__/main.cpython-310.pyc b/menu/create/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e17b3807 Binary files /dev/null and b/menu/create/__pycache__/main.cpython-310.pyc differ diff --git a/menu/create/__pycache__/os_image.cpython-310.pyc b/menu/create/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..ff85c12c Binary files /dev/null and b/menu/create/__pycache__/os_image.cpython-310.pyc differ diff --git a/menu/create/__pycache__/os_install.cpython-310.pyc b/menu/create/__pycache__/os_install.cpython-310.pyc new file mode 100644 index 00000000..800f28d5 Binary files /dev/null and b/menu/create/__pycache__/os_install.cpython-310.pyc differ diff --git a/menu/create/__pycache__/scu.cpython-310.pyc b/menu/create/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..ad8f7528 Binary files /dev/null and b/menu/create/__pycache__/scu.cpython-310.pyc differ diff --git a/menu/create/__pycache__/user_inputs.cpython-310.pyc b/menu/create/__pycache__/user_inputs.cpython-310.pyc new file mode 100644 index 00000000..3bc00e85 Binary files /dev/null and b/menu/create/__pycache__/user_inputs.cpython-310.pyc differ diff --git a/menu/create/helm/__init__.py b/menu/create/helm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/helm/chart.py b/menu/create/helm/chart.py new file mode 100644 index 00000000..fa604e78 --- /dev/null +++ b/menu/create/helm/chart.py @@ -0,0 +1,137 @@ +import sys +import traceback +import click + +from lib.helm import output as helm_output +from lib.helm import main as helm + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("chart") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--file", "chart_values_filename", default='', callback=validations.empty_string_to_none, help="Chart values filename") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_helm_chart_command( + ctx, + cluster_name, + chart_values_filename, + devel + ): + """Create helm chart""" + + # iserver create helm chart + + ctx.developer = devel + ctx.output = 'default' + + try: + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name, mandatory=['helm']) + if settings is None: + raise ErrorExit + + chart_info = validations.validate_helm_chart(ctx, chart_values_filename) + if chart_info is None: + raise ErrorExit + + ctx.my_output.default('Chart directory : %s' % (chart_info['directory'])) + ctx.my_output.default('Chart name : %s' % (chart_info['chart'])) + ctx.my_output.default('Version : %s' % (chart_info['version'])) + ctx.my_output.default('AppVersion : %s' % (chart_info['appVersion'])) + ctx.my_output.default('Values : %s\n' % (chart_values_filename)) + + helm_handler = helm.Helm( + settings['helm']['ip'], + settings['helm']['username'], + password=settings['helm']['password'], + key_filename=settings['helm']['key_filename'], + log_id=ctx.run_id + ) + + if helm_handler.is_chart(chart_info['chart']): + if helm_handler.is_chart_release(chart_info['chart']): + ctx.my_output.default('Chart already defined and release exists') + if not common.get_confirmation(): + raise ErrorExit + else: + ctx.my_output.default('Chart already defined') + if not common.get_confirmation(): + raise ErrorExit + + if not helm_handler.delete_chart(chart_info['chart']): + ctx.my_output.error('Chart delete failed') + raise ErrorExit + + ctx.my_output.default('Chart deleted') + + ctx.my_output.default( + 'Chart %s will be uploaded from %s to helm repository at %s@%s' % ( + chart_info['chart'], + chart_info['directory'], + settings['helm']['username'], + settings['helm']['ip'] + ) + ) + + success = helm_handler.create_chart( + chart_info['chart'], + chart_info['directory'], + chart_info['values'], + verbose=True + ) + if not success: + ctx.my_output.error('Chart upload failed') + raise ErrorExit + + ctx.my_output.default('Upload completed', before_newline=True) + + output_handler = helm_output.HelmOutput( + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + charts = helm_handler.get_charts( + chart_filter=['name:%s' % (chart_info['chart'])], + release_info=True, + values_info=True, + files_info=True, + cache_enabled=False + ) + + output_handler.print_charts( + charts, + title=True + ) + + output_handler.print_chart_files( + charts, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/helm/main.py b/menu/create/helm/main.py new file mode 100644 index 00000000..fa601815 --- /dev/null +++ b/menu/create/helm/main.py @@ -0,0 +1,18 @@ +import click + +from menu.create.helm.chart import create_helm_chart_command +from menu.create.helm.release import create_helm_release_command + + +class Failure(Exception): + pass + + +@click.group("helm") +@click.pass_obj +def create_helm_menu(ctx): + """Create helm commands""" + + +create_helm_menu.add_command(create_helm_chart_command) +create_helm_menu.add_command(create_helm_release_command) diff --git a/menu/create/helm/release.py b/menu/create/helm/release.py new file mode 100644 index 00000000..03eb403e --- /dev/null +++ b/menu/create/helm/release.py @@ -0,0 +1,228 @@ +import sys +import traceback +import click + +from lib.helm import output as helm_output +from lib.helm import main as helm + +from lib import file_helper + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("release") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--chart", "chart_name", default='', callback=validations.empty_string_to_none, help="Chart name") +@click.option("--file", "chart_values_filename", default='', callback=validations.empty_string_to_none, help="Chart values filename") +@click.option("--namespace", default='default', help="Release namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Release name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_helm_release_command( + ctx, + cluster_name, + chart_name, + chart_values_filename, + namespace, + name, + devel + ): + """Create helm release""" + + # iserver create helm release + + ctx.developer = devel + ctx.output = 'default' + + try: + if chart_name is None: + ctx.my_output.error('Define chart name') + raise ErrorExit + + if name is None: + ctx.my_output.error('Define release name') + raise ErrorExit + + if len(name.split('/')) == 2: + (namespace, name) = name.split('/') + + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name, mandatory=['helm', 'tools', 'virtctl']) + if settings is None: + raise ErrorExit + + output_handler = helm_output.HelmOutput( + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + silent=True + ) + if ocp_handler is None: + raise ErrorExit + + helm_handler = helm.Helm( + settings['helm']['ip'], + settings['helm']['username'], + password=settings['helm']['password'], + key_filename=settings['helm']['key_filename'], + log_id=ctx.run_id + ) + + if not helm_handler.is_chart(chart_name): + ctx.my_output.error( + 'Chart does not exist: %s' % (chart_name) + ) + raise ErrorExit + + if helm_handler.is_release(namespace, name): + ctx.my_output.error( + 'Release exists: %s/%s' % (namespace, name) + ) + raise ErrorExit + + if chart_values_filename is None: + ctx.my_output.default('Using default chart value') + values = helm_handler.get_chart_file(chart_name, 'values.yaml', convert_yaml=True) + if values is None: + ctx.my_output.error('Failed to read release values') + raise ErrorExit + + if chart_values_filename is not None: + ctx.my_output.default('Using custom chart value') + values = file_helper.get_file_yaml(chart_values_filename) + if values is None: + ctx.my_output.error('Failed to read release values') + raise ErrorExit + + day0 = helm_handler.get_release_day0(chart_name, namespace, name, values) + if day0 is None: + ctx.my_output.error('Failed to get release day0 information') + raise ErrorExit + + if len(day0) > 0: + for item in day0: + create_dv = True + pvc_namespace = item['dv']['metadata']['namespace'] + pvc_name = item['dv']['metadata']['name'] + if ocp_handler.k8s_handler.is_pvc(pvc_namespace, pvc_name, cache_enabled=True): + if ocp_handler.k8s_handler.is_pvc_used(namespace, name): + ctx.my_output.default('Day0 PVC %s/%s already exists and is used. It cannot be overwritten.' % (pvc_namespace, pvc_name)) + raise ErrorExit + + ctx.my_output.default('Day0 PVC %s/%s already exists. Reuse it?' % (pvc_namespace, pvc_name)) + if not common.get_confirmation(): + if not ocp_handler.k8s_handler.delete_namespaced_pvc(pvc_namespace, pvc_name): + ctx.my_output.error('PVC delete failed') + raise ErrorExit + ctx.my_output.default('PVC deleted') + + if create_dv: + success = ocp_handler.create_ocp_vm_day0( + item['filename'], + item['content'], + 'config.iso', + item['dv'] + ) + if not success: + ctx.my_output.error('Release day0 preparation not supported') + raise ErrorExit + + success, reason = helm_handler.create_release(chart_name, namespace, name, values) + if not success: + ctx.my_output.error('Release create failed: %s' % (reason)) + + ctx.my_output.default('Delete release?') + if common.get_confirmation(): + releases = helm_handler.get_releases( + release_filter=['namespace:%s' % (namespace), 'name:%s' % (name)], + chart_info=True, + values_info=True, + day0_info=True + ) + if releases is None: + ctx.my_output.error('Failed to get release information') + raise ErrorExit + + if len(releases) == 0: + ctx.my_output.error('Release not found') + raise ErrorExit + + if len(releases) > 1: + ctx.my_output.error('Multiple releases found') + raise ErrorExit + + if helm_handler.delete_release(namespace, name): + ctx.my_output.default('Release deleted') + else: + ctx.my_output.error('Release delete failed') + raise ErrorExit + + for release in releases: + if release['day0'] is not None: + for item in release['day0']: + if ocp_handler.k8s_handler.is_pvc(item['dv']['metadata']['namespace'], item['dv']['metadata']['name'], cache_enabled=False): + success = ocp_handler.k8s_handler.delete_namespaced_pvc( + item['dv']['metadata']['namespace'], + item['dv']['metadata']['name'] + ) + if not success: + ctx.my_output.error('Failed to delete release day0 pvc') + raise ErrorExit + + ctx.my_output.default( + 'Release day0 deleted: %s/%s' % ( + item['dv']['metadata']['namespace'], + item['dv']['metadata']['name'] + ) + ) + + raise ErrorExit + + ctx.my_output.default('Helm release created') + + release = helm_handler.get_release( + namespace, + name, + day0_info=True, + cache_enabled=False + ) + output_handler.print_releases( + [release], + title=False + ) + + if len(release['day0']) > 0: + output_handler.print_releases_day0( + [release], + title=False + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/k8s/__init__.py b/menu/create/k8s/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/k8s/main.py b/menu/create/k8s/main.py new file mode 100644 index 00000000..98ad8a67 --- /dev/null +++ b/menu/create/k8s/main.py @@ -0,0 +1,20 @@ +import click + +from menu.create.k8s.pvc import create_k8s_pvc_command +from menu.create.k8s.srnnp import create_k8s_srnnp_command +from menu.create.k8s.vm import create_k8s_vm_command + + +class Failure(Exception): + pass + + +@click.group("k8s") +@click.pass_obj +def create_k8s_menu(ctx): + """Create Kubernetes commands""" + + +create_k8s_menu.add_command(create_k8s_pvc_command) +create_k8s_menu.add_command(create_k8s_srnnp_command) +create_k8s_menu.add_command(create_k8s_vm_command) diff --git a/menu/create/k8s/pvc.py b/menu/create/k8s/pvc.py new file mode 100644 index 00000000..e3a016c2 --- /dev/null +++ b/menu/create/k8s/pvc.py @@ -0,0 +1,234 @@ +import os +import time +import sys +import traceback +import threading +import click + +from lib.k8s import output as k8s_output +from lib.linux import main as linux + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pvc") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--namespace", default='default', callback=validations.empty_string_to_none, help="Namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Name") +@click.option("--type", "file_type", type=click.Choice(['file', 'day0'], case_sensitive=False), default='file', help="PVC source file type") +@click.option("--size", default='', callback=validations.empty_string_to_none, help="Target PVC size") +@click.option("--file", "source_filename", default='', callback=validations.empty_string_to_none, help="Source filename") +@click.option("--rfile", "remote_filename", default='', callback=validations.empty_string_to_none, help="Remote source filename") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_k8s_pvc_command( + ctx, + cluster_name, + namespace, + name, + file_type, + size, + source_filename, + remote_filename, + devel + ): + """Create k8s pvc""" + + # iserver create k8s pvc + + ctx.developer = devel + ctx.output = 'default' + + try: + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name, silent=True) + if settings is None: + raise ErrorExit + + if 'tools' not in settings or settings['tools'] is None: + ctx.my_output.error('Tools not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + if 'virtctl' not in settings or settings['virtctl'] is None: + ctx.my_output.error('Virtctl not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster_name, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + if namespace is None: + namespace = input('PVC Namespace: ') + if namespace is None or len(namespace) == 0: + raise ErrorExit + + if name is None: + name = input('PVC Name: ') + if name is None or len(name) == 0: + raise ErrorExit + + if k8s_handlers.is_data_volume(namespace, name): + ctx.my_output.error( + 'Data volume already exists: %s/%s' % (namespace, name) + ) + raise ErrorExit + + ctx.my_output.default('Data volume does not exist: %s/%s' % (namespace, name)) + + if not k8s_handlers.is_pvc(namespace, name, cache_enabled=False): + ctx.my_output.default('Persistent volume claim does not exist: %s/%s' % (namespace, name)) + else: + if k8s_handlers.is_pvc_used(namespace, name): + ctx.my_output.default('PVC %s/%s already exists and is used. It cannot be overwritten.' % (namespace, name)) + raise ErrorExit + + ctx.my_output.default('PVC %s/%s already exists. Remove it?' % (namespace, name)) + if not common.get_confirmation(): + return + + if not k8s_handlers.delete_namespaced_pvc(namespace, name): + ctx.my_output.error('PVC delete failed') + raise ErrorExit + + ctx.my_output.default('PVC deleted') + + if source_filename is not None and remote_filename is not None: + ctx.my_output.error('Define local or remote filename') + raise ErrorExit + + if source_filename is None and remote_filename is None: + ctx.my_output.default('Local source file?') + if common.get_confirmation(): + source_filename = input('Local filename: ') + if source_filename is None or len(source_filename) == 0: + raise ErrorExit + else: + remote_filename = input('Remote filename: ') + if remote_filename is None or len(remote_filename) == 0: + raise ErrorExit + + if source_filename is not None: + if not os.path.isfile(source_filename): + ctx.my_output.error('Local filename not found: %s' % (source_filename)) + raise ErrorExit + + if remote_filename is not None: + virtctl_handler = linux.Linux( + settings['virtctl']['ip'], + settings['virtctl']['username'], + password=settings['virtctl']['password'], + key_filename=settings['virtctl']['key_filename'], + log_id=ctx.run_id + ) + if not virtctl_handler.ssh_handler.is_file(remote_filename): + ctx.my_output.error( + 'Remote filename not found at %s@%s:%s' % ( + settings['virtctl']['username'], + settings['virtctl']['ip'], + remote_filename + ) + ) + raise ErrorExit + + if size is None: + size = input('Target pvc size (e.g., 1Gi): ') + if size is None or len(size) == 0: + raise ErrorExit + + if source_filename is not None: + ctx.my_output.default( + 'Creating PVC %s/%s type %s from local file %s' % ( + namespace, + name, + file_type, + source_filename + ) + ) + else: + ctx.my_output.default( + 'Creating PVC %s/%s type %s from remote file %s@%s:%s' % ( + namespace, + name, + file_type, + settings['virtctl']['username'], + settings['virtctl']['ip'], + remote_filename + ) + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + success = k8s_handlers.create_pvc_via_data_volume_upload( + namespace, + name, + settings['tools'], + settings['virtctl'], + file_type=file_type, + source_filename=source_filename, + remote_filename=remote_filename, + size=size, + must_bound=False + ) + if not success: + ctx.busy = False + time.sleep(.1) + ctx.my_output.error('PVC creation failed') + + if k8s_handlers.is_data_volume(namespace, name, cache_enabled=False): + if not k8s_handlers.delete_data_volume(namespace, name): + ctx.my_output.error('DV/PVC delete failed: %s/%s' % (namespace, name)) + raise ErrorExit + ctx.my_output.default('DV/PVC deleted: %s/%s' % (namespace, name)) + else: + if not k8s_handlers.delete_namespaced_pvc(namespace, name): + ctx.my_output.error('PVC delete failed: %s/%s' % (namespace, name)) + raise ErrorExit + ctx.my_output.default('PVC deleted: %s/%s' % (namespace, name)) + + raise ErrorExit + + ctx.busy = False + ctx.my_output.default('PVC created') + + pvcs = k8s_handlers.get_pvcs( + object_filter=['namespace:%s' % (namespace), 'name:%s' % (name)], + usage_info=False, + pv_info=True, + cache_enabled=False + ) + k8s_output_handler.print_pvcs( + pvcs, + title=True + ) + k8s_output_handler.print_pvcs_metadata( + pvcs, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/k8s/srnnp.py b/menu/create/k8s/srnnp.py new file mode 100644 index 00000000..3c771e7f --- /dev/null +++ b/menu/create/k8s/srnnp.py @@ -0,0 +1,193 @@ +import sys +import traceback +import click +import yaml + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("srnnp") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--namespace", default='openshift-sriov-network-operator', callback=validations.empty_string_to_none, help="Policy namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Policy name") +@click.option("--type", "device_type", type=click.Choice(['vfio', 'net'], case_sensitive=False), help="Device type") +@click.option("--resource", "resource_name", default='', callback=validations.empty_string_to_none, help="Resource name") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Node name") +@click.option("--intf", "interface_name", default='', callback=validations.empty_string_to_none, help="Interface name") +@click.option("--vf", "vf_count", type=click.INT, help="VF count") +@click.option("--range", "vf_range", default='', callback=validations.empty_string_to_none, help="VF range") +@click.option("--no-create", "no_create", is_flag=True, show_default=True, default=False, help="No creation") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_k8s_srnnp_command( + ctx, + cluster_name, + namespace, + name, + device_type, + resource_name, + node_name, + interface_name, + vf_count, + vf_range, + no_create, + devel + ): + """Create k8s srnnp""" + + # iserver create k8s srnnp + + ctx.developer = devel + ctx.output = 'default' + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster_name, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + if namespace is None: + ctx.my_output.error('Define policy namespace') + raise ErrorExit + + if namespace not in ['openshift-sriov-network-operator']: + ctx.my_output.error('Unsupported policy namespace') + raise ErrorExit + + if name is None: + ctx.my_output.error('Define policy name') + raise ErrorExit + + if resource_name is None: + ctx.my_output.error('Define resource name') + raise ErrorExit + + if node_name is None: + ctx.my_output.error('Define node name') + raise ErrorExit + + if interface_name is None: + ctx.my_output.error('Define interface name') + raise ErrorExit + + if vf_count is None or vf_count <= 0: + ctx.my_output.error('Define non-zero VF count') + raise ErrorExit + + if vf_range is not None: + if len(vf_range.split('-')) != 2: + ctx.my_output.error('Define valid vf range') + raise ErrorExit + + if k8s_handlers.is_sriov_network_node_policy(name): + ctx.my_output.error('Policy already defined: %s' % (name)) + raise ErrorExit + + ctx.my_output.default( + 'SR-IOV Network Node Policy will be created: %s/%s' % ( + namespace, + name + ) + ) + + srnnp_with_resource = k8s_handlers.get_sriov_network_node_policy_with_resource_name(resource_name) + if srnnp_with_resource is not None: + ctx.my_output.error('Resource name already used: %s' % (resource_name)) + raise ErrorExit + + ctx.my_output.default( + 'Resource name: %s' % ( + resource_name + ) + ) + + node_info = k8s_handlers.get_node(node_name) + if node_info is None: + ctx.my_output.error('Node not found: %s' % (node_name)) + raise ErrorExit + + ctx.my_output.default( + 'Node name: %s' % ( + node_name + ) + ) + + srnns_with_interface = k8s_handlers.get_sriov_network_node_state_with_node_interface(node_name, interface_name) + if len(srnns_with_interface) == 0: + ctx.my_output.error('Interface %s state on node %s not found' % (interface_name, node_name)) + raise ErrorExit + + if len(srnns_with_interface) > 1: + ctx.my_output.error('Multiple interface %s state on node %s found' % (interface_name, node_name)) + raise ErrorExit + + k8s_output_handler.print_sriov_network_nodes_state( + srnns_with_interface, + title=True + ) + + body = 'apiVersion: sriovnetwork.openshift.io/v1' + body = '%s\nkind: SriovNetworkNodePolicy' % (body) + body = '%s\nmetadata:' % (body) + body = '%s\n namespace: %s' % (body, namespace) + body = '%s\n name: %s' % (body, name) + body = '%s\nspec:' % (body) + body = '%s\n resourceName: %s' % (body, resource_name) + body = '%s\n nodeSelector:' % (body) + body = '%s\n topology.topolvm.io/node: "%s"' % (body, node_name) + body = '%s\n numVfs: %s' % (body, vf_count) + body = '%s\n nicSelector:' % (body) + if vf_range is None: + body = '%s\n pfNames: [%s]' % (body, interface_name) + else: + body = '%s\n pfNames: ["%s#%s"]' % (body, interface_name, vf_range) + if device_type == 'vfio': + body = '%s\n deviceType: vfio-pci' % (body) + if device_type == 'net': + body = '%s\n deviceType: netdevice' % (body) + + if no_create: + return + + ctx.my_output.default('\n%s\n' % (body)) + if not common.get_confirmation(): + raise ErrorExit + + body_yaml = yaml.safe_load(body) + if not k8s_handlers.create_sriov_network_node_policy(body_yaml): + ctx.my_output.error( + 'SR-IOV network node policy create failed' + ) + raise ErrorExit + + ctx.my_output.default( + 'SR-IOV network node policy created (note: node may be reloaded)' + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/k8s/vm.py b/menu/create/k8s/vm.py new file mode 100644 index 00000000..2c74514b --- /dev/null +++ b/menu/create/k8s/vm.py @@ -0,0 +1,80 @@ +import sys +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", "cluster_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Cluster Name") +@click.option("--file", "vm_filename", is_flag=False, show_default=False, default='', type=click.STRING, help="VM Definition YAML") +@click.option("--report", is_flag=True, show_default=True, default=False, help="Enable report") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def create_k8s_vm_command( + ctx, + cluster_name, + vm_filename, + report, + verbose, + debug + ): + """Create virtual machine""" + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + if len(vm_filename) == 0: + ctx.my_output.error('Define VM definition yaml location') + raise ErrorExit + + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name, silent=True) + if settings is None: + raise ErrorExit + + if settings['tools'] is None: + ctx.my_output.error('Tools not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + if settings['virtctl'] is None: + ctx.my_output.error('Virtctl not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + ctx.my_output.default('Validate vm deployment file') + validated_input = validations.validate_ocp_vm_yaml_file(ctx, vm_filename) + if validated_input is None: + ctx.busy = False + raise ErrorExit + + ctx.my_output.default('Validate ocp cluster') + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + if not ocp_handler.create_vm_deployment(validated_input, report=report): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/main.py b/menu/create/main.py new file mode 100644 index 00000000..59d08748 --- /dev/null +++ b/menu/create/main.py @@ -0,0 +1,34 @@ +import click + +from menu.create.helm.main import create_helm_menu +from menu.create.k8s.main import create_k8s_menu +from menu.create.nso.main import create_nso_menu +from menu.create.ocp.main import create_ocp_menu +from menu.create.osp.main import create_osp_menu +from menu.create.os_install.main import create_os_install_menu +from menu.create.os_image import create_os_image_command +from menu.create.server.main import create_server_menu +from menu.create.scu import create_scu_command +from menu.create.vc.main import create_vc_menu + + +class Failure(Exception): + pass + + +@click.group("create") +@click.pass_obj +def create_menu(ctx): + """Create commands""" + + +create_menu.add_command(create_helm_menu) +create_menu.add_command(create_k8s_menu) +create_menu.add_command(create_nso_menu) +create_menu.add_command(create_ocp_menu) +create_menu.add_command(create_osp_menu) +create_menu.add_command(create_os_install_menu) +create_menu.add_command(create_os_image_command) +create_menu.add_command(create_server_menu) +create_menu.add_command(create_scu_command) +create_menu.add_command(create_vc_menu) diff --git a/menu/create/nso/__init__.py b/menu/create/nso/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/nso/__pycache__/__init__.cpython-310.pyc b/menu/create/nso/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c00fc53a Binary files /dev/null and b/menu/create/nso/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/create/nso/__pycache__/main.cpython-310.pyc b/menu/create/nso/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..154aedb6 Binary files /dev/null and b/menu/create/nso/__pycache__/main.cpython-310.pyc differ diff --git a/menu/create/nso/main.py b/menu/create/nso/main.py new file mode 100644 index 00000000..e2aa4014 --- /dev/null +++ b/menu/create/nso/main.py @@ -0,0 +1,16 @@ +import click + +from menu.create.nso.nfvo.main import create_nso_nfvo_menu + + +class Failure(Exception): + pass + + +@click.group("nso") +@click.pass_obj +def create_nso_menu(ctx): + """Create nso commands""" + + +create_nso_menu.add_command(create_nso_nfvo_menu) diff --git a/menu/create/nso/nfvo/__init__.py b/menu/create/nso/nfvo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/nso/nfvo/__pycache__/__init__.cpython-310.pyc b/menu/create/nso/nfvo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e1c8bc34 Binary files /dev/null and b/menu/create/nso/nfvo/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/create/nso/nfvo/__pycache__/main.cpython-310.pyc b/menu/create/nso/nfvo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e01047be Binary files /dev/null and b/menu/create/nso/nfvo/__pycache__/main.cpython-310.pyc differ diff --git a/menu/create/nso/nfvo/__pycache__/vnfd.cpython-310.pyc b/menu/create/nso/nfvo/__pycache__/vnfd.cpython-310.pyc new file mode 100644 index 00000000..fcf80338 Binary files /dev/null and b/menu/create/nso/nfvo/__pycache__/vnfd.cpython-310.pyc differ diff --git a/menu/create/nso/nfvo/__pycache__/vnfi.cpython-310.pyc b/menu/create/nso/nfvo/__pycache__/vnfi.cpython-310.pyc new file mode 100644 index 00000000..f3ca85a9 Binary files /dev/null and b/menu/create/nso/nfvo/__pycache__/vnfi.cpython-310.pyc differ diff --git a/menu/create/nso/nfvo/main.py b/menu/create/nso/nfvo/main.py new file mode 100644 index 00000000..51be0f23 --- /dev/null +++ b/menu/create/nso/nfvo/main.py @@ -0,0 +1,18 @@ +import click + +from menu.create.nso.nfvo.vnfd import create_nso_nfvo_vnfd_command +from menu.create.nso.nfvo.vnfi import create_nso_nfvo_vnfi_command + + +class Failure(Exception): + pass + + +@click.group("nfvo") +@click.pass_obj +def create_nso_nfvo_menu(ctx): + """Create nso nfvo commands""" + + +create_nso_nfvo_menu.add_command(create_nso_nfvo_vnfd_command) +create_nso_nfvo_menu.add_command(create_nso_nfvo_vnfi_command) diff --git a/menu/create/nso/nfvo/vnfd.py b/menu/create/nso/nfvo/vnfd.py new file mode 100644 index 00000000..60bf9fc3 --- /dev/null +++ b/menu/create/nso/nfvo/vnfd.py @@ -0,0 +1,105 @@ +import sys +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vnfd") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--nfvo", "nfvo_version", type=click.Choice(['3.x', '4.x'], case_sensitive=False), default='4.x', show_default=True, help="NFVO Version") +@click.option("--etsi", "nfvo_etsi", is_flag=True, show_default=True, default=False, help="NFVO ETSI") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--xml", "vnfd_filename", is_flag=False, show_default=False, default='', type=click.STRING, help="VNFD XML") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def create_nso_nfvo_vnfd_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + nfvo_version, + nfvo_etsi, + restconf_disabled, + vnfd_filename, + verbose, + debug + ): + """Create nso vnfd""" + + # iocp create nso vnfd + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + if len(vnfd_filename) == 0: + ctx.my_output.error('Define vnfd xml location') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + user_input = validations.validate_xml_file(ctx, vnfd_filename) + if user_input is None: + raise ErrorExit + + nso_handler = validations.validate_nso_ncs( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo_version, + nfvo_etsi + ) + if nso_handler is None: + raise ErrorExit + + success = nso_handler.create_vnfd( + user_input + ) + if not success: + ctx.busy = False + ctx.my_output.error( + 'VNFD create failed' + ) + raise ErrorExit + + ctx.busy = False + ctx.my_output.default( + 'VNFD created' + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/nso/nfvo/vnfi.py b/menu/create/nso/nfvo/vnfi.py new file mode 100644 index 00000000..7bb1af55 --- /dev/null +++ b/menu/create/nso/nfvo/vnfi.py @@ -0,0 +1,133 @@ +import sys +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vnfi") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--nfvo", "nfvo_version", type=click.Choice(['3.x', '4.x'], case_sensitive=False), default='4.x', show_default=True, help="NFVO Version") +@click.option("--etsi", "nfvo_etsi", is_flag=True, show_default=True, default=False, help="NFVO ETSI") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--xml", "vnfi_filename", is_flag=False, show_default=False, default='', type=click.STRING, help="VNF-INFO XML") +@click.option("--wait", is_flag=True, show_default=True, default=False, help="Wait for active") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def create_nso_nfvo_vnfi_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + nfvo_version, + nfvo_etsi, + restconf_disabled, + vnfi_filename, + wait, + verbose, + debug + ): + """Create nso nfvo vnfi""" + + # iocp create nso nfvo vnfi + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + if len(vnfi_filename) == 0: + ctx.my_output.error('Define vnfi xml location') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + user_input = validations.validate_xml_file(ctx, vnfi_filename) + if user_input is None: + raise ErrorExit + + nso_handler = validations.validate_nso_ncs( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo_version, + nfvo_etsi + ) + if nso_handler is None: + raise ErrorExit + + vnfi_name = nso_handler.get_vnfi_name(user_input) + if nso_handler.is_vnfi(vnfi_name): + ctx.busy = False + ctx.my_output.error( + 'VNF-INFO already created' + ) + return + + success = nso_handler.create_vnfi( + user_input + ) + if not success: + ctx.busy = False + ctx.my_output.error( + 'VNF-INFO %s create failed' % (vnfi_name) + ) + raise ErrorExit + + ctx.busy = False + ctx.my_output.default( + 'VNF-INFO %s created' % (vnfi_name) + ) + + if wait: + ctx.my_output.default( + 'Wait until VNF-INFO reaches ready state' + ) + success = nso_handler.wait_for_vnfi_ready(vnfi_name) + if not success: + raise ErrorExit + + if not nso_handler.is_vnfi_ready(vnfi_name, cache=False): + ctx.my_output.error( + 'VNF-INFO %s activation failed' % (vnfi_name) + ) + raise ErrorExit + + ctx.my_output.error( + 'VNF-INFO %s ready' % (vnfi_name) + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/ocp/__init__.py b/menu/create/ocp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/ocp/__pycache__/__init__.cpython-310.pyc b/menu/create/ocp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c4e20174 Binary files /dev/null and b/menu/create/ocp/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/create/ocp/__pycache__/cluster.cpython-310.pyc b/menu/create/ocp/__pycache__/cluster.cpython-310.pyc new file mode 100644 index 00000000..c87b6866 Binary files /dev/null and b/menu/create/ocp/__pycache__/cluster.cpython-310.pyc differ diff --git a/menu/create/ocp/__pycache__/main.cpython-310.pyc b/menu/create/ocp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..ea6c7b99 Binary files /dev/null and b/menu/create/ocp/__pycache__/main.cpython-310.pyc differ diff --git a/menu/create/ocp/__pycache__/vm.cpython-310.pyc b/menu/create/ocp/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..5e42fb09 Binary files /dev/null and b/menu/create/ocp/__pycache__/vm.cpython-310.pyc differ diff --git a/menu/create/ocp/addon/__init__.py b/menu/create/ocp/addon/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/ocp/addon/__pycache__/__init__.cpython-310.pyc b/menu/create/ocp/addon/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4d483b11 Binary files /dev/null and b/menu/create/ocp/addon/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/create/ocp/addon/__pycache__/iwo.cpython-310.pyc b/menu/create/ocp/addon/__pycache__/iwo.cpython-310.pyc new file mode 100644 index 00000000..cec39ece Binary files /dev/null and b/menu/create/ocp/addon/__pycache__/iwo.cpython-310.pyc differ diff --git a/menu/create/ocp/addon/__pycache__/main.cpython-310.pyc b/menu/create/ocp/addon/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6257d3bf Binary files /dev/null and b/menu/create/ocp/addon/__pycache__/main.cpython-310.pyc differ diff --git a/menu/create/ocp/addon/iwo.py b/menu/create/ocp/addon/iwo.py new file mode 100644 index 00000000..413df5ba --- /dev/null +++ b/menu/create/ocp/addon/iwo.py @@ -0,0 +1,55 @@ +import sys +import traceback +import click + +from menu import defaults +from menu import validations + +from lib.iwo.lcm import main as iwo + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("iwo") +@click.pass_obj +@click.option("--cluster", "cluster_name", is_flag=False, show_default=False, default='', callback=validations.validate_ocp_cluster_name, type=click.STRING, help="Cluster Name") +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--chart", "chart_filename", is_flag=False, show_default=False, default='', callback=validations.validate_file, help="IWO Helm Chart Filename") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def create_ocp_addon_iwo_command(ctx, cluster_name, iaccount, chart_filename, verbose, debug): + """Create OCP IWO Addon""" + + # iocp create ocp addon iwo + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + iwo_lcm_handler = iwo.IwoLcm( + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + success = iwo_lcm_handler.create( + cluster_name, + iaccount, + chart_filename + ) + if not success: + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/ocp/addon/main.py b/menu/create/ocp/addon/main.py new file mode 100644 index 00000000..ed1c47d7 --- /dev/null +++ b/menu/create/ocp/addon/main.py @@ -0,0 +1,16 @@ +import click + +from menu.create.ocp.addon.iwo import create_ocp_addon_iwo_command + + +class Failure(Exception): + pass + + +@click.group("addon") +@click.pass_obj +def create_ocp_addon_menu(ctx): + """Create OpenShift addon commands""" + + +create_ocp_addon_menu.add_command(create_ocp_addon_iwo_command) diff --git a/menu/create/ocp/cluster/bm.py b/menu/create/ocp/cluster/bm.py new file mode 100644 index 00000000..b8f75c2e --- /dev/null +++ b/menu/create/ocp/cluster/bm.py @@ -0,0 +1,44 @@ +import sys +import traceback +import click + +from lib.workflow import ocp_bm_install + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("bm") +@click.pass_obj +@click.option("--dir", "location", is_flag=False, show_default=False, default='', type=click.STRING, help="Cluster definition directory") +def create_ocp_cluster_bm_command(ctx, location): + """Create bare metal OCP cluster""" + + try: + success, user_settings, data, infra, manifests = ocp_bm_install.get_input_files( + location, + log_id=ctx.run_id + ) + if not success: + raise ErrorExit + + success = ocp_bm_install.run( + user_settings, + data, + infra, + manifests, + log_id=ctx.run_id + ) + if not success: + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/ocp/cluster/main.py b/menu/create/ocp/cluster/main.py new file mode 100644 index 00000000..379bc512 --- /dev/null +++ b/menu/create/ocp/cluster/main.py @@ -0,0 +1,18 @@ +import click + +from menu.create.ocp.cluster.bm import create_ocp_cluster_bm_command +from menu.create.ocp.cluster.vsphere import create_ocp_cluster_vshpere_command + + +class Failure(Exception): + pass + + +@click.group("cluster") +@click.pass_obj +def create_ocp_cluster_menu(ctx): + """Create OpenShift cluster commands""" + + +create_ocp_cluster_menu.add_command(create_ocp_cluster_bm_command) +create_ocp_cluster_menu.add_command(create_ocp_cluster_vshpere_command) diff --git a/menu/create/ocp/cluster/vsphere.py b/menu/create/ocp/cluster/vsphere.py new file mode 100644 index 00000000..9999236a --- /dev/null +++ b/menu/create/ocp/cluster/vsphere.py @@ -0,0 +1,45 @@ +import sys +import traceback +import click + +from lib.ocp.lcm import main as ocp + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vsphere") +@click.pass_obj +@click.option("--dir", "location", is_flag=False, show_default=False, default='', type=click.STRING, help="Cluster definition directory") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def create_ocp_cluster_vshpere_command(ctx, location, verbose, debug): + """Create vsphere OCP cluster""" + + try: + if len(location) == 0: + ctx.my_output.error('Cluster definition directory required') + raise ErrorExit + + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + ocp_handler = ocp.Ocp(verbose=verbose, debug=debug, log_id=ctx.run_id) + if not ocp_handler.set_ocp_user_input(location): + raise ErrorExit + + if not ocp_handler.create(): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/ocp/main.py b/menu/create/ocp/main.py new file mode 100644 index 00000000..594d4ee3 --- /dev/null +++ b/menu/create/ocp/main.py @@ -0,0 +1,20 @@ +import click + +from menu.create.ocp.addon.main import create_ocp_addon_menu +from menu.create.ocp.cluster.main import create_ocp_cluster_menu +from menu.create.ocp.migrate import create_ocp_migrate_command + + +class Failure(Exception): + pass + + +@click.group("ocp") +@click.pass_obj +def create_ocp_menu(ctx): + """Create OpenShift commands""" + + +create_ocp_menu.add_command(create_ocp_addon_menu) +create_ocp_menu.add_command(create_ocp_cluster_menu) +create_ocp_menu.add_command(create_ocp_migrate_command) diff --git a/menu/create/ocp/migrate.py b/menu/create/ocp/migrate.py new file mode 100644 index 00000000..c6d42f54 --- /dev/null +++ b/menu/create/ocp/migrate.py @@ -0,0 +1,285 @@ +import os +import sys +import uuid +import traceback +import click + +from lib import file_helper +from lib.k8s import output as k8s_output +from lib.osp import output as osp_output +from lib.workflow import osp_ocp_migration + +from menu import common +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("migrate") +@click.pass_obj +@click.option("--osp", "osp_cluster_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OpenStack Cluster Name") +@click.option("--src", "source_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OpenStack Virtual Machine Name") +@click.option("--ocp", "ocp_cluster_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OpenShift Cluster Name") +@click.option("--dest", "destination_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OpenShift Virtual Machine Name") +@click.option("--rule", "deployment_directory", is_flag=False, show_default=False, default='', type=click.STRING, help="Migration rules directory") +@click.option("--confirm", "confirmation_mode", is_flag=True, show_default=False, default=False, help="Confirmation mode") +def create_ocp_migrate_command( + ctx, + osp_cluster_name, + source_name, + ocp_cluster_name, + destination_name, + deployment_directory, + confirmation_mode + ): + """Migrate virtual machine""" + + # iocp create ocp migrate + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + if len(osp_cluster_name) == 0: + osp_cluster_name = validations.select_osp_name(ctx) + if osp_cluster_name is None: + raise ErrorExit + osp_handlers = validations.validate_osp_name(ctx, osp_cluster_name, silent=True) + else: + osp_handlers = validations.validate_osp_name(ctx, osp_cluster_name, silent=False) + if osp_handlers is None: + raise ErrorExit + + if len(source_name) == 0: + ctx.my_output.default('Get virtual machines...', after_newline=True) + + vms = osp_handlers.get_virtual_machines( + object_filter=[], + tenant_info=True, + flavor_info=True, + image_info=True, + volume_info=True, + network_info=True, + subnet_info=True + ) + osp_virtual_machine_info = osp_output_handler.select_virtual_machine(vms) + if osp_virtual_machine_info is None: + raise ErrorExit + + else: + if len(source_name.split('/')) != 2: + ctx.my_output.error('Source format: /') + raise ErrorExit + + (tenant_name, vm_name) = source_name.split('/') + osp_virtual_machine_info = osp_handlers.get_virtual_machine_by_name( + vm_name, + tenant_name=tenant_name, + tenant_info=True, + flavor_info=True, + image_info=True, + volume_info=True, + network_info=True, + subnet_info=True + ) + + if osp_virtual_machine_info is None: + ctx.my_output.error('Virtual machine not found: %s/%s' % (tenant_name, vm_name)) + raise ErrorExit + + osp_output_handler.print_virtual_machines( + [osp_virtual_machine_info] + ) + + osp_output_handler.print_virtual_machines_net( + [osp_virtual_machine_info] + ) + + if len(ocp_cluster_name) == 0: + ocp_cluster_name = validations.select_ocp_name(ctx) + if osp_cluster_name is None: + raise ErrorExit + + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + settings = validations.validate_ocp_cluster_settings(ctx, ocp_cluster_name, silent=True) + if settings is None: + raise ErrorExit + + if settings['virtctl'] is None: + ctx.my_output.error('Virtctl not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + k8s_handlers = validations.validate_kubernetes_name(ctx, ocp_cluster_name, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + if len(destination_name) == 0: + ctx.my_output.default('Get namespaces...', after_newline=True) + + namespaces = k8s_handlers.get_namespaces() + namespace_info = k8s_output_handler.select_namespace(namespaces) + namespace = namespace_info['name'] + if namespace is None: + raise ErrorExit + + ctx.my_output.default('Get virtual machines...', before_newline=True, after_newline=True) + + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + virtual_machine_instances = k8s_handlers.get_virtual_machine_instances( + object_filter=object_filter, + vm_info=True, + service_info=False + ) + + k8s_output_handler.print_virtual_machine_instances( + virtual_machine_instances, + title=True + ) + + vmi = input('Target virtual machine name (empty to autogenerate): ') + if len(vmi) == 0: + vmi = str(uuid.uuid4()).split('-')[-1] + ctx.my_outpu.default('Generated name: %s' % (vmi)) + + if k8s_handlers.is_virtual_machine_instance(namespace, vmi): + ctx.my_output.default('Virtual machine found: %s/%s' % (namespace, vmi)) + raise ErrorExit + + else: + if len(destination_name.split('/')) > 2: + ctx.my_output.error('Destination format: /') + raise ErrorExit + + if len(destination_name.split('/')) == 1: + namespace = 'default' + vmi = destination_name + + if len(destination_name.split('/')) == 2: + (namespace, vmi) = destination_name.split('/') + + if not k8s_handlers.is_namespace(namespace): + ctx.my_output.error('Namespace not found: %s/%s' % (tenant_name, vm_name)) + raise ErrorExit + + if k8s_handlers.is_virtual_machine_instance(namespace, vmi): + ctx.my_output.default('Virtual machine found: %s/%s' % (namespace, vmi)) + raise ErrorExit + + if len(deployment_directory) == 0: + deployment_directory = input('Rule files directory: ') + if len(deployment_directory) == 0: + raise ErrorExit + + if not os.path.isdir(deployment_directory): + ctx.my_output.error('Directory does not exist: %s' % (deployment_directory)) + raise ErrorExit + + rules_filename = os.path.join(deployment_directory, 'rules.yaml') + if not os.path.isfile(rules_filename): + ctx.my_output.error( + 'Virtual machine migration rules not found: %s' % (rules_filename) + ) + raise ErrorExit + + migration_rules = file_helper.get_file_yaml(rules_filename) + if migration_rules is None: + ctx.my_output.error( + 'Failed to read virtual machine migration rules: %s' % (rules_filename) + ) + raise ErrorExit + + vmi_filename = os.path.join(deployment_directory, 'vmi.yaml') + if not os.path.isfile(vmi_filename): + ctx.my_output.error( + 'Virtual machine instance file not found: %s' % (vmi_filename) + ) + raise ErrorExit + + if 'service' in migration_rules: + for service_name in migration_rules['service']: + service_filename = os.path.join(deployment_directory, '%s.yaml' % (service_name)) + if not os.path.isfile(service_filename): + ctx.my_output.error( + 'Service file not found: %s' % (service_filename) + ) + raise ErrorExit + + if 'sriov_network' in migration_rules: + for network_name in migration_rules['sriov_network']: + network_filename = os.path.join(deployment_directory, '%s.yaml' % (network_name)) + if not os.path.isfile(network_filename): + ctx.my_output.error( + 'SRIOV network file not found: %s' % (network_filename) + ) + raise ErrorExit + + ctx.my_output.default('Rules valid') + + if confirmation_mode and not common.get_confirmation(): + raise ErrorExit + + success = osp_ocp_migration.run( + ctx, + osp_handlers, + osp_virtual_machine_info, + k8s_handlers, + namespace, + vmi, + settings, + deployment_directory, + confirmation_mode=confirmation_mode + ) + if not success: + raise ErrorExit + + object_filter = [] + object_filter.append( + 'namespace:%s' % (namespace) + ) + + object_filter.append( + 'name:%s' % (vmi) + ) + + virtual_machine_instances = k8s_handlers.get_virtual_machine_instances( + object_filter=object_filter, + vm_info=True, + service_info=True, + cache_enabled=False + ) + + k8s_output_handler.print_virtual_machine_instances( + virtual_machine_instances, + title=False + ) + + k8s_output_handler.print_virtual_machine_instances_phase( + virtual_machine_instances, + title=False + ) + + k8s_output_handler.print_virtual_machine_instances_interface( + virtual_machine_instances, + title=False + ) + + k8s_output_handler.print_virtual_machine_instances_service( + virtual_machine_instances, + title=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/os_image.py b/menu/create/os_image.py new file mode 100644 index 00000000..df80d5da --- /dev/null +++ b/menu/create/os_image.py @@ -0,0 +1,131 @@ +import sys +import traceback +import click + +from progress.bar import Bar + +from lib.intersight import os_image + +from menu import user_inputs +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-image") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--file", "filename", is_flag=False, show_default=False, default='', type=click.STRING, help="Input yaml file") +@click.option("--name", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Name") +@click.option("--vendor", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Vendor") +@click.option("--version", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Version") +@click.option("--type", "link_type", type=click.Choice(['url', 'nfs'], case_sensitive=False), default='url', help="Link type") +@click.option("--link", is_flag=False, show_default=False, default='', type=click.STRING, help="Link") +@click.option("--organization", "organization_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Organization Name") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_os_image_command(ctx, iaccount, filename, organization_name, name, vendor, version, link_type, link, interactive, devel): + """Create os image""" + + # iserver create os-image + + ctx.developer = devel + + try: + image_handler = os_image.OsImage(iaccount, log_id=ctx.run_id) + + if len(filename) > 0: + ctx.my_output.default('Input file verification...') + images = validations.validate_yaml_file(ctx, filename) + if images is None: + raise ErrorExit + + if len(filename) == 0: + if interactive: + images = image_handler.get_all() + image_handler.print(images) + + ctx.my_output.default('') + ctx.my_output.default('Define new image', underline=True) + ctx.my_output.default('') + + name = user_inputs.get_value(ctx, 'Image name') + vendor = user_inputs.get_os_image_vendor(ctx, iaccount) + version = user_inputs.get_os_image_version(ctx, iaccount, vendor) + link_type = user_inputs.get_selection(ctx, 'Select link type', ['url', 'nfs']) + link = user_inputs.get_value(ctx, 'Link') + organization_name = user_inputs.get_organization_name(ctx, iaccount) + + if not interactive: + if len(name) == 0: + ctx.my_output.error('Define name') + raise ErrorExit + + if len(vendor) == 0: + ctx.my_output.error('Define vendor') + raise ErrorExit + + if len(version) == 0: + ctx.my_output.error('Define version') + raise ErrorExit + + if len(link) == 0: + ctx.my_output.error('Define link') + raise ErrorExit + + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + raise ErrorExit + + images = [] + item = {} + item['Name'] = name + item['Vendor'] = vendor + item['Version'] = version + item['Link'] = link + item['Type'] = link_type + item['Organization'] = organization_name + images.append(item) + + ctx.my_output.default('Input parameters verification...') + + for image_definition in images: + success, reason = image_handler.validate_add(image_definition) + if not success: + ctx.my_output.error('Input parameters validation failed') + ctx.my_output.default(reason) + raise ErrorExit + + ctx.my_output.default('Input parameters verified') + + bar_handler = Bar('Progress', max=len(images)) + bar_handler.goto(0) + failed = [] + for item in images: + if not image_handler.add(item): + failed.append(item) + bar_handler.next() + bar_handler.finish() + + if len(failed) > 0: + ctx.my_output.error('Some create tasks failed') + for item in failed: + ctx.my_output.default('- %s' % (item)) + raise ErrorExit + + images = image_handler.get_all() + image_handler.print(images) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/os_install/__init__.py b/menu/create/os_install/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/os_install/__pycache__/__init__.cpython-310.pyc b/menu/create/os_install/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c2350dfb Binary files /dev/null and b/menu/create/os_install/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/batch.cpython-310.pyc b/menu/create/os_install/__pycache__/batch.cpython-310.pyc new file mode 100644 index 00000000..8f18324a Binary files /dev/null and b/menu/create/os_install/__pycache__/batch.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/common.cpython-310.pyc b/menu/create/os_install/__pycache__/common.cpython-310.pyc new file mode 100644 index 00000000..df5c3e2a Binary files /dev/null and b/menu/create/os_install/__pycache__/common.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/dhcp.cpython-310.pyc b/menu/create/os_install/__pycache__/dhcp.cpython-310.pyc new file mode 100644 index 00000000..4231d85a Binary files /dev/null and b/menu/create/os_install/__pycache__/dhcp.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/embedded.cpython-310.pyc b/menu/create/os_install/__pycache__/embedded.cpython-310.pyc new file mode 100644 index 00000000..3cb90a64 Binary files /dev/null and b/menu/create/os_install/__pycache__/embedded.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/main.cpython-310.pyc b/menu/create/os_install/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3154226c Binary files /dev/null and b/menu/create/os_install/__pycache__/main.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/static.cpython-310.pyc b/menu/create/os_install/__pycache__/static.cpython-310.pyc new file mode 100644 index 00000000..25b6ffef Binary files /dev/null and b/menu/create/os_install/__pycache__/static.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/user_inputs.cpython-310.pyc b/menu/create/os_install/__pycache__/user_inputs.cpython-310.pyc new file mode 100644 index 00000000..b46e4a52 Binary files /dev/null and b/menu/create/os_install/__pycache__/user_inputs.cpython-310.pyc differ diff --git a/menu/create/os_install/__pycache__/validations.cpython-310.pyc b/menu/create/os_install/__pycache__/validations.cpython-310.pyc new file mode 100644 index 00000000..d70cbd71 Binary files /dev/null and b/menu/create/os_install/__pycache__/validations.cpython-310.pyc differ diff --git a/menu/create/os_install/batch.py b/menu/create/os_install/batch.py new file mode 100644 index 00000000..0ac867e8 --- /dev/null +++ b/menu/create/os_install/batch.py @@ -0,0 +1,92 @@ +import sys +import copy +import json +import traceback +import click + +from menu import common +from menu import defaults +from menu import validations +from menu import main as menu_main +from menu.create.os_install import validations as os_install_validations +from menu.create.os_install import common as os_install_common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("batch") +@click.pass_obj +@click.argument("location", required=True, type=click.STRING) +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--one-by-one", is_flag=True, show_default=True, default=False, help="One by one") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait disabled") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_os_install_batch_command(ctx, iaccount, location, dry_run, one_by_one, no_wait, verbose, devel): + """Batch OS installation""" + + # iserver create os-install batch + + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + ctx.my_output.default('Check isctl version...') + isctl_success, isctl_output = menu_main.check_isctl() + if not isctl_success: + ctx.my_output.error('isctl command execution failed') + raise ErrorExit + + if not menu_main.check_isctl_version(isctl_output, '0.1.18'): + ctx.my_output.error('Minimum isctl version 0.1.18 is required') + raise ErrorExit + + ctx.my_output.default('Validate input parameters...') + attributes = os_install_validations.get_batch_attributes( + ctx, + iaccount, + location + ) + if attributes is None: + raise ErrorExit + + if len(attributes) == 0: + ctx.my_output.error('No valid server defined') + raise ErrorExit + + verbose_attributes = copy.deepcopy(attributes) + for attribute in verbose_attributes: + del attribute['server'] + ctx.my_output.info(json.dumps(verbose_attributes, indent=4)) + + if one_by_one: + no_wait = False + for attribute in attributes: + if not os_install_common.run(ctx, iaccount, [attribute], dry_run=dry_run, wait=not no_wait, verbose=verbose): + raise ErrorExit + + if not one_by_one: + server_ids = [] + for attribute in attributes: + if attribute['server']['Moid'] in server_ids: + ctx.my_output.error('Server cannot be defined more than once in parallel execution: %s' % (attribute['server']['Name'])) + raise ErrorExit + server_ids.append(attribute['server']['Moid']) + + if not os_install_common.run(ctx, iaccount, attributes, dry_run=dry_run, wait=not no_wait, verbose=verbose): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/os_install/common.py b/menu/create/os_install/common.py new file mode 100644 index 00000000..bcca3cfe --- /dev/null +++ b/menu/create/os_install/common.py @@ -0,0 +1,107 @@ +import json + +from progress.bar import IncrementalBar + +from lib.intersight import os_install +from lib.intersight.lcm import common as lcm_server_common +from lib.intersight.lcm import power as lcm_server_power + + +def servers_power_cycle(ctx, iaccount, attributes, verbose): + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=False, + wait=True, + silent=False, + verbose=verbose, + debug=False, + log_id=ctx.run_id + ) + + bar_handler = IncrementalBar('Power cycle the servers', max=len(attributes)) + bar_handler.goto(0) + for attribute in attributes: + if not lcm_server_power_handler.power_cycle([attribute['server']]): + bar_handler.finish() + ctx.my_output.error('Power cycle failed') + ctx.my_output.debug(json.dumps(attribute, indent=4)) + return False + + bar_handler.next() + + bar_handler.finish() + + return True + + +def request_os_install(ctx, iaccount, attributes, dry_run, verbose): + os_install_handler = os_install.OsInstall( + iaccount, + dry_run=dry_run, + verbose=verbose, + log_id=ctx.run_id + ) + + if not dry_run and not verbose: + bar_handler = IncrementalBar('Request OS installation', max=len(attributes)) + bar_handler.goto(0) + + for attribute in attributes: + response = os_install_handler.create_os_install(attribute) + if not response['success']: + if not dry_run and not verbose: + bar_handler.finish() + ctx.my_output.error('OS installation request failed') + ctx.my_output.default(response['response']) + ctx.my_output.debug(json.dumps(attribute, indent=4)) + return False + + if not dry_run and not verbose: + bar_handler.next() + + if not dry_run and not verbose: + bar_handler.finish() + + return True + + +def wait_workflows(ctx, iaccount, servers, verbose): + lcm_handler = lcm_server_common.LcmServerCommon( + iaccount, + verbose=verbose, + log_id=ctx.run_id + ) + + success = lcm_handler.wait_workflows( + servers, + 'Operating System Install', + max_start_time=180, + max_complete_time=3600, + summary=True + ) + if not success: + ctx.my_output.error('OS installation failed') + return False + + ctx.my_output.default('OS installation successful') + return True + + +def run(ctx, iaccount, attributes, dry_run=False, wait=True, verbose=False): + if not dry_run: + if not servers_power_cycle(ctx, iaccount, attributes, verbose): + return False + + if not request_os_install(ctx, iaccount, attributes, dry_run, verbose): + return False + + if dry_run: + return True + + if wait: + servers = [] + for attribute in attributes: + servers.append(attribute['server']) + return wait_workflows(ctx, iaccount, servers, verbose) + + return True diff --git a/menu/create/os_install/dhcp.py b/menu/create/os_install/dhcp.py new file mode 100644 index 00000000..9530c855 --- /dev/null +++ b/menu/create/os_install/dhcp.py @@ -0,0 +1,120 @@ +import sys +import json +import traceback +import click + +from menu import common +from menu import defaults +from menu import validations +from menu import main as menu_main +from menu.create.os_install import validations as os_install_validations +from menu.create.os_install import common as os_install_common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("dhcp") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--name", "name_filter", default='', help="Name loose match filter") +@click.option("--serial", "serial_filter", default='', help="Serial number") +@click.option("--scu", "scu_name", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Name") +@click.option("--image", "image_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Image Name") +@click.option("--interface", "interface_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Interface name") +@click.option("--mac", "interface_mac", is_flag=False, show_default=False, default='', type=click.STRING, help="Interface mac address") +@click.option("--hostname", is_flag=False, show_default=False, default='', type=click.STRING, help="Hostname") +@click.option("--password", is_flag=False, show_default=False, default='', type=click.STRING, help="Password") +@click.option("--organization", "organization_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Organization name") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait disabled") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_os_install_dhcp_command( + ctx, + iaccount, + name_filter, + ip_filter, + serial_filter, + scu_name, + image_name, + interface_name, + interface_mac, + hostname, + password, + organization_name, + interactive, + dry_run, + no_wait, + verbose, + devel + ): + """OS installation with dhcp""" + + # iserver create os-install dhcp + # iserver.py create os-install dhcp --ip 10.58.50.46 --scu dummy --image dummy --interface eno5 --hostname kvm --password cisco --organization EMEAR-SPDC-Specialists --dry-run --verbose + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + ctx.my_output.default('Check isctl version...') + isctl_success, isctl_output = menu_main.check_isctl() + if not isctl_success: + ctx.my_output.error('isctl command execution failed') + raise ErrorExit + + if not menu_main.check_isctl_version(isctl_output, '0.1.18'): + ctx.my_output.error('Minimum isctl version 0.1.18 is required') + raise ErrorExit + + if name_filter == '' and ip_filter == '' and serial_filter == '': + interactive = True + + if not interactive: + ctx.my_output.default('Validate input parameters...') + + attributes = os_install_validations.get_dhcp_attributes( + ctx, + iaccount, + name_filter, + ip_filter, + serial_filter, + scu_name, + image_name, + interface_name, + interface_mac, + hostname, + password, + organization_name, + interactive=interactive + ) + if attributes is None: + raise ErrorExit + + ctx.my_output.info( + json.dumps( + attributes, + indent=4 + ) + ) + + if common.get_confirmation(): + if not os_install_common.run(ctx, iaccount, attributes, dry_run=dry_run, wait=not no_wait, verbose=verbose): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/os_install/embedded.py b/menu/create/os_install/embedded.py new file mode 100644 index 00000000..5065c119 --- /dev/null +++ b/menu/create/os_install/embedded.py @@ -0,0 +1,104 @@ +import sys +import json +import traceback +import click + +from menu import common +from menu import defaults +from menu import validations +from menu import main as menu_main +from menu.create.os_install import validations as os_install_validations +from menu.create.os_install import common as os_install_common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("embedded") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--name", "name_filter", default='', help="Name loose match filter") +@click.option("--serial", "serial_filter", default='', help="Serial number") +@click.option("--scu", "scu_name", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Name") +@click.option("--image", "image_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Image Name") +@click.option("--organization", "organization_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Organization name") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait disabled") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_os_install_embedded_command( + ctx, + iaccount, + name_filter, + ip_filter, + serial_filter, + scu_name, + image_name, + organization_name, + interactive, + dry_run, + no_wait, + verbose, + devel + ): + """OS installation with embedded kickstart""" + + # iserver create os-install embedded + # iserver.py create os-install embedded --ip 10.58.50.46 --scu dummy --image dummy --organization EMEAR-SPDC-Specialists --dry-run --verbose + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + ctx.my_output.default('Check isctl version...') + isctl_success, isctl_output = menu_main.check_isctl() + if not isctl_success: + ctx.my_output.error('isctl command execution failed') + raise ErrorExit + + if not menu_main.check_isctl_version(isctl_output, '0.1.18'): + ctx.my_output.error('Minimum isctl version 0.1.18 is required') + raise ErrorExit + + ctx.my_output.default('Validate input parameters...') + + attributes = os_install_validations.get_embedded_attributes( + ctx, + iaccount, + name_filter, + ip_filter, + serial_filter, + scu_name, + image_name, + organization_name, + interactive=interactive + ) + if attributes is None: + raise ErrorExit + + ctx.my_output.info( + json.dumps( + attributes, + indent=4 + ) + ) + + if common.get_confirmation(): + if not os_install_common.run(ctx, iaccount, attributes, dry_run=dry_run, wait=not no_wait, verbose=verbose): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/os_install/main.py b/menu/create/os_install/main.py new file mode 100644 index 00000000..1ebb220f --- /dev/null +++ b/menu/create/os_install/main.py @@ -0,0 +1,22 @@ +import click + +from menu.create.os_install.embedded import create_os_install_embedded_command +from menu.create.os_install.dhcp import create_os_install_dhcp_command +from menu.create.os_install.static import create_os_install_static_command +from menu.create.os_install.batch import create_os_install_batch_command + + +class Failure(Exception): + pass + + +@click.group("os-install") +@click.pass_obj +def create_os_install_menu(ctx): + """Create os installation commands""" + + +create_os_install_menu.add_command(create_os_install_embedded_command) +create_os_install_menu.add_command(create_os_install_dhcp_command) +create_os_install_menu.add_command(create_os_install_static_command) +create_os_install_menu.add_command(create_os_install_batch_command) diff --git a/menu/create/os_install/static.py b/menu/create/os_install/static.py new file mode 100644 index 00000000..09f5e3c5 --- /dev/null +++ b/menu/create/os_install/static.py @@ -0,0 +1,132 @@ +import sys +import json +import traceback +import click + +from menu import common +from menu import defaults +from menu import validations +from menu import main as menu_main +from menu.create.os_install import validations as os_install_validations +from menu.create.os_install import common as os_install_common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("static") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--name", "name_filter", default='', help="Name loose match filter") +@click.option("--serial", "serial_filter", default='', help="Serial number") +@click.option("--scu", "scu_name", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Name") +@click.option("--image", "image_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Image Name") +@click.option("--interface", "interface_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Interface name") +@click.option("--mac", "interface_mac", is_flag=False, show_default=False, default='', type=click.STRING, help="Interface mac address") +@click.option("--address", is_flag=False, show_default=False, default='', callback=validations.validate_ip, type=click.STRING, help="IP address") +@click.option("--prefix", is_flag=False, show_default=False, default=24, callback=validations.validate_prefix_length, type=click.INT, help="Prefix length") +@click.option("--gateway", is_flag=False, show_default=False, default='', callback=validations.validate_ip, type=click.STRING, help="IP gateway") +@click.option("--nameserver", is_flag=False, show_default=False, default='', callback=validations.validate_ip, type=click.STRING, help="Nameserver") +@click.option("--hostname", is_flag=False, show_default=False, default='', type=click.STRING, help="Hostname") +@click.option("--password", is_flag=False, show_default=False, default='', type=click.STRING, help="Password") +@click.option("--organization", "organization_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Organization name") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait disabled") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_os_install_static_command( + ctx, + iaccount, + name_filter, + ip_filter, + serial_filter, + scu_name, + image_name, + interface_name, + interface_mac, + address, + prefix, + gateway, + nameserver, + hostname, + password, + organization_name, + interactive, + dry_run, + no_wait, + verbose, + devel + ): + """OS installation with static""" + + # iserver create os-install static + # iserver.py create os-install static --ip 10.58.50.46 --scu dummy --image dummy --interface eno5 --hostname kvm --password cisco --address 10.1.1.1 --prefix 24 --gateway 10.1.1.2 --nameserver 10.3.3.4 --organization EMEAR-SPDC-Specialists --dry-run --verbose + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + ctx.my_output.default('Check isctl version...') + isctl_success, isctl_output = menu_main.check_isctl() + if not isctl_success: + ctx.my_output.error('isctl command execution failed') + raise ErrorExit + + if not menu_main.check_isctl_version(isctl_output, '0.1.18'): + ctx.my_output.error('Minimum isctl version 0.1.18 is required') + raise ErrorExit + + if name_filter == '' and ip_filter == '' and serial_filter == '': + interactive = True + + if not interactive: + ctx.my_output.default('Validate input parameters...') + + attributes = os_install_validations.get_static_attributes( + ctx, + iaccount, + name_filter, + ip_filter, + serial_filter, + scu_name, + image_name, + interface_name, + interface_mac, + address, + prefix, + gateway, + nameserver, + hostname, + password, + organization_name, + interactive=interactive + ) + if attributes is None: + raise ErrorExit + + ctx.my_output.info( + json.dumps( + attributes, + indent=4 + ) + ) + + if common.get_confirmation(): + if not os_install_common.run(ctx, iaccount, attributes, dry_run=dry_run, wait=not no_wait, verbose=verbose): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/os_install/validations.py b/menu/create/os_install/validations.py new file mode 100644 index 00000000..fa375ef8 --- /dev/null +++ b/menu/create/os_install/validations.py @@ -0,0 +1,658 @@ +import os + +from progress.bar import IncrementalBar + +from lib.intersight import compute_info +from lib.intersight import os_configuration_file +from lib import ip_helper + +from menu import user_inputs +from menu import common +from menu import validations + + +def validate_embedded_attributes(ctx, iaccount, filename, attributes): + ''' + type: embedded + server: + ip: 10.58.50.46 + image: dummy + scu: dummmy + organization: EMEAR-SPDC-Specialists + ''' + for attribute in ['server', 'image', 'scu', 'organization']: + if attribute not in attributes: + ctx.my_output.error('[%s] Attribute %s required' % (filename, attribute)) + return None + + found = False + for attribute in ['ip', 'name', 'serial']: + if attribute in attributes['server']: + found = True + else: + attributes['server'][attribute] = '' + + if not found: + ctx.my_output.error('[%s] Attribute server.[ip|name|serial] required' % (filename)) + return None + + if len(attributes['server']['ip']) > 0: + if not ip_helper.is_valid_ipv4_address(attributes['server']['ip']): + ctx.my_output.error('[%s] Invalid IPv4 address: %s' % (filename, attributes['server']['ip'])) + return None + + attributes = get_embedded_attributes( + ctx, + iaccount, + attributes['server']['name'], + attributes['server']['ip'], + attributes['server']['serial'], + attributes['scu'], + attributes['image'], + attributes['organization'] + ) + + return attributes[0] + + +def validate_dhcp_attributes(ctx, iaccount, filename, attributes): + ''' + type: dhcp + server: + ip: 10.58.50.46 + image: dummy + scu: dummmy + interface: + name: eno5 + hostname: kvm + password: cisco + organization: EMEAR-SPDC-Specialists + ''' + for attribute in ['server', 'image', 'scu', 'interface', 'organization', 'hostname', 'password']: + if attribute not in attributes: + ctx.my_output.error('[%s] Attribute %s required' % (filename, attribute)) + return None + + found = False + for attribute in ['ip', 'name', 'serial']: + if attribute in attributes['server']: + found = True + else: + attributes['server'][attribute] = '' + + if not found: + ctx.my_output.error('[%s] Attribute server.[ip|name|serial] required' % (filename)) + return None + + if len(attributes['server']['ip']) > 0: + if not ip_helper.is_valid_ipv4_address(attributes['server']['ip']): + ctx.my_output.error('[%s] Invalid IPv4 address: %s' % (filename, attributes['server']['ip'])) + return None + + found = False + for attribute in ['name', 'mac']: + if attribute in attributes['interface']: + found = True + else: + attributes['interface'][attribute] = '' + + if not found: + ctx.my_output.error('[%s] Attribute interface.[name|mac] required' % (filename)) + return None + + attributes = get_dhcp_attributes( + ctx, + iaccount, + attributes['server']['name'], + attributes['server']['ip'], + attributes['server']['serial'], + attributes['scu'], + attributes['image'], + attributes['interface']['name'], + attributes['interface']['mac'], + attributes['hostname'], + attributes['password'], + attributes['organization'], + interactive=False + ) + return attributes[0] + + +def validate_static_attributes(ctx, iaccount, filename, attributes): + ''' + type: static + server: + ip: 10.58.50.46 + image: Ubuntu 22.04LTS + scu: SCU 6.2.2a + interface: + name: eno5 + ip: 10.58.25.163 + netmask: 255.255.255.240 + gateway: 10.58.25.174 + hostname: iserver-test + password: cisco + nameserver: 144.254.71.184 + organization: EMEAR-SPDC-Specialists + ''' + for attribute in ['server', 'image', 'scu', 'interface', 'organization', 'hostname', 'password', 'nameserver']: + if attribute not in attributes: + ctx.my_output.error('[%s] Attribute %s required' % (filename, attribute)) + return None + + found = False + for attribute in ['ip', 'name', 'serial']: + if attribute in attributes['server']: + found = True + else: + attributes['server'][attribute] = '' + + if not found: + ctx.my_output.error('[%s] Attribute server.[ip|name|serial] required' % (filename)) + return None + + if len(attributes['server']['ip']) > 0: + if not ip_helper.is_valid_ipv4_address(attributes['server']['ip']): + ctx.my_output.error('[%s] Invalid IPv4 address: %s' % (filename, attributes['server']['ip'])) + return None + + found = False + for attribute in ['name', 'mac']: + if attribute in attributes['interface']: + found = True + else: + attributes['interface'][attribute] = '' + + if not found: + ctx.my_output.error('[%s] Attribute interface.[name|mac] required' % (filename)) + return None + + for attribute in ['ip', 'netmask', 'gateway']: + if attribute not in attributes['interface']: + ctx.my_output.error('[%s] Attribute interface.%s required' % (filename, attribute)) + return None + + if len(attributes['interface']['ip']) > 0: + if not ip_helper.is_valid_ipv4_address(attributes['interface']['ip']): + ctx.my_output.error('[%s] Invalid IPv4 address: %s' % (filename, attributes['interface']['ip'])) + return None + + if len(attributes['interface']['gateway']) > 0: + if not ip_helper.is_valid_ipv4_address(attributes['interface']['gateway']): + ctx.my_output.error('[%s] Invalid IPv4 address: %s' % (filename, attributes['interface']['gateway'])) + return None + + if len(attributes['interface']['netmask']) == 0: + ctx.my_output.error('[%s] netmask value required' % (filename)) + return None + + prefix = ip_helper.netmask_to_prefix(attributes['interface']['netmask']) + if prefix is None: + ctx.my_output.error('[%s] invalud netmask value: %s' % (filename, attributes['interface']['netmask'])) + return None + + if len(attributes['nameserver']) > 0: + if not ip_helper.is_valid_ipv4_address(attributes['nameserver']): + ctx.my_output.error('[%s] Invalid IPv4 address: %s' % (filename, attributes['nameserver'])) + return None + + attributes = get_static_attributes( + ctx, + iaccount, + attributes['server']['name'], + attributes['server']['ip'], + attributes['server']['serial'], + attributes['scu'], + attributes['image'], + attributes['interface']['name'], + attributes['interface']['mac'], + attributes['interface']['ip'], + prefix, + attributes['interface']['gateway'], + attributes['nameserver'], + attributes['hostname'], + attributes['password'], + attributes['organization'] + ) + + return attributes[0] + + +def validate_attributes(ctx, iaccount, filename, attributes): + if attributes is None: + return None + + if 'type' not in attributes: + ctx.my_output.error('type attribute required') + return None + + if attributes['type'] not in ['embedded', 'dhcp', 'static']: + ctx.my_output.error('type attribute allowed values: embedded, dhcp, static') + return None + + if attributes['type'] == 'embedded': + return validate_embedded_attributes(ctx, iaccount, filename, attributes) + + if attributes['type'] == 'dhcp': + return validate_dhcp_attributes(ctx, iaccount, filename, attributes) + + return validate_static_attributes(ctx, iaccount, filename, attributes) + + +def get_batch_attributes(ctx, iaccount, location): + filenames = [] + if os.path.isdir(location): + for file_in_dir in os.listdir(location): + filenames.append( + os.path.join(location, file_in_dir) + ) + + if os.path.isfile(location): + filenames.append(location) + + if len(filenames) == 0: + ctx.my_output.error('No input files found') + return None + + attributes = [] + bar_handler = IncrementalBar('Input file', max=len(filenames)) + bar_handler.goto(0) + for filename in filenames: + file_attributes = validate_attributes( + ctx, + iaccount, + filename, + validations.validate_yaml_file(ctx, filename) + ) + if file_attributes is None: + bar_handler.finish() + ctx.my_output.error('\nInvalid file content: %s' % (filename)) + return None + + attributes.append(file_attributes) + bar_handler.next() + + bar_handler.finish() + + return attributes + + +def validate_server(ctx, iaccount, name_filter, ip_filter, serial_filter, workflow=86400): + server = common.get_selected_servers( + ctx, + iaccount, + None, + serial_filter, + name_filter, + ip_filter, + + workflow=workflow, + include_object=True, + show_servers=True, + confirm=True + ) + if server is None: + return None + + if server['Workflow']['Running'] is not None: + ctx.my_output.error('Active workflow on server %s. Cannot continue' % (server['Name'])) + return None + + return server + + +def get_embedded_attributes(ctx, iaccount, name_filter, ip_filter, serial_filter, scu_name, image_name, organization_name, interactive=False): + if name_filter == '' and ip_filter == '' and serial_filter == '': + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = user_inputs.get_value(ctx, 'Server name') + + if server_selection_mode == 'serial': + serial_filter = user_inputs.get_value(ctx, 'Server serial number') + + if server_selection_mode == 'ip': + ip_filter = user_inputs.get_value(ctx, 'Server management IP address') + + if not interactive: + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + return None + + server = validate_server(ctx, iaccount, name_filter, ip_filter, serial_filter) + if server is None: + return None + + if interactive: + scu_name = user_inputs.get_scu_name(ctx, iaccount) + image_name = user_inputs.get_os_image_name(ctx, iaccount) + + organization_name = user_inputs.get_organization_name(ctx, iaccount) + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + return None + + settings = common.get_server_selection_settings( + iaccount, + workflow=None, + action=True, + registration=False, + enabled=['storage'] + ) + + compute_handler = compute_info.ComputeInfo(iaccount, settings=settings, log_id=ctx.run_id) + server_info = compute_handler.get_server_info(server['IntersightObject']) + + scu_info = validations.validate_scu(ctx, iaccount, scu_name) + if scu_info is None: + return None + + image_info = validations.validate_os_image(ctx, iaccount, image_name) + if image_info is None: + return None + + attributes = {} + attributes['type'] = 'embedded' + attributes['server_id'] = server_info['Moid'] + attributes['server_name'] = server_info['Name'] + attributes['scu_id'] = scu_info['Moid'] + attributes['image'] = {} + attributes['image']['id'] = image_info['Moid'] + attributes['image']['name'] = image_info['Name'] + attributes['image']['vendor_id'] = image_info['VendorId'] + attributes['image']['version_id'] = image_info['VersionId'] + + if server_info['VirtualDiskCount'] == 0: + ctx.my_output.error('No virtual disk detected on the server') + return None + + virtual_disk = server_info['VirtualDisks'][0] + attributes['storage_controller_slot'] = virtual_disk['StorageControllerId'] + attributes['virtual_drive_id'] = virtual_disk['VirtualDriveId'] + attributes['virtual_drive_name'] = virtual_disk['Name'] + + attributes['organization_id'] = organization_id + attributes['server'] = server + + return [attributes] + + +def get_dhcp_attributes(ctx, iaccount, name_filter, ip_filter, serial_filter, scu_name, image_name, interface_name, interface_mac, hostname, password, organization_name, interactive=False): + if name_filter == '' and ip_filter == '' and serial_filter == '': + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = user_inputs.get_value(ctx, 'Server name') + + if server_selection_mode == 'serial': + serial_filter = user_inputs.get_value(ctx, 'Server serial number') + + if server_selection_mode == 'ip': + ip_filter = user_inputs.get_value(ctx, 'Server management IP address') + + if not interactive: + if interface_name == '' and interface_mac == '': + ctx.my_output.error('Define either interface name or interface mac for sending dhcp request') + return None + + if hostname == '': + ctx.my_output.error('Define hostname') + return None + + if password == '': + ctx.my_output.error('Define password') + return None + + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + return None + + server = validate_server(ctx, iaccount, name_filter, ip_filter, serial_filter) + if server is None: + return None + + if interactive: + scu_name = user_inputs.get_scu_name(ctx, iaccount) + image_name = user_inputs.get_os_image_name(ctx, iaccount) + ctx.my_output.default('Define interface by name or mac address') + interface_name = user_inputs.get_value(ctx, '- interface name', empty=True) + interface_mac = user_inputs.get_value(ctx, '- interface mac', empty=True) + hostname = user_inputs.get_value(ctx, 'Hostname') + password = user_inputs.get_value(ctx, 'Password') + organization_name = user_inputs.get_organization_name(ctx, iaccount) + + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + return None + + settings = common.get_server_selection_settings( + iaccount, + workflow=86400, + action=True, + registration=False, + enabled=['storage'] + ) + + compute_handler = compute_info.ComputeInfo(iaccount, settings=settings, log_id=ctx.run_id) + server_info = compute_handler.get_server_info(server['IntersightObject']) + + scu_info = validations.validate_scu(ctx, iaccount, scu_name) + if scu_info is None: + return None + + image_info = validations.validate_os_image(ctx, iaccount, image_name) + if image_info is None: + return None + + attributes = {} + attributes['type'] = 'template' + attributes['server_id'] = server_info['Moid'] + attributes['server_name'] = server_info['Name'] + attributes['scu_id'] = scu_info['Moid'] + attributes['image'] = {} + attributes['image']['id'] = image_info['Moid'] + attributes['image']['name'] = image_info['Name'] + attributes['image']['vendor_id'] = image_info['VendorId'] + attributes['image']['version_id'] = image_info['VersionId'] + attributes['ip_config'] = 'dhcp' + attributes['interface_name'] = interface_name + attributes['interface_mac'] = interface_mac + attributes['hostname'] = hostname + attributes['password'] = password + + if server_info['VirtualDiskCount'] == 0: + ctx.my_output.error('No virtual disk detected on the server') + return None + + virtual_disk = server_info['VirtualDisks'][0] + attributes['storage_controller_slot'] = virtual_disk['StorageControllerId'] + attributes['virtual_drive_id'] = virtual_disk['VirtualDriveId'] + attributes['virtual_drive_name'] = virtual_disk['Name'] + + attributes['organization_id'] = organization_id + attributes['server'] = server_info + + os_configuration_file_handler = os_configuration_file.OsConfigurationFile(iaccount, log_id=ctx.run_id) + os_configuration_files = os_configuration_file_handler.get_file_for_os( + attributes['image']['version_id'] + ) + if len(os_configuration_files) == 0: + ctx.my_output.error('No autoconfiguration file found for image: %s' % (attributes['image']['name'])) + return None + + if len(os_configuration_files) > 1: + ctx.my_output.error('Multiple autoconfiguration files found for image: %s' % (attributes['image']['name'])) + for item in os_configuration_files: + ctx.my_output.default('- Moid [%s] Name [%s]' % (item['Moid'], item['Name'])) + return None + + attributes['configuration_file_id'] = os_configuration_files[0]['Moid'] + + return [attributes] + + +def get_static_attributes(ctx, iaccount, name_filter, ip_filter, serial_filter, scu_name, image_name, interface_name, interface_mac, address, prefix, gateway, nameserver, hostname, password, organization_name, interactive=False): + if name_filter == '' and ip_filter == '' and serial_filter == '': + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = user_inputs.get_value(ctx, 'Server name') + + if server_selection_mode == 'serial': + serial_filter = user_inputs.get_value(ctx, 'Server serial number') + + if server_selection_mode == 'ip': + ip_filter = user_inputs.get_value(ctx, 'Server management IP address') + + if not interactive: + if interface_name == '' and interface_mac == '': + ctx.my_output.error('Define either interface name or interface mac for sending dhcp request') + return None + + if hostname == '': + ctx.my_output.error('Define hostname') + return None + + if password == '': + ctx.my_output.error('Define password') + return None + + if address == '': + ctx.my_output.error('Define IP address') + return None + + netmask = ip_helper.prefix_to_netmask(prefix) + cidr = '%s/%s' % ( + address, + str(prefix) + ) + + if gateway == '': + ctx.my_output.error('Define gateway address') + return None + + if not ip_helper.is_ipv4_in_cidr(gateway, cidr): + ctx.my_output.error('Gateway must be part of the subnet') + return None + + if nameserver == '': + ctx.my_output.error('Define nameserver address') + return None + + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + return None + + server = validate_server(ctx, iaccount, name_filter, ip_filter, serial_filter) + if server is None: + return None + + if interactive: + scu_name = user_inputs.get_scu_name(ctx, iaccount) + image_name = user_inputs.get_os_image_name(ctx, iaccount) + ctx.my_output.default('Define interface by name or mac address') + interface_name = user_inputs.get_value(ctx, '- interface name', empty=True) + interface_mac = user_inputs.get_value(ctx, '- interface mac', empty=True) + address = user_inputs.get_ip_address(ctx, 'Interface IP address') + prefix = user_inputs.get_prefix_length(ctx, 'Prefix length') + gateway = user_inputs.get_ip_address(ctx, 'Gateway IP address') + + netmask = ip_helper.prefix_to_netmask(prefix) + cidr = '%s/%s' % ( + address, + str(prefix) + ) + + if not ip_helper.is_ipv4_in_cidr(gateway, cidr): + ctx.my_output.error('Gateway must be part of the subnet') + return None + + nameserver = user_inputs.get_value(ctx, 'Nameserver IP address') + hostname = user_inputs.get_value(ctx, 'Hostname') + password = user_inputs.get_value(ctx, 'Password') + + organization_name = user_inputs.get_organization_name(ctx, iaccount) + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + return None + + settings = common.get_server_selection_settings( + iaccount, + workflow=None, + action=True, + registration=False + ) + settings['storage'] = True + + compute_handler = compute_info.ComputeInfo(iaccount, settings=settings, log_id=ctx.run_id) + server_info = compute_handler.get_server_info(server['IntersightObject']) + + scu_info = validations.validate_scu(ctx, iaccount, scu_name) + if scu_info is None: + return None + + image_info = validations.validate_os_image(ctx, iaccount, image_name) + if image_info is None: + return None + + attributes = {} + attributes['type'] = 'template' + attributes['server_id'] = server_info['Moid'] + attributes['server_name'] = server_info['Name'] + attributes['scu_id'] = scu_info['Moid'] + attributes['image'] = {} + attributes['image']['id'] = image_info['Moid'] + attributes['image']['name'] = image_info['Name'] + attributes['image']['vendor_id'] = image_info['VendorId'] + attributes['image']['version_id'] = image_info['VersionId'] + attributes['ip_config'] = 'static' + attributes['interface_name'] = interface_name + attributes['interface_mac'] = interface_mac + attributes['ipv4_address'] = address + attributes['ipv4_mask'] = netmask + attributes['ipv4_gateway'] = gateway + attributes['nameserver'] = nameserver + attributes['hostname'] = hostname + attributes['password'] = password + + if server_info['VirtualDiskCount'] == 0: + ctx.my_output.error('No virtual disk detected on the server') + return None + + virtual_disk = server_info['VirtualDisks'][0] + attributes['storage_controller_slot'] = virtual_disk['StorageControllerId'] + attributes['virtual_drive_id'] = virtual_disk['VirtualDriveId'] + attributes['virtual_drive_name'] = virtual_disk['Name'] + + attributes['organization_id'] = organization_id + attributes['server'] = server + + os_configuration_file_handler = os_configuration_file.OsConfigurationFile(iaccount, log_id=ctx.run_id) + os_configuration_files = os_configuration_file_handler.get_file_for_os( + attributes['image']['version_id'] + ) + if len(os_configuration_files) == 0: + ctx.my_output.error('No autoconfiguration file found for image: %s' % (attributes['image']['name'])) + return None + + if len(os_configuration_files) > 1: + ctx.my_output.error('Multiple autoconfiguration files found for image: %s' % (attributes['image']['name'])) + for item in os_configuration_files: + ctx.my_output.default('- Moid [%s] Name [%s]' % (item['Moid'], item['Name'])) + return None + + attributes['configuration_file_id'] = os_configuration_files[0]['Moid'] + + return [attributes] diff --git a/menu/create/osp/__init__.py b/menu/create/osp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/osp/fip.py b/menu/create/osp/fip.py new file mode 100644 index 00000000..7601f49a --- /dev/null +++ b/menu/create/osp/fip.py @@ -0,0 +1,252 @@ +import os +import time +import json +import sys +import traceback +import threading +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("fip") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Tenant name") +@click.option("--port", "port_id", default='', callback=validations.empty_string_to_none, help="Port id") +@click.option("--network", "network_name", default='', callback=validations.empty_string_to_none, help="Floating network name") +@click.option("--ip", "floating_ip", default='', callback=validations.empty_string_to_none, help="Floating IP address") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_fip_command( + ctx, + cluster_name, + tenant_name, + port_id, + network_name, + floating_ip, + devel + ): + """Create osp fip""" + + # iserver create osp fip + + ctx.developer = devel + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + tenant_id = None + if port_id is None: + object_filter = [] + if tenant_name is not None: + object_filter.append( + 'tenant_name:%s' % (tenant_name) + ) + + vms = osp_handlers.get_virtual_machines( + object_filter=object_filter, + tenant_info=True, + flavor_info=True, + image_info=True, + volume_info=True, + network_info=True, + subnet_info=True + ) + selected_vm = osp_output_handler.select_virtual_machine(vms) + if selected_vm is None: + raise ErrorExit + + tenant_id = selected_vm['tenant_id'] + tenant_name = selected_vm['tenant_name'] + ctx.my_output.default('Tenant id: %s' % (tenant_id)) + ctx.my_output.default('Tenant name: %s' % (tenant_name)) + + object_filter = [] + object_filter.append( + 'vm_id:%s' % (selected_vm['id']) + ) + ports = osp_handlers.get_ports( + object_filter=object_filter, + tenant_info=True, + network_info=True, + subnet_info=True, + fip_info=True + ) + selected_port = osp_output_handler.select_port(ports) + if selected_port is None: + raise ErrorExit + + port_id = selected_port['id'] + ctx.my_output.default('Port id: %s' % (selected_port['id'])) + + if network_name is not None: + network_info = osp_handlers.get_network( + network_name=network_name + ) + if network_info is None: + ctx.my_output.error('Network not found: %s' % (network_name)) + raise ErrorExit + + if not network_info['external']: + ctx.my_output.error('Network must be external: %s' % (network_name)) + raise ErrorExit + + network_id = network_info['id'] + + if network_name is None: + object_filter = [] + object_filter.append( + 'external:true' + ) + + networks = osp_handlers.get_networks( + object_filter=object_filter, + tenant_info=True, + subnet_info=True, + port_info=False, + router_info=True + ) + selected_network = osp_output_handler.select_network(networks) + if selected_network is None: + raise ErrorExit + + network_id = selected_network['id'] + network_name = selected_network['name'] + + ctx.my_output.default('External network id: %s' % (network_id)) + ctx.my_output.default('External network name: %s' % (network_name)) + + object_filter = [] + object_filter.append( + 'network_id:%s' % (network_id) + ) + subnets = osp_handlers.get_subnets( + object_filter=object_filter, + tenant_info=True, + network_info=True + ) + if subnets is None: + ctx.my_output.error('Network subnet info failed: %s' % (network_name)) + raise ErrorExit + + if len(subnets) == 0: + ctx.my_output.error('Network must have subnet: %s' % (network_name)) + raise ErrorExit + + if len(subnets) == 1: + selected_subnet = subnets[0] + else: + selected_subnet = osp_output_handler.select_subnet(subnets) + if selected_subnet is None: + raise ErrorExit + + subnet_id = selected_subnet['id'] + subnet_name = selected_subnet['name'] + subnet_cidr = selected_subnet['cidr'] + ctx.my_output.default('External subnet id: %s' % (subnet_id)) + ctx.my_output.default('External subnet name: %s' % (subnet_name)) + ctx.my_output.default('External subnet cidr: %s' % (subnet_cidr)) + + if tenant_id is None: + tenants = osp_handlers.get_tenants() + selected_tenant = osp_output_handler.select_tenant(tenants) + if selected_tenant is None: + raise ErrorExit + + tenant_id = selected_tenant['id'] + + if floating_ip is None: + ctx.my_output.default('Automatic allocation of floating IP?') + if not common.get_confirmation(title=False): + object_filter = [] + object_filter.append( + 'subnet_id:%s' % (subnet_id) + ) + ports = osp_handlers.get_ports( + object_filter=object_filter, + tenant_info=True, + network_info=True, + subnet_info=True, + fip_info=True + ) + + ctx.my_output.default('Floating IP usage', underline=True) + osp_output_handler.print_ports(ports, title=False) + + floating_ip = input("Define new floating IP: ") + if not ip_helper.is_valid_ipv4_address(floating_ip): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + if floating_ip is not None: + if not ip_helper.is_ipv4_in_cidr(floating_ip, subnet_cidr): + ctx.my_output.error('Floating IP %s not in subnet %s' % (floating_ip, subnet_cidr)) + raise ErrorExit + + if osp_handlers.is_floating_ip(floating_ip): + ctx.my_output.error('Floating IP already used') + + floating_ip_info = osp_handlers.get_floating_ip( + floating_ip=floating_ip, + tenant_info=True, + network_info=True, + port_info=True, + router_info=True + ) + if floating_ip_info is None: + ctx.my_output.error('Floating IP not found') + raise ErrorExit + + osp_output_handler.print_floating_ips( + [floating_ip_info], + title=False + ) + + raise ErrorExit + + floating_ip_id = osp_handlers.create_floating_ip_mo( + tenant_id, + port_id, + network_id, + subnet_id, + floating_ip_address=floating_ip + ) + if floating_ip_id is None: + ctx.my_output.error('Floating IP create failed') + raise ErrorExit + + ctx.my_output.default('Floating IP created: %s' % (floating_ip_id)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/osp/flv.py b/menu/create/osp/flv.py new file mode 100644 index 00000000..01e8235b --- /dev/null +++ b/menu/create/osp/flv.py @@ -0,0 +1,103 @@ +import os +import time +import json +import sys +import traceback +import threading +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("flv") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--name", "flavor_name", default='', callback=validations.empty_string_to_none, help="Flavor name") +@click.option("--cpu", default=1, type=click.INT, help="CPU") +@click.option("--mem", default=2048, type=click.INT, help="Memory") +@click.option("--disk", default=20, type=click.INT, help="Disk") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_flv_command( + ctx, + cluster_name, + flavor_name, + cpu, + mem, + disk, + devel + ): + """Create osp flv""" + + ctx.developer = devel + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + if flavor_name is None: + flavor_name = input('New flavor name: ') + if flavor_name is None or len(flavor_name) == 0: + raise ErrorExit + + cpu = common.get_integer('CPU: ') + if cpu <= 0: + raise ErrorExit + + mem = common.get_integer('Memory [MB]: ') + if mem <= 0: + raise ErrorExit + + disk = common.get_integer('Disk [GB]: ') + if disk < 0: + raise ErrorExit + + if osp_handlers.is_flavor(flavor_name=flavor_name): + ctx.my_output.error('Flavor already exists: %s' % (flavor_name)) + raise ErrorExit + + ctx.my_output.default('Creating new flavor...') + new_flavor_id = osp_handlers.create_flavor_mo( + flavor_name, + mem, + cpu, + disk + ) + + if new_flavor_id is None: + ctx.my_output.error('Flavor create failed') + raise ErrorExit + + ctx.my_output.default('Flavor created: %s' % (new_flavor_id)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/osp/img.py b/menu/create/osp/img.py new file mode 100644 index 00000000..2b3f1789 --- /dev/null +++ b/menu/create/osp/img.py @@ -0,0 +1,161 @@ +import os +import time +import json +import sys +import traceback +import threading +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("img") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--name", "image_name", default='', callback=validations.empty_string_to_none, help="Image name") +@click.option("--src", "source_filename", default='', callback=validations.empty_string_to_none, help="Source filename (upload)") +@click.option("--dst", "destination_filename", default='', callback=validations.empty_string_to_none, help="Destination filename (download)") +@click.option("--disk", "disk_format", type=click.Choice(['qcow2', 'raw'], case_sensitive=False), default='qcow2', help="Upload disk format") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_img_command( + ctx, + cluster_name, + image_name, + source_filename, + destination_filename, + disk_format, + devel + ): + """Create osp img""" + + ctx.developer = devel + ctx.output = 'default' + + try: + if source_filename is None and destination_filename is None: + ctx.my_output.error('Define souce (upload) filename or destination (download) filename') + raise ErrorExit + + if source_filename is not None and destination_filename is not None: + ctx.my_output.error('Define souce (upload) filename or destination (download) filename') + raise ErrorExit + + if source_filename is not None: + if not os.path.isfile(source_filename): + ctx.my_output.error('File not found: %s' % (source_filename)) + raise ErrorExit + + if destination_filename is not None: + if os.path.isfile(destination_filename): + ctx.my_output.default('Overwrite existing file?') + if not common.get_confirmation(): + raise ErrorExit + + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + if source_filename is not None: + if image_name is None: + image_name = input('Target image name: ') + if len(image_name) == 0: + raise ErrorExit + + if len(image_name.split(' ')) > 1: + ctx.my_output.error('Image name cannot have white spaces') + raise ErrorExit + + if osp_handlers.is_image(image_name=image_name): + ctx.my_output.error('Image exists: %s' % (image_name)) + raise ErrorExit + + ctx.my_output.default( + 'Create image %s from file %s with disk format %s' % ( + image_name, + source_filename, + disk_format + ) + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + new_image_id = osp_handlers.create_image_mo( + image_name, + source_filename, + disk_format=disk_format + ) + + ctx.busy = False + + if new_image_id is None: + ctx.my_output.error('Create image failed') + raise ErrorExit + + ctx.my_output.default('New image created: %s' % (new_image_id)) + + if destination_filename is not None: + if image_name is None: + images = osp_handlers.get_images() + image_info = osp_output_handler.select_image(images) + if image_info is None: + raise ErrorExit + else: + image_info = osp_handlers.get_image(image_name=image_name) + if image_info is None: + ctx.my_output.error('Image does not exist: %s' % (image_name)) + raise ErrorExit + + ctx.my_output.default( + 'Image %s download to file %s' % ( + image_info['name'], + destination_filename + ) + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + success = osp_handlers.download_image( + image_info['id'], + destination_filename + ) + + ctx.busy = False + + if not success: + ctx.my_output.error('Image download failed') + raise ErrorExit + + ctx.my_output.default('Image downloaded') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/osp/main.py b/menu/create/osp/main.py new file mode 100644 index 00000000..0f546b6f --- /dev/null +++ b/menu/create/osp/main.py @@ -0,0 +1,28 @@ +import click + +from menu.create.osp.fip import create_osp_fip_command +from menu.create.osp.flv import create_osp_flv_command +from menu.create.osp.img import create_osp_img_command +from menu.create.osp.net import create_osp_net_command +from menu.create.osp.rule import create_osp_rule_command +from menu.create.osp.sub import create_osp_subnet_command +from menu.create.osp.vm import create_osp_vm_command + + +class Failure(Exception): + pass + + +@click.group("osp") +@click.pass_obj +def create_osp_menu(ctx): + """Create OpenStack commands""" + + +create_osp_menu.add_command(create_osp_fip_command) +create_osp_menu.add_command(create_osp_flv_command) +create_osp_menu.add_command(create_osp_img_command) +create_osp_menu.add_command(create_osp_net_command) +create_osp_menu.add_command(create_osp_rule_command) +create_osp_menu.add_command(create_osp_subnet_command) +create_osp_menu.add_command(create_osp_vm_command) diff --git a/menu/create/osp/net.py b/menu/create/osp/net.py new file mode 100644 index 00000000..149a7586 --- /dev/null +++ b/menu/create/osp/net.py @@ -0,0 +1,169 @@ +import os +import time +import json +import sys +import traceback +import threading +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("net") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--name", "network_name", default='', callback=validations.empty_string_to_none, help="Network name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Tenant name") +@click.option("--type", "network_type", type=click.Choice(['tenant', 'provider', 'external'], case_sensitive=False), default='tenant', help="Network type") +@click.option("--phy", "physical_network", default='', callback=validations.empty_string_to_none, help="Physical network") +@click.option("--prov", "provider_network_type", default='', callback=validations.empty_string_to_none, help="Provider network type") +@click.option("--vlan", "provider_segmentation_id", default='', callback=validations.empty_string_to_none, help="Provider segmentation id") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_net_command( + ctx, + cluster_name, + network_name, + tenant_name, + network_type, + physical_network, + provider_network_type, + provider_segmentation_id, + devel + ): + """Create osp net""" + + ctx.developer = devel + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + user_input_mode = False + + if network_name is None: + user_input_mode = True + network_name = input('New network name: ') + if network_name is None or len(network_name) == 0: + raise ErrorExit + + if osp_handlers.is_network_name(network_name): + ctx.my_output.error('Network already defined: %s' % (network_name)) + raise ErrorExit + + if tenant_name is None: + user_input_mode = True + tenants = osp_handlers.get_tenants() + if tenants is None: + ctx.my_output.error('Failed to get tenants') + raise ErrorExit + + selected_tenant = osp_output_handler.select_tenant(tenants) + if selected_tenant is None: + raise ErrorExit + + tenant_id = selected_tenant['id'] + tenant_name = selected_tenant['name'] + else: + tenant = osp_handlers.get_tenant(tenant_name=tenant_name) + if tenant is None: + ctx.my_output.error('Tenant not found: %s' % (tenant_name)) + raise ErrorExit + + tenant_id = tenant['id'] + + if user_input_mode: + network_type = input('Network type (tenant, provider, external): ') + if network_type is None or len(network_type) == 0 or network_type not in ['tenant', 'provider', 'external']: + raise ErrorExit + + if network_type == 'tenant': + new_network_id = osp_handlers.create_tenant_network_mo( + tenant_id, + network_name + ) + if new_network_id is None: + ctx.my_output.error('Create failed') + raise ErrorExit + + ctx.my_output.default('New tenant network created: %s' % (new_network_id)) + return + + if network_type == 'external': + if physical_network is None: + physical_network = input('Physical network name: ') + if physical_network is None or len(physical_network) == 0: + raise ErrorExit + + new_network_id = osp_handlers.create_external_network_mo( + network_name, + physical_network + ) + if new_network_id is None: + ctx.my_output.error('Create failed') + raise ErrorExit + + ctx.my_output.default('New external network created: %s' % (new_network_id)) + return + + if network_type == 'provider': + if physical_network is None: + physical_network = input('Physical network name: ') + if physical_network is None or len(physical_network) == 0: + raise ErrorExit + + if provider_network_type is None: + provider_network_type = input('Provider network type: ') + if provider_network_type is None or len(provider_network_type) == 0: + raise ErrorExit + + if provider_segmentation_id is None: + provider_segmentation_id = common.get_integer('Provider segmentation id: ') + if provider_segmentation_id is None: + raise ErrorExit + + new_network_id = osp_handlers.create_provider_network_mo( + tenant_id, + network_name, + physical_network, + provider_network_type, + provider_segmentation_id + ) + if new_network_id is None: + ctx.my_output.error('Create failed') + raise ErrorExit + + ctx.my_output.default('New provider network created: %s' % (new_network_id)) + return + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/osp/rule.py b/menu/create/osp/rule.py new file mode 100644 index 00000000..038489cd --- /dev/null +++ b/menu/create/osp/rule.py @@ -0,0 +1,174 @@ +import sys +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("rule") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Tenant name") +@click.option("--name", "security_group_name", default='', callback=validations.empty_string_to_none, help="Security group name") +@click.option("--type", "ethertype", type=click.Choice(['ipv4', 'ipv6'], case_sensitive=False), help="EtherType") +@click.option("--direction", type=click.Choice(['ingress', 'egress'], case_sensitive=False), help="Direction") +@click.option("--protocol", type=click.Choice(['icmp', 'sctp', 'tcp', 'udp'], case_sensitive=False), help="Protocol") +@click.option("--sport", "start_port", default=-1, type=click.INT, help="Start port range") +@click.option("--eport", "end_port", default=-1, type=click.INT, help="End port range") +@click.option("--prefix", "remote_ip_prefix", default='0.0.0.0/0', callback=validations.validate_subnet, help="Remote prefix") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_rule_command( + ctx, + cluster_name, + tenant_name, + security_group_name, + ethertype, + direction, + protocol, + start_port, + end_port, + remote_ip_prefix, + devel + ): + """Create osp security group rule""" + + ctx.developer = devel + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + if security_group_name is not None: + if len(security_group_name.split('/')) == 2: + (tenant_name, security_group_name) = security_group_name.split('/') + + if tenant_name is None: + tenants = osp_handlers.get_tenants() + selected_tenant = osp_output_handler.select_tenant(tenants) + if selected_tenant is None: + raise ErrorExit + + tenant_id = selected_tenant['id'] + tenant_name = selected_tenant['name'] + else: + tenant_info = osp_handlers.get_tenant( + tenant_name=tenant_name + ) + if tenant_info is None: + ctx.my_output.error('Tenant not found: %s' % (tenant_name)) + raise ErrorExit + + tenant_id = tenant_info['id'] + + if security_group_name is None: + object_filter = [] + object_filter.append( + 'tenant_name:%s' % (tenant_name) + ) + security_groups = osp_handlers.get_security_groups( + object_filter=object_filter, + tenant_info=True + ) + + security_group_info = osp_output_handler.select_security_group( + security_groups + ) + if security_group_info is None: + raise ErrorExit + + security_group_id = security_group_info['id'] + security_group_name = security_group_info['name'] + else: + security_group_info = osp_handlers.get_security_group( + tenant_id=tenant_id, + security_group_name=security_group_name + ) + if security_group_info is None: + raise ErrorExit + + security_group_id = security_group_info['id'] + + if ethertype is None: + ethertype = common.get_value_from_list('EtherType', ['ipv4', 'ipv6'], before_newline=True) + if ethertype is None: + raise ErrorExit + + if direction is None: + direction = common.get_value_from_list('Direction', ['ingress', 'egress'], before_newline=True) + if direction is None: + raise ErrorExit + + if protocol is None: + protocol = common.get_value_from_list('Protocol', ['icmp', 'sctp', 'tcp', 'udp'], before_newline=True) + if protocol is None: + raise ErrorExit + + if protocol != 'icmp': + if start_port < 0: + start_port = common.get_integer('Start port: ', before_newline=True) + if start_port is None: + raise ErrorExit + + if end_port < 0: + end_port = common.get_integer('End port: ', before_newline=True) + if end_port is None: + raise ErrorExit + + if len(security_group_name.split('/')) == 2: + (security_group_name, tenant_name) = security_group_name.split('/') + + if start_port > 0 and end_port > 1: + rule_id = osp_handlers.create_security_group_rule_mo( + security_group_id=security_group_id, + ethertype=ethertype, + protocol=protocol, + direction=direction, + port_range_min=start_port, + port_range_max=end_port, + remote_ip_prefix=remote_ip_prefix + ) + else: + rule_id = osp_handlers.create_security_group_rule_mo( + security_group_id=security_group_id, + ethertype=ethertype, + protocol=protocol, + direction=direction, + remote_ip_prefix=remote_ip_prefix + ) + + if rule_id is None: + ctx.my_output.error('Security group rule create failed') + raise ErrorExit + + ctx.my_output.default('Security group rule created: %s' % (rule_id)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/osp/sub.py b/menu/create/osp/sub.py new file mode 100644 index 00000000..a04505d9 --- /dev/null +++ b/menu/create/osp/sub.py @@ -0,0 +1,202 @@ +import os +import time +import json +import sys +import traceback +import threading +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sub") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--network-name", default='', callback=validations.empty_string_to_none, help="Network name") +@click.option("--network-id", default='', callback=validations.empty_string_to_none, help="Network id") +@click.option("--name", "subnet_name", default='', callback=validations.empty_string_to_none, help="Subnet name") +@click.option("--cidr", default='', callback=validations.empty_string_to_none, help="Subnet cidr") +@click.option("--gateway", default='', callback=validations.empty_string_to_none, help="Subnet gateway") +@click.option("--dns", multiple=True, help="Subnet dns") +@click.option("--dhcp", type=click.Choice(['enabled', 'disabled'], case_sensitive=False), help="DHCP") +@click.option("--start", "start_ip", default='', callback=validations.empty_string_to_none, help="DHCP start") +@click.option("--end", "end_ip", default='', callback=validations.empty_string_to_none, help="DHCP end") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_subnet_command( + ctx, + cluster_name, + network_name, + network_id, + subnet_name, + cidr, + gateway, + dns, + dhcp, + start_ip, + end_ip, + devel + ): + """Create osp subnet""" + + ctx.developer = devel + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + user_input_mode = False + + if network_name is None and network_id is None: + user_input_mode = True + networks = osp_handlers.get_networks(tenant_info=True, subnet_info=True, router_info=True) + if networks is None: + ctx.my_output.error('Failed to get networks') + raise ErrorExit + + network_info = osp_output_handler.select_network(networks) + if network_info is None: + raise ErrorExit + + network_id = network_info['id'] + network_name = network_info['name'] + tenant_id = network_info['tenant_id'] + tenant_name = network_info['tenant_name'] + else: + if network_name is not None: + network_info = osp_handlers.get_network(network_name=network_name, tenant_info=True) + if network_info is None: + ctx.my_output.error('Network not found: %s' % (network_name)) + raise ErrorExit + + network_id = network_info['id'] + tenant_id = network_info['tenant_id'] + tenant_name = network_info['tenant_name'] + + if network_id is not None: + network_info = osp_handlers.get_network(network_id=network_id, tenant_info=True) + if network_info is None: + ctx.my_output.error('Network not found: %s' % (network_id)) + raise ErrorExit + + network_name = network_info['name'] + tenant_id = network_info['tenant_id'] + tenant_name = network_info['tenant_name'] + + if subnet_name is None: + user_input_mode = True + subnet_name = input('New subnet name (default %s-subnet): ' % (network_name)) + if subnet_name is None or len(subnet_name) == 0: + subnet_name = '%s-subnet' % (network_name) + + if osp_handlers.is_subnet_name(subnet_name): + ctx.my_output.error('Subnet already defined: %s' % (subnet_name)) + raise ErrorExit + + if cidr is None: + user_input_mode = True + cidr = input('Subnet cidr: ') + if cidr is None or len(cidr) == 0 or not ip_helper.is_valid_ipv4_cidr(cidr): + raise ErrorExit + + if user_input_mode: + if gateway is None: + gateway = input('Subnet gateway: ') + if gateway is None or len(gateway) == 0: + gateway = None + + if gateway is not None: + if not ip_helper.is_ipv4_in_cidr(gateway, cidr): + ctx.my_output.error('Gateway not in cidr') + raise ErrorExit + + if user_input_mode: + if len(dns) == 0: + dns_servers = input('DNS servers comma separated: ') + if dns_servers is not None and len(dns_servers) > 0: + dns = dns_servers.split(',') + + for dns_entry in dns: + if not ip_helper.is_valid_ipv4_address(dns_entry): + ctx.my_output.error('Invalid dns ipv4 address: %s' % (dns_entry)) + raise ErrorExit + + if user_input_mode or len(dhcp) == 0: + ctx.my_output.default('DHCP enabled') + if common.get_confirmation(title=False): + dhcp = 'enabled' + else: + dhcp = 'disabled' + + if dhcp == 'disabled': + dhcp_enabled = False + start_ip = None + end_ip = None + + if dhcp == 'enabled': + dhcp_enabled = True + if user_input_mode: + if start_ip is None: + start_ip = input('DHCP start ip: ') + if start_ip is None or len(start_ip) == 0: + start_ip = None + + if start_ip is not None and not ip_helper.is_ipv4_in_cidr(start_ip, cidr): + raise ErrorExit + + if start_ip is not None and end_ip is None: + end_ip = input('DHCP end ip: ') + if end_ip is None or len(end_ip) == 0: + end_ip = None + + if end_ip and not ip_helper.is_ipv4_in_cidr(end_ip, cidr): + raise ErrorExit + + new_subnet = osp_handlers.create_subnet_mo( + network_id, + cidr, + tenant_id=tenant_id, + subnet_name=subnet_name, + gateway=gateway, + dns=dns, + dhcp=dhcp_enabled, + start_ip=start_ip, + end_ip=end_ip + ) + if new_subnet is None: + ctx.my_output.error('Create failed') + raise ErrorExit + + ctx.my_output.default('New subnet created: %s' % (new_subnet['id'])) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/osp/vm.py b/menu/create/osp/vm.py new file mode 100644 index 00000000..71fbcf47 --- /dev/null +++ b/menu/create/osp/vm.py @@ -0,0 +1,319 @@ +import os +import time +import json +import sys +import traceback +import threading +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import progress +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Tenant name") +@click.option("--name", "vm_name", default='', callback=validations.empty_string_to_none, help="Virtual machine name") +@click.option("--img", "image_name", default='', callback=validations.empty_string_to_none, help="Image name") +@click.option("--flv", "flavor_name", default='', callback=validations.empty_string_to_none, help="Flavor name") +@click.option("--net", "networks_info", multiple=True, help="Network name[:subnet][:ip]") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_osp_vm_command( + ctx, + cluster_name, + tenant_name, + vm_name, + image_name, + flavor_name, + networks_info, + devel + ): + """Create osp vm""" + + ctx.developer = devel + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster_name) + if osp_handlers is None: + raise ErrorExit + + if tenant_name is None: + tenants = osp_handlers.get_tenants() + if tenants is None: + ctx.my_output.error('Failed to get tenants') + raise ErrorExit + + selected_tenant = osp_output_handler.select_tenant(tenants) + if selected_tenant is None: + raise ErrorExit + + tenant_id = selected_tenant['id'] + tenant_name = selected_tenant['name'] + else: + tenant_info = osp_handlers.get_tenant(tenant_name=tenant_name) + if tenant_info is None: + ctx.my_output.error( + 'Tenant not found: %s' % (tenant_name) + ) + raise ErrorExit + + tenant_id = tenant_info['id'] + + if vm_name is None: + vm_name = input('New virtual machine name: ') + if vm_name is None or len(vm_name) == 0: + raise ErrorExit + + if osp_handlers.is_virtual_machine_by_name(vm_name, tenant_id=tenant_id): + ctx.my_output.error( + 'Virtual machine already defined: %s/%s' % ( + tenant_name, + vm_name + ) + ) + raise ErrorExit + + ctx.my_output.default( + 'Virtual machine does not exist yet: %s/%s' % ( + tenant_name, + vm_name + ) + ) + + if image_name is None: + images = osp_handlers.get_images() + if images is None: + ctx.my_output.error('Failed to get images') + raise ErrorExit + + image_info = osp_output_handler.select_image(images) + if image_info is None: + raise ErrorExit + + image_id = image_info['id'] + image_name = image_info['name'] + else: + image_info = osp_handlers.get_image(image_name=image_name) + if image_info is None: + ctx.my_output.error('Image does not exist: %s' % (image_name)) + raise ErrorExit + image_id = image_info['id'] + + if flavor_name is None: + flavors = osp_handlers.get_flavors() + if flavors is None: + ctx.my_output.error('Failed to get flavors') + raise ErrorExit + + flavor_info = osp_output_handler.select_flavor(flavors) + if flavor_info is None: + raise ErrorExit + + flavor_id = flavor_info['id'] + flavor_name = flavor_info['name'] + else: + flavor_info = osp_handlers.get_flavor(flavor_name=flavor_name) + if flavor_info is None: + ctx.my_output.error('Image does not exist: %s' % (flavor_name)) + raise ErrorExit + flavor_id = flavor_info['id'] + + nics = [] + nics_info = [] + + if len(networks_info) > 0: + for user_network_info in networks_info: + network_name = user_network_info.split(':')[0] + network_info = osp_handlers.get_network(network_name=network_name, subnet_info=True) + if network_info is None: + ctx.my_output.error('Network not found: %s' % (network_name)) + raise ErrorExit + + subnet_name = None + ip_address = None + if len(user_network_info.split(':')) == 2: + user_input = user_network_info.split(':')[1] + if ip_helper.is_valid_ipv4_address(user_input): + ip_address = user_input + else: + subnet_name = user_input + if len(user_network_info.split(':')) == 3: + user_input = user_network_info.split(':')[2] + if ip_helper.is_valid_ipv4_address(user_input): + ip_address = user_input + else: + subnet_name = user_input + + if subnet_name is not None: + network_subnet_info = None + for subnet_info in network_info['subnet_info']: + if subnet_info['name'] == subnet_name: + network_subnet_info = subnet_info + break + + if network_subnet_info is None: + ctx.my_output.error('Invalid subnet %s for network %s' % (subnet_name, network_name)) + raise ErrorExit + + if subnet_name is None: + if len(network_info['subnet_info']) > 1: + ctx.my_output.error('Define subnet as multiple subnets defined for network: %s' % (network_name)) + raise ErrorExit + + network_subnet_info = network_info['subnet_info'][0] + + if ip_address is not None: + if not ip_helper.is_ipv4_in_cidr(ip_address, network_subnet_info['cidr']): + ctx.my_output.error('Selected IP %s not in subnet cidr %s' % ip_address, network_subnet_info['cidr']) + raise ErrorExit + + nic = {} + nic['net-id'] = network_info['id'] + if subnet_name is not None: + nic['subnet-id'] = network_subnet_info['id'] + if ip_address is not None: + nic['v4-fixed-ip'] = ip_address + nics.append( + nic + ) + + nic_info = {} + nic_info['net-id'] = network_info['id'] + nic_info['net-name'] = network_info['name'] + nic_info['subnet-id'] = network_subnet_info['id'] + nic_info['subnet-name'] = network_subnet_info['name'] + if ip_address is not None: + nic_info['ip'] = ip_address + else: + nic_info['ip'] = 'dhcp' + + nics_info.append( + nic_info + ) + + if len(networks_info) == 0: + nic_index = 1 + networks = osp_handlers.get_networks(tenant_info=True, subnet_info=True, router_info=True) + if networks is None: + ctx.my_output.error('Failed to get networks') + raise ErrorExit + + while True: + network_info = osp_output_handler.select_network(networks) + if network_info is None and nic_index == 1: + raise ErrorExit + + if network_info is None: + break + + network_subnet_info = None + if len(network_info['subnet_info']) == 1: + network_subnet_info = network_info['subnet_info'][0] + if len(network_info['subnet_info']) > 1: + network_subnet_info = osp_output_handler.select_subnet(network_info['subnet_info']) + if network_subnet_info is None: + raise ErrorExit + + if network_subnet_info is None: + subnet_name = None + + if network_subnet_info is not None: + subnet_name = network_subnet_info['name'] + ip_address = input('IPv4 address (empty for DHCP): ') + if len(ip_address) == 0: + ip_address = None + else: + if network_subnet_info is None: + ctx.my_output.error('Network has no subnet') + raise ErrorExit + + if not ip_helper.is_ipv4_in_cidr(ip_address, network_subnet_info['cidr']): + ctx.my_output.error('IP addess %s is not in network subnet cidr %s' % (ip_address, network_subnet_info['cidr'])) + raise ErrorExit + + + nic = {} + nic['net-id'] = network_info['id'] + if subnet_name is not None: + nic['subnet-id'] = network_subnet_info['id'] + if ip_address is not None: + nic['v4-fixed-ip'] = ip_address + nics.append( + nic + ) + + nic_info = {} + nic_info['net-id'] = network_info['id'] + nic_info['net-name'] = network_info['name'] + nic_info['subnet-id'] = network_subnet_info['id'] + nic_info['subnet-name'] = network_subnet_info['name'] + if ip_address is not None: + nic_info['ip'] = ip_address + else: + nic_info['ip'] = 'dhcp' + + nics_info.append( + nic_info + ) + + nic_index = nic_index + 1 + + ctx.my_output.default('Create virtual machine') + ctx.my_output.default('- tenant: %s [%s]' % (tenant_name, tenant_id)) + ctx.my_output.default('- name: %s' % (vm_name)) + ctx.my_output.default('- image: %s [%s]' % (image_name, image_id)) + ctx.my_output.default('- flavor: %s [%s]' % (flavor_name, flavor_id)) + for nic_info in nics_info: + ctx.my_output.default( + '- network %s [%s] subnet %s [%s] ip %s' % ( + nic_info['net-name'], + nic_info['net-id'], + nic_info['subnet-name'], + nic_info['subnet-id'], + nic_info['ip'] + ) + ) + + new_virtual_machine_id = osp_handlers.create_virtual_machine_mo( + vm_name, + image_id, + flavor_id, + nics=nics + ) + if new_virtual_machine_id is None: + ctx.my_output.error('Create failed') + raise ErrorExit + + ctx.my_output.default('New virtual machine created: %s' % (new_virtual_machine_id)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/scu.py b/menu/create/scu.py new file mode 100644 index 00000000..1df51429 --- /dev/null +++ b/menu/create/scu.py @@ -0,0 +1,135 @@ +import sys +import json +import traceback +import click + +from progress.bar import Bar + +from lib.intersight import scu + +from menu import user_inputs +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("scu") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--file", "filename", is_flag=False, show_default=False, default='', type=click.STRING, help="Input yaml file") +@click.option("--organization", "organization_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Organization Name") +@click.option("--name", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Name") +@click.option("--version", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Version") +@click.option("--type", "link_type", type=click.Choice(['url', 'nfs'], case_sensitive=False), default='url', help="Link type") +@click.option("--link", is_flag=False, show_default=False, default='', type=click.STRING, help="Link") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_scu_command(ctx, iaccount, filename, organization_name, name, version, link_type, link, interactive, devel): + """Create software configuration utilities""" + + # iserver create scu + + ctx.developer = devel + + try: + scu_handler = scu.SoftwareConfigurationUtility(iaccount, log_id=ctx.run_id) + + if len(filename) > 0: + ctx.my_output.default('Input file verification...') + scus = validations.validate_yaml_file(ctx, filename) + if scus is None: + raise ErrorExit + + if len(filename) == 0: + if len(name) == 0 and len(version) == 0 and len(link) == 0: + interactive = True + + if interactive: + ctx.my_output.default('Get scus...') + items = scu_handler.get_all() + scu_handler.print(items) + + ctx.my_output.default('') + ctx.my_output.default('Define new scu', underline=True) + ctx.my_output.default('') + + name = user_inputs.get_value(ctx, 'Name') + version = user_inputs.get_value(ctx, 'Version') + link_type = user_inputs.get_selection(ctx, 'Select link type', ['url', 'nfs']) + link = user_inputs.get_value(ctx, 'Link') + organization_name = user_inputs.get_organization_name(ctx, iaccount) + + if not interactive: + if len(name) == 0: + ctx.my_output.error('Define name') + raise ErrorExit + + if len(version) == 0: + ctx.my_output.error('Define version') + raise ErrorExit + + if len(link) == 0: + ctx.my_output.error('Define link') + raise ErrorExit + + organization_id = validations.validate_organization(ctx, iaccount, organization_name) + if organization_id is None: + raise ErrorExit + + scus = [] + item = {} + item['Name'] = name + item['Version'] = version + item['Link'] = link + item['Type'] = link_type + item['Organization'] = organization_name + scus.append(item) + + ctx.my_output.default('\nInput parameters verification...') + ctx.my_output.debug( + json.dumps( + scus, + indent=4 + ) + ) + + for scu_definition in scus: + success, reason = scu_handler.validate_add(scu_definition) + if not success: + ctx.my_output.error('Input parameters validation failed') + ctx.my_output.default(reason) + raise ErrorExit + + ctx.my_output.default('Input parameters verified') + + bar_handler = Bar('Progress', max=len(scus)) + bar_handler.goto(0) + failed = [] + for item in scus: + if not scu_handler.add(item): + failed.append(item) + bar_handler.next() + bar_handler.finish() + + if len(failed) > 0: + ctx.my_output.error('Some create tasks failed') + for item in failed: + ctx.my_output.default('- %s' % (item)) + raise ErrorExit + + items = scu_handler.get_all() + scu_handler.print(items) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/server/__init__.py b/menu/create/server/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/server/main.py b/menu/create/server/main.py new file mode 100644 index 00000000..acba6711 --- /dev/null +++ b/menu/create/server/main.py @@ -0,0 +1,16 @@ +import click + +from menu.create.server.user import create_server_user_command + + +class Failure(Exception): + pass + + +@click.group("server") +@click.pass_obj +def create_server_menu(ctx): + """Create server commands""" + + +create_server_menu.add_command(create_server_user_command) diff --git a/menu/create/server/user.py b/menu/create/server/user.py new file mode 100644 index 00000000..3b54c05f --- /dev/null +++ b/menu/create/server/user.py @@ -0,0 +1,133 @@ +import sys +import threading +import traceback +import click + +from lib.imc import endpoint as imc_endpoint +from lib.redfish import endpoint as redfish_endpoint +from lib.redfish import output as redfish_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("user") +@click.pass_obj +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--admin", "admin_password", default='', help="Admin password") +@click.option("--username", default='', help="Username") +@click.option("--password", default='', help="Password") +@click.option("--role", type=click.Choice(['admin', 'user', 'readonly'], case_sensitive=False), default='readonly', help="Role") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def create_server_user_command(ctx, endpoint_ip, admin_password, username, password, role, devel): + """Create server user account""" + + ctx.developer = devel + + try: + if len(admin_password) == 0: + ctx.my_output.error( + 'Define admin password' + ) + raise ErrorExit + + if len(username) == 0: + ctx.my_output.error( + 'Define username' + ) + raise ErrorExit + + if len(password) == 0: + ctx.my_output.error( + 'Define password' + ) + raise ErrorExit + + if len(password) > 20: + ctx.my_output.error( + 'Define password with maximum length of 20 characters' + ) + raise ErrorExit + + redfish_output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + endpoint_ip, + 443, + 'admin', + admin_password, + get_timeout=120, + auto_connect=True, + ssl_verify=False, + log_id=ctx.run_id + ) + + if redfish_handler.endpoint_handler.is_account_username(username): + ctx.my_output.error( + 'Username %s is already defined' % (username) + ) + raise ErrorExit + + account_id = redfish_handler.endpoint_handler.get_account_empty_id() + if account_id is None: + ctx.my_output.error( + 'Failed to allocate new account id' + ) + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + imc_handler = imc_endpoint.ImcEndpoint( + endpoint_ip, + 22, + 'admin', + admin_password, + log_id=ctx.run_id + ) + + success = imc_handler.add_user( + account_id, + username, + password, + role + ) + if not success: + ctx.my_output.error( + 'User create failed' + ) + raise ErrorExit + + ctx.busy = False + + ctx.my_output.default( + 'User created' + ) + + accounts = redfish_handler.endpoint_handler.get_template_properties('account', cache_enabled=False) + if accounts is None: + ctx.my_output.error( + 'Failed to get existing accounts' + ) + raise ErrorExit + + redfish_output_handler.print_ucsc_properties( + 'account', + accounts, + title=True + ) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/create/vc/__init__.py b/menu/create/vc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/create/vc/main.py b/menu/create/vc/main.py new file mode 100644 index 00000000..7a93ca21 --- /dev/null +++ b/menu/create/vc/main.py @@ -0,0 +1,16 @@ +import click + +from menu.create.vc.vm import create_vc_vm_command + + +class Failure(Exception): + pass + + +@click.group("vc") +@click.pass_obj +def create_vc_menu(ctx): + """Create vCenter commands""" + + +create_vc_menu.add_command(create_vc_vm_command) diff --git a/menu/create/vc/vm.py b/menu/create/vc/vm.py new file mode 100644 index 00000000..7e98b200 --- /dev/null +++ b/menu/create/vc/vm.py @@ -0,0 +1,83 @@ +import sys +import traceback +import click + +from lib.vc import virtual_machine_deployment_validator + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--vc", "vcenter", default='', callback=validations.validate_vc_name, help="vCenter name") +@click.option("--ip", "vcenter_ip", default='', callback=validations.validate_ip, help="vCenter IP") +@click.option("--username", "vcenter_username", default='', help="vCenter Username") +@click.option("--password", "vcenter_password", default='', help="vCenter Password") +@click.option("--dir", "vm_directory", is_flag=False, show_default=False, default='', type=click.STRING, help="VM definition directory") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def create_vc_vm_command( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password, + vm_directory, + dry_run, + verbose, + debug + ): + """Create vCehter virtual machine""" + + # iserver create vc vm + + try: + vc_handler = validations.validate_vcenter( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password + ) + if vc_handler is None: + raise ErrorExit + + ctx.my_output.default('Validate virtual machine deployment definition...') + vm_input_validator_handler = virtual_machine_deployment_validator.VcVirtualMachineDeploymentValidator( + log_id=ctx.run_id, + verbose=verbose, + debug=debug + ) + vm_parameters = vm_input_validator_handler.validate_create(vm_directory) + if vm_parameters is None: + raise ErrorExit + + ctx.my_output.default('Creating virtual machine...') + success = vc_handler.create_vm_deployment( + vm_parameters, + screen_base_directory=ctx.log.logs_directory, + dry_run=dry_run + ) + if not success: + raise ErrorExit + + ctx.my_output.default('Done') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/defaults.py b/menu/defaults.py new file mode 100644 index 00000000..daed7660 --- /dev/null +++ b/menu/defaults.py @@ -0,0 +1,17 @@ +import traceback +import click + + +def default_from_context(default_name): + + class OptionDefaultFromContext(click.Option): + + def get_default(self, ctx, call=False): + try: + self.default = ctx.obj.defaults[default_name] + return super(OptionDefaultFromContext, self).get_default(ctx) + except BaseException: + print(traceback.format_exc()) + return None + + return OptionDefaultFromContext diff --git a/menu/delete/__init__.py b/menu/delete/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/__pycache__/__init__.cpython-310.pyc b/menu/delete/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c6331349 Binary files /dev/null and b/menu/delete/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/__pycache__/main.cpython-310.pyc b/menu/delete/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8e54a62d Binary files /dev/null and b/menu/delete/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/__pycache__/os_image.cpython-310.pyc b/menu/delete/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..609d856a Binary files /dev/null and b/menu/delete/__pycache__/os_image.cpython-310.pyc differ diff --git a/menu/delete/__pycache__/scu.cpython-310.pyc b/menu/delete/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..59a87fb3 Binary files /dev/null and b/menu/delete/__pycache__/scu.cpython-310.pyc differ diff --git a/menu/delete/aci/__init__.py b/menu/delete/aci/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/aci/__pycache__/__init__.cpython-310.pyc b/menu/delete/aci/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..41c153e2 Binary files /dev/null and b/menu/delete/aci/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/aci/__pycache__/controller.cpython-310.pyc b/menu/delete/aci/__pycache__/controller.cpython-310.pyc new file mode 100644 index 00000000..d5ffbf36 Binary files /dev/null and b/menu/delete/aci/__pycache__/controller.cpython-310.pyc differ diff --git a/menu/delete/aci/__pycache__/main.cpython-310.pyc b/menu/delete/aci/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..617343ed Binary files /dev/null and b/menu/delete/aci/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/aci/__pycache__/manager.cpython-310.pyc b/menu/delete/aci/__pycache__/manager.cpython-310.pyc new file mode 100644 index 00000000..025d01c6 Binary files /dev/null and b/menu/delete/aci/__pycache__/manager.cpython-310.pyc differ diff --git a/menu/delete/aci/controller.py b/menu/delete/aci/controller.py new file mode 100644 index 00000000..ab7e3f8a --- /dev/null +++ b/menu/delete/aci/controller.py @@ -0,0 +1,50 @@ +import sys +import traceback +import click + +from lib.aci import settings + +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("controller") +@click.pass_obj +@click.option("--name", "apic_name", default='', help="APIC name") +def delete_aci_controller_command( + ctx, + apic_name + ): + """Delete aci controller information""" + + # iserver delete aci controller + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + settings_handler = settings.ApicSettings(log_id=ctx.run_id) + success = settings_handler.delete_apic_controller( + apic_name, + ) + if not success: + ctx.my_output.error('Failed to delete apic entry') + raise ErrorExit + + ctx.my_output.default('APIC entry deleted: %s' % (apic_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/aci/main.py b/menu/delete/aci/main.py new file mode 100644 index 00000000..bce1deb1 --- /dev/null +++ b/menu/delete/aci/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.aci.controller import delete_aci_controller_command + + +class Failure(Exception): + pass + + +@click.group("aci") +@click.pass_obj +def delete_aci_menu(ctx): + """Delete aci commands""" + + +delete_aci_menu.add_command(delete_aci_controller_command) diff --git a/menu/delete/cvim/__init__.py b/menu/delete/cvim/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/cvim/cluster.py b/menu/delete/cvim/cluster.py new file mode 100644 index 00000000..8c7b95e0 --- /dev/null +++ b/menu/delete/cvim/cluster.py @@ -0,0 +1,52 @@ +import sys +import traceback +import click + +from lib.cvim import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="K8s cluster name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_cvim_cluster( + ctx, + cluster_name, + devel + ): + """Delete cvim cluster""" + + # iserver delete cvim cluster + + ctx.developer = devel + + try: + settings_handler = settings.CvimSettings(log_id=ctx.run_id) + cluster = settings_handler.get_cvim_cluster(cluster_name) + + if cluster is None: + ctx.my_output.default('Cisco VIM cluster not defined') + raise ErrorExit + + if not settings_handler.delete_cvim_cluster(cluster_name): + ctx.my_output.default('Cisco VIM cluster delete failed') + raise ErrorExit + + ctx.my_output.default('Cisco VIM cluster deleted') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/cvim/main.py b/menu/delete/cvim/main.py new file mode 100644 index 00000000..41c78f98 --- /dev/null +++ b/menu/delete/cvim/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.cvim.cluster import delete_cvim_cluster + + +class Failure(Exception): + pass + + +@click.group("cvim") +@click.pass_obj +def delete_cvim_menu(ctx): + """Delete cvim commands""" + + +delete_cvim_menu.add_command(delete_cvim_cluster) diff --git a/menu/delete/helm/__init__.py b/menu/delete/helm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/helm/chart.py b/menu/delete/helm/chart.py new file mode 100644 index 00000000..7d2badb4 --- /dev/null +++ b/menu/delete/helm/chart.py @@ -0,0 +1,131 @@ +import sys +import traceback +import click + +from progress.bar import Bar + +from lib.helm import output as helm_output +from lib.helm import main as helm + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("chart") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--no-confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_helm_chart_command( + ctx, + cluster_name, + name, + no_confirm, + devel + ): + """Delete helm chart""" + + # iserver delete helm chart + + ctx.developer = devel + ctx.output = 'default' + + try: + output_handler = helm_output.HelmOutput( + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name, mandatory=['helm']) + if settings is None: + raise ErrorExit + + helm_handler = helm.Helm( + settings['helm']['ip'], + settings['helm']['username'], + password=settings['helm']['password'], + key_filename=settings['helm']['key_filename'], + log_id=ctx.run_id + ) + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + charts = helm_handler.get_charts( + chart_filter=object_filter, + release_info=True + ) + if charts is None: + ctx.my_output.error('No chart matching search criteria') + return + + output_handler.print_charts( + charts, + title=True + ) + + if not no_confirm: + if not common.get_confirmation(): + return + + bar_handler = Bar('Verify', max=len(charts)) + bar_handler.goto(0) + for chart in charts: + if helm_handler.is_chart_release(chart['chart']): + ctx.my_output.error( + 'Chart %s has active release' % (chart['chart']) + ) + bar_handler.finish() + raise ErrorExit + + bar_handler.next() + + bar_handler.finish() + + bar_handler = Bar('Progress', max=len(charts)) + bar_handler.goto(0) + failed = [] + for chart in charts: + if not helm_handler.delete_chart(chart['chart']): + failed.append(chart) + bar_handler.next() + bar_handler.finish() + + if len(failed) > 0: + ctx.my_output.error('Not all helm charts deleted') + for chart in failed: + ctx.my_output.default('- %s' % (chart['chart'])) + raise ErrorExit + + ctx.my_output.default('Helm charts deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/helm/main.py b/menu/delete/helm/main.py new file mode 100644 index 00000000..b43f3962 --- /dev/null +++ b/menu/delete/helm/main.py @@ -0,0 +1,18 @@ +import click + +from menu.delete.helm.chart import delete_helm_chart_command +from menu.delete.helm.release import delete_helm_release_command + + +class Failure(Exception): + pass + + +@click.group("helm") +@click.pass_obj +def delete_helm_menu(ctx): + """Delete helm commands""" + + +delete_helm_menu.add_command(delete_helm_chart_command) +delete_helm_menu.add_command(delete_helm_release_command) diff --git a/menu/delete/helm/release.py b/menu/delete/helm/release.py new file mode 100644 index 00000000..92865d33 --- /dev/null +++ b/menu/delete/helm/release.py @@ -0,0 +1,168 @@ +import sys +import traceback +import click + +from lib.helm import output as helm_output +from lib.helm import main as helm + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("release") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--no-confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_helm_release_command( + ctx, + cluster_name, + namespace, + name, + no_confirm, + devel + ): + """Delete helm release""" + + # iserver delete helm release + + ctx.developer = devel + ctx.output = 'default' + + try: + if name is not None: + if len(name.split('/')) == 2: + (namespace, name) = name.split('/') + + output_handler = helm_output.HelmOutput( + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name, mandatory=['helm']) + if settings is None: + raise ErrorExit + + if settings['helm'] is None: + ctx.my_output.error('Helm not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + helm_handler = helm.Helm( + settings['helm']['ip'], + settings['helm']['username'], + password=settings['helm']['password'], + key_filename=settings['helm']['key_filename'], + log_id=ctx.run_id + ) + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + silent=True + ) + if ocp_handler is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + releases = helm_handler.get_releases( + release_filter=object_filter, + chart_info=True, + values_info=True, + day0_info=True + ) + if releases is None: + ctx.my_output.error('No helm releases matching search criteria') + return + + if len(releases) == 0: + ctx.my_output.default('No helm releases matching search criteria') + return + + output_handler.print_releases( + releases, + title=True + ) + + output_handler.print_releases_day0( + releases, + title=False + ) + + if not no_confirm: + if not common.get_confirmation(): + return + + for release in releases: + if release['day0'] is not None: + for item in release['day0']: + if ocp_handler.k8s_handler.is_pvc(item['dv']['metadata']['namespace'], item['dv']['metadata']['name'], cache_enabled=False): + success = ocp_handler.k8s_handler.delete_namespaced_pvc( + item['dv']['metadata']['namespace'], + item['dv']['metadata']['name'] + ) + if not success: + ctx.my_output.error( + 'Failed to delete release day0 information: %s/%s' % ( + item['dv']['metadata']['namespace'], + item['dv']['metadata']['name'] + ) + ) + raise ErrorExit + + ctx.my_output.default( + 'Day0 pvc deleted: %s/%s' % ( + item['dv']['metadata']['namespace'], + item['dv']['metadata']['name'] + ) + ) + + if not helm_handler.delete_release(release['namespace'], release['name']): + raise ErrorExit + + ctx.my_output.default( + 'Release deleted: %s/%s' % ( + release['namespace'], + release['name'] + ) + ) + + ctx.my_output.default('Helm releases deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/k8s/__init__.py b/menu/delete/k8s/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/k8s/cluster.py b/menu/delete/k8s/cluster.py new file mode 100644 index 00000000..6ae01bb7 --- /dev/null +++ b/menu/delete/k8s/cluster.py @@ -0,0 +1,59 @@ +import sys +import threading +import traceback +import click + +from lib.k8s import settings + +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="K8s cluster name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_k8s_cluster( + ctx, + cluster_name, + devel + ): + """Delete k8s cluster""" + + # iserver delete k8s cluster + + ctx.developer = devel + + try: + settings_handler = settings.K8sSettings(log_id=ctx.run_id) + cluster = settings_handler.get_k8s_cluster(cluster_name) + + if cluster is None: + ctx.my_output.default('Kubernetes cluster not defined') + raise ErrorExit + + if cluster['source'] != 'user': + ctx.my_output.default('Kubernetes cluster cannot be deleted') + raise ErrorExit + + if not settings_handler.delete_k8s_cluster(cluster_name): + ctx.my_output.default('Kubernetes cluster delete failed') + raise ErrorExit + + ctx.my_output.default('Kubernetes cluster deleted') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/k8s/dv.py b/menu/delete/k8s/dv.py new file mode 100644 index 00000000..863d8075 --- /dev/null +++ b/menu/delete/k8s/dv.py @@ -0,0 +1,120 @@ +import sys +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress +from progress.bar import Bar + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("dv") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_k8s_dv_command( + ctx, + cluster, + namespace, + name, + no_confirm + ): + """Delete k8s dv (ocp)""" + + # iserver delete k8s dv + + ctx.developer = False + ctx.output = 'default' + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + dvs = k8s_handlers.get_data_volumes( + object_filter=object_filter, + cache_enabled=False + ) + + ctx.busy = False + + if len(dvs) == 0: + ctx.my_output.default('No object found') + return + + k8s_output_handler.print_data_volumes( + dvs, + title=True + ) + + if not no_confirm: + value = input('Confirm (Y/N) ') + if value.lower() != 'y': + return + + bar_handler = Bar('Delete objects', max=len(dvs)) + bar_handler.goto(0) + + success = True + for dv_info in dvs: + success = success and k8s_handlers.delete_data_volume(dv_info['namespace'], dv_info['name']) + bar_handler.next() + + bar_handler.finish() + + if not success: + ctx.my_output.error('Some delete api calls failed') + raise ErrorExit + + ctx.my_output.default('Done') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/k8s/main.py b/menu/delete/k8s/main.py new file mode 100644 index 00000000..aedcf3a0 --- /dev/null +++ b/menu/delete/k8s/main.py @@ -0,0 +1,24 @@ +import click + +from menu.delete.k8s.cluster import delete_k8s_cluster +from menu.delete.k8s.dv import delete_k8s_dv_command +from menu.delete.k8s.pvc import delete_k8s_pvc_command +from menu.delete.k8s.srnnp import delete_k8s_srnnp_command +from menu.delete.k8s.vm import delete_k8s_vm_command + + +class Failure(Exception): + pass + + +@click.group("k8s") +@click.pass_obj +def delete_k8s_menu(ctx): + """Delete k8s commands""" + + +delete_k8s_menu.add_command(delete_k8s_cluster) +delete_k8s_menu.add_command(delete_k8s_dv_command) +delete_k8s_menu.add_command(delete_k8s_pvc_command) +delete_k8s_menu.add_command(delete_k8s_srnnp_command) +delete_k8s_menu.add_command(delete_k8s_vm_command) diff --git a/menu/delete/k8s/pvc.py b/menu/delete/k8s/pvc.py new file mode 100644 index 00000000..8f0a2d43 --- /dev/null +++ b/menu/delete/k8s/pvc.py @@ -0,0 +1,147 @@ +import sys +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress +from progress.bar import Bar + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pvc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_k8s_pvc_command( + ctx, + cluster, + namespace, + name, + no_confirm + ): + """Delete k8s pvc""" + + # iserver delete k8s pvc + + ctx.developer = False + ctx.output = 'default' + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + pvcs = k8s_handlers.get_pvcs( + object_filter=object_filter, + usage_info=True, + cache_enabled=False + ) + + ctx.busy = False + + if len(pvcs) == 0: + ctx.my_output.default('No object found') + return + + k8s_output_handler.print_pvcs_with_usage( + pvcs, + title=True + ) + + delete_allowed = True + for pvc in pvcs: + if pvc['used']: + ctx.my_output.error( + 'PVC %s/%s is used and cannot be deleted' % (pvc['namespace'], pvc['name']) + ) + delete_allowed = False + continue + + if pvc['owner'] is not None: + ctx.my_output.error( + 'PVC %s/%s is owned by different object: %s' % (pvc['namespace'], pvc['name'], pvc['owner']) + ) + delete_allowed = False + continue + + if not delete_allowed: + raise ErrorExit + + if not no_confirm: + value = input('Confirm (Y/N) ') + if value.lower() != 'y': + return + + bar_handler = Bar('Delete objects', max=len(pvcs)) + bar_handler.goto(0) + + success = True + used = [] + for pvc_info in pvcs: + if pvc_info['used']: + used.append(pvc_info) + else: + success = success and k8s_handlers.delete_namespaced_pvc(pvc_info['namespace'], pvc_info['name']) + bar_handler.next() + + bar_handler.finish() + + if not success: + ctx.my_output.error('Some delete api calls failed') + raise ErrorExit + + if len(used) > 0: + ctx.my_output.default('Used pvcs not deleted') + + ctx.my_output.default('Done') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/k8s/srnnp.py b/menu/delete/k8s/srnnp.py new file mode 100644 index 00000000..29638476 --- /dev/null +++ b/menu/delete/k8s/srnnp.py @@ -0,0 +1,105 @@ +import sys +import traceback +import click +import yaml + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("srnnp") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--namespace", default='openshift-sriov-network-operator', callback=validations.empty_string_to_none, help="Policy namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Policy name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_k8s_srnnp_command( + ctx, + cluster_name, + namespace, + name, + devel + ): + """Delete k8s srnnp""" + + # iserver delete k8s srnnp + + ctx.developer = devel + ctx.output = 'default' + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster_name, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + if namespace is None: + ctx.my_output.error('Define policy namespace') + raise ErrorExit + + if namespace not in ['openshift-sriov-network-operator']: + ctx.my_output.error('Unsupported policy namespace') + raise ErrorExit + + if name is None: + ctx.my_output.error('Define policy name') + raise ErrorExit + + sriov_network_node_policy_info = k8s_handlers.get_sriov_network_node_policy( + name, + sriov_network_info=True + ) + if sriov_network_node_policy_info is None: + ctx.my_output.error('SR-IOV network node policy not found: %s' % (name)) + raise ErrorExit + + k8s_output_handler.print_sriov_network_node_policies( + [sriov_network_node_policy_info], + title=False + ) + + if sriov_network_node_policy_info['sriov_network_count'] > 0: + ctx.my_output.error( + 'SR-IOV network node policy is used and cannot be deleted' + ) + raise ErrorExit + + if not common.get_confirmation(): + raise ErrorExit + + if not k8s_handlers.delete_sriov_network_node_policy(sriov_network_node_policy_info['namespace'], sriov_network_node_policy_info['name']): + ctx.my_output.error( + 'SR-IOV network node policy delete failed' + ) + raise ErrorExit + + ctx.my_output.default( + 'SR-IOV network node policy deleted' + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/k8s/vm.py b/menu/delete/k8s/vm.py new file mode 100644 index 00000000..38e7e056 --- /dev/null +++ b/menu/delete/k8s/vm.py @@ -0,0 +1,73 @@ +import sys +import threading +import traceback +import click + +from lib import file_helper + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", "cluster_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Cluster Name") +@click.option("--file", "vm_filename", is_flag=False, show_default=False, default='', type=click.STRING, help="VM Definition YAML") +@click.option("--sriov", "include_sriov_policy", is_flag=True, show_default=True, default=False, help="Delete sriov policy") +@click.option("--image", "include_image", is_flag=True, show_default=True, default=False, help="Delete image") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def delete_k8s_vm_command( + ctx, + cluster_name, + vm_filename, + include_sriov_policy, + include_image, + verbose, + debug + ): + """Delete OCP virtual machine""" + + # iocp delete ocp vm + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + validated_input = validations.validate_ocp_vm_yaml_file(ctx, vm_filename) + if validated_input is None: + ctx.busy = False + raise ErrorExit + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + ctx.busy = False + + if not ocp_handler.delete_vm_deployment(validated_input, include_sriov_policy=include_sriov_policy, include_image=include_image): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/linux/__init__.py b/menu/delete/linux/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/linux/main.py b/menu/delete/linux/main.py new file mode 100644 index 00000000..b0711df7 --- /dev/null +++ b/menu/delete/linux/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.linux.server import delete_linux_server_command + + +class Failure(Exception): + pass + + +@click.group("linux") +@click.pass_obj +def delete_linux_menu(ctx): + """Delete linux commands""" + + +delete_linux_menu.add_command(delete_linux_server_command) diff --git a/menu/delete/linux/server.py b/menu/delete/linux/server.py new file mode 100644 index 00000000..91884f52 --- /dev/null +++ b/menu/delete/linux/server.py @@ -0,0 +1,59 @@ +import sys +import traceback +import click + +from menu import validations + +from lib.linux import settings +from lib.linux import output as linux_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Linux name") +def delete_linux_server_command( + ctx, + name + ): + """Delete linux server""" + + # iserver delete linux server + + ctx.developer = False + ctx.output = 'default' + + try: + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + settings_handler = settings.LinuxSettings(log_id=ctx.run_id) + + if settings_handler.get_linux_server(name) is None: + ctx.my_output.error('Server %s not found' % (name)) + raise ErrorExit + + if not settings_handler.delete_linux_server(name): + ctx.my_output.error('Server %s delete failed' % (name)) + raise ErrorExit + + ctx.my_output.default('Server %s deleted' % (name)) + servers = settings_handler.get_linux_servers() + linux_output_handler.print_linux_servers( + servers, + show_password=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/main.py b/menu/delete/main.py new file mode 100644 index 00000000..5ac1cef4 --- /dev/null +++ b/menu/delete/main.py @@ -0,0 +1,44 @@ +import click + +from menu.delete.aci.main import delete_aci_menu +from menu.delete.cvim.main import delete_cvim_menu +from menu.delete.helm.main import delete_helm_menu +from menu.delete.k8s.main import delete_k8s_menu +from menu.delete.linux.main import delete_linux_menu +from menu.delete.nso.main import delete_nso_menu +from menu.delete.nx.main import delete_nx_menu +from menu.delete.ocp.main import delete_ocp_menu +from menu.delete.osp.main import delete_osp_menu +from menu.delete.os_image import delete_os_image_command +from menu.delete.redfish.main import delete_redfish_menu +from menu.delete.scu import delete_scu_command +from menu.delete.server.main import delete_server_menu +from menu.delete.ucsm.main import delete_ucsm_menu +from menu.delete.vc.main import delete_vc_menu + + +class Failure(Exception): + pass + + +@click.group("delete") +@click.pass_obj +def delete_menu(ctx): + """Delete commands""" + + +delete_menu.add_command(delete_aci_menu) +delete_menu.add_command(delete_cvim_menu) +delete_menu.add_command(delete_helm_menu) +delete_menu.add_command(delete_k8s_menu) +delete_menu.add_command(delete_linux_menu) +delete_menu.add_command(delete_nso_menu) +delete_menu.add_command(delete_nx_menu) +delete_menu.add_command(delete_ocp_menu) +delete_menu.add_command(delete_osp_menu) +delete_menu.add_command(delete_os_image_command) +delete_menu.add_command(delete_redfish_menu) +delete_menu.add_command(delete_scu_command) +delete_menu.add_command(delete_server_menu) +delete_menu.add_command(delete_ucsm_menu) +delete_menu.add_command(delete_vc_menu) diff --git a/menu/delete/nso/__init__.py b/menu/delete/nso/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/nso/__pycache__/__init__.cpython-310.pyc b/menu/delete/nso/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c00fc53a Binary files /dev/null and b/menu/delete/nso/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/nso/__pycache__/main.cpython-310.pyc b/menu/delete/nso/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..756a56c2 Binary files /dev/null and b/menu/delete/nso/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/nso/main.py b/menu/delete/nso/main.py new file mode 100644 index 00000000..f910782b --- /dev/null +++ b/menu/delete/nso/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.nso.nfvo.main import delete_nso_nfvo_menu + + +class Failure(Exception): + pass + + +@click.group("nso") +@click.pass_obj +def delete_nso_menu(ctx): + """Delete nso commands""" + + +delete_nso_menu.add_command(delete_nso_nfvo_menu) diff --git a/menu/delete/nso/nfvo/__init__.py b/menu/delete/nso/nfvo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/nso/nfvo/__pycache__/__init__.cpython-310.pyc b/menu/delete/nso/nfvo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e1c8bc34 Binary files /dev/null and b/menu/delete/nso/nfvo/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/nso/nfvo/__pycache__/main.cpython-310.pyc b/menu/delete/nso/nfvo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6710917e Binary files /dev/null and b/menu/delete/nso/nfvo/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/nso/nfvo/__pycache__/vnfd.cpython-310.pyc b/menu/delete/nso/nfvo/__pycache__/vnfd.cpython-310.pyc new file mode 100644 index 00000000..9e6067fa Binary files /dev/null and b/menu/delete/nso/nfvo/__pycache__/vnfd.cpython-310.pyc differ diff --git a/menu/delete/nso/nfvo/__pycache__/vnfi.cpython-310.pyc b/menu/delete/nso/nfvo/__pycache__/vnfi.cpython-310.pyc new file mode 100644 index 00000000..ddabe397 Binary files /dev/null and b/menu/delete/nso/nfvo/__pycache__/vnfi.cpython-310.pyc differ diff --git a/menu/delete/nso/nfvo/main.py b/menu/delete/nso/nfvo/main.py new file mode 100644 index 00000000..9cd0a3ad --- /dev/null +++ b/menu/delete/nso/nfvo/main.py @@ -0,0 +1,18 @@ +import click + +from menu.delete.nso.nfvo.vnfd import delete_nso_nfvo_vnfd_command +from menu.delete.nso.nfvo.vnfi import delete_nso_nfvo_vnfi_command + + +class Failure(Exception): + pass + + +@click.group("nfvo") +@click.pass_obj +def delete_nso_nfvo_menu(ctx): + """Delete nso nfvo commands""" + + +delete_nso_nfvo_menu.add_command(delete_nso_nfvo_vnfd_command) +delete_nso_nfvo_menu.add_command(delete_nso_nfvo_vnfi_command) diff --git a/menu/delete/nso/nfvo/vnfd.py b/menu/delete/nso/nfvo/vnfd.py new file mode 100644 index 00000000..d13f0b37 --- /dev/null +++ b/menu/delete/nso/nfvo/vnfd.py @@ -0,0 +1,108 @@ +import sys +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vnfd") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--nfvo", "nfvo_version", type=click.Choice(['3.x', '4.x'], case_sensitive=False), default='4.x', show_default=True, help="NFVO Version") +@click.option("--etsi", "nfvo_etsi", is_flag=True, show_default=True, default=False, help="NFVO ETSI") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--id", "vnfd_id", is_flag=False, show_default=False, default='', type=click.STRING, help="VNFD ID") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def delete_nso_nfvo_vnfd_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + nfvo_version, + nfvo_etsi, + restconf_disabled, + vnfd_id, + verbose, + debug + ): + """Create nso nfvo vnfd""" + + # iocp create nso nfvo vnfd + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + if len(vnfd_id) == 0: + ctx.my_output.error('Define vnfd id') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + nso_handler = validations.validate_nso_ncs( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo_version, + nfvo_etsi + ) + if nso_handler is None: + raise ErrorExit + + if not nso_handler.is_vnfd(vnfd_id): + ctx.busy = False + ctx.my_output.default( + 'VNFD already deleted' + ) + return + + success = nso_handler.delete_vnfd( + vnfd_id + ) + if not success: + ctx.busy = False + ctx.my_output.error( + 'VNFD delete failed' + ) + raise ErrorExit + + ctx.busy = False + ctx.my_output.default( + 'VNFD deleted' + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/nso/nfvo/vnfi.py b/menu/delete/nso/nfvo/vnfi.py new file mode 100644 index 00000000..587cc3ce --- /dev/null +++ b/menu/delete/nso/nfvo/vnfi.py @@ -0,0 +1,108 @@ +import sys +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vnfi") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--nfvo", "nfvo_version", type=click.Choice(['3.x', '4.x'], case_sensitive=False), default='4.x', show_default=True, help="NFVO Version") +@click.option("--etsi", "nfvo_etsi", is_flag=True, show_default=True, default=False, help="NFVO ETSI") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--name", "vnfi_name", is_flag=False, show_default=False, default='', type=click.STRING, help="VNF-INFO Name") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def delete_nso_nfvo_vnfi_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + nfvo_version, + nfvo_etsi, + restconf_disabled, + vnfi_name, + verbose, + debug + ): + """Delete nso nfvo vnfi""" + + # iocp delete nso nfvo vnfi + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + if len(vnfi_name) == 0: + ctx.my_output.error('Define vnfi id') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + nso_handler = validations.validate_nso_ncs( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo_version, + nfvo_etsi + ) + if nso_handler is None: + raise ErrorExit + + if not nso_handler.is_vnfi(vnfi_name): + ctx.busy = False + ctx.my_output.default( + 'VNF-INFO already deleted' + ) + return + + success = nso_handler.delete_vnfi( + vnfi_name + ) + if not success: + ctx.busy = False + ctx.my_output.error( + 'VNFD delete failed' + ) + raise ErrorExit + + ctx.busy = False + ctx.my_output.default( + 'VNF-INFO deleted' + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/nx/__init__.py b/menu/delete/nx/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/nx/device.py b/menu/delete/nx/device.py new file mode 100644 index 00000000..ae4d9d0b --- /dev/null +++ b/menu/delete/nx/device.py @@ -0,0 +1,50 @@ +import sys +import traceback +import click + +from lib.nexus import settings + +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("device") +@click.pass_obj +@click.option("--name", "device_name", default='', help="Nexus device name") +def delete_nx_device_command( + ctx, + device_name + ): + """Delete nexus device information""" + + # iserver delete nx device + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + settings_handler = settings.NexusSettings(log_id=ctx.run_id) + success = settings_handler.delete_nexus_device( + device_name + ) + if not success: + ctx.my_output.error('Failed to delete nexus device') + raise ErrorExit + + ctx.my_output.default('Nexus device deleted: %s' % (device_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/nx/main.py b/menu/delete/nx/main.py new file mode 100644 index 00000000..f84ee50e --- /dev/null +++ b/menu/delete/nx/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.nx.device import delete_nx_device_command + + +class Failure(Exception): + pass + + +@click.group("nx") +@click.pass_obj +def delete_nx_menu(ctx): + """Delete nx commands""" + + +delete_nx_menu.add_command(delete_nx_device_command) diff --git a/menu/delete/ocp/__init__.py b/menu/delete/ocp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/ocp/__pycache__/__init__.cpython-310.pyc b/menu/delete/ocp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e8a7f318 Binary files /dev/null and b/menu/delete/ocp/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/ocp/__pycache__/cluster.cpython-310.pyc b/menu/delete/ocp/__pycache__/cluster.cpython-310.pyc new file mode 100644 index 00000000..db945833 Binary files /dev/null and b/menu/delete/ocp/__pycache__/cluster.cpython-310.pyc differ diff --git a/menu/delete/ocp/__pycache__/main.cpython-310.pyc b/menu/delete/ocp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..eccdc0eb Binary files /dev/null and b/menu/delete/ocp/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/ocp/__pycache__/vm.cpython-310.pyc b/menu/delete/ocp/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..523c2a21 Binary files /dev/null and b/menu/delete/ocp/__pycache__/vm.cpython-310.pyc differ diff --git a/menu/delete/ocp/addon/__init__.py b/menu/delete/ocp/addon/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/ocp/addon/__pycache__/__init__.cpython-310.pyc b/menu/delete/ocp/addon/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..4d483b11 Binary files /dev/null and b/menu/delete/ocp/addon/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/ocp/addon/__pycache__/iwo.cpython-310.pyc b/menu/delete/ocp/addon/__pycache__/iwo.cpython-310.pyc new file mode 100644 index 00000000..8279ab7e Binary files /dev/null and b/menu/delete/ocp/addon/__pycache__/iwo.cpython-310.pyc differ diff --git a/menu/delete/ocp/addon/__pycache__/main.cpython-310.pyc b/menu/delete/ocp/addon/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..41605584 Binary files /dev/null and b/menu/delete/ocp/addon/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/ocp/addon/iwo.py b/menu/delete/ocp/addon/iwo.py new file mode 100644 index 00000000..9f862123 --- /dev/null +++ b/menu/delete/ocp/addon/iwo.py @@ -0,0 +1,53 @@ +import sys +import traceback +import click + +from menu import defaults +from menu import validations + +from lib.iwo.lcm import main as iwo + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("iwo") +@click.pass_obj +@click.option("--cluster", "cluster_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Cluster Name") +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def delete_ocp_addon_iwo_command(ctx, cluster_name, iaccount, verbose, debug): + """Delete OCP IWO Addon""" + + # iocp delete ocp addon iwo + + try: + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + iwo_lcm_handler = iwo.IwoLcm( + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + success = iwo_lcm_handler.delete( + cluster_name, + iaccount + ) + if not success: + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/ocp/addon/main.py b/menu/delete/ocp/addon/main.py new file mode 100644 index 00000000..42e09428 --- /dev/null +++ b/menu/delete/ocp/addon/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.ocp.addon.iwo import delete_ocp_addon_iwo_command + + +class Failure(Exception): + pass + + +@click.group("addon") +@click.pass_obj +def delete_ocp_addon_menu(ctx): + """Delete OpenShift addon commands""" + + +delete_ocp_addon_menu.add_command(delete_ocp_addon_iwo_command) diff --git a/menu/delete/ocp/cluster/__init__.py b/menu/delete/ocp/cluster/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/ocp/cluster/main.py b/menu/delete/ocp/cluster/main.py new file mode 100644 index 00000000..ee4933b8 --- /dev/null +++ b/menu/delete/ocp/cluster/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.ocp.cluster.vsphere import delete_ocp_cluster_vshpere_command + + +class Failure(Exception): + pass + + +@click.group("cluster") +@click.pass_obj +def delete_ocp_cluster_menu(ctx): + """Delete OpenShift cluster commands""" + + +delete_ocp_cluster_menu.add_command(delete_ocp_cluster_vshpere_command) diff --git a/menu/delete/ocp/cluster/vsphere.py b/menu/delete/ocp/cluster/vsphere.py new file mode 100644 index 00000000..ee0068a7 --- /dev/null +++ b/menu/delete/ocp/cluster/vsphere.py @@ -0,0 +1,47 @@ +import sys +import traceback +import click + +from lib.ocp.lcm import main as ocp + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vsphere") +@click.pass_obj +@click.option("--dir", "location", is_flag=False, show_default=False, default='', type=click.STRING, help="Cluster definition directory") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def delete_ocp_cluster_vshpere_command(ctx, location, verbose, debug): + """Delete OCP vsphere cluster""" + + # iocp delete cluster + + try: + if len(location) == 0: + ctx.my_output.error('Cluster definition directory required') + raise ErrorExit + + if debug: + verbose = True + ctx.my_output.set_flags(False, verbose, debug) + + ocp_handler = ocp.Ocp(verbose=verbose, debug=debug, log_id=ctx.run_id) + if not ocp_handler.set_ocp_user_input(location): + raise ErrorExit + + if not ocp_handler.delete(): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/ocp/main.py b/menu/delete/ocp/main.py new file mode 100644 index 00000000..99b58cae --- /dev/null +++ b/menu/delete/ocp/main.py @@ -0,0 +1,18 @@ +import click + +from menu.delete.ocp.addon.main import delete_ocp_addon_menu +from menu.delete.ocp.cluster.main import delete_ocp_cluster_menu + + +class Failure(Exception): + pass + + +@click.group("ocp") +@click.pass_obj +def delete_ocp_menu(ctx): + """Delete OpenShift commands""" + + +delete_ocp_menu.add_command(delete_ocp_addon_menu) +delete_ocp_menu.add_command(delete_ocp_cluster_menu) diff --git a/menu/delete/os_image.py b/menu/delete/os_image.py new file mode 100644 index 00000000..467e83bc --- /dev/null +++ b/menu/delete/os_image.py @@ -0,0 +1,68 @@ +import sys +import traceback +import click + +from lib.intersight import os_image +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-image") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--id", "image_id", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Image object Moid") +@click.option("--name", "image_name", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Image object Name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_os_image_command(ctx, image_id, image_name, iaccount, devel): + """Delete operating system image metadata""" + + # iwectl delete os-image + + ctx.developer = devel + + try: + image_handler = os_image.OsImage(iaccount, log_id=ctx.run_id) + images = image_handler.get_all() + + if image_id == '' and image_name == '': + image_handler.print(images) + ctx.my_output.error('Define --id or --name parameters') + raise ErrorExit + + if len(image_name) > 0: + image_attributes = image_handler.get_by_name(image_name) + if image_attributes is None: + image_handler.print(images) + ctx.my_output.error('Name not found: %s' % (image_name)) + raise ErrorExit + image_id = image_attributes['Moid'] + + if not image_handler.is_moid(image_id): + image_handler.print(images) + ctx.my_output.error('Object not found: %s' % (image_id)) + raise ErrorExit + + success = image_handler.delete(image_id) + if not success: + ctx.my_output.error('Object delete failed: %s' % (image_id)) + raise ErrorExit + + ctx.my_output.default('Object deleted: %s\n' % (image_id)) + + images = image_handler.get_all() + image_handler.print(images) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/__init__.py b/menu/delete/osp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/osp/cluster.py b/menu/delete/osp/cluster.py new file mode 100644 index 00000000..090332b0 --- /dev/null +++ b/menu/delete/osp/cluster.py @@ -0,0 +1,56 @@ +import sys +import traceback +import click + +from lib.osp import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="K8s cluster name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_osp_cluster( + ctx, + cluster_name, + devel + ): + """Delete osp cluster""" + + # iserver delete osp cluster + + ctx.developer = devel + + try: + settings_handler = settings.OspSettings(log_id=ctx.run_id) + cluster = settings_handler.get_openstack_cluster(cluster_name) + + if cluster is None: + ctx.my_output.default('Openstack cluster not defined') + raise ErrorExit + + if cluster['source'] != 'user': + ctx.my_output.default('Openstack cluster cannot be deleted') + raise ErrorExit + + if not settings_handler.delete_openstack_cluster(cluster_name): + ctx.my_output.default('Openstack cluster delete failed') + raise ErrorExit + + ctx.my_output.default('Openstack cluster deleted') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/fip.py b/menu/delete/osp/fip.py new file mode 100644 index 00000000..055feb65 --- /dev/null +++ b/menu/delete/osp/fip.py @@ -0,0 +1,104 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import common +from menu import validations + + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("fip") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--ip", "floating_ip_address", default='', callback=validations.validate_ip, help="Select by floating address") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_fip_command( + ctx, + cluster, + floating_ip_address, + no_confirm + ): + """Delete osp fip""" + + # iserver delete osp fip + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + object_filter = [] + + if len(floating_ip_address) == 0: + fips = osp_handlers.get_floating_ips( + object_filter=object_filter, + tenant_info=True, + network_info=True, + router_info=True, + port_info=True + ) + + osp_output_handler.print_floating_ips( + fips, + title=True + ) + + floating_ip_address = input("Define floating IP to be deleted: ") + if not ip_helper.is_valid_ipv4_address(floating_ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + floating_ip_info = osp_handlers.get_floating_ip( + floating_ip=floating_ip_address + ) + + if floating_ip_info is None: + ctx.my_output.error('Failed to get floating IP details') + raise ErrorExit + + osp_output_handler.print_floating_ips( + [floating_ip_info], + title=False + ) + + if not no_confirm: + if not common.get_confirmation(): + raise ErrorExit + + if not osp_handlers.delete_floating_ip_mo(floating_ip_info['id']): + ctx.my_output.error('Failed to delete floating IP') + raise ErrorExit + + ctx.my_output.default('Floating IP deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/flv.py b/menu/delete/osp/flv.py new file mode 100644 index 00000000..a38ae16d --- /dev/null +++ b/menu/delete/osp/flv.py @@ -0,0 +1,94 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import common +from menu import validations + + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("flv") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--id", "flavor_id", default='', callback=validations.empty_string_to_none, help="Flavor id") +@click.option("--name", "flavor_name", default='', callback=validations.empty_string_to_none, help="Flavor name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_flv_command( + ctx, + cluster, + flavor_id, + flavor_name, + no_confirm + ): + """Delete osp flavor""" + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + if flavor_id is None and flavor_name is None: + flavors = osp_handlers.get_flavors() + flavor_info = osp_output_handler.select_flavor(flavors) + if flavor_info is None: + raise ErrorExit + + if flavor_id is not None: + flavor_info = osp_handlers.get_flavor( + flavor_id=flavor_id + ) + if flavor_info is None: + ctx.my_output.error('Flavor not found by id') + raise ErrorExit + + if flavor_name is not None: + flavor_info = osp_handlers.get_flavor( + flavor_name=flavor_name + ) + if flavor_info is None: + ctx.my_output.error('Flavor not found by name') + raise ErrorExit + + ctx.my_output.default('Delete flavor %s [%s]' % (flavor_info['name'], flavor_info['id'])) + if not no_confirm: + if not common.get_confirmation(): + raise ErrorExit + + success = osp_handlers.delete_flavor_mo(flavor_info['id']) + if not success: + ctx.my_output.error('Failed') + raise ErrorExit + + ctx.my_output.default('Deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/img.py b/menu/delete/osp/img.py new file mode 100644 index 00000000..959a5838 --- /dev/null +++ b/menu/delete/osp/img.py @@ -0,0 +1,94 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import common +from menu import validations + + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("img") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--id", "image_id", default='', callback=validations.empty_string_to_none, help="Image id") +@click.option("--name", "image_name", default='', callback=validations.empty_string_to_none, help="Image name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_img_command( + ctx, + cluster, + image_id, + image_name, + no_confirm + ): + """Delete osp image""" + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + if image_id is None and image_name is None: + images = osp_handlers.get_images() + image_info = osp_output_handler.select_image(images) + if image_info is None: + raise ErrorExit + + if image_id is not None: + image_info = osp_handlers.get_image( + image_id=image_id + ) + if image_info is None: + ctx.my_output.error('Image not found by id') + raise ErrorExit + + if image_name is not None: + image_info = osp_handlers.get_image( + image_name=image_name + ) + if image_info is None: + ctx.my_output.error('Image not found by name') + raise ErrorExit + + ctx.my_output.default('Delete image %s [%s]' % (image_info['name'], image_info['id'])) + if not no_confirm: + if not common.get_confirmation(): + raise ErrorExit + + success = osp_handlers.delete_image_mo(image_info['id']) + if not success: + ctx.my_output.error('Failed') + raise ErrorExit + + ctx.my_output.default('Deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/main.py b/menu/delete/osp/main.py new file mode 100644 index 00000000..21ba9e14 --- /dev/null +++ b/menu/delete/osp/main.py @@ -0,0 +1,30 @@ +import click + +from menu.delete.osp.cluster import delete_osp_cluster +from menu.delete.osp.fip import delete_osp_fip_command +from menu.delete.osp.flv import delete_osp_flv_command +from menu.delete.osp.img import delete_osp_img_command +from menu.delete.osp.net import delete_osp_net_command +from menu.delete.osp.rule import delete_osp_rule_command +from menu.delete.osp.sub import delete_osp_sub_command +from menu.delete.osp.vm import delete_osp_vm_command + + +class Failure(Exception): + pass + + +@click.group("osp") +@click.pass_obj +def delete_osp_menu(ctx): + """Delete osp commands""" + + +delete_osp_menu.add_command(delete_osp_cluster) +delete_osp_menu.add_command(delete_osp_fip_command) +delete_osp_menu.add_command(delete_osp_flv_command) +delete_osp_menu.add_command(delete_osp_img_command) +delete_osp_menu.add_command(delete_osp_net_command) +delete_osp_menu.add_command(delete_osp_rule_command) +delete_osp_menu.add_command(delete_osp_sub_command) +delete_osp_menu.add_command(delete_osp_vm_command) diff --git a/menu/delete/osp/net.py b/menu/delete/osp/net.py new file mode 100644 index 00000000..7cdf7680 --- /dev/null +++ b/menu/delete/osp/net.py @@ -0,0 +1,106 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import common +from menu import validations + + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sub") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--id", "network_id", default='', callback=validations.empty_string_to_none, help="Network id") +@click.option("--name", "network_name", default='', callback=validations.empty_string_to_none, help="Network name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_net_command( + ctx, + cluster, + network_id, + network_name, + no_confirm + ): + """Delete osp network""" + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + if network_id is None and network_name is None: + networks = osp_handlers.get_networks() + network_info = osp_output_handler.select_network(networks) + if network_info is None: + raise ErrorExit + + network_id = network_info['id'] + network_name = network_info['name'] + + if network_id is not None: + network_info = osp_handlers.get_network( + network_id=network_id + ) + if network_info is None: + ctx.my_output.error('Network not found by id') + raise ErrorExit + + if network_name is not None: + network_info = osp_handlers.get_network( + network_name=network_name + ) + if network_info is None: + ctx.my_output.error('Network not found by name') + raise ErrorExit + + ctx.my_output.default('Delete network %s [%s]' % (network_info['name'], network_info['id'])) + for subnet_info in network_info['subnet_info']: + ctx.my_output.default('Delete subnet %s [%s]' % (subnet_info['name'], subnet_info['id'])) + + if not no_confirm: + if not common.get_confirmation(): + raise ErrorExit + + for subnet_info in network_info['subnet_info']: + success = osp_handlers.delete_subnet_mo(subnet_info['id']) + if not success: + ctx.my_output.error('Subnet delete failed: %s' % (subnet_info['id'])) + raise ErrorExit + + success = osp_handlers.delete_network_mo(network_id) + if not success: + ctx.my_output.error('Network delete failed') + raise ErrorExit + + ctx.my_output.default('Deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/rule.py b/menu/delete/osp/rule.py new file mode 100644 index 00000000..cef4492a --- /dev/null +++ b/menu/delete/osp/rule.py @@ -0,0 +1,139 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import common +from menu import validations + + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("rule") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Security group tenant") +@click.option("--name", "security_group_name", default='', callback=validations.empty_string_to_none, help="Security group name") +@click.option("--id", "security_group_rule_id", default='', callback=validations.empty_string_to_none, help="Rule id") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_rule_command( + ctx, + cluster, + tenant_name, + security_group_name, + security_group_rule_id, + no_confirm + ): + """Delete osp security group rule""" + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + if security_group_name is not None: + if len(security_group_name.split('/')) == 2: + (tenant_name, security_group_name) = security_group_name.split('/') + + if tenant_name is None: + tenants = osp_handlers.get_tenants() + selected_tenant = osp_output_handler.select_tenant(tenants) + if selected_tenant is None: + raise ErrorExit + + tenant_id = selected_tenant['id'] + tenant_name = selected_tenant['name'] + else: + tenant_info = osp_handlers.get_tenant( + tenant_name=tenant_name + ) + if tenant_info is None: + ctx.my_output.error('Tenant not found: %s' % (tenant_name)) + raise ErrorExit + + tenant_id = tenant_info['id'] + + if security_group_name is None: + object_filter = [] + object_filter.append( + 'tenant_name:%s' % (tenant_name) + ) + security_groups = osp_handlers.get_security_groups( + object_filter=object_filter, + tenant_info=True + ) + + security_group_info = osp_output_handler.select_security_group( + security_groups + ) + if security_group_info is None: + raise ErrorExit + + security_group_id = security_group_info['id'] + security_group_name = security_group_info['name'] + else: + security_group_info = osp_handlers.get_security_group( + tenant_id=tenant_id, + security_group_name=security_group_name + ) + if security_group_info is None: + raise ErrorExit + + security_group_id = security_group_info['id'] + + if security_group_rule_id is None: + security_group_info = osp_handlers.get_security_group( + security_group_id=security_group_id, + tenant_info=True, + rule_info=True + ) + + rule_info = osp_output_handler.select_security_group_rule( + [security_group_info] + ) + + security_group_rule_id = rule_info['id'] + else: + if not osp_handlers.is_security_group_rule(security_group_rule_id): + ctx.my_output.error('Security group rule id not found: %s' % (security_group_rule_id)) + raise ErrorExit + + if not no_confirm: + if not common.get_confirmation(): + raise ErrorExit + + if not osp_handlers.delete_security_group_rule_mo(security_group_rule_id): + ctx.my_output.error('Failed to delete security group rule: %s' % (security_group_rule_id)) + raise ErrorExit + + ctx.my_output.default('Security group rule deleted: %s' % (security_group_rule_id)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/sub.py b/menu/delete/osp/sub.py new file mode 100644 index 00000000..c20176b4 --- /dev/null +++ b/menu/delete/osp/sub.py @@ -0,0 +1,109 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.osp import output as osp_output + +from menu import common +from menu import validations + + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sub") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--id", "subnet_id", default='', callback=validations.empty_string_to_none, help="Subnet id") +@click.option("--name", "subnet_name", default='', callback=validations.empty_string_to_none, help="Subnet name") +@click.option("--network-name", "network_name", default='', callback=validations.empty_string_to_none, help="Filter by network name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_sub_command( + ctx, + cluster, + subnet_id, + subnet_name, + network_name, + no_confirm + ): + """Delete osp subnet""" + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + if subnet_id is None and subnet_name is None: + object_filter = [] + if network_name is not None: + object_filter.append('network_name:%s' % (network_name)) + + subnets = osp_handlers.get_subnets( + object_filter=object_filter, + tenant_info=True, + network_info=True + ) + subnet_info = osp_output_handler.select_subnet(subnets) + if subnet_info is None: + raise ErrorExit + + subnet_id = subnet_info['id'] + subnet_name = subnet_info['name'] + + if subnet_id is not None: + subnet_info = osp_handlers.get_subnet( + subnet_id=subnet_id + ) + if subnet_info is None: + ctx.my_output.error('Subnet not found by id') + raise ErrorExit + + subnet_name = subnet_info['name'] + + if subnet_id is None and subnet_name is not None: + subnet_info = osp_handlers.get_subnet( + subnet_name=subnet_name + ) + if subnet_info is None: + ctx.my_output.error('Subnet not found by name') + raise ErrorExit + + ctx.my_output.default('Delete subnet %s [%s]' % (subnet_info['name'], subnet_info['id'])) + if not no_confirm: + if not common.get_confirmation(): + raise ErrorExit + + success = osp_handlers.delete_subnet_mo(subnet_id) + if not success: + ctx.my_output.error('Failed') + raise ErrorExit + + ctx.my_output.default('Deleted') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/osp/vm.py b/menu/delete/osp/vm.py new file mode 100644 index 00000000..5ab8153d --- /dev/null +++ b/menu/delete/osp/vm.py @@ -0,0 +1,148 @@ +import sys +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress +from progress.bar import Bar + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", default='', help="OpenStack cluster name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +def delete_osp_vm_command( + ctx, + cluster, + tenant, + name, + no_confirm + ): + """Delete osp vm""" + + # iserver delete osp vm + + ctx.developer = False + ctx.output = 'default' + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is None and tenant is None: + vms = osp_handlers.get_virtual_machines( + tenant_info=True, + flavor_info=True, + image_info=True, + volume_info=True, + network_info=True, + subnet_info=True + ) + if vms is None or len(vms) == 0: + ctx.my_output.default('No virtual machine found') + raise ErrorExit + + selected_vm = osp_output_handler.select_virtual_machine(vms) + if selected_vm is None: + raise ErrorExit + + success = osp_handlers.delete_virtual_machine(selected_vm['id']) + if not success: + ctx.my_output.error('Virtual machine delete failed') + raise ErrorExit + + ctx.my_output.default('Virtual machine deleted') + return + + if tenant is not None: + object_filter.append( + 'tenant:%s' % (tenant) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + vms = osp_handlers.get_virtual_machines( + object_filter=object_filter, + tenant_info=True, + flavor_info=True, + image_info=True, + volume_info=True + ) + + if vms is None: + ctx.my_output.error( + 'Failed to get virtual machines' + ) + raise ErrorExit + + ctx.busy = False + + if len(vms) == 0: + ctx.my_output.default('No virtual machines found') + return + + osp_output_handler.print_virtual_machines( + vms, + title=True + ) + + if not no_confirm: + value = input('Confirm (Y/N) ') + if value.lower() != 'y': + return + + bar_handler = Bar('Delete objects', max=len(vms)) + bar_handler.goto(0) + + success = True + for vm_info in vms: + success = success and osp_handlers.delete_virtual_machine(vm_info['id']) + bar_handler.next() + + bar_handler.finish() + + if not success: + ctx.my_output.error('Some delete api calls failed') + raise ErrorExit + + ctx.my_output.default('Done') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/redfish/__init__.py b/menu/delete/redfish/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/redfish/__pycache__/__init__.cpython-310.pyc b/menu/delete/redfish/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d976fb8d Binary files /dev/null and b/menu/delete/redfish/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/access.cpython-310.pyc b/menu/delete/redfish/__pycache__/access.cpython-310.pyc new file mode 100644 index 00000000..269d7dc1 Binary files /dev/null and b/menu/delete/redfish/__pycache__/access.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/adhoc.cpython-310.pyc b/menu/delete/redfish/__pycache__/adhoc.cpython-310.pyc new file mode 100644 index 00000000..639c2ba0 Binary files /dev/null and b/menu/delete/redfish/__pycache__/adhoc.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/cache.cpython-310.pyc b/menu/delete/redfish/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..b2674469 Binary files /dev/null and b/menu/delete/redfish/__pycache__/cache.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/configuration.cpython-310.pyc b/menu/delete/redfish/__pycache__/configuration.cpython-310.pyc new file mode 100644 index 00000000..ec185923 Binary files /dev/null and b/menu/delete/redfish/__pycache__/configuration.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/endpoint.cpython-310.pyc b/menu/delete/redfish/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..acf18466 Binary files /dev/null and b/menu/delete/redfish/__pycache__/endpoint.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/fi.cpython-310.pyc b/menu/delete/redfish/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..6e60a725 Binary files /dev/null and b/menu/delete/redfish/__pycache__/fi.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/main.cpython-310.pyc b/menu/delete/redfish/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..025d72e6 Binary files /dev/null and b/menu/delete/redfish/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/settings.cpython-310.pyc b/menu/delete/redfish/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..93874417 Binary files /dev/null and b/menu/delete/redfish/__pycache__/settings.cpython-310.pyc differ diff --git a/menu/delete/redfish/__pycache__/ucsc.cpython-310.pyc b/menu/delete/redfish/__pycache__/ucsc.cpython-310.pyc new file mode 100644 index 00000000..fc22bd90 Binary files /dev/null and b/menu/delete/redfish/__pycache__/ucsc.cpython-310.pyc differ diff --git a/menu/delete/redfish/access.py b/menu/delete/redfish/access.py new file mode 100644 index 00000000..12a049ab --- /dev/null +++ b/menu/delete/redfish/access.py @@ -0,0 +1,108 @@ +import sys +import threading +import traceback +import click + +from progress.bar import Bar + +from lib.redfish import endpoint_settings + +from menu import common +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("access") +@click.pass_obj +@click.option("--type", "endpoint_type", type=click.Choice(['any', 'standard', 'ucsc', 'fi', 'dell', 'hpe'], case_sensitive=False), default='any', help="Redfish endpoint type") +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip_subnet, help="Redfish management IP") +@click.option("--serial", "serial_number", default='', help="Endpoint serial number") +@click.option("--failed", is_flag=True, show_default=True, default=False, help="Authentication failure") +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show redfish password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_redfish_access_command( + ctx, + endpoint_type, + endpoint_ip, + serial_number, + failed, + show_password, + devel + ): + """Delete redfish access information""" + + # iserver delete redfish access + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + endpoints = endpoint_settings_handler.get_redfish_endpoints_settings( + endpoint_type=endpoint_type, + endpoint_ip=endpoint_ip, + serial_number=serial_number + ) + + ctx.busy = False + + if len(endpoints) == 0: + ctx.my_output.default('No redfish endpoints found') + return + + if failed: + failed_endpoints = [] + bar_handler = Bar('Progress', max=len(endpoints)) + bar_handler.goto(0) + + for item in endpoints: + if not endpoint_settings_handler.verify_redfish_endpoint_authentication(item['endpoint_id']): + failed_endpoints.append(item) + bar_handler.next() + + bar_handler.finish() + + if len(failed_endpoints) == 0: + ctx.my_output.default('No redfish endpoints found') + return + + endpoints = failed_endpoints + + endpoint_settings_handler.print_redfish_endpoint_settings( + endpoints, + show_password=show_password, + verify=False + ) + + if common.get_confirmation(): + bar_handler = Bar('Progress', max=len(endpoints)) + bar_handler.goto(0) + for item in endpoints: + endpoint_settings_handler.delete_redfish_endpoint_settings( + item['endpoint_id'] + ) + bar_handler.next() + + bar_handler.finish() + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/redfish/cache.py b/menu/delete/redfish/cache.py new file mode 100644 index 00000000..23d7c5dc --- /dev/null +++ b/menu/delete/redfish/cache.py @@ -0,0 +1,64 @@ +import sys +import threading +import traceback +import click + +from lib.redfish import cache + +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cache") +@click.pass_obj +@click.option("--name", "custom_cache_name", default='', help="Cache entry name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_redfish_cache_command( + ctx, + custom_cache_name, + devel + ): + """Delete redfish endpoint cache""" + + # iserver delete redfish cache + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if custom_cache_name == '': + ctx.my_output.error('Define cache entry name') + raise ErrorExit + + redfish_cache_handler = cache.RedfishCache() + if custom_cache_name == 'all': + success = redfish_cache_handler.delete_redfish_cache_entries() + if not success: + ctx.my_output.error('All cache entries delete failed') + raise ErrorExit + + ctx.my_output.default('All cache entries deleted') + + else: + success = redfish_cache_handler.delete_redfish_cache_entry(custom_cache_name) + if not success: + ctx.my_output.error('Cache entry delete failed') + raise ErrorExit + + ctx.my_output.default('Cache entry deleted: %s' % (custom_cache_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/redfish/main.py b/menu/delete/redfish/main.py new file mode 100644 index 00000000..5ca0f22f --- /dev/null +++ b/menu/delete/redfish/main.py @@ -0,0 +1,18 @@ +import click + +from menu.delete.redfish.cache import delete_redfish_cache_command +from menu.delete.redfish.access import delete_redfish_access_command + + +class Failure(Exception): + pass + + +@click.group("redfish") +@click.pass_obj +def delete_redfish_menu(ctx): + """Delete redfish commands""" + + +delete_redfish_menu.add_command(delete_redfish_cache_command) +delete_redfish_menu.add_command(delete_redfish_access_command) diff --git a/menu/delete/scu.py b/menu/delete/scu.py new file mode 100644 index 00000000..b2b1e610 --- /dev/null +++ b/menu/delete/scu.py @@ -0,0 +1,71 @@ +import sys +import traceback +import click + +from lib.intersight import scu + +from menu import user_inputs +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("scu") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--id", "scu_id", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU object Moid") +@click.option("--name", "scu_name", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU object Name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_scu_command(ctx, scu_id, scu_name, iaccount, devel): + """Delete software configuration utilities""" + + # iwectl delete scu + + ctx.developer = devel + + try: + scu_handler = scu.SoftwareConfigurationUtility(iaccount, log_id=ctx.run_id) + + ctx.my_output.default('Get scus...') + scus = scu_handler.get_all() + + if scu_id == '' and scu_name == '': + scu_handler.print(scus) + scu_id = user_inputs.get_value(ctx, 'SCU ID') + + if len(scu_name) > 0: + scu_attributes = scu_handler.get_by_name(scu_name) + if scu_attributes is None: + scu_handler.print(scus) + ctx.my_output.error('SCU Name not found: %s' % (scu_name)) + raise ErrorExit + scu_id = scu_attributes['Moid'] + + if not scu_handler.is_moid(scu_id): + scu_handler.print(scus) + ctx.my_output.error('Object not found: %s' % (scu_id)) + raise ErrorExit + + success = scu_handler.delete(scu_id) + if not success: + ctx.my_output.error('Object delete failed: %s' % (scu_id)) + raise ErrorExit + + ctx.my_output.default('Object deleted: %s\n' % (scu_id)) + + scus = scu_handler.get_all() + scu_handler.print(scus) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/server/main.py b/menu/delete/server/main.py new file mode 100644 index 00000000..dd636e9e --- /dev/null +++ b/menu/delete/server/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.server.user import delete_server_user_command + + +class Failure(Exception): + pass + + +@click.group("server") +@click.pass_obj +def delete_server_menu(ctx): + """Create server commands""" + + +delete_server_menu.add_command(delete_server_user_command) diff --git a/menu/delete/server/user.py b/menu/delete/server/user.py new file mode 100644 index 00000000..86f1d6c0 --- /dev/null +++ b/menu/delete/server/user.py @@ -0,0 +1,136 @@ +import sys +import threading +import traceback +import click + +from lib.imc import endpoint as imc_endpoint +from lib.redfish import endpoint as redfish_endpoint +from lib.redfish import output as redfish_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("user") +@click.pass_obj +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--admin", "admin_password", default='', help="Admin password") +@click.option("--username", default='', help="Username") +@click.option("--no-confirm", "no_confirm", is_flag=True, show_default=True, default=False, help="No confirmation mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_server_user_command(ctx, endpoint_ip, admin_password, username, no_confirm, devel): + """Delete server user account""" + + ctx.developer = devel + + try: + if len(admin_password) == 0: + ctx.my_output.error( + 'Define admin password' + ) + raise ErrorExit + + if len(username) == 0: + ctx.my_output.error( + 'Define username to be deleted' + ) + raise ErrorExit + + redfish_output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + endpoint_ip, + 443, + 'admin', + admin_password, + get_timeout=120, + auto_connect=True, + ssl_verify=False, + log_id=ctx.run_id + ) + + if username == '__NOT_ADMIN__': + usernames = redfish_handler.endpoint_handler.get_non_admin_role_usernames() + if usernames is None: + ctx.my_output.error( + 'Failed to get non-admin accounts' + ) + raise ErrorExit + + if len(usernames) == 0: + ctx.my_output.error( + 'No non-admin accounts' + ) + return + + if username != '__NOT_ADMIN__': + usernames = [username] + + to_be_deleted = [] + for candidate in usernames: + if not redfish_handler.endpoint_handler.is_account_username(candidate): + ctx.my_output.default( + 'Username %s is already not defined' % (candidate) + ) + continue + + to_be_deleted.append(candidate) + + if len(to_be_deleted) > 0: + imc_handler = imc_endpoint.ImcEndpoint( + endpoint_ip, + 22, + 'admin', + admin_password, + log_id=ctx.run_id + ) + + for item in to_be_deleted: + account = redfish_handler.endpoint_handler.get_account_by_username(item) + redfish_output_handler.print_ucsc_properties( + 'account', + [account], + title=False + ) + + if not no_confirm: + value = input('Confirm (Y/N) ') + if value.lower() != 'y': + ctx.my_output.default( + 'No action taken' + ) + return + + ctx.my_output.default( + 'Deleting user %s...' % (item) + ) + + success = imc_handler.delete_user( + account['id'] + ) + if not success: + ctx.my_output.error( + 'User %s delete failed' % (item) + ) + raise ErrorExit + + ctx.my_output.default( + 'User %s deleted' % (item) + ) + + ctx.busy = False + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/ucsm/__init__.py b/menu/delete/ucsm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/ucsm/__pycache__/__init__.cpython-310.pyc b/menu/delete/ucsm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..41c153e2 Binary files /dev/null and b/menu/delete/ucsm/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/delete/ucsm/__pycache__/main.cpython-310.pyc b/menu/delete/ucsm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..92fa26a1 Binary files /dev/null and b/menu/delete/ucsm/__pycache__/main.cpython-310.pyc differ diff --git a/menu/delete/ucsm/__pycache__/manager.cpython-310.pyc b/menu/delete/ucsm/__pycache__/manager.cpython-310.pyc new file mode 100644 index 00000000..025d01c6 Binary files /dev/null and b/menu/delete/ucsm/__pycache__/manager.cpython-310.pyc differ diff --git a/menu/delete/ucsm/main.py b/menu/delete/ucsm/main.py new file mode 100644 index 00000000..796f2c94 --- /dev/null +++ b/menu/delete/ucsm/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.ucsm.manager import delete_ucsm_manager_command + + +class Failure(Exception): + pass + + +@click.group("ucsm") +@click.pass_obj +def delete_ucsm_menu(ctx): + """Delete ucsm commands""" + + +delete_ucsm_menu.add_command(delete_ucsm_manager_command) diff --git a/menu/delete/ucsm/manager.py b/menu/delete/ucsm/manager.py new file mode 100644 index 00000000..7e184854 --- /dev/null +++ b/menu/delete/ucsm/manager.py @@ -0,0 +1,52 @@ +import sys +import traceback +import click + +from lib.ucsm import settings + +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("manager") +@click.pass_obj +@click.option("--name", "ucsm_name", default='', help="UCSM name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def delete_ucsm_manager_command( + ctx, + ucsm_name, + devel + ): + """Delete ucsm manager information""" + + # iserver delete ucsm manager + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + settings_handler = settings.UcsmSettings(log_id=ctx.run_id) + success = settings_handler.delete_ucsm_manager( + ucsm_name, + ) + if not success: + ctx.my_output.error('Failed to delete ucsm entry') + raise ErrorExit + + ctx.my_output.default('UCSM entry deleted: %s' % (ucsm_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/delete/vc/__init__.py b/menu/delete/vc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/delete/vc/main.py b/menu/delete/vc/main.py new file mode 100644 index 00000000..cfa10d2f --- /dev/null +++ b/menu/delete/vc/main.py @@ -0,0 +1,16 @@ +import click + +from menu.delete.vc.vm import delete_vc_vm_command + + +class Failure(Exception): + pass + + +@click.group("vc") +@click.pass_obj +def delete_vc_menu(ctx): + """Delete vCenter commands""" + + +delete_vc_menu.add_command(delete_vc_vm_command) diff --git a/menu/delete/vc/vm.py b/menu/delete/vc/vm.py new file mode 100644 index 00000000..2b515c09 --- /dev/null +++ b/menu/delete/vc/vm.py @@ -0,0 +1,112 @@ +import sys +import traceback +import click + +from lib.vc import virtual_machine_deployment_validator +from lib.vc import vcenter + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--vc", "vcenter_name", default='', callback=validations.validate_vc_name, help="vCenter name") +@click.option("--ip", "vcenter_ip", default='', callback=validations.validate_ip, help="vCenter IP") +@click.option("--username", "vcenter_username", default='', help="vCenter Username") +@click.option("--password", "vcenter_password", default='', help="vCenter Password") +@click.option("--name", "vm_name", is_flag=False, show_default=False, default='', type=click.STRING, help="VM name") +@click.option("--dir", "vm_directory", is_flag=False, show_default=False, default='', type=click.STRING, help="VM definition directory") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose mode") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def delete_vc_vm_command( + ctx, + vcenter_name, + vcenter_ip, + vcenter_username, + vcenter_password, + vm_name, + vm_directory, + verbose, + debug + ): + """Delete vCehter virtual machine""" + + try: + if len(vm_directory) == 0 and len(vm_name) == 0: + ctx.my_output.error( + 'Define vm by name or definition directory' + ) + raise ErrorExit + + if len(vm_directory) > 0 and len(vm_name) > 0: + ctx.my_output.error( + 'Define vm by name or definition directory' + ) + raise ErrorExit + + if len(vm_name) > 0: + vc_handler = validations.validate_vcenter( + ctx, + vcenter_name, + vcenter_ip, + vcenter_username, + vcenter_password + ) + if vc_handler is None: + raise ErrorExit + + ctx.my_output.default('Delete virtual machine...') + success = vc_handler.delete_vm( + name=vm_name + ) + if not success: + raise ErrorExit + + if len(vm_directory) > 0: + ctx.my_output.default('Validate virtual machine definition...') + + vm_input_validator_handler = virtual_machine_deployment_validator.VcVirtualMachineDeploymentValidator( + log_id=ctx.run_id, + verbose=verbose, + debug=debug + ) + vm_parameters = vm_input_validator_handler.validate_delete(vm_directory) + if vm_parameters is None: + raise ErrorExit + + vc_handler = vcenter.Vcenter( + vm_parameters['vcenter']['ip'], + vm_parameters['vcenter']['username'], + vm_parameters['vcenter']['password'], + port=vm_parameters['vcenter']['port'], + log_id=ctx.run_id + ) + if not vc_handler.is_vc_connected(): + ctx.my_output.error('Vcenter connection failed') + raise ErrorExit + + ctx.my_output.default('Delete virtual machine deployment...') + success = vc_handler.delete_vm_deployment( + vm_parameters + ) + if not success: + raise ErrorExit + + ctx.my_output.default('Done') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/__init__.py b/menu/get/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/__pycache__/__init__.cpython-310.pyc b/menu/get/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e5f64665 Binary files /dev/null and b/menu/get/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/__pycache__/chassis.cpython-310.pyc b/menu/get/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..f6a913a1 Binary files /dev/null and b/menu/get/__pycache__/chassis.cpython-310.pyc differ diff --git a/menu/get/__pycache__/chassiz.cpython-310.pyc b/menu/get/__pycache__/chassiz.cpython-310.pyc new file mode 100644 index 00000000..1f17f065 Binary files /dev/null and b/menu/get/__pycache__/chassiz.cpython-310.pyc differ diff --git a/menu/get/__pycache__/main.cpython-310.pyc b/menu/get/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..285d1d91 Binary files /dev/null and b/menu/get/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/__pycache__/os_config.cpython-310.pyc b/menu/get/__pycache__/os_config.cpython-310.pyc new file mode 100644 index 00000000..1876d4ea Binary files /dev/null and b/menu/get/__pycache__/os_config.cpython-310.pyc differ diff --git a/menu/get/__pycache__/os_image.cpython-310.pyc b/menu/get/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..c5765290 Binary files /dev/null and b/menu/get/__pycache__/os_image.cpython-310.pyc differ diff --git a/menu/get/__pycache__/os_vendor.cpython-310.pyc b/menu/get/__pycache__/os_vendor.cpython-310.pyc new file mode 100644 index 00000000..1091f6bf Binary files /dev/null and b/menu/get/__pycache__/os_vendor.cpython-310.pyc differ diff --git a/menu/get/__pycache__/os_version.cpython-310.pyc b/menu/get/__pycache__/os_version.cpython-310.pyc new file mode 100644 index 00000000..8d91ad6a Binary files /dev/null and b/menu/get/__pycache__/os_version.cpython-310.pyc differ diff --git a/menu/get/__pycache__/power.cpython-310.pyc b/menu/get/__pycache__/power.cpython-310.pyc new file mode 100644 index 00000000..e3d316ba Binary files /dev/null and b/menu/get/__pycache__/power.cpython-310.pyc differ diff --git a/menu/get/__pycache__/scu.cpython-310.pyc b/menu/get/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..ccbf7f6a Binary files /dev/null and b/menu/get/__pycache__/scu.cpython-310.pyc differ diff --git a/menu/get/__pycache__/server.cpython-310.pyc b/menu/get/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..fbd3caf2 Binary files /dev/null and b/menu/get/__pycache__/server.cpython-310.pyc differ diff --git a/menu/get/__pycache__/servers.cpython-310.pyc b/menu/get/__pycache__/servers.cpython-310.pyc new file mode 100644 index 00000000..1d9429bd Binary files /dev/null and b/menu/get/__pycache__/servers.cpython-310.pyc differ diff --git a/menu/get/__pycache__/summary.cpython-310.pyc b/menu/get/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..a1cebe66 Binary files /dev/null and b/menu/get/__pycache__/summary.cpython-310.pyc differ diff --git a/menu/get/__pycache__/thermal.cpython-310.pyc b/menu/get/__pycache__/thermal.cpython-310.pyc new file mode 100644 index 00000000..8f4c38df Binary files /dev/null and b/menu/get/__pycache__/thermal.cpython-310.pyc differ diff --git a/menu/get/__pycache__/workflow.cpython-310.pyc b/menu/get/__pycache__/workflow.cpython-310.pyc new file mode 100644 index 00000000..fded839b Binary files /dev/null and b/menu/get/__pycache__/workflow.cpython-310.pyc differ diff --git a/menu/get/__pycache__/workflows.cpython-310.pyc b/menu/get/__pycache__/workflows.cpython-310.pyc new file mode 100644 index 00000000..68f9b4d6 Binary files /dev/null and b/menu/get/__pycache__/workflows.cpython-310.pyc differ diff --git a/menu/get/aci/__init__.py b/menu/get/aci/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..99c54617 Binary files /dev/null and b/menu/get/aci/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/aaep.cpython-310.pyc b/menu/get/aci/__pycache__/aaep.cpython-310.pyc new file mode 100644 index 00000000..9c64cb5c Binary files /dev/null and b/menu/get/aci/__pycache__/aaep.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/ap.cpython-310.pyc b/menu/get/aci/__pycache__/ap.cpython-310.pyc new file mode 100644 index 00000000..5e50a4c5 Binary files /dev/null and b/menu/get/aci/__pycache__/ap.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/bd.cpython-310.pyc b/menu/get/aci/__pycache__/bd.cpython-310.pyc new file mode 100644 index 00000000..4b48b786 Binary files /dev/null and b/menu/get/aci/__pycache__/bd.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/cache.cpython-310.pyc b/menu/get/aci/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..21564c7c Binary files /dev/null and b/menu/get/aci/__pycache__/cache.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/contract.cpython-310.pyc b/menu/get/aci/__pycache__/contract.cpython-310.pyc new file mode 100644 index 00000000..650b9632 Binary files /dev/null and b/menu/get/aci/__pycache__/contract.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/controller.cpython-310.pyc b/menu/get/aci/__pycache__/controller.cpython-310.pyc new file mode 100644 index 00000000..84150ccc Binary files /dev/null and b/menu/get/aci/__pycache__/controller.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/endpoint.cpython-310.pyc b/menu/get/aci/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..e41a547e Binary files /dev/null and b/menu/get/aci/__pycache__/endpoint.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/endpoints.cpython-310.pyc b/menu/get/aci/__pycache__/endpoints.cpython-310.pyc new file mode 100644 index 00000000..9c7bca0b Binary files /dev/null and b/menu/get/aci/__pycache__/endpoints.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/ep.cpython-310.pyc b/menu/get/aci/__pycache__/ep.cpython-310.pyc new file mode 100644 index 00000000..13e0061a Binary files /dev/null and b/menu/get/aci/__pycache__/ep.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/epg.cpython-310.pyc b/menu/get/aci/__pycache__/epg.cpython-310.pyc new file mode 100644 index 00000000..d9e6d6c4 Binary files /dev/null and b/menu/get/aci/__pycache__/epg.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/l2out.cpython-310.pyc b/menu/get/aci/__pycache__/l2out.cpython-310.pyc new file mode 100644 index 00000000..998d8b91 Binary files /dev/null and b/menu/get/aci/__pycache__/l2out.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/l3out.cpython-310.pyc b/menu/get/aci/__pycache__/l3out.cpython-310.pyc new file mode 100644 index 00000000..51990470 Binary files /dev/null and b/menu/get/aci/__pycache__/l3out.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/main.cpython-310.pyc b/menu/get/aci/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..62d78331 Binary files /dev/null and b/menu/get/aci/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/node.cpython-310.pyc b/menu/get/aci/__pycache__/node.cpython-310.pyc new file mode 100644 index 00000000..3308d794 Binary files /dev/null and b/menu/get/aci/__pycache__/node.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/tenant.cpython-310.pyc b/menu/get/aci/__pycache__/tenant.cpython-310.pyc new file mode 100644 index 00000000..765faef5 Binary files /dev/null and b/menu/get/aci/__pycache__/tenant.cpython-310.pyc differ diff --git a/menu/get/aci/__pycache__/vrf.cpython-310.pyc b/menu/get/aci/__pycache__/vrf.cpython-310.pyc new file mode 100644 index 00000000..ab5e8edc Binary files /dev/null and b/menu/get/aci/__pycache__/vrf.cpython-310.pyc differ diff --git a/menu/get/aci/aaep.py b/menu/get/aci/aaep.py new file mode 100644 index 00000000..9ee90493 --- /dev/null +++ b/menu/get/aci/aaep.py @@ -0,0 +1,274 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("aaep") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "aae_name", default='', callback=validations.empty_string_to_none, help="Filter by profile name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|epg|node|intf|pol|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_aaep_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + aae_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci aaep""" + + # iserver get aci aaep + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|epg|node|intf|pol|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policy_global_aae_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if aae_name is not None: + policy_global_aae_filter.append( + 'name:%s' % (aae_name) + ) + + if fault: + policy_global_aae_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + domain_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + node_info = False + + if 'state' in view: + domain_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + aae = apic_handler.get_policy_global_aae( + policy_global_aae_filter=policy_global_aae_filter, + domain_info=domain_info, + node_info=node_info, + fault_info=fault_info, + hfault_info=hfault_info, + event_info=event_info, + hfault_filter=hfault_filter, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for item in aae: + if 'eventLog' in item: + if item['eventLog'] is not None: + event = event + item['eventLog'] + + if 'faultRecord' in item: + if item['faultRecord'] is not None: + fault_record = fault_record + item['faultRecord'] + + if 'faultInst' in item: + if item['faultInst'] is not None: + fault_inst = fault_inst + item['faultInst'] + + if 'auditLog' in item: + if item['auditLog'] is not None: + audit = audit + item['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + aae, + indent=4 + ) + ) + return + + ctx.my_output.json_output(aae) + + if 'state' in view: + aci_output_handler.print_policies_global_aae( + aae, + title=True + ) + + if 'epg' in view: + aci_output_handler.print_policies_global_aae_epg( + aae, + title=True + ) + + if 'pol' in view: + aci_output_handler.print_policies_global_aae_reln( + aae, + title=True + ) + + if 'node' in view: + aci_output_handler.print_policies_global_aae_node( + aae, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_policies_global_aae_interface( + aae, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_policies_global_aae_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_policies_global_aae_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_policies_global_aae_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_policies_global_aae_audit_logs( + audit, + when=fault_when, + title=True + ) + + ctx.my_output.default('Filter: name, fault, severity, when', before_newline=True) + ctx.my_output.default('View: state (def), epg, node, intf, pol, fault, hfault, event, audit, diag, all') + + if aae is None or len(aae) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/ap.py b/menu/get/aci/ap.py new file mode 100644 index 00000000..009cd648 --- /dev/null +++ b/menu/get/aci/ap.py @@ -0,0 +1,282 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ap") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "ap_name", default='', callback=validations.validate_apic_tenant_name, help="Filter by application profile name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--epg", "epg_name", default='', callback=validations.empty_string_to_none, help="Filter by epg name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|node|intf|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_ap_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + ap_name, + tenant_name, + epg_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci application profile""" + + # iserver get aci ap + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|node|intf|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + application_profile_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if ap_name is not None: + application_profile_filter.append( + 'name:%s' % (ap_name['name']) + ) + + if ap_name['tenant'] is not None: + tenant_filtered = True + application_profile_filter.append( + 'tenant:%s' % (ap_name['tenant']) + ) + + if tenant_name is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + application_profile_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if epg_name is not None: + application_profile_filter.append( + 'epg:%s' % (epg_name) + ) + + if fault: + application_profile_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + node_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + application_profiles = apic_handler.get_application_profiles( + application_profile_filter=application_profile_filter, + epg_info=True, + node_info=node_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for application_profile in application_profiles: + if 'eventLog' in application_profile: + if application_profile['eventLog'] is not None: + event = event + application_profile['eventLog'] + + if 'faultRecord' in application_profile: + if application_profile['faultRecord'] is not None: + fault_record = fault_record + application_profile['faultRecord'] + + if 'faultInst' in application_profile: + if application_profile['faultInst'] is not None: + fault_inst = fault_inst + application_profile['faultInst'] + + if 'auditLog' in application_profile: + if application_profile['auditLog'] is not None: + audit = audit + application_profile['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + application_profiles, + indent=4 + ) + ) + return + + ctx.my_output.json_output(application_profiles) + + if 'state' in view: + aci_output_handler.print_application_profiles( + application_profiles, + title=True + ) + + if 'node' in view: + aci_output_handler.print_application_profiles_node( + application_profiles, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_application_profiles_interface( + application_profiles, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_application_profiles_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_application_profiles_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_application_profiles_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_application_profiles_audit_logs( + audit, + when=fault_when, + title=True + ) + + if application_profiles is None or len(application_profiles) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/bd.py b/menu/get/aci/bd.py new file mode 100644 index 00000000..32798281 --- /dev/null +++ b/menu/get/aci/bd.py @@ -0,0 +1,367 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("bd") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "bridge_domain_name", default='', callback=validations.validate_apic_tenant_name, help="Filter by bridge domain name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--vrf", "vrf_name", default='', callback=validations.empty_string_to_none, help="Filter by vrf name") +@click.option("--epg", "epg_name", default='', callback=validations.empty_string_to_none, help="Filter by epg name") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by subnet with IP") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by subnet within subnet") +@click.option("--l3out", "l3out_name", default='', callback=validations.empty_string_to_none, help="Filter by l3out name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|l2|l3|mcast|vrf|node|intf|fault|hfault|event|audit|diag|all|verbose]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_bd_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + bridge_domain_name, + tenant_name, + vrf_name, + epg_name, + ip_address, + ip_subnet, + l3out_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci bridge domain""" + + # iserver get aci bd + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|l2|l3|mcast|vrf|node|intf|fault|hfault|event|audit|diag|all|verbose', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + bridge_domain_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if bridge_domain_name is not None: + bridge_domain_filter.append( + 'name:%s' % (bridge_domain_name['name']) + ) + + if bridge_domain_name['tenant'] is not None: + tenant_filtered = True + bridge_domain_filter.append( + 'tenant:%s' % (bridge_domain_name['tenant']) + ) + + if tenant_name is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + bridge_domain_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if vrf_name is not None: + bridge_domain_filter.append( + 'vrf:%s' % (vrf_name) + ) + + if epg_name is not None: + bridge_domain_filter.append( + 'epg:%s' % (epg_name) + ) + + if len(ip_subnet) > 0: + bridge_domain_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if len(ip_address) > 0: + bridge_domain_filter.append( + 'ip:%s' % (ip_address) + ) + + if l3out_name is not None: + bridge_domain_filter.append( + 'l3out:%s' % (l3out_name) + ) + + if fault: + bridge_domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + endpoint_info = True + endpoint_vm_info = False + endpoint_fabric_info = False + snoop_info = False + vrf_info = False + epg_info = True + node_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'vrf' in view: + vrf_info = True + epg_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if 'verbose' in view: + vrf_info = True + epg_info = True + endpoint_vm_info = True + endpoint_fabric_info = True + snoop_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + bridge_domains = apic_handler.get_bridge_domains( + bridge_domain_filter=bridge_domain_filter, + endpoint_info=endpoint_info, + endpoint_vm_info=endpoint_vm_info, + endpoint_fabric_info=endpoint_fabric_info, + snoop_info=snoop_info, + vrf_info=vrf_info, + epg_info=epg_info, + node_info=node_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for bridge_domain in bridge_domains: + if 'eventLog' in bridge_domain: + if bridge_domain['eventLog'] is not None: + event = event + bridge_domain['eventLog'] + + if 'faultRecord' in bridge_domain: + if bridge_domain['faultRecord'] is not None: + fault_record = fault_record + bridge_domain['faultRecord'] + + if 'faultInst' in bridge_domain: + if bridge_domain['faultInst'] is not None: + fault_inst = fault_inst + bridge_domain['faultInst'] + + if 'auditLog' in bridge_domain: + if bridge_domain['auditLog'] is not None: + audit = audit + bridge_domain['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + bridge_domains, + indent=4 + ) + ) + return + + ctx.my_output.json_output(bridge_domains) + + if 'state' in view: + aci_output_handler.print_bridge_domains( + bridge_domains, + title=True + ) + + if 'l2' in view: + aci_output_handler.print_bridge_domains_l2( + bridge_domains, + title=True + ) + + if 'l3' in view: + aci_output_handler.print_bridge_domains_l3( + bridge_domains, + title=True + ) + + if 'mcast' in view: + aci_output_handler.print_bridge_domains_mcast( + bridge_domains, + title=True + ) + + if 'vrf' in view: + aci_output_handler.print_bridge_domains_vrf( + bridge_domains, + title=True + ) + + if 'node' in view: + aci_output_handler.print_bridge_domains_node( + bridge_domains, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_bridge_domains_interface( + bridge_domains, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_bridge_domains_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_bridge_domains_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_bridge_domains_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_bridge_domains_audit_logs( + audit, + when=fault_when, + title=True + ) + + if 'verbose' in view: + aci_output_handler.print_bridge_domains( + bridge_domains, + title=True + ) + for bridge_domain in bridge_domains: + aci_output_handler.print_bridge_domain(bridge_domain) + + ctx.my_output.default('Filter: name, tenant, vrf, epg, address, subnet, l3out, fault, severity, when', before_newline=True) + ctx.my_output.default('View: state (def), l2, l3, mcast, vrf, node, intf, fault, hfault, event, audit, diag, all') + + if bridge_domains is None or len(bridge_domains) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/cache.py b/menu/get/aci/cache.py new file mode 100644 index 00000000..ab140a63 --- /dev/null +++ b/menu/get/aci/cache.py @@ -0,0 +1,80 @@ +import sys +import traceback +import click + +from menu import validations + +from lib.aci import settings +from lib.aci import cache +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cache") +@click.pass_obj +@click.option("--apic", "apic_name", default='', callback=validations.empty_string_to_none, help="APIC name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_cache_command( + ctx, + apic_name, + devel + ): + """Get aci cache""" + + # iserver get aci cache + + ctx.developer = devel + + try: + settings_handler = settings.ApicSettings(log_id=ctx.run_id) + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + + if apic_name is None: + controllers = settings_handler.get_apic_controllers() + if controllers is None: + ctx.my_output.error('Failed to get ACI controllers') + raise ErrorExit + else: + controller = settings_handler.get_apic_controller(apic_name) + if controller is None: + ctx.my_output.error('Failed to get ACI controller: %s' % (apic_name)) + raise ErrorExit + + controllers = [controller] + + aci_output_handler.print_apic_controllers( + controllers, + show_password=False + ) + + for controller in controllers: + if apic_name is None or controller['name'] == apic_name: + if controller['cache']['enabled']: + cache_handler = cache.Cache( + controller['name'] + ) + stats = cache_handler.get_cache_stats() + + ctx.my_output.default( + 'Cache: %s' % (controller['name']), + underline=True, + before_newline=True + ) + + aci_output_handler.print_cache_stats(stats) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/contract/__init__.py b/menu/get/aci/contract/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/contract/filter.py b/menu/get/aci/contract/filter.py new file mode 100644 index 00000000..643a1dc1 --- /dev/null +++ b/menu/get/aci/contract/filter.py @@ -0,0 +1,265 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("filter") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", default='', callback=validations.validate_apic_tenant_name, help="Filter by name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|usage|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_contract_filter_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + name, + tenant, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci contract""" + + # iserver get aci contract + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|usage|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + object_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if name is not None: + object_filter.append( + 'name:%s' % (name['name']) + ) + + if name['tenant'] is not None: + tenant_filtered = True + object_filter.append( + 'tenant:%s' % (name['tenant']) + ) + + if tenant is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + object_filter.append( + 'tenant:%s' % (tenant) + ) + + if fault: + object_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + usage_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'usage' in view: + usage_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + contract_filters = apic_handler.get_contract_filters( + filter_filter=object_filter, + usage_info=usage_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for contract_filter in contract_filters: + if 'eventLog' in contract_filter: + if contract_filter['eventLog'] is not None: + event = event + contract_filter['eventLog'] + + if 'faultRecord' in contract_filter: + if contract_filter['faultRecord'] is not None: + fault_record = fault_record + contract_filter['faultRecord'] + + if 'faultInst' in contract_filter: + if contract_filter['faultInst'] is not None: + fault_inst = fault_inst + contract_filter['faultInst'] + + if 'auditLog' in contract_filter: + if contract_filter['auditLog'] is not None: + audit = audit + contract_filter['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + contract_filters, + indent=4 + ) + ) + return + + ctx.my_output.json_output(contract_filters) + + if 'state' in view: + aci_output_handler.print_contract_filters( + contract_filters, + title=True + ) + + if 'usage' in view: + aci_output_handler.print_contract_filters_usage( + contract_filters, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_contract_filters_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_contract_filters_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_contract_filters_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_contract_filters_audit_logs( + audit, + when=fault_when, + title=True + ) + + if contract_filters is None or len(contract_filters) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/contract/main.py b/menu/get/aci/contract/main.py new file mode 100644 index 00000000..93afdc5c --- /dev/null +++ b/menu/get/aci/contract/main.py @@ -0,0 +1,20 @@ +import click + +from menu.get.aci.contract.standard import get_aci_contract_standard_command +from menu.get.aci.contract.taboo import get_aci_contract_taboo_command +from menu.get.aci.contract.filter import get_aci_contract_filter_command + + +class Failure(Exception): + pass + + +@click.group("contract") +@click.pass_obj +def get_aci_contract_menu(ctx): + """Get aci contract commands""" + + +get_aci_contract_menu.add_command(get_aci_contract_standard_command) +get_aci_contract_menu.add_command(get_aci_contract_taboo_command) +get_aci_contract_menu.add_command(get_aci_contract_filter_command) diff --git a/menu/get/aci/contract/standard.py b/menu/get/aci/contract/standard.py new file mode 100644 index 00000000..ca15eb09 --- /dev/null +++ b/menu/get/aci/contract/standard.py @@ -0,0 +1,261 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("standard") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", default='', callback=validations.validate_apic_tenant_name, help="Filter by name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|usage|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_contract_standard_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + name, + tenant, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci contract""" + + # iserver get aci contract + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|usage|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + object_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if name is not None: + object_filter.append( + 'name:%s' % (name['name']) + ) + + if name['tenant'] is not None: + tenant_filtered = True + object_filter.append( + 'tenant:%s' % (name['tenant']) + ) + + if tenant is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + object_filter.append( + 'tenant:%s' % (tenant) + ) + + if fault: + object_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + contracts = apic_handler.get_standard_contracts( + contract_filter=object_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for contract in contracts: + if 'eventLog' in contract: + if contract['eventLog'] is not None: + event = event + contract['eventLog'] + + if 'faultRecord' in contract: + if contract['faultRecord'] is not None: + fault_record = fault_record + contract['faultRecord'] + + if 'faultInst' in contract: + if contract['faultInst'] is not None: + fault_inst = fault_inst + contract['faultInst'] + + if 'auditLog' in contract: + if contract['auditLog'] is not None: + audit = audit + contract['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + contracts, + indent=4 + ) + ) + return + + ctx.my_output.json_output(contracts) + + if 'state' in view: + aci_output_handler.print_standard_contracts( + contracts, + show_contract_filters=True, + title=True + ) + + if 'usage' in view: + aci_output_handler.print_standard_contracts_usage( + contracts, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_standard_contracts_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_standard_contracts_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_standard_contracts_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_standard_contracts_audit_logs( + audit, + when=fault_when, + title=True + ) + + if contracts is None or len(contracts) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/contract/taboo.py b/menu/get/aci/contract/taboo.py new file mode 100644 index 00000000..f910794f --- /dev/null +++ b/menu/get/aci/contract/taboo.py @@ -0,0 +1,261 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("taboo") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", default='', callback=validations.validate_apic_tenant_name, help="Filter by name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|usage|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_contract_taboo_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + name, + tenant, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci contract""" + + # iserver get aci contract + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|usage|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + object_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if name is not None: + object_filter.append( + 'name:%s' % (name['name']) + ) + + if name['tenant'] is not None: + tenant_filtered = True + object_filter.append( + 'tenant:%s' % (name['tenant']) + ) + + if tenant is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + object_filter.append( + 'tenant:%s' % (tenant) + ) + + if fault: + object_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + contracts = apic_handler.get_taboo_contracts( + taboo_filter=object_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for contract in contracts: + if 'eventLog' in contract: + if contract['eventLog'] is not None: + event = event + contract['eventLog'] + + if 'faultRecord' in contract: + if contract['faultRecord'] is not None: + fault_record = fault_record + contract['faultRecord'] + + if 'faultInst' in contract: + if contract['faultInst'] is not None: + fault_inst = fault_inst + contract['faultInst'] + + if 'auditLog' in contract: + if contract['auditLog'] is not None: + audit = audit + contract['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + contracts, + indent=4 + ) + ) + return + + ctx.my_output.json_output(contracts) + + if 'state' in view: + aci_output_handler.print_taboo_contracts( + contracts, + show_taboo_filters=True, + title=True + ) + + if 'usage' in view: + aci_output_handler.print_taboo_contracts_usage( + contracts, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_taboo_contracts_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_taboo_contracts_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_taboo_contracts_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_taboo_contracts_audit_logs( + audit, + when=fault_when, + title=True + ) + + if contracts is None or len(contracts) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/controller.py b/menu/get/aci/controller.py new file mode 100644 index 00000000..4d240972 --- /dev/null +++ b/menu/get/aci/controller.py @@ -0,0 +1,53 @@ +import sys +import traceback +import click + +from lib.aci import settings +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("controller") +@click.pass_obj +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_controller_command( + ctx, + show_password, + devel + ): + """Get aci controllers""" + + # iserver get aci controller + + ctx.developer = devel + + try: + settings_handler = settings.ApicSettings(log_id=ctx.run_id) + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + + controllers = settings_handler.get_apic_controllers() + if controllers is None: + ctx.my_output.error('Failed to get ACI controllers') + raise ErrorExit + + aci_output_handler.print_apic_controllers( + controllers, + show_password=show_password + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/domain/__init__.py b/menu/get/aci/domain/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/domain/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/domain/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b06e4275 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/domain/__pycache__/aaa.cpython-310.pyc b/menu/get/aci/domain/__pycache__/aaa.cpython-310.pyc new file mode 100644 index 00000000..a13824c1 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/aaa.cpython-310.pyc differ diff --git a/menu/get/aci/domain/__pycache__/l2.cpython-310.pyc b/menu/get/aci/domain/__pycache__/l2.cpython-310.pyc new file mode 100644 index 00000000..bb65dd50 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/l2.cpython-310.pyc differ diff --git a/menu/get/aci/domain/__pycache__/l3.cpython-310.pyc b/menu/get/aci/domain/__pycache__/l3.cpython-310.pyc new file mode 100644 index 00000000..39d18376 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/l3.cpython-310.pyc differ diff --git a/menu/get/aci/domain/__pycache__/main.cpython-310.pyc b/menu/get/aci/domain/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..aa81dbe8 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/domain/__pycache__/phy.cpython-310.pyc b/menu/get/aci/domain/__pycache__/phy.cpython-310.pyc new file mode 100644 index 00000000..6a3c8c48 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/phy.cpython-310.pyc differ diff --git a/menu/get/aci/domain/__pycache__/vmm.cpython-310.pyc b/menu/get/aci/domain/__pycache__/vmm.cpython-310.pyc new file mode 100644 index 00000000..d5d993f4 Binary files /dev/null and b/menu/get/aci/domain/__pycache__/vmm.cpython-310.pyc differ diff --git a/menu/get/aci/domain/aaa.py b/menu/get/aci/domain/aaa.py new file mode 100644 index 00000000..d4ac226c --- /dev/null +++ b/menu/get/aci/domain/aaa.py @@ -0,0 +1,197 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("aaa") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by pool name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|event|fault|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_domain_aaa_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + domain_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci domain aaa""" + + # iserver get aci domain aaa + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|event|fault|diag|all', + 'state', + [ + 'diag:event,fault' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + domain_filter = [] + fault_filter = [] + event_filter = [] + + if domain_name is not None: + domain_filter.append( + 'name:%s' % (domain_name) + ) + + if fault: + domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + fault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + fault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + fault_info = False + event_info = False + if 'fault' in view: + fault_info = True + + if 'event' in view: + event_info = True + + domains = apic_handler.get_domains_aaa( + domain_filter=domain_filter, + fault_info=fault_info, + event_info=event_info, + fault_filter=fault_filter, + event_filter=event_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + + for domain in domains: + if 'eventLog' in domain: + if domain['eventLog'] is not None: + event = event + domain['eventLog'] + + if 'faultRecord' in domain: + if domain['faultRecord'] is not None: + fault_record = fault_record + domain['faultRecord'] + + if 'faultInst' in domain: + if domain['faultInst'] is not None: + fault_inst = fault_inst + domain['faultInst'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + domains, + indent=4 + ) + ) + return + + ctx.my_output.json_output(domains) + + if 'state' in view: + aci_output_handler.print_domains_aaa( + domains, + title=True + ) + + if 'event' in view: + aci_output_handler.print_domains_aaa_event_logs( + event, + when=fault_when, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_domains_aaa_fault_inst( + fault_inst, + title=True + ) + + aci_output_handler.print_domains_aaa_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if domains is None or len(domains) == 0: + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/domain/l2.py b/menu/get/aci/domain/l2.py new file mode 100644 index 00000000..7c6a6dd0 --- /dev/null +++ b/menu/get/aci/domain/l2.py @@ -0,0 +1,311 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("l2") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--aaep", "aaep_name", default='', callback=validations.empty_string_to_none, help="Filter by aaep name") +@click.option("--pool", "pool_name", default='', callback=validations.empty_string_to_none, help="Filter by vlan pool name") +@click.option("--vlan", "vlan_id", default=-1, help="Filter by vlan id") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|node|intf|vlan|reln|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_domain_l2_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + domain_name, + aaep_name, + pool_name, + vlan_id, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci domain l2""" + + # iserver get aci domain l2 + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|node|intf|vlan|reln|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + domain_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if domain_name is not None: + domain_filter.append( + 'name:%s' % (domain_name) + ) + + if aaep_name is not None: + domain_filter.append( + 'aaep:%s' % (aaep_name) + ) + + if pool_name is not None: + domain_filter.append( + 'pool:%s' % (pool_name) + ) + + if vlan_id > 0: + domain_filter.append( + 'vlan:%s' % (vlan_id) + ) + + if fault: + domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + vlan_info = False + vlan_usage_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + node_info = False + intf_vlan_info = False + + if 'state' in view: + vlan_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'vlan' in view: + vlan_info = True + node_info = True + intf_vlan_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + if node_info: + ctx.my_output.default( + '[INFO] Requires per-domain api call' + ) + + if intf_vlan_info: + ctx.my_output.default( + '[INFO] Requires per-interface api call' + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + domains = apic_handler.get_domains_l2( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info, + node_info=node_info, + intf_vlan_info=intf_vlan_info, + fault_info=fault_info, + hfault_info=hfault_info, + event_info=event_info, + audit_info=audit_info, + hfault_filter=hfault_filter, + event_filter=event_filter, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for domain in domains: + if 'eventLog' in domain: + if domain['eventLog'] is not None: + event = event + domain['eventLog'] + + if 'faultRecord' in domain: + if domain['faultRecord'] is not None: + fault_record = fault_record + domain['faultRecord'] + + if 'faultInst' in domain: + if domain['faultInst'] is not None: + fault_inst = fault_inst + domain['faultInst'] + + if 'auditLog' in domain: + if domain['auditLog'] is not None: + audit = audit + domain['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + domains, + indent=4 + ) + ) + return + + ctx.my_output.json_output(domains) + + if 'state' in view: + aci_output_handler.print_domains_l2( + domains, + title=True + ) + + if 'node' in view: + aci_output_handler.print_domains_l2_node( + domains, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_domains_l2_interface( + domains, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_domains_l2_vlan( + domains, + title=True + ) + + if 'reln' in view: + aci_output_handler.print_domains_l2_reln( + domains, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_domains_l2_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_domains_l2_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_domains_l2_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_domains_l2_audit_logs( + audit, + when=fault_when, + title=True + ) + + if domains is None or len(domains) == 0: + raise ErrorExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/domain/l3.py b/menu/get/aci/domain/l3.py new file mode 100644 index 00000000..e8319946 --- /dev/null +++ b/menu/get/aci/domain/l3.py @@ -0,0 +1,311 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("l3") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--aaep", "aaep_name", default='', callback=validations.empty_string_to_none, help="Filter by aaep name") +@click.option("--pool", "pool_name", default='', callback=validations.empty_string_to_none, help="Filter by vlan pool name") +@click.option("--vlan", "vlan_id", default=-1, help="Filter by vlan id") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|node|intf|vlan|reln|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_domain_l3_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + domain_name, + aaep_name, + pool_name, + vlan_id, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci domain l3""" + + # iserver get aci domain l3 + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|node|intf|vlan|reln|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + domain_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if domain_name is not None: + domain_filter.append( + 'name:%s' % (domain_name) + ) + + if aaep_name is not None: + domain_filter.append( + 'aaep:%s' % (aaep_name) + ) + + if pool_name is not None: + domain_filter.append( + 'pool:%s' % (pool_name) + ) + + if vlan_id > 0: + domain_filter.append( + 'vlan:%s' % (vlan_id) + ) + + if fault: + domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + vlan_info = False + vlan_usage_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + node_info = False + intf_vlan_info = False + + if 'state' in view: + vlan_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'vlan' in view: + vlan_info = True + node_info = True + intf_vlan_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + if node_info: + ctx.my_output.default( + '[INFO] Requires per-domain api call' + ) + + if intf_vlan_info: + ctx.my_output.default( + '[INFO] Requires per-interface api call' + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + domains = apic_handler.get_domains_l3( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info, + node_info=node_info, + intf_vlan_info=intf_vlan_info, + fault_info=fault_info, + hfault_info=hfault_info, + event_info=event_info, + audit_info=audit_info, + hfault_filter=hfault_filter, + event_filter=event_filter, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for domain in domains: + if 'eventLog' in domain: + if domain['eventLog'] is not None: + event = event + domain['eventLog'] + + if 'faultRecord' in domain: + if domain['faultRecord'] is not None: + fault_record = fault_record + domain['faultRecord'] + + if 'faultInst' in domain: + if domain['faultInst'] is not None: + fault_inst = fault_inst + domain['faultInst'] + + if 'auditLog' in domain: + if domain['auditLog'] is not None: + audit = audit + domain['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + domains, + indent=4 + ) + ) + return + + ctx.my_output.json_output(domains) + + if 'state' in view: + aci_output_handler.print_domains_l3( + domains, + title=True + ) + + if 'node' in view: + aci_output_handler.print_domains_l3_node( + domains, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_domains_l3_interface( + domains, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_domains_l3_vlan( + domains, + title=True + ) + + if 'reln' in view: + aci_output_handler.print_domains_l3_reln( + domains, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_domains_l3_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_domains_l3_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_domains_l3_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_domains_l3_audit_logs( + audit, + when=fault_when, + title=True + ) + + if domains is None or len(domains) == 0: + raise ErrorExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/domain/main.py b/menu/get/aci/domain/main.py new file mode 100644 index 00000000..a5a1fcf0 --- /dev/null +++ b/menu/get/aci/domain/main.py @@ -0,0 +1,24 @@ +import click + +from menu.get.aci.domain.aaa import get_aci_domain_aaa_command +from menu.get.aci.domain.l2 import get_aci_domain_l2_command +from menu.get.aci.domain.l3 import get_aci_domain_l3_command +from menu.get.aci.domain.vmm import get_aci_domain_vmm_command +from menu.get.aci.domain.phy import get_aci_domain_phy_command + + +class Failure(Exception): + pass + + +@click.group("domain") +@click.pass_obj +def get_aci_domain_menu(ctx): + """Get aci domain commands""" + + +get_aci_domain_menu.add_command(get_aci_domain_aaa_command) +get_aci_domain_menu.add_command(get_aci_domain_l2_command) +get_aci_domain_menu.add_command(get_aci_domain_l3_command) +get_aci_domain_menu.add_command(get_aci_domain_vmm_command) +get_aci_domain_menu.add_command(get_aci_domain_phy_command) diff --git a/menu/get/aci/domain/phy.py b/menu/get/aci/domain/phy.py new file mode 100644 index 00000000..5f4ef51a --- /dev/null +++ b/menu/get/aci/domain/phy.py @@ -0,0 +1,311 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("phy") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--aaep", "aaep_name", default='', callback=validations.empty_string_to_none, help="Filter by aaep name") +@click.option("--pool", "pool_name", default='', callback=validations.empty_string_to_none, help="Filter by vlan pool name") +@click.option("--vlan", "vlan_id", default=-1, help="Filter by vlan id") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|node|intf|vlan|reln|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_domain_phy_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + domain_name, + aaep_name, + pool_name, + vlan_id, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci domain phy""" + + # iserver get aci domain phy + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|node|intf|vlan|reln|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise NoResultExit + + domain_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if domain_name is not None: + domain_filter.append( + 'name:%s' % (domain_name) + ) + + if aaep_name is not None: + domain_filter.append( + 'aaep:%s' % (aaep_name) + ) + + if pool_name is not None: + domain_filter.append( + 'pool:%s' % (pool_name) + ) + + if vlan_id > 0: + domain_filter.append( + 'vlan:%s' % (vlan_id) + ) + + if fault: + domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + vlan_info = False + vlan_usage_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + node_info = False + intf_vlan_info = False + + if 'state' in view: + vlan_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'vlan' in view: + vlan_info = True + node_info = True + intf_vlan_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + if node_info: + ctx.my_output.default( + '[INFO] Requires per-domain api call' + ) + + if intf_vlan_info: + ctx.my_output.default( + '[INFO] Requires per-interface api call' + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + domains = apic_handler.get_domains_phy( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info, + node_info=node_info, + intf_vlan_info=intf_vlan_info, + fault_info=fault_info, + hfault_info=hfault_info, + event_info=event_info, + audit_info=audit_info, + hfault_filter=hfault_filter, + event_filter=event_filter, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for domain in domains: + if 'eventLog' in domain: + if domain['eventLog'] is not None: + event = event + domain['eventLog'] + + if 'faultRecord' in domain: + if domain['faultRecord'] is not None: + fault_record = fault_record + domain['faultRecord'] + + if 'faultInst' in domain: + if domain['faultInst'] is not None: + fault_inst = fault_inst + domain['faultInst'] + + if 'auditLog' in domain: + if domain['auditLog'] is not None: + audit = audit + domain['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + domains, + indent=4 + ) + ) + return + + ctx.my_output.json_output(domains) + + if 'state' in view: + aci_output_handler.print_domains_phy( + domains, + title=True + ) + + if 'node' in view: + aci_output_handler.print_domains_phy_node( + domains, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_domains_phy_interface( + domains, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_domains_phy_vlan( + domains, + title=True + ) + + if 'reln' in view: + aci_output_handler.print_domains_phy_reln( + domains, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_domains_phy_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_domains_phy_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_domains_phy_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_domains_phy_audit_logs( + audit, + when=fault_when, + title=True + ) + + if domains is None or len(domains) == 0: + raise ErrorExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/domain/vmm.py b/menu/get/aci/domain/vmm.py new file mode 100644 index 00000000..35639cac --- /dev/null +++ b/menu/get/aci/domain/vmm.py @@ -0,0 +1,337 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmm") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--aaep", "aaep_name", default='', callback=validations.empty_string_to_none, help="Filter by aaep name") +@click.option("--pool", "pool_name", default='', callback=validations.empty_string_to_none, help="Filter by vlan pool name") +@click.option("--vlan", "vlan_id", default=-1, help="Filter by vlan id") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|prop|vc|epg|node|intf|vlan|reln|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_domain_vmm_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + domain_name, + aaep_name, + pool_name, + vlan_id, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci domain vmm""" + + # iserver get aci domain vmm + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|prop|vc|epg|node|intf|vlan|reln|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + domain_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if domain_name is not None: + domain_filter.append( + 'name:%s' % (domain_name) + ) + + if aaep_name is not None: + domain_filter.append( + 'aaep:%s' % (aaep_name) + ) + + if pool_name is not None: + domain_filter.append( + 'pool:%s' % (pool_name) + ) + + if vlan_id > 0: + domain_filter.append( + 'vlan:%s' % (vlan_id) + ) + + if fault: + domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + vlan_info = False + vlan_usage_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + node_info = False + intf_vlan_info = False + controller_info = False + + if 'state' in view: + vlan_info = True + + if 'epg' in view: + vlan_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'vlan' in view: + vlan_info = True + node_info = True + intf_vlan_info = True + + if 'vc' in view: + controller_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + if node_info: + ctx.my_output.default( + '[INFO] Requires per-domain api call' + ) + + if intf_vlan_info: + ctx.my_output.default( + '[INFO] Requires per-interface api call' + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + domains = apic_handler.get_domains_vmm( + domain_filter=domain_filter, + vlan_info=vlan_info, + vlan_usage_info=vlan_usage_info, + node_info=node_info, + intf_vlan_info=intf_vlan_info, + controller_info=controller_info, + fault_info=fault_info, + hfault_info=hfault_info, + event_info=event_info, + audit_info=audit_info, + hfault_filter=hfault_filter, + event_filter=event_filter, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for domain in domains: + if 'eventLog' in domain: + if domain['eventLog'] is not None: + event = event + domain['eventLog'] + + if 'faultRecord' in domain: + if domain['faultRecord'] is not None: + fault_record = fault_record + domain['faultRecord'] + + if 'faultInst' in domain: + if domain['faultInst'] is not None: + fault_inst = fault_inst + domain['faultInst'] + + if 'auditLog' in domain: + if domain['auditLog'] is not None: + audit = audit + domain['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + domains, + indent=4 + ) + ) + return + + ctx.my_output.json_output(domains) + + if 'state' in view: + aci_output_handler.print_domains_vmm( + domains, + title=True + ) + + if 'prop' in view: + aci_output_handler.print_domains_vmm_prop( + domains, + title=True + ) + + if 'vc' in view: + aci_output_handler.print_domains_vmm_vcenter( + domains, + title=True + ) + + if 'epg' in view: + aci_output_handler.print_domains_vmm_epg( + domains, + title=True + ) + + if 'node' in view: + aci_output_handler.print_domains_vmm_node( + domains, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_domains_vmm_interface( + domains, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_domains_vmm_vlan( + domains, + title=True + ) + + if 'reln' in view: + aci_output_handler.print_domains_vmm_reln( + domains, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_domains_vmm_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_domains_vmm_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_domains_vmm_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_domains_vmm_audit_logs( + audit, + when=fault_when, + title=True + ) + + if domains is None or len(domains) == 0: + raise ErrorExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/ep.py b/menu/get/aci/ep.py new file mode 100644 index 00000000..9c2066f3 --- /dev/null +++ b/menu/get/aci/ep.py @@ -0,0 +1,296 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output +from lib import context + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ep") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--mac", "mac_address_filter", default='', callback=validations.empty_string_to_none, help="MAC filter") +@click.option("--address", "ip_address_filter", default='', callback=validations.validate_ip_subnet, help="IP address filter") +@click.option("--subnet", "ip_subnet_filter", default='', callback=validations.validate_ip_subnet, help="IP subnet filter") +@click.option("--tenant", "tenant_filter", default='', callback=validations.empty_string_to_none, help="Tenant filter") +@click.option("--bd", "bd_filter", default='', callback=validations.empty_string_to_none, help="Bridge Domain filter") +@click.option("--epg", "epg_filter", default='', callback=validations.empty_string_to_none, help="EPG filter") +@click.option("--vlan", "vlan_filter", default='', callback=validations.empty_string_to_none, help="VLAN filter") +@click.option("--ap", "ap_filter", default='', callback=validations.empty_string_to_none, help="App filter") +@click.option("--vrf", "vrf_filter", default='', callback=validations.empty_string_to_none, help="VRF filter") +@click.option("--node", "node_filter", multiple=True, help="Node filter") +@click.option("--vmm", "vmm_filter", default='', callback=validations.empty_string_to_none, help="VMM filter") +@click.option("--hv", "hv_filter", default='', callback=validations.empty_string_to_none, help="Hypevisor filter") +@click.option("--vm", "vm_filter", default='', callback=validations.empty_string_to_none, help="VM filter") +@click.option("--view", "-v", default=['state'], help="[state|vm|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_ep_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + mac_address_filter, + ip_address_filter, + ip_subnet_filter, + tenant_filter, + bd_filter, + epg_filter, + vlan_filter, + ap_filter, + vrf_filter, + node_filter, + vmm_filter, + hv_filter, + vm_filter, + view, + output, + no_cache, + devel + ): + """Get aci endpoints""" + + # iserver get aci endpoints + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|vm|all', + 'state', + [] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + vm_info = False + fabric_info = False + + if 'state' in view: + fabric_info = True + + if 'vm' in view: + vm_info = True + + endpoint_filter = [] + + if mac_address_filter is not None: + endpoint_filter.append( + 'mac:%s' % (mac_address_filter) + ) + + if len(ip_address_filter) > 0: + endpoint_filter.append( + 'ip:%s' % (ip_address_filter) + ) + + if len(ip_subnet_filter) > 0: + endpoint_filter.append( + 'subnet:%s' % (ip_subnet_filter) + ) + + if tenant_filter is not None: + endpoint_filter.append( + 'tenant:%s' % (tenant_filter) + ) + + if bd_filter is not None: + endpoint_filter.append( + 'bd:%s' % (bd_filter) + ) + + if epg_filter is not None: + endpoint_filter.append( + 'epg:%s' % (epg_filter) + ) + + if vlan_filter is not None: + endpoint_filter.append( + 'vlan:%s' % (vlan_filter) + ) + + if ap_filter is not None: + endpoint_filter.append( + 'ap:%s' % (ap_filter) + ) + + if vrf_filter is not None: + endpoint_filter.append( + 'vrf:%s' % (vrf_filter) + ) + + if len(node_filter) > 0: + fabric_info = True + endpoint_filter.append( + 'node:%s' % (','.join(node_filter)) + ) + + if vmm_filter is not None: + vm_info = True + endpoint_filter.append( + 'vmm:%s' % (vmm_filter) + ) + + if hv_filter is not None: + vm_info = True + endpoint_filter.append( + 'hv:%s' % (hv_filter) + ) + + if vm_filter is not None: + vm_info = True + endpoint_filter.append( + 'vm:%s' % (vm_filter) + ) + + if vm_info: + endpoint_filter.append( + 'vm-info:enabled' + ) + + if output not in ['json']: + if fabric_info: + ctx.my_output.default( + '[INFO] May trigger per policy-group api call' + ) + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + endpoints = [] + ep_context = {} + ep_context['apic'] = [] + ep_context['node'] = {} + ep_context['interface'] = {} + + for apic_handler in apic_handlers: + apic_endpoints = apic_handler['handler'].get_endpoints( + endpoint_filter=endpoint_filter, + vm_info=vm_info, + fabric_info=fabric_info + ) + for apic_endpoint in apic_endpoints: + apic_endpoint['apic'] = apic_handler['name'] + + endpoints = endpoints + apic_endpoints + + if fabric_info: + if len(apic_endpoints) > 0: + ep_context['apic'].append( + apic_handler['name'] + ) + ep_context['node'][apic_handler['name']] = [] + ep_context['interface'][apic_handler['name']] = [] + + for endpoint in apic_endpoints: + for ep_fabric in endpoint['fabric']: + node_name = apic_handler['handler'].get_node_name(ep_fabric['node_id']) + if node_name not in ep_context['node'][apic_handler['name']]: + ep_context['node'][apic_handler['name']].append( + node_name + ) + + interface_name = 'pod-%s:node-%s:%s' % ( + ep_fabric['pod_id'], + ep_fabric['node_id'], + ep_fabric['port_id'] + ) + if interface_name not in ep_context['interface'][apic_handler['name']]: + ep_context['interface'][apic_handler['name']].append( + interface_name + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + endpoints, + indent=4 + ) + ) + return + + ctx.my_output.json_output(endpoints) + + if 'state' in view: + aci_output_handler.print_endpoints( + endpoints, + title=True + ) + + if len(endpoints) > 0: + context_handler = context.Context(log_id=ctx.run_id) + success = context_handler.set( + 'ep', + ep_context + ) + if not success: + ctx.my_output.error('Failed to set interface context') + else: + ctx.my_output.default('Interface context: ep') + + if 'vm' in view: + aci_output_handler.print_endpoints_vmm( + endpoints + ) + + ctx.my_output.default('Filter: mac, address, subnet, tenant, bd, epg, vlan, ap, vrf, node, vmm, hv, vm', before_newline=True) + ctx.my_output.default('View: state (def), vm, all') + + if len(endpoints) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/epg.py b/menu/get/aci/epg.py new file mode 100644 index 00000000..aa6e44b3 --- /dev/null +++ b/menu/get/aci/epg.py @@ -0,0 +1,495 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("epg") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--ap", "profile_name", default='', callback=validations.empty_string_to_none, help="Filter by application profile name") +@click.option("--name", "epg_name", default='', callback=validations.validate_apic_tenant_ap_name, help="Filter by epg name") +@click.option("--pctag", default='', callback=validations.empty_string_to_none, help="Filter by pcTag") +@click.option("--bd", "bd_name", default='', callback=validations.empty_string_to_none, help="Filter by bridge domain name") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by IP subnet") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by IP address") +@click.option("--contract", "contract_name", default='', callback=validations.empty_string_to_none, help="Filter by contract name") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by deployed node name") +@click.option("--domain", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--member", "member_type", type=click.Choice(['any', 'dyn', 'st'], case_sensitive=False), default='any', show_default=True) +@click.option("--pg", "pg_name", default='', callback=validations.empty_string_to_none, help="Filter by policy group name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|prop|bd|contract|ep|node|stport|domain|member|fault|hfault|event|audit|diag|all|verbose]", show_default=True, multiple=True) +@click.option("--pivot", is_flag=True, show_default=True, default=False, help="Pivot view") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_epg_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + epg_name, + tenant_name, + profile_name, + pctag, + bd_name, + ip_subnet, + ip_address, + node_name, + contract_name, + domain_name, + member_type, + pg_name, + fault, + fault_severity, + fault_when, + view, + pivot, + output, + no_cache, + devel + ): + """Get aci epg""" + + # iserver get aci aepg + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|prop|bd|contract|ep|node|stport|domain|member|fault|hfault|event|audit|diag|all|verbose', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + bd_info = False + locale_info = False + ifconn_info = False + endpoint_info = False + endpoint_vm_info = False + endpoint_fabric_info = False + contract_info = False + vrf_info = False + l3out_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + epg_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + ap_filtered = False + + if epg_name is not None: + epg_filter.append( + 'name:%s' % (epg_name['name']) + ) + + if epg_name['tenant'] is not None: + tenant_filtered = True + epg_filter.append( + 'tenant:%s' % (epg_name['tenant']) + ) + + if epg_name['ap'] is not None: + ap_filtered = True + epg_filter.append( + 'profile:%s' % (epg_name['ap']) + ) + + if tenant_name is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + epg_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if profile_name is not None: + if ap_filtered: + ctx.my_output.error( + 'Define profile in one place' + ) + raise ErrorExit + + epg_filter.append( + 'profile:%s' % (profile_name) + ) + + if node_name is not None: + locale_info = True + epg_filter.append( + 'node:%s' % (node_name) + ) + + if bd_name is not None: + bd_info = True + epg_filter.append( + 'bd:%s' % (bd_name) + ) + + if contract_name is not None: + contract_info = True + epg_filter.append( + 'contract:%s' % (contract_name) + ) + + if pctag is not None: + epg_filter.append( + 'pctag:%s' % (pctag) + ) + + if len(ip_subnet) > 0: + bd_info = True + epg_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if len(ip_address) > 0: + bd_info = True + epg_filter.append( + 'ip:%s' % (ip_address) + ) + + if domain_name is not None: + epg_filter.append( + 'domain:%s' % (domain_name) + ) + + if member_type != 'any': + ifconn_info = True + epg_filter.append( + 'member_type:%s' % (member_type) + ) + + if pg_name is not None: + ifconn_info = True + epg_filter.append( + 'pg:%s' % (pg_name) + ) + + if fault: + epg_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if 'state' in view: + bd_info = True + locale_info = True + ifconn_info = True + endpoint_info = True + contract_info = True + + if 'ep' in view: + bd_info = True + endpoint_info = True + + if 'bd' in view: + bd_info = True + endpoint_info = True + vrf_info = True + + if 'contract' in view: + contract_info = True + + if 'node' in view: + locale_info = True + + if 'stport' in view: + ifconn_info = True + + if 'domain' in view: + ifconn_info = True + + if 'member' in view: + ifconn_info = True + + if 'verbose' in view: + pivot = False + bd_info = True + locale_info = True + ifconn_info = True + endpoint_info = True + endpoint_vm_info = True + endpoint_fabric_info = True + contract_info = True + vrf_info = True + l3out_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + epgs = apic_handler.get_epgs( + epg_filter=epg_filter, + bd_info=bd_info, + locale_info=locale_info, + ifconn_info=ifconn_info, + endpoint_info=endpoint_info, + endpoint_vm_info=endpoint_vm_info, + endpoint_fabric_info=endpoint_fabric_info, + contract_info=contract_info, + vrf_info=vrf_info, + l3out_info=l3out_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for epg in epgs: + if 'eventLog' in epg: + if epg['eventLog'] is not None: + event = event + epg['eventLog'] + + if 'faultRecord' in epg: + if epg['faultRecord'] is not None: + fault_record = fault_record + epg['faultRecord'] + + if 'faultInst' in epg: + if epg['faultInst'] is not None: + fault_inst = fault_inst + epg['faultInst'] + + if 'auditLog' in epg: + if epg['auditLog'] is not None: + audit = audit + epg['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + epgs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(epgs) + + if 'state' in view: + aci_output_handler.print_epgs( + epgs, + title=True + ) + + if 'prop' in view: + aci_output_handler.print_epgs_properties( + epgs, + title=True + ) + + if 'bd' in view: + aci_output_handler.print_epgs_bridge_domain( + epgs, + title=True + ) + + if 'ep' in view: + endpoints = [] + for epg in epgs: + endpoints = endpoints + epg['fvCEp'] + + aci_output_handler.print_epgs_endpoint( + endpoints, + title=True + ) + + if 'contract' in view: + if not pivot: + aci_output_handler.print_epgs_contract( + epgs, + title=True + ) + + if pivot: + aci_output_handler.print_epgs_contract_pivot( + epgs, + title=True + ) + + if 'domain' in view: + if not pivot: + aci_output_handler.print_epgs_domain( + epgs, + title=True + ) + + if pivot: + aci_output_handler.print_epgs_domain_pivot( + epgs, + title=True + ) + + if 'node' in view: + if not pivot: + aci_output_handler.print_epgs_node( + epgs, + title=True + ) + + if pivot: + aci_output_handler.print_epgs_node_pivot( + epgs, + title=True + ) + + if 'member' in view: + aci_output_handler.print_epgs_member( + epgs, + title=True + ) + + if 'stport' in view: + aci_output_handler.print_epgs_static_port( + epgs, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_epgs_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_epgs_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_epgs_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_epgs_audit_logs( + audit, + when=fault_when, + title=True + ) + + if 'verbose' in view: + aci_output_handler.print_epgs( + epgs, + title=True + ) + + for epg in epgs: + aci_output_handler.print_epg( + epg + ) + + ctx.my_output.default('Filter: tenant, ap, name, pctag, bd, subnet, address, contract, node, domain, member, pg, fault, severity, when', before_newline=True) + ctx.my_output.default('View: state (def), prop, bd, contract, ep, node, stport, domain, member, fault, hfault, event, audit, diag, all, verbose') + + if epgs is None or len(epgs) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/__init__.py b/menu/get/aci/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/intf/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..fcb2ea0e Binary files /dev/null and b/menu/get/aci/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/cloudsec.cpython-310.pyc b/menu/get/aci/intf/__pycache__/cloudsec.cpython-310.pyc new file mode 100644 index 00000000..b589a130 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/cloudsec.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/fc.cpython-310.pyc b/menu/get/aci/intf/__pycache__/fc.cpython-310.pyc new file mode 100644 index 00000000..ff99a830 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/fc.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/fcpc.cpython-310.pyc b/menu/get/aci/intf/__pycache__/fcpc.cpython-310.pyc new file mode 100644 index 00000000..a08c6837 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/fcpc.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/l3.cpython-310.pyc b/menu/get/aci/intf/__pycache__/l3.cpython-310.pyc new file mode 100644 index 00000000..758f7cd2 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/l3.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/l3e.cpython-310.pyc b/menu/get/aci/intf/__pycache__/l3e.cpython-310.pyc new file mode 100644 index 00000000..d3272685 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/l3e.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/lb.cpython-310.pyc b/menu/get/aci/intf/__pycache__/lb.cpython-310.pyc new file mode 100644 index 00000000..661a5b90 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/lb.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/macsec.cpython-310.pyc b/menu/get/aci/intf/__pycache__/macsec.cpython-310.pyc new file mode 100644 index 00000000..4620cab3 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/macsec.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/main.cpython-310.pyc b/menu/get/aci/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..800b89f2 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/mgmt.cpython-310.pyc b/menu/get/aci/intf/__pycache__/mgmt.cpython-310.pyc new file mode 100644 index 00000000..7c3147d4 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/mgmt.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/pc.cpython-310.pyc b/menu/get/aci/intf/__pycache__/pc.cpython-310.pyc new file mode 100644 index 00000000..a2936a0e Binary files /dev/null and b/menu/get/aci/intf/__pycache__/pc.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/phy.cpython-310.pyc b/menu/get/aci/intf/__pycache__/phy.cpython-310.pyc new file mode 100644 index 00000000..753149df Binary files /dev/null and b/menu/get/aci/intf/__pycache__/phy.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/summary.cpython-310.pyc b/menu/get/aci/intf/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..50e39f93 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/summary.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/svi.cpython-310.pyc b/menu/get/aci/intf/__pycache__/svi.cpython-310.pyc new file mode 100644 index 00000000..5dac1f75 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/svi.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/tun.cpython-310.pyc b/menu/get/aci/intf/__pycache__/tun.cpython-310.pyc new file mode 100644 index 00000000..30d8e9f0 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/tun.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/vfc.cpython-310.pyc b/menu/get/aci/intf/__pycache__/vfc.cpython-310.pyc new file mode 100644 index 00000000..1565ae65 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/vfc.cpython-310.pyc differ diff --git a/menu/get/aci/intf/__pycache__/vpc.cpython-310.pyc b/menu/get/aci/intf/__pycache__/vpc.cpython-310.pyc new file mode 100644 index 00000000..56897043 Binary files /dev/null and b/menu/get/aci/intf/__pycache__/vpc.cpython-310.pyc differ diff --git a/menu/get/aci/intf/cloudsec.py b/menu/get/aci/intf/cloudsec.py new file mode 100644 index 00000000..89340e44 --- /dev/null +++ b/menu/get/aci/intf/cloudsec.py @@ -0,0 +1,287 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("cloudsec") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_cloudsec_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node cloudsec interface""" + + # iserver get aci node intf cloudsec + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_cloudsec( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_cloudsec_state( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_cloudsec_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_cloudsec_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_cloudsec_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_cloudsec_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/fc.py b/menu/get/aci/intf/fc.py new file mode 100644 index 00000000..2f92c42b --- /dev/null +++ b/menu/get/aci/intf/fc.py @@ -0,0 +1,287 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("fc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_fc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node fc interface""" + + # iserver get aci node intf fc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_fc( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_fc_state( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_fc_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_fc_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_fc_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_fc_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/fcpc.py b/menu/get/aci/intf/fcpc.py new file mode 100644 index 00000000..07503abe --- /dev/null +++ b/menu/get/aci/intf/fcpc.py @@ -0,0 +1,287 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("fcpc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_fcpc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node fcpc interface""" + + # iserver get aci node intf fcpc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_fcpc( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_fcpc_state( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_fcpc_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_fcpc_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_fcpc_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_fcpc_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/l3e.py b/menu/get/aci/intf/l3e.py new file mode 100644 index 00000000..5204fb03 --- /dev/null +++ b/menu/get/aci/intf/l3e.py @@ -0,0 +1,286 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("l3e") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_l3e_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node encapsulated routed interface""" + + # iserver get aci node intf l3e + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_encap_routed( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_encap_routed_state( + interfaces + ) + + if 'fault' in view: + aci_output_handler.print_interface_encap_routed_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_encap_routed_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_encap_routed_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_encap_routed_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/lb.py b/menu/get/aci/intf/lb.py new file mode 100644 index 00000000..5c97c2fc --- /dev/null +++ b/menu/get/aci/intf/lb.py @@ -0,0 +1,288 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("lb") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by IP") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by subnet") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_lb_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + ip_address, + ip_subnet, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node loobpack interface""" + + # iserver get aci node intf lb + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + if len(ip_subnet) > 0: + interface_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if len(ip_address) > 0: + interface_filter.append( + 'ip:%s' % (ip_address) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_loopback( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_loopback_state( + interfaces + ) + + if 'fault' in view: + aci_output_handler.print_interface_loopback_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_loopback_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_loopback_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_loopback_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/macsec.py b/menu/get/aci/intf/macsec.py new file mode 100644 index 00000000..9376dc3f --- /dev/null +++ b/menu/get/aci/intf/macsec.py @@ -0,0 +1,304 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("macsec") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--type", "port_type", type=click.Choice(['any', 'leaf', 'fabric'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all|verbose]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_macsec_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + port_type, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node macsec interface""" + + # iserver get aci node intf macsec + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all|verbose', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + interface_filter.append( + 'type:%s' % (port_type) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + stats_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if 'verbose' in view: + stats_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_macsec( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + stats_info=stats_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_macsec_state( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_macsec_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_macsec_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_macsec_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_macsec_audit_logs( + audit, + when=fault_when, + title=True + ) + + if 'verbose' in view: + for interface in interfaces: + aci_output_handler.print_interface_macsec_verbose( + interface + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/main.py b/menu/get/aci/intf/main.py new file mode 100644 index 00000000..550e2a39 --- /dev/null +++ b/menu/get/aci/intf/main.py @@ -0,0 +1,42 @@ +import click + +from menu.get.aci.intf.cloudsec import get_aci_node_intf_cloudsec_command +from menu.get.aci.intf.fc import get_aci_node_intf_fc_command +from menu.get.aci.intf.fcpc import get_aci_node_intf_fcpc_command +from menu.get.aci.intf.l3e import get_aci_node_intf_l3e_command +from menu.get.aci.intf.lb import get_aci_node_intf_lb_command +from menu.get.aci.intf.macsec import get_aci_node_intf_macsec_command +from menu.get.aci.intf.mgmt import get_aci_node_intf_mgmt_command +from menu.get.aci.intf.pc import get_aci_node_intf_pc_command +from menu.get.aci.intf.phy import get_aci_node_intf_phy_command +from menu.get.aci.intf.summary import get_aci_node_intf_summary_command +from menu.get.aci.intf.svi import get_aci_node_intf_svi_command +from menu.get.aci.intf.tun import get_aci_node_intf_tun_command +from menu.get.aci.intf.vfc import get_aci_node_intf_vfc_command +from menu.get.aci.intf.vpc import get_aci_node_intf_vpc_command + + +class Failure(Exception): + pass + + +@click.group("intf") +@click.pass_obj +def get_aci_node_intf_menu(ctx): + """Get aci node interface commands""" + + +get_aci_node_intf_menu.add_command(get_aci_node_intf_cloudsec_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_fc_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_fcpc_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_l3e_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_lb_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_macsec_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_mgmt_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_pc_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_phy_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_summary_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_svi_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_tun_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_vfc_command) +get_aci_node_intf_menu.add_command(get_aci_node_intf_vpc_command) diff --git a/menu/get/aci/intf/mgmt.py b/menu/get/aci/intf/mgmt.py new file mode 100644 index 00000000..33d8a427 --- /dev/null +++ b/menu/get/aci/intf/mgmt.py @@ -0,0 +1,299 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("mgmt") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|addr|nei|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_mgmt_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node management interface""" + + # iserver get aci node intf mgmt + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|addr|nei|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + state_info = False + stats_info = False + cdp_info = False + lldp_info = False + + if 'state' in view: + state_info = True + + if 'nei' in view: + cdp_info = True + lldp_info = True + + if 'addr' in view: + stats_info = True + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interface_management( + node_info['podId'], + node_info['id'], + state_info=state_info, + stats_info=stats_info, + cdp_info=cdp_info, + lldp_info=lldp_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_management_state( + interfaces, + title=True + ) + + if 'addr' in view: + aci_output_handler.print_interfaces_management_address( + interfaces, + title=True + ) + + if 'nei' in view: + aci_output_handler.print_interfaces_management_neighbor( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_management_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_management_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_management_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_management_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/pc.py b/menu/get/aci/intf/pc.py new file mode 100644 index 00000000..67ad3723 --- /dev/null +++ b/menu/get/aci/intf/pc.py @@ -0,0 +1,354 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_channel_id", default='', callback=validations.empty_string_to_none, help="Filter by port channel id") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--speed", default='', callback=validations.empty_string_to_none, help="Filter by speed") +@click.option("--domain", default='', callback=validations.empty_string_to_none, help="Filter by domain id") +@click.option("--state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True, help="Filter by state") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|phy|lacp|vlan|stats|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_pc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_channel_id, + name, + speed, + domain, + state, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node port channel interface""" + + # iserver get aci node intf pc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|phy|lacp|vlan|stats|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_channel_id is not None: + interface_filter.append( + 'id:%s' % (port_channel_id) + ) + + if name is not None: + interface_filter.append( + 'name:%s' % (name) + ) + + if speed is not None: + interface_filter.append( + 'speed:%s' % (speed) + ) + + if domain is not None: + interface_filter.append( + 'domain:%s' % (domain) + ) + + interface_filter.append( + 'state:%s' % (state) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + member_info = False + lacp_info = False + vlan_info = False + fault_info = False + event_info = False + + if 'phy' in view: + member_info = True + + if 'lacp' in view: + lacp_info = True + + if 'vlan' in view: + vlan_info = True + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interface_port_channel( + pod_id=node_info['podId'], + node_id=node_info['id'], + interface_port_channel_filter=interface_filter, + vpc_domain_info=True, + member_info=member_info, + lacp_info=lacp_info, + vlan_info=vlan_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_port_channel_state( + interfaces, + title=True + ) + + if 'phy' in view: + aci_output_handler.print_interfaces_port_channel_member( + interfaces, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_interfaces_port_channel_vlan( + interfaces, + title=True + ) + + if 'stats' in view: + aci_output_handler.print_interfaces_port_channel_stats( + interfaces, + title=True + ) + + aci_output_handler.print_interfaces_port_channel_ether( + interfaces, + title=True + ) + + if 'lacp' in view: + lacp = [] + for interface_info in interfaces: + lacp = lacp + interface_info['lacp'] + + aci_output_handler.print_interfaces_port_channel_lacp( + lacp, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_port_channel_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_port_channel_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_port_channel_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_port_channel_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/phy.py b/menu/get/aci/intf/phy.py new file mode 100644 index 00000000..be44c3ed --- /dev/null +++ b/menu/get/aci/intf/phy.py @@ -0,0 +1,746 @@ +import sys +import copy +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output +from lib import context + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("phy") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "interface_ids", multiple=True, default=[], help="Filter by interface id") +@click.option("--switching", type=click.Choice(['any', 'enabled', 'disabled'], case_sensitive=False), default='any', show_default=True, help="Filter by switching state") +@click.option("--oper", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True, help="Filter by operational state") +@click.option("--type", "interface_type", type=click.Choice(['any', 'leaf', 'fab'], case_sensitive=False), default='any', show_default=True, help="Filter by port type") +@click.option("--qos", type=click.Choice(['any', 'data', 'data-rx', 'data-tx', 'drops', 'drops-rx', 'drops-tx'], case_sensitive=False), default='any', show_default=True, help="Filter by qos counters") +@click.option("--layer", type=click.Choice(['any', 'l2', 'l3'], case_sensitive=False), default='any', show_default=True, help="Filter by layer") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--speed", type=click.Choice(['any', '1G', '10G', '25G', '40G', '100G', '400G'], case_sensitive=False), default='any', show_default=True, help="Filter by interface speed") +@click.option("--fec", default='', callback=validations.empty_string_to_none, show_default=True, help="Filter by fec") +@click.option("--optics", default='', callback=validations.empty_string_to_none, help="Filter by transceiver optics") +@click.option("--trans", default='', callback=validations.empty_string_to_none, help="Filter by transceiver type") +@click.option("--epg", default='', callback=validations.empty_string_to_none, help="Filter by epg name") +@click.option("--vlan", default='', callback=validations.empty_string_to_none, help="Filter by vlan value") +@click.option("--evlan", default='', callback=validations.empty_string_to_none, help="Filter by encapsulation vlan value") +@click.option("--fvxlan", default='', callback=validations.empty_string_to_none, help="Filter by fabric vxlan value") +@click.option("--nei", default='', callback=validations.empty_string_to_none, help="Filter by cdp/lldp neight system name") +@click.option("--ctx", "user_context", default='', help="Filter by context") +@click.option("--set-ctx", "set_context", is_flag=True, show_default=True, default=False, help="Set phy context") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|l2|trans|vlan|epg|load|eee|nei|cdp|lldp|pg|pol|aaep|ether|err|qos|fault|hfault|event|audit|diag|all|verbose]", show_default=True, multiple=True) +@click.option("--pivot", is_flag=True, show_default=True, default=False, help="Pivot view") +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_phy_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + interface_ids, + switching, + oper, + interface_type, + qos, + layer, + mac, + speed, + fec, + trans, + optics, + epg, + vlan, + evlan, + fvxlan, + nei, + user_context, + set_context, + fault, + fault_severity, + fault_when, + view, + pivot, + output, + no_cache, + devel + ): + """Get aci node physical interface""" + + # iserver get aci node intf phy + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|l2|trans|vlan|epg|load|eee|nei|cdp|lldp|pg|pol|aaep|ether|err|qos|fault|hfault|event|audit|diag|all|verbose', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + context_handler = context.Context(log_id=ctx.run_id) + + if len(user_context) == 0: + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(user_context) > 0: + context_interfaces = context_handler.get( + user_context + ) + if context_interfaces is None: + ctx.my_output.error('Unknown context: %s' % (user_context)) + raise ErrorExit + + if len(context_interfaces) == 0: + ctx.my_output.error('Empty context: %s' % (user_context)) + raise ErrorExit + + apic_handlers = validations.validate_apic_controllers_with_context_interfaces( + ctx, + context_interfaces + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + + ether_stats_info = False + fc_stats_info = False + epg_stats_info = False + load_info = False + eee_info = False + cdp_info = False + lldp_info = False + policy_info = False + qos_info = False + cap_info = False + pc_info = False + + if 'trans' in view: + fc_stats_info = True + + if 'load' in view: + load_info = True + + if 'qos' in view or 'live' in view: + qos_info = True + + if 'ether' in view or 'err' in view: + ether_stats_info = True + + if 'eee' in view: + eee_info = True + + if 'epg' in view or 'vlan' in view: + epg_stats_info = True + + if 'nei' in view: + cdp_info = True + lldp_info = True + + if 'cdp' in view: + cdp_info = True + + if 'lldp' in view: + lldp_info = True + + if 'pol' in view or 'pg' in view or 'aaep' in view: + policy_info = True + + if 'verbose' in view: + cap_info = True + pc_info = True + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if len(interface_ids) > 0: + ids = [] + for interface_id in interface_ids: + if len(interface_id.split('-')) == 2: + (start_id, end_id) = interface_id.split('-') + if len(start_id.split('/')) != len(end_id.split('/')): + ctx.my_output.error( + 'Unsupported port range' + ) + raise ErrorExit + + if len(start_id.split('/')) not in [2, 3]: + ctx.my_output.error( + 'Unsupported port range' + ) + raise ErrorExit + + if '*' in start_id.split('/') or '*' in end_id.split('/'): + ctx.my_output.error( + 'Unsupported port range' + ) + raise ErrorExit + + module_id = '/'.join(start_id.split('/')[:-1]) + start_port_id = start_id.split('/')[-1] + end_port_id = end_id.split('/')[-1] + + if int(start_port_id) > int(end_port_id): + ctx.my_output.error( + 'Unsupported port range' + ) + raise ErrorExit + + port_id = int(start_port_id) + while True: + range_id = '%s/%s' % ( + module_id, + port_id + ) + if range_id.startswith('eth'): + ids.append( + range_id + ) + else: + ids.append( + 'eth%s' % (range_id) + ) + + port_id = port_id + 1 + if port_id > int(end_port_id): + break + + if len(interface_id.split('-')) == 1: + if interface_id.startswith('eth'): + ids.append( + interface_id + ) + else: + ids.append( + 'eth%s' % (interface_id) + ) + + interface_filter.append( + 'ids:%s' % (','.join(ids)) + ) + + if switching != 'any': + interface_filter.append( + 'switching:%s' % (switching) + ) + + if oper != 'any': + interface_filter.append( + 'oper:%s' % (oper) + ) + + if interface_type != 'any': + interface_filter.append( + 'type:%s' % (interface_type) + ) + + if layer != 'any': + if layer == 'l2': + interface_filter.append( + 'layer:switched' + ) + if layer == 'l3': + interface_filter.append( + 'layer:routed' + ) + + if mac is not None: + interface_filter.append( + 'mac:%s' % (mac) + ) + + if speed != 'any': + interface_filter.append( + 'speed:%s' % (speed) + ) + + if fec is not None: + interface_filter.append( + 'fec:%s' % (fec) + ) + + if trans is not None: + fc_stats_info = True + interface_filter.append( + 'trans:%s' % (trans) + ) + + if optics is not None: + fc_stats_info = True + interface_filter.append( + 'optics:%s' % (optics) + ) + + if epg is not None: + epg_stats_info = True + interface_filter.append( + 'epg:%s' % (epg) + ) + + if vlan is not None: + epg_stats_info = True + interface_filter.append( + 'vlan:%s' % (vlan) + ) + + if evlan is not None: + epg_stats_info = True + interface_filter.append( + 'evlan:%s' % (evlan) + ) + + if fvxlan is not None: + epg_stats_info = True + interface_filter.append( + 'fvxlan:%s' % (fvxlan) + ) + + if nei is not None: + cdp_info = True + lldp_info = True + interface_filter.append( + 'nei:%s' % (nei) + ) + + if qos != 'any': + qos_info = True + interface_filter.append( + 'qos:%s' % (qos) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if 'live' in view: + qos_references = {} + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + key = '%s.%s' % ( + node_info['podId'], + node_info['id'] + ) + qos_references[key] = None + + previous_output = None + initial = True + while True: + interfaces = [] + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + key = '%s.%s' % ( + node_info['podId'], + node_info['id'] + ) + node_interfaces = apic_handler['handler'].get_interfaces_phy( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + qos_info=qos_info, + qos_references=qos_references[key] + ) + + interfaces = interfaces + node_interfaces + if initial: + qos_references[key] = copy.deepcopy(node_interfaces) + + if initial: + initial = False + continue + + aci_output_handler.my_output.clear_output() + aci_output_handler.print_interfaces_phy_qos( + interfaces, + stream='output' + ) + printed_output = aci_output_handler.my_output.get_output() + + if previous_output is not None: + for counter in range(0, len(previous_output.split('\n')) + 1): + print('\033[1A', end='\x1b[2K') + + print(printed_output) + previous_output = printed_output + + user_input = ctx.my_output.get_input('Press enter to exit...', timeout=2) + if user_input is not None: + break + + return + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + context_phy = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + if len(user_context) == 0: + aif = copy.deepcopy(interface_filter) + else: + node_context_interfaces = [] + for context_interface in context_interfaces: + #aci:apic21:pod-1:node-2208:eth1/2/3 + if apic_handler['name'] == context_interface.split(':')[1]: + if context_interface.split(':')[2].split('-')[1] == node_info['podId']: + if context_interface.split(':')[3].split('-')[1] == node_info['id']: + node_context_interfaces.append( + context_interface.split(':')[4] + ) + + aif = [] + aif.append( + 'ids:%s' % (','.join(node_context_interfaces)) + ) + + node_interfaces = apic_handler['handler'].get_interfaces_phy( + node_info['podId'], + node_info['id'], + interface_filter=aif, + fc_stats_info=fc_stats_info, + epg_stats_info=epg_stats_info, + load_info=load_info, + eee_info=eee_info, + cdp_info=cdp_info, + lldp_info=lldp_info, + policy_info=policy_info, + qos_info=qos_info, + ether_stats_info=ether_stats_info, + cap_info=cap_info, + pc_info=pc_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + interface_name = 'apic:%s:pod-%s:node-%s:%s' % ( + interface['apic'], + interface['podId'], + interface['nodeId'], + interface['id'] + ) + if interface_name not in context_phy: + context_phy.append( + interface_name + ) + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_phy_state( + interfaces, + title=True + ) + + if 'l2' in view: + aci_output_handler.print_interfaces_phy_l2( + interfaces, + title=True + ) + + if 'trans' in view: + aci_output_handler.print_interfaces_phy_trans( + interfaces, + title=True + ) + + if 'epg' in view: + aci_output_handler.print_interfaces_phy_epg( + interfaces, + title=True + ) + + if 'vlan' in view: + if pivot: + aci_output_handler.print_interfaces_phy_vlan_pivot( + interfaces, + title=True + ) + + if not pivot: + aci_output_handler.print_interfaces_phy_vlan( + interfaces, + title=True + ) + + if 'load' in view: + aci_output_handler.print_interfaces_phy_load( + interfaces, + title=True + ) + + if 'eee' in view: + aci_output_handler.print_interfaces_phy_eee( + interfaces, + title=True + ) + + if 'nei' in view: + aci_output_handler.print_interfaces_phy_nei( + interfaces, + title=True + ) + + if 'cdp' in view: + aci_output_handler.print_interfaces_phy_cdp( + interfaces, + title=True + ) + + if 'lldp' in view: + aci_output_handler.print_interfaces_phy_lldp( + interfaces, + title=True + ) + + if 'pol' in view: + aci_output_handler.print_interfaces_phy_policy( + interfaces, + title=True + ) + + if 'pg' in view: + aci_output_handler.print_interfaces_phy_policy_group( + interfaces, + title=True + ) + + if 'aaep' in view: + aci_output_handler.print_interfaces_phy_aaep( + interfaces, + title=True + ) + + if 'qos' in view: + aci_output_handler.print_interfaces_phy_qos( + interfaces, + title=True + ) + + if 'ether' in view: + aci_output_handler.print_interfaces_phy_ether( + interfaces, + title=True + ) + + if 'err' in view: + aci_output_handler.print_interfaces_phy_err( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_phy_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_phy_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_phy_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_phy_audit_logs( + audit, + when=fault_when, + title=True + ) + + if 'verbose' in view: + for interface in interfaces: + aci_output_handler.print_interface_phy( + interface + ) + + if set_context: + if not context_handler.set('phy', context_phy): + ctx.my_output.error('Failed to set interface context') + + if len(interfaces) == 0: + raise NoResultExit + + ctx.my_output.default('Filter: id, switching, oper, type, qos, layer, mac, speed, fec, optics, trans', before_newline=True) + ctx.my_output.default(' epg, vlan, evlan, fvxlan, nei, fault, severity, when') + ctx.my_output.default('View: state (def), l2, trans, vlan, epg, load, eee, nei, cdp, lldp') + ctx.my_output.default(' pg, pol, aaep, ether, err, qos, fault, hfault, event, audit, diag, all, verbose') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/summary.py b/menu/get/aci/intf/summary.py new file mode 100644 index 00000000..44f79ecd --- /dev/null +++ b/menu/get/aci/intf/summary.py @@ -0,0 +1,116 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("summary") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Node name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_summary_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_name, + output, + no_cache, + devel + ): + """Get aci node interface summary""" + + # iserver get aci node intf summary + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + node_info = validations.validate_apic_node_name( + ctx, + apic_handler, + node_name, + pod_id=pod_id + ) + if node_info is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + summary = apic_handler.get_interface_summary( + pod_id=node_info['podId'], + node_id=node_info['id'] + ) + + ctx.busy = False + + if summary is None: + ctx.my_output.error( + 'Failed to get interface summary' + ) + raise ErrorExit + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + summary, + indent=4 + ) + ) + return + + ctx.my_output.json_output(summary) + + aci_output_handler.print_interface_summary( + summary + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/svi.py b/menu/get/aci/intf/svi.py new file mode 100644 index 00000000..ef803dbd --- /dev/null +++ b/menu/get/aci/intf/svi.py @@ -0,0 +1,341 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("svi") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--name", "interface_name", default='', callback=validations.empty_string_to_none, help="Interface name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--type", "vlan_type", type=click.Choice(['any', 'int', 'ext'], case_sensitive=False), default='any', show_default=True) +@click.option("--mac", "mac_address", default='', callback=validations.empty_string_to_none, help="MAC Address filter") +@click.option("--vlan", default='', callback=validations.empty_string_to_none, help="VLAN filter") +@click.option("--fabric", default='', callback=validations.empty_string_to_none, help="Fabric encap filter") +@click.option("--access", default='', callback=validations.empty_string_to_none, help="Access encap filter") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="IP Address filter") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="IP Subnet filter") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|stats|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_svi_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + interface_name, + admin_state, + oper_state, + vlan_type, + mac_address, + vlan, + fabric, + access, + ip_address, + ip_subnet, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node svi interface""" + + # iserver get aci node intf svi + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|stats|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if interface_name is not None: + interface_filter.append( + 'id:%s' % (interface_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + interface_filter.append( + 'type:%s' % (vlan_type) + ) + + if mac_address is not None: + interface_filter.append( + 'mac:%s' % (mac_address) + ) + + if vlan is not None: + interface_filter.append( + 'vlan:%s' % (vlan) + ) + + if fabric is not None: + interface_filter.append( + 'fabric:%s' % (fabric) + ) + + if access is not None: + interface_filter.append( + 'access:%s' % (access) + ) + + if len(ip_subnet) > 0: + interface_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if len(ip_address) > 0: + interface_filter.append( + 'ip:%s' % (ip_address) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_svi( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_svi_state( + interfaces, + title=True + ) + + if 'stats' in view: + aci_output_handler.print_interfaces_svi_counter( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_svi_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_svi_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_svi_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_svi_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/tun.py b/menu/get/aci/intf/tun.py new file mode 100644 index 00000000..3ac99655 --- /dev/null +++ b/menu/get/aci/intf/tun.py @@ -0,0 +1,318 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("tun") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--layer", type=click.Choice(['any', 'l2', 'l3'], case_sensitive=False), default='any', show_default=True) +@click.option("--vrf", default='', callback=validations.empty_string_to_none, help="Filter by vrf") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by IP") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by subnet") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--resolve", "-r", is_flag=True, show_default=True, default=False, help="Resolve identifiers") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_tun_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + layer, + vrf, + ip_address, + ip_subnet, + fault, + fault_severity, + fault_when, + view, + resolve, + output, + no_cache, + devel + ): + """Get aci node tunnel interface""" + + # iserver get aci node intf tunnel + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + if vrf is not None: + interface_filter.append( + 'vrf:%s' % (vrf) + ) + + if layer is not None: + interface_filter.append( + 'layer:%s' % (layer) + ) + + if len(ip_address) > 0: + interface_filter.append( + 'ip:%s' % (ip_address) + ) + + if len(ip_subnet) > 0: + interface_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_tunnel( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + resolve=resolve, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_tunnel_state( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_tunnel_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_tunnel_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_tunnel_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_tunnel_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/vfc.py b/menu/get/aci/intf/vfc.py new file mode 100644 index 00000000..0c511fca --- /dev/null +++ b/menu/get/aci/intf/vfc.py @@ -0,0 +1,287 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vfc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "port_name", default='', callback=validations.empty_string_to_none, help="Port name") +@click.option("--admin", "admin_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--oper", "oper_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_vfc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + port_name, + admin_state, + oper_state, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node vfc interface""" + + # iserver get aci node intf vfc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if port_name is not None: + interface_filter.append( + 'id:%s' % (port_name) + ) + + interface_filter.append( + 'admin:%s' % (admin_state) + ) + + interface_filter.append( + 'oper:%s' % (oper_state) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interfaces_vfc( + node_info['podId'], + node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_vfc_state( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_vfc_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_vfc_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_vfc_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_vfc_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/intf/vpc.py b/menu/get/aci/intf/vpc.py new file mode 100644 index 00000000..41accc73 --- /dev/null +++ b/menu/get/aci/intf/vpc.py @@ -0,0 +1,311 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vpc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "vpc_domain_id", default='', callback=validations.empty_string_to_none, help="Filter by vpc domain id") +@click.option("--state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--member", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True) +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|addr|member|vlan|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_intf_vpc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + vpc_domain_id, + state, + member, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node virtual port channel interface""" + + # iserver get aci node intf vpc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|addr|member|vlan|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers_with_nodes( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + node_role, + pod_id=pod_id, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + interface_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if vpc_domain_id is not None: + interface_filter.append( + 'id:%s' % (vpc_domain_id) + ) + + interface_filter.append( + 'state:%s' % (state) + ) + + interface_filter.append( + 'member:%s' % (member) + ) + + if fault: + interface_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + interfaces = [] + members = [] + fault_record = [] + fault_inst = [] + event = [] + audit = [] + + for apic_handler in apic_handlers: + for node_info in apic_handler['nodes']: + node_interfaces = apic_handler['handler'].get_interface_virtual_port_channel( + pod_id=node_info['podId'], + node_id=node_info['id'], + interface_filter=interface_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + if node_interfaces is None: + continue + + interfaces = interfaces + node_interfaces + + for interface in node_interfaces: + if 'eventLog' in interface: + if interface['eventLog'] is not None: + event = event + interface['eventLog'] + + if 'faultRecord' in interface: + if interface['faultRecord'] is not None: + fault_record = fault_record + interface['faultRecord'] + + if 'faultInst' in interface: + if interface['faultInst'] is not None: + fault_inst = fault_inst + interface['faultInst'] + + if 'auditLog' in interface: + if interface['auditLog'] is not None: + audit = audit + interface['auditLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + audit = sorted( + audit, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + interfaces, + indent=4 + ) + ) + return + + ctx.my_output.json_output(interfaces) + + if 'state' in view: + aci_output_handler.print_interfaces_virtual_port_channel_state( + interfaces, + title=True + ) + + if 'addr' in view: + aci_output_handler.print_interfaces_virtual_port_channel_address( + interfaces, + title=True + ) + + if 'member' in view: + aci_output_handler.print_interfaces_virtual_port_channel_member( + members, + title=True + ) + + aci_output_handler.print_interfaces_virtual_port_channel_vlan( + members, + title=False + ) + + if 'vlan' in view: + aci_output_handler.print_interfaces_virtual_port_channel_vlan_epg( + members, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_interface_virtual_port_channel_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_interface_virtual_port_channel_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_interface_virtual_port_channel_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_interface_virtual_port_channel_audit_logs( + audit, + when=fault_when, + title=True + ) + + if len(interfaces) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/l2out.py b/menu/get/aci/l2out.py new file mode 100644 index 00000000..476160ec --- /dev/null +++ b/menu/get/aci/l2out.py @@ -0,0 +1,275 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("l2out") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "l2out_name", default='', callback=validations.validate_apic_tenant_name, help="Filter by application profile name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|node|intf|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_l2out_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + l2out_name, + tenant_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci l2out""" + + # iserver get aci l2out + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|node|intf|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + l2out_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if l2out_name is not None: + l2out_filter.append( + 'name:%s' % (l2out_name['name']) + ) + + if l2out_name['tenant'] is not None: + tenant_filtered = True + l2out_filter.append( + 'tenant:%s' % (l2out_name['tenant']) + ) + + if tenant_name is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + l2out_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if fault: + l2out_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + node_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + l2outs = apic_handler.get_l2outs( + l2out_filter=l2out_filter, + path_info=True, + node_info=node_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for l2out in l2outs: + if 'eventLog' in l2out: + if l2out['eventLog'] is not None: + event = event + l2out['eventLog'] + + if 'faultRecord' in l2out: + if l2out['faultRecord'] is not None: + fault_record = fault_record + l2out['faultRecord'] + + if 'faultInst' in l2out: + if l2out['faultInst'] is not None: + fault_inst = fault_inst + l2out['faultInst'] + + if 'auditLog' in l2out: + if l2out['auditLog'] is not None: + audit = audit + l2out['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + l2outs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(l2outs) + + if 'state' in view: + aci_output_handler.print_l2outs( + l2outs, + title=True + ) + + if 'node' in view: + aci_output_handler.print_l2outs_node( + l2outs, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_l2outs_interface( + l2outs, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_l2outs_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_l2outs_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_l2outs_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_l2outs_audit_logs( + audit, + when=fault_when, + title=True + ) + + if l2outs is None or len(l2outs) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/l3out.py b/menu/get/aci/l3out.py new file mode 100644 index 00000000..3d98ef56 --- /dev/null +++ b/menu/get/aci/l3out.py @@ -0,0 +1,339 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("l3out") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "l3out_name", default='', callback=validations.validate_apic_tenant_name, help="Filter by l3out name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--vrf", "vrf_name", default='', callback=validations.empty_string_to_none, help="Filter by vrf name") +@click.option("--domain", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--node", "node_id", default='', callback=validations.empty_string_to_none, help="Filter by node id") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|epg|bgp|eigrp|mpls|ospf|pim|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_l3out_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + l3out_name, + tenant_name, + vrf_name, + domain_name, + node_id, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci l3out""" + + # iserver get aci l3out + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|epg|node|bgp|eigrp|mpls|ospf|pim|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + l3out_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if l3out_name is not None: + l3out_filter.append( + 'name:%s' % (l3out_name['name']) + ) + + if l3out_name['tenant'] is not None: + tenant_filtered = True + l3out_filter.append( + 'tenant:%s' % (l3out_name['tenant']) + ) + + if tenant_name is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + l3out_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if vrf_name is not None: + l3out_filter.append( + 'vrf:%s' % (vrf_name) + ) + + if domain_name is not None: + l3out_filter.append( + 'domain:%s' % (domain_name) + ) + + if 'bgp' in view: + l3out_filter.append( + 'bgp:enabled' + ) + + if 'eigrp' in view: + l3out_filter.append( + 'eigrp:enabled' + ) + + if 'ospf' in view: + l3out_filter.append( + 'ospf:enabled' + ) + + if 'mpls' in view: + l3out_filter.append( + 'mpls:enabled' + ) + + if 'pim' in view: + l3out_filter.append( + 'pim:enabled' + ) + + if node_id is not None: + l3out_filter.append( + 'node:%s' % (node_id) + ) + + if fault: + l3out_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + l3outs = apic_handler.get_l3outs( + l3out_filter=l3out_filter, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for l3out in l3outs: + if 'eventLog' in l3out: + if l3out['eventLog'] is not None: + event = event + l3out['eventLog'] + + if 'faultRecord' in l3out: + if l3out['faultRecord'] is not None: + fault_record = fault_record + l3out['faultRecord'] + + if 'faultInst' in l3out: + if l3out['faultInst'] is not None: + fault_inst = fault_inst + l3out['faultInst'] + + if 'auditLog' in l3out: + if l3out['auditLog'] is not None: + audit = audit + l3out['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + l3outs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(l3outs) + + if 'state' in view: + aci_output_handler.print_l3outs( + l3outs, + title=True + ) + + if 'bgp' in view: + aci_output_handler.print_l3outs_bgp( + l3outs, + title=True + ) + + if 'eigrp' in view: + aci_output_handler.print_l3outs_eigrp( + l3outs, + title=True + ) + + if 'ospf' in view: + aci_output_handler.print_l3outs_ospf( + l3outs, + title=True + ) + + if 'pim' in view: + aci_output_handler.print_l3outs_pim( + l3outs, + title=True + ) + + if 'mpls' in view: + aci_output_handler.print_l3outs_mpls( + l3outs, + title=True + ) + + if 'epg' in view: + aci_output_handler.print_l3outs_epg( + l3outs, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_l3outs_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_l3outs_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_l3outs_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_l3outs_audit_logs( + audit, + when=fault_when, + title=True + ) + + ctx.my_output.default('Filter: name, tenant, vrf, domain, node, fault, severity, when', before_newline=True) + ctx.my_output.default('View: state (def), epg, bgp, eigrp, ospf, pim, mpls, fault, hfault, event, audit, diag, all') + + if l3outs is None or len(l3outs) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/mac.py b/menu/get/aci/mac.py new file mode 100644 index 00000000..86cf777f --- /dev/null +++ b/menu/get/aci/mac.py @@ -0,0 +1,191 @@ +import sys +import threading +import traceback +import click + +from lib.aci import output as aci_output +from lib import context + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("mac") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--mac", "-m", multiple=True, help="MAC address") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +def get_aci_mac_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + mac, + output + ): + """Get aci mac address related objects""" + + ctx.developer = False + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=True + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + else: + ctx.my_output.error( + 'Define single APIC' + ) + raise ErrorExit + + apic_handler = apic_handlers[0]['handler'] + + if len(mac) == 0: + ctx.my_output.error( + 'Define MAC address' + ) + raise ErrorExit + + endpoint_filter = [] + interface_filter = [] + adjacency_filter = [] + + for mac_address in mac: + if len(mac_address.split('ctx:')) == 2: + context_handler = context.Context(log_id=ctx.run_id) + new_mac = context_handler.get( + mac_address.split('ctx:')[1] + ) + if output not in ['json']: + ctx.my_output.default('Ctx: %s' % (new_mac)) + if new_mac is None: + ctx.my_output.error('Unknown context: %s' % (mac_address.split('ctx:')[1])) + raise ErrorExit + + else: + new_mac = [mac_address] + + for entry in new_mac: + endpoint_filter.append( + 'mac:%s' % (entry) + ) + + interface_filter.append( + 'mac:%s' % (entry) + ) + + adjacency_filter.append( + 'mac:%s' % (entry) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + endpoints = [] + lacp = [] + lldp = [] + + for apic_handler in apic_handlers: + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler['handler'], + ['any'], + 'any', + pod_id='', + silent=True + ) + + apic_endpoints = apic_handler['handler'].get_endpoints( + endpoint_filter=endpoint_filter + ) + for apic_endpoint in apic_endpoints: + apic_endpoint['apic'] = apic_handler['name'] + + endpoints = endpoints + apic_endpoints + + for node_info in nodes_info: + proto_info = apic_handler['handler'].get_protocol_lacp( + node_info['podId'], + node_info['id'], + interface_info=True, + interface_filter=interface_filter + ) + if proto_info is not None and proto_info['interfaces'] is not None: + lacp = lacp + proto_info['interfaces'] + + proto_info = apic_handler['handler'].get_protocol_lldp( + node_info['podId'], + node_info['id'], + adjacency_filter=adjacency_filter, + instance_info=False, + stats_info=False, + adjacency_info=True, + fault_info=False, + hfault_info=False + ) + if proto_info is not None and proto_info['adjacency'] is not None: + lldp = lldp + proto_info['adjacency'] + + ctx.busy = False + + if len(endpoints) > 0: + aci_output_handler.print_endpoints( + endpoints, + title=True + ) + + if len(lacp) > 0: + aci_output_handler.print_proto_lacp_interfaces( + lacp, + title=True + ) + + if len(lldp) > 0: + aci_output_handler.print_lldp_adjacency_endpoints( + lldp, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/main.py b/menu/get/aci/main.py new file mode 100644 index 00000000..9ae97c32 --- /dev/null +++ b/menu/get/aci/main.py @@ -0,0 +1,62 @@ +import click + +from menu.get.aci.aaep import get_aci_aaep_command +from menu.get.aci.ap import get_aci_ap_command +from menu.get.aci.bd import get_aci_bd_command +from menu.get.aci.cache import get_aci_cache_command +from menu.get.aci.contract.main import get_aci_contract_menu +from menu.get.aci.controller import get_aci_controller_command +from menu.get.aci.domain.main import get_aci_domain_menu +from menu.get.aci.ep import get_aci_ep_command +from menu.get.aci.epg import get_aci_epg_command +from menu.get.aci.intf.main import get_aci_node_intf_menu +from menu.get.aci.l2out import get_aci_l2out_command +from menu.get.aci.l3out import get_aci_l3out_command +from menu.get.aci.mac import get_aci_mac_command +from menu.get.aci.mo import get_aci_mo_command +from menu.get.aci.node import get_aci_node_command +from menu.get.aci.pg.main import get_aci_pg_menu +from menu.get.aci.policy.main import get_aci_policy_menu +from menu.get.aci.pool.main import get_aci_pool_menu +from menu.get.aci.proto.main import get_aci_node_proto_menu +from menu.get.aci.psirt import get_aci_psirt_command +from menu.get.aci.system.main import get_aci_system_menu +from menu.get.aci.tenant import get_aci_tenant_command +from menu.get.aci.vrf import get_aci_vrf_command +from menu.get.aci.server import get_aci_server_command + + +class Failure(Exception): + pass + + +@click.group("aci") +@click.pass_obj +def get_aci_menu(ctx): + """Get aci commands""" + + +get_aci_menu.add_command(get_aci_aaep_command) +get_aci_menu.add_command(get_aci_epg_command) +get_aci_menu.add_command(get_aci_ap_command) +get_aci_menu.add_command(get_aci_bd_command) +get_aci_menu.add_command(get_aci_cache_command) +get_aci_menu.add_command(get_aci_contract_menu) +get_aci_menu.add_command(get_aci_controller_command) +get_aci_menu.add_command(get_aci_domain_menu) +get_aci_menu.add_command(get_aci_ep_command) +get_aci_menu.add_command(get_aci_node_intf_menu) +get_aci_menu.add_command(get_aci_l2out_command) +get_aci_menu.add_command(get_aci_l3out_command) +get_aci_menu.add_command(get_aci_mac_command) +get_aci_menu.add_command(get_aci_mo_command) +get_aci_menu.add_command(get_aci_node_command) +get_aci_menu.add_command(get_aci_pg_menu) +get_aci_menu.add_command(get_aci_policy_menu) +get_aci_menu.add_command(get_aci_pool_menu) +get_aci_menu.add_command(get_aci_psirt_command) +get_aci_menu.add_command(get_aci_node_proto_menu) +get_aci_menu.add_command(get_aci_system_menu) +get_aci_menu.add_command(get_aci_tenant_command) +get_aci_menu.add_command(get_aci_vrf_command) +get_aci_menu.add_command(get_aci_server_command) diff --git a/menu/get/aci/mo.py b/menu/get/aci/mo.py new file mode 100644 index 00000000..0fcabc81 --- /dev/null +++ b/menu/get/aci/mo.py @@ -0,0 +1,169 @@ +import sys +import json +import threading +import traceback +import click + +from lib import log_helper +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("mo") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--dn", "-d", "mo_dn", default='', help="Managed object distinguished name") +@click.option("--class", "-c", "class_name", default='', help="Class name") +@click.option("--option", "-x", "extra_options", help="Extra options", multiple=True) +@click.option("--node", is_flag=True, show_default=True, default=False, help="Node specific") +@click.option("--limit", "imdata_limit", default=1, help="Limit objects") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +def get_aci_mo_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + mo_dn, + class_name, + extra_options, + node, + imdata_limit, + output + ): + """Get aci managed object""" + + # iserver get aci managed object + + ctx.developer = False + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=True + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + else: + ctx.my_output.error( + 'Define single APIC' + ) + raise ErrorExit + + apic_handler = apic_handlers[0]['handler'] + + if len(mo_dn) == 0 and len(class_name) == 0: + ctx.my_output.error( + 'Define DN or Class' + ) + raise ErrorExit + + if len(mo_dn) > 0 and len(class_name) > 0: + ctx.my_output.error( + 'Define DN or Class' + ) + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if len(class_name) > 0: + query = None + if len(extra_options) > 0: + query = '&'.join(extra_options) + managed_objects = apic_handler.get_class( + class_name, + query=query, + node_class=node + ) + request_info = apic_handler.get_request_info() + + if len(mo_dn) > 0: + query = None + if len(extra_options) > 0: + query = '&'.join(extra_options) + managed_objects = apic_handler.get_managed_object( + mo_dn, + query=query, + node_mo=node + ) + request_info = apic_handler.get_request_info() + + ctx.busy = False + + if request_info['connected']: + if output not in ['json']: + ctx.my_output.default('URL: %s' % (request_info['url'])) + ctx.my_output.default('Response code: %s' % (request_info['status_code'])) + ctx.my_output.default('Duration [ms]: %s' % (request_info['duration'])) + if request_info['error'] is not None: + ctx.my_output.default('Error: %s' % (request_info['error'])) + + if managed_objects is not None: + if output not in ['json']: + ctx.my_output.default('Total count: %s' % (managed_objects['totalCount'])) + + if imdata_limit == 0: + ctx.my_output.default( + json.dumps( + managed_objects['imdata'], + indent=4 + ) + ) + + if imdata_limit > 0: + ctx.my_output.default( + json.dumps( + managed_objects['imdata'][:imdata_limit], + indent=4 + ) + ) + + log_handler = log_helper.Log(log_id=ctx.run_id) + log_handler.apic_mo( + 'result', + managed_objects + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/node.py b/menu/get/aci/node.py new file mode 100644 index 00000000..0ed5c955 --- /dev/null +++ b/menu/get/aci/node.py @@ -0,0 +1,254 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("node") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--role", "node_role", type=click.Choice(['any', 'controller', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "node_id", default='', callback=validations.empty_string_to_none, help="Filter by node id") +@click.option("--name", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--model", default='', callback=validations.empty_string_to_none, help="Filter by model") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by subnet with IP") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by subnet within subnet") +@click.option("--view", "-v", default=['state'], help="[state|intf|ip|power|psu|sensor|temp|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_role, + pod_id, + node_id, + node_name, + model, + ip_address, + ip_subnet, + view, + output, + no_cache, + devel + ): + """Get aci node""" + + # iserver get aci node + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|intf|ip|power|psu|sensor|temp|all', + 'state', + [] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + power_info = False + psu_info = False + sensor_info = False + temp_info = False + system_info = False + + node_filter = [] + if node_id is not None: + node_filter.append( + 'id:%s' % (node_id) + ) + + if node_name is not None: + node_filter.append( + 'name:%s' % (node_name) + ) + + if pod_id is not None: + node_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_role != 'any': + node_filter.append( + 'role:%s' % (node_role) + ) + + if model is not None: + node_filter.append( + 'model:%s' % (model) + ) + + if len(ip_subnet) > 0: + system_info = True + node_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if len(ip_address) > 0: + system_info = True + node_filter.append( + 'ip:%s' % (ip_address) + ) + + interfaces_summary_info = False + if 'intf' in view: + interfaces_summary_info = True + if node_role == 'any': + node_filter.append( + 'role:!controller' + ) + + if 'power' in view: + power_info = True + + if 'psu' in view: + psu_info = True + + if 'sensor' in view: + sensor_info = True + + if 'ip' in view: + system_info = True + + if 'temp' in view: + temp_info = True + + nodes = [] + + for apic_handler in apic_handlers: + apic_nodes = apic_handler['handler'].get_nodes( + node_filter=node_filter, + interfaces_summary_info=interfaces_summary_info, + power_info=power_info, + psu_info=psu_info, + sensor_info=sensor_info, + system_info=system_info, + temp_info=temp_info + ) + if apic_nodes is None: + continue + + nodes = nodes + apic_nodes + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + nodes, + indent=4 + ) + ) + return + + ctx.my_output.json_output(nodes) + + if 'state' in view: + aci_output_handler.print_nodes( + nodes, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_nodes_intf( + nodes, + title=True + ) + + if 'ip' in view: + aci_output_handler.print_nodes_system( + nodes, + title=True + ) + + if 'power' in view: + aci_output_handler.print_nodes_power( + nodes, + title=True + ) + + if 'psu' in view: + aci_output_handler.print_nodes_psu( + nodes, + title=True + ) + + if 'sensor' in view: + aci_output_handler.print_nodes_sensor( + nodes, + title=True + ) + + if 'temp' in view: + aci_output_handler.print_nodes_temp( + nodes, + title=True + ) + + ctx.my_output.default('Filter: pod, role, id, name, model, address, subnet', before_newline=True) + ctx.my_output.default('View: state (def), intf, ip, power, psu, sensor, temp, all') + + if len(nodes) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/pg/__init__.py b/menu/get/aci/pg/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/pg/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/pg/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c748afca Binary files /dev/null and b/menu/get/aci/pg/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/pg/__pycache__/main.cpython-310.pyc b/menu/get/aci/pg/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..119678f0 Binary files /dev/null and b/menu/get/aci/pg/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/__init__.py b/menu/get/aci/pg/access/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/pg/access/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/pg/access/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..48796ab3 Binary files /dev/null and b/menu/get/aci/pg/access/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/__pycache__/main.cpython-310.pyc b/menu/get/aci/pg/access/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..93f49416 Binary files /dev/null and b/menu/get/aci/pg/access/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/intf/__init__.py b/menu/get/aci/pg/access/intf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/pg/access/intf/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/pg/access/intf/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..9a0c79eb Binary files /dev/null and b/menu/get/aci/pg/access/intf/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/intf/__pycache__/main.cpython-310.pyc b/menu/get/aci/pg/access/intf/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..d621b4f2 Binary files /dev/null and b/menu/get/aci/pg/access/intf/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/intf/__pycache__/port.cpython-310.pyc b/menu/get/aci/pg/access/intf/__pycache__/port.cpython-310.pyc new file mode 100644 index 00000000..7de7a8df Binary files /dev/null and b/menu/get/aci/pg/access/intf/__pycache__/port.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/intf/__pycache__/vpc.cpython-310.pyc b/menu/get/aci/pg/access/intf/__pycache__/vpc.cpython-310.pyc new file mode 100644 index 00000000..d733371c Binary files /dev/null and b/menu/get/aci/pg/access/intf/__pycache__/vpc.cpython-310.pyc differ diff --git a/menu/get/aci/pg/access/intf/main.py b/menu/get/aci/pg/access/intf/main.py new file mode 100644 index 00000000..95c7e9b3 --- /dev/null +++ b/menu/get/aci/pg/access/intf/main.py @@ -0,0 +1,18 @@ +import click + +from menu.get.aci.pg.access.intf.port import get_aci_pg_access_interface_port_command +from menu.get.aci.pg.access.intf.vpc import get_aci_pg_access_interface_vpc_command + + +class Failure(Exception): + pass + + +@click.group("intf") +@click.pass_obj +def get_aci_pg_access_interface_menu(ctx): + """Get aci policy group access interface commands""" + + +get_aci_pg_access_interface_menu.add_command(get_aci_pg_access_interface_port_command) +get_aci_pg_access_interface_menu.add_command(get_aci_pg_access_interface_vpc_command) diff --git a/menu/get/aci/pg/access/intf/port.py b/menu/get/aci/pg/access/intf/port.py new file mode 100644 index 00000000..d4548b96 --- /dev/null +++ b/menu/get/aci/pg/access/intf/port.py @@ -0,0 +1,298 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("port") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--aaep", default='', callback=validations.empty_string_to_none, help="Filter by aaep") +@click.option("--policy", default='', callback=validations.empty_string_to_none, help="Filter by policy") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|aaep|node|intf|vlan|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_pg_access_interface_port_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + name, + aaep, + policy, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci policy group interface port""" + + # iserver get aci pg intf port + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|aaep|node|intf|vlan|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + policy_group_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if name is not None: + policy_group_filter.append( + 'name:%s' % (name) + ) + + if aaep is not None: + policy_group_filter.append( + 'aaep:%s' % (aaep) + ) + + if policy is not None: + policy_group_filter.append( + 'policy:%s' % (policy) + ) + + if fault: + policy_group_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + aaep_info = False + node_info = False + vlan_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'aaep' in view: + aaep_info = True + + if 'node' in view: + aaep_info = True + node_info = True + + if 'intf' in view: + aaep_info = True + node_info = True + + if 'vlan' in view: + aaep_info = True + node_info = True + vlan_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + if node_info: + ctx.my_output.default('[INFO] Requires per-group API call') + if vlan_info: + ctx.my_output.default('[INFO] Requires per-interface API call') + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policy_groups = apic_handler.get_policy_groups_access_interface_port( + policy_group_filter=policy_group_filter, + aaep_info=aaep_info, + node_info=node_info, + vlan_info=vlan_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for policy_group in policy_groups: + if 'eventLog' in policy_group: + if policy_group['eventLog'] is not None: + event = event + policy_group['eventLog'] + + if 'faultRecord' in policy_group: + if policy_group['faultRecord'] is not None: + fault_record = fault_record + policy_group['faultRecord'] + + if 'faultInst' in policy_group: + if policy_group['faultInst'] is not None: + fault_inst = fault_inst + policy_group['faultInst'] + + if 'auditLog' in policy_group: + if policy_group['auditLog'] is not None: + audit = audit + policy_group['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + policy_groups, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policy_groups) + + if 'state' in view: + aci_output_handler.print_policy_groups_access_interface_port( + policy_groups, + title=True + ) + + if 'aaep' in view: + aci_output_handler.print_policy_groups_access_interface_port_aaep( + policy_groups, + title=True + ) + + if 'node' in view: + aci_output_handler.print_policy_groups_access_interface_port_node( + policy_groups, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_policy_groups_access_interface_port_interface( + policy_groups, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_policy_groups_access_interface_port_vlan( + policy_groups, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_policy_groups_access_interface_port_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_policy_groups_access_interface_port_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_policy_groups_access_interface_port_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_policy_groups_access_interface_port_audit_logs( + audit, + when=fault_when, + title=True + ) + + if policy_groups is None or len(policy_groups) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/pg/access/intf/vpc.py b/menu/get/aci/pg/access/intf/vpc.py new file mode 100644 index 00000000..82015b18 --- /dev/null +++ b/menu/get/aci/pg/access/intf/vpc.py @@ -0,0 +1,318 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vpc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--aaep", default='', callback=validations.empty_string_to_none, help="Filter by aaep") +@click.option("--policy", default='', callback=validations.empty_string_to_none, help="Filter by policy") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|aaep|node|intf|vlan|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_pg_access_interface_vpc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + name, + aaep, + policy, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci policy group interface vpc""" + + # iserver get aci pg intf vpc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|aaep|node|intf|vlan|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + policy_group_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if name is not None: + policy_group_filter.append( + 'name:%s' % (name) + ) + + if aaep is not None: + policy_group_filter.append( + 'aaep:%s' % (aaep) + ) + + if policy is not None: + policy_group_filter.append( + 'policy:%s' % (policy) + ) + + if fault: + policy_group_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + aaep_info = False + node_info = False + vlan_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'aaep' in view: + aaep_info = True + + if 'node' in view: + aaep_info = True + node_info = True + + if 'intf' in view: + aaep_info = True + node_info = True + + if 'vlan' in view: + aaep_info = True + node_info = True + vlan_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + if node_info: + ctx.my_output.default('[INFO] Requires per-group API call') + if vlan_info: + ctx.my_output.default('[INFO] Requires per-interface API call') + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policy_groups = apic_handler.get_policy_groups_access_interface_vpc( + policy_group_filter=policy_group_filter, + aaep_info=aaep_info, + node_info=node_info, + vlan_info=vlan_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for policy_group in policy_groups: + if 'eventLog' in policy_group: + if policy_group['eventLog'] is not None: + event = event + policy_group['eventLog'] + + if 'faultRecord' in policy_group: + if policy_group['faultRecord'] is not None: + fault_record = fault_record + policy_group['faultRecord'] + + if 'faultInst' in policy_group: + if policy_group['faultInst'] is not None: + fault_inst = fault_inst + policy_group['faultInst'] + + if 'auditLog' in policy_group: + if policy_group['auditLog'] is not None: + audit = audit + policy_group['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + policy_groups, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policy_groups) + + if 'state' in view: + aci_output_handler.print_policy_groups_access_interface_vpc( + policy_groups, + title=True + ) + + if 'aaep' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_aaep( + policy_groups, + title=True + ) + + if 'node' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_node( + policy_groups, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_interface( + policy_groups, + title=True + ) + + if 'vlan' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_vlan( + policy_groups, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_policy_groups_access_interface_vpc_audit_logs( + audit, + when=fault_when, + title=True + ) + + # if 'default' in view: + # aci_output_handler.print_policy_groups_access_interface_vpc_policies( + # policy_groups + # ) + + # if 'node' in view: + # aci_output_handler.print_policy_groups_access_interface_vpc_nodes( + # policy_groups + # ) + + # if 'port' in view: + # aci_output_handler.print_policy_groups_access_interface_vpc_ports( + # policy_groups + # ) + + # if 'aaep' in view: + # aci_output_handler.print_policy_groups_access_interface_vpc_aaep( + # policy_groups + # ) + + if policy_groups is None or len(policy_groups) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/pg/access/main.py b/menu/get/aci/pg/access/main.py new file mode 100644 index 00000000..206f1ef4 --- /dev/null +++ b/menu/get/aci/pg/access/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.aci.pg.access.intf.main import get_aci_pg_access_interface_menu + + +class Failure(Exception): + pass + + +@click.group("access") +@click.pass_obj +def get_aci_pg_access_menu(ctx): + """Get aci policy group access commands""" + + +get_aci_pg_access_menu.add_command(get_aci_pg_access_interface_menu) diff --git a/menu/get/aci/pg/main.py b/menu/get/aci/pg/main.py new file mode 100644 index 00000000..eabb7f74 --- /dev/null +++ b/menu/get/aci/pg/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.aci.pg.access.main import get_aci_pg_access_menu + + +class Failure(Exception): + pass + + +@click.group("pg") +@click.pass_obj +def get_aci_pg_menu(ctx): + """Get aci policy group commands""" + + +get_aci_pg_menu.add_command(get_aci_pg_access_menu) diff --git a/menu/get/aci/policy/__init__.py b/menu/get/aci/policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/policy/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/policy/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..105e75c1 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/auth.cpython-310.pyc b/menu/get/aci/policy/__pycache__/auth.cpython-310.pyc new file mode 100644 index 00000000..9fd6e00a Binary files /dev/null and b/menu/get/aci/policy/__pycache__/auth.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/cdp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/cdp.cpython-310.pyc new file mode 100644 index 00000000..af6596ee Binary files /dev/null and b/menu/get/aci/policy/__pycache__/cdp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/copp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/copp.cpython-310.pyc new file mode 100644 index 00000000..52e0013d Binary files /dev/null and b/menu/get/aci/policy/__pycache__/copp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/dpp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/dpp.cpython-310.pyc new file mode 100644 index 00000000..4f8d6f4e Binary files /dev/null and b/menu/get/aci/policy/__pycache__/dpp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/drain.cpython-310.pyc b/menu/get/aci/policy/__pycache__/drain.cpython-310.pyc new file mode 100644 index 00000000..1c84d685 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/drain.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/fc.cpython-310.pyc b/menu/get/aci/policy/__pycache__/fc.cpython-310.pyc new file mode 100644 index 00000000..300b9402 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/fc.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/flap.cpython-310.pyc b/menu/get/aci/policy/__pycache__/flap.cpython-310.pyc new file mode 100644 index 00000000..1095bb2c Binary files /dev/null and b/menu/get/aci/policy/__pycache__/flap.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/l2.cpython-310.pyc b/menu/get/aci/policy/__pycache__/l2.cpython-310.pyc new file mode 100644 index 00000000..e4a66de6 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/l2.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/lacp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/lacp.cpython-310.pyc new file mode 100644 index 00000000..13a5b562 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/lacp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/lacp_member.cpython-310.pyc b/menu/get/aci/policy/__pycache__/lacp_member.cpython-310.pyc new file mode 100644 index 00000000..0e5b55e1 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/lacp_member.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/link.cpython-310.pyc b/menu/get/aci/policy/__pycache__/link.cpython-310.pyc new file mode 100644 index 00000000..78ed0a3f Binary files /dev/null and b/menu/get/aci/policy/__pycache__/link.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/link_fc.cpython-310.pyc b/menu/get/aci/policy/__pycache__/link_fc.cpython-310.pyc new file mode 100644 index 00000000..e42bd1b7 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/link_fc.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/lldp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/lldp.cpython-310.pyc new file mode 100644 index 00000000..09c8c178 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/lldp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/main.cpython-310.pyc b/menu/get/aci/policy/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3c7273d5 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/mcp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/mcp.cpython-310.pyc new file mode 100644 index 00000000..e089b0e3 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/mcp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/pfc.cpython-310.pyc b/menu/get/aci/policy/__pycache__/pfc.cpython-310.pyc new file mode 100644 index 00000000..39f0b62b Binary files /dev/null and b/menu/get/aci/policy/__pycache__/pfc.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/portsec.cpython-310.pyc b/menu/get/aci/policy/__pycache__/portsec.cpython-310.pyc new file mode 100644 index 00000000..4cb7e09b Binary files /dev/null and b/menu/get/aci/policy/__pycache__/portsec.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/storm.cpython-310.pyc b/menu/get/aci/policy/__pycache__/storm.cpython-310.pyc new file mode 100644 index 00000000..b0c7d70c Binary files /dev/null and b/menu/get/aci/policy/__pycache__/storm.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/stp.cpython-310.pyc b/menu/get/aci/policy/__pycache__/stp.cpython-310.pyc new file mode 100644 index 00000000..60bbc961 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/stp.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/synce.cpython-310.pyc b/menu/get/aci/policy/__pycache__/synce.cpython-310.pyc new file mode 100644 index 00000000..702d075a Binary files /dev/null and b/menu/get/aci/policy/__pycache__/synce.cpython-310.pyc differ diff --git a/menu/get/aci/policy/__pycache__/transceiver.cpython-310.pyc b/menu/get/aci/policy/__pycache__/transceiver.cpython-310.pyc new file mode 100644 index 00000000..a2bb1751 Binary files /dev/null and b/menu/get/aci/policy/__pycache__/transceiver.cpython-310.pyc differ diff --git a/menu/get/aci/policy/auth.py b/menu/get/aci/policy/auth.py new file mode 100644 index 00000000..2a353a1a --- /dev/null +++ b/menu/get/aci/policy/auth.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("auth") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_auth_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface 802.1x""" + + # iserver get aci policy interface auth + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_auth( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_auth_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_auth_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_auth_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_auth_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_auth( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/cdp.py b/menu/get/aci/policy/cdp.py new file mode 100644 index 00000000..08fddea5 --- /dev/null +++ b/menu/get/aci/policy/cdp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("cdp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_cdp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface cdp""" + + # iserver get aci policy interface cdp + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_cdp( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_cdp_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_cdp_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_cdp_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_cdp_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_cdp( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/copp.py b/menu/get/aci/policy/copp.py new file mode 100644 index 00000000..80117db3 --- /dev/null +++ b/menu/get/aci/policy/copp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("copp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_copp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface copp""" + + # iserver get aci policy interface copp + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_copp( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_copp_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_copp_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_copp_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_copp_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_copp( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/dpp.py b/menu/get/aci/policy/dpp.py new file mode 100644 index 00000000..1b532066 --- /dev/null +++ b/menu/get/aci/policy/dpp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("dpp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_dpp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface dpp""" + + # iserver get aci policy interface dpp + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_dpp( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_dpp_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_dpp_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_dpp_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_dpp_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_dpp( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/drain.py b/menu/get/aci/policy/drain.py new file mode 100644 index 00000000..087303dc --- /dev/null +++ b/menu/get/aci/policy/drain.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("drain") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_drain_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface slow drain""" + + # iserver get aci policy interface drain + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_slow_drain( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_slow_drain_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_slow_drain_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_slow_drain_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_slow_drain_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_slow_drain( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/fc.py b/menu/get/aci/policy/fc.py new file mode 100644 index 00000000..8738e8cd --- /dev/null +++ b/menu/get/aci/policy/fc.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("fc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_fc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface fc""" + + # iserver get aci policy interface fc + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_fc( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_fc_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_fc_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_fc_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_fc_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_fc( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/flap.py b/menu/get/aci/policy/flap.py new file mode 100644 index 00000000..96b64db3 --- /dev/null +++ b/menu/get/aci/policy/flap.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("flap") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_flap_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface flap""" + + # iserver get aci policy interface flap + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_link_flap( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_link_flap_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_link_flap_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_link_flap_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_link_flap_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_link_flap( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/l2.py b/menu/get/aci/policy/l2.py new file mode 100644 index 00000000..6f5a5410 --- /dev/null +++ b/menu/get/aci/policy/l2.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("l2") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_l2_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface l2""" + + # iserver get aci policy interface l2 + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_l2( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_l2_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_l2_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_l2_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_l2_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_l2( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/lacp.py b/menu/get/aci/policy/lacp.py new file mode 100644 index 00000000..d0374228 --- /dev/null +++ b/menu/get/aci/policy/lacp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("lacp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_port_channel_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface port_channel""" + + # iserver get aci policy interface port_channel + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_port_channel( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_port_channel_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_port_channel_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_port_channel_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_port_channel_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_port_channel( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/lacp_member.py b/menu/get/aci/policy/lacp_member.py new file mode 100644 index 00000000..f6776a7a --- /dev/null +++ b/menu/get/aci/policy/lacp_member.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("lacp-m") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_port_channel_member_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface port_channel_member""" + + # iserver get aci policy interface port_channel_member + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_port_channel_member( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_port_channel_member_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_port_channel_member_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_port_channel_member_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_port_channel_member_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_port_channel_member( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/link.py b/menu/get/aci/policy/link.py new file mode 100644 index 00000000..52ca0afd --- /dev/null +++ b/menu/get/aci/policy/link.py @@ -0,0 +1,181 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("link") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_link_level_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface link""" + + # iserver get aci policy interface link + + ctx.developer = devel + ctx.output = output + if len(view) == 0: + view = ['default'] + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_link_level( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_link_level_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_link_level_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_link_level_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_link_level_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_link_level( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/link_fc.py b/menu/get/aci/policy/link_fc.py new file mode 100644 index 00000000..c2e3d358 --- /dev/null +++ b/menu/get/aci/policy/link_fc.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("link-fc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_link_level_fc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface link""" + + # iserver get aci policy interface link + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_link_level_fc( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_link_level_fc_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_link_level_fc_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_link_level_fc_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_link_level_fc_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_link_level_fc( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/lldp.py b/menu/get/aci/policy/lldp.py new file mode 100644 index 00000000..cc9ad90c --- /dev/null +++ b/menu/get/aci/policy/lldp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("lldp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_lldp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface lldp""" + + # iserver get aci policy interface lldp + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_lldp( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_lldp_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_lldp_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_lldp_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_lldp_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_lldp( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/main.py b/menu/get/aci/policy/main.py new file mode 100644 index 00000000..9a7fc1e5 --- /dev/null +++ b/menu/get/aci/policy/main.py @@ -0,0 +1,54 @@ +import click + +from menu.get.aci.policy.auth import get_aci_policy_auth_command +from menu.get.aci.policy.cdp import get_aci_policy_cdp_command +from menu.get.aci.policy.copp import get_aci_policy_copp_command +from menu.get.aci.policy.dpp import get_aci_policy_dpp_command +from menu.get.aci.policy.drain import get_aci_policy_drain_command +from menu.get.aci.policy.fc import get_aci_policy_fc_command +from menu.get.aci.policy.flap import get_aci_policy_flap_command +from menu.get.aci.policy.l2 import get_aci_policy_l2_command +from menu.get.aci.policy.lacp import get_aci_policy_port_channel_command +from menu.get.aci.policy.lacp_member import get_aci_policy_port_channel_member_command +from menu.get.aci.policy.link import get_aci_policy_link_level_command +from menu.get.aci.policy.link_fc import get_aci_policy_link_level_fc_command +from menu.get.aci.policy.lldp import get_aci_policy_lldp_command +from menu.get.aci.policy.mcp import get_aci_policy_mcp_command +from menu.get.aci.policy.pfc import get_aci_policy_pfc_command +from menu.get.aci.policy.portsec import get_aci_policy_port_security_command +from menu.get.aci.policy.storm import get_aci_policy_storm_control_command +from menu.get.aci.policy.stp import get_aci_policy_stp_command +from menu.get.aci.policy.synce import get_aci_policy_synce_command +from menu.get.aci.policy.transceiver import get_aci_policy_transceiver_command + + +class Failure(Exception): + pass + + +@click.group("policy") +@click.pass_obj +def get_aci_policy_menu(ctx): + """Get aci policy commands""" + + +get_aci_policy_menu.add_command(get_aci_policy_auth_command) +get_aci_policy_menu.add_command(get_aci_policy_cdp_command) +get_aci_policy_menu.add_command(get_aci_policy_copp_command) +get_aci_policy_menu.add_command(get_aci_policy_dpp_command) +get_aci_policy_menu.add_command(get_aci_policy_drain_command) +get_aci_policy_menu.add_command(get_aci_policy_fc_command) +get_aci_policy_menu.add_command(get_aci_policy_flap_command) +get_aci_policy_menu.add_command(get_aci_policy_l2_command) +get_aci_policy_menu.add_command(get_aci_policy_link_level_command) +get_aci_policy_menu.add_command(get_aci_policy_link_level_fc_command) +get_aci_policy_menu.add_command(get_aci_policy_lldp_command) +get_aci_policy_menu.add_command(get_aci_policy_mcp_command) +get_aci_policy_menu.add_command(get_aci_policy_pfc_command) +get_aci_policy_menu.add_command(get_aci_policy_port_channel_command) +get_aci_policy_menu.add_command(get_aci_policy_port_channel_member_command) +get_aci_policy_menu.add_command(get_aci_policy_port_security_command) +get_aci_policy_menu.add_command(get_aci_policy_storm_control_command) +get_aci_policy_menu.add_command(get_aci_policy_stp_command) +get_aci_policy_menu.add_command(get_aci_policy_synce_command) +get_aci_policy_menu.add_command(get_aci_policy_transceiver_command) diff --git a/menu/get/aci/policy/mcp.py b/menu/get/aci/policy/mcp.py new file mode 100644 index 00000000..43d49f25 --- /dev/null +++ b/menu/get/aci/policy/mcp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("mcp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_mcp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface mcp""" + + # iserver get aci policy interface mcp + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_mcp( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_mcp_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_mcp_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_mcp_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_mcp_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_mcp( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/pfc.py b/menu/get/aci/policy/pfc.py new file mode 100644 index 00000000..01f508c2 --- /dev/null +++ b/menu/get/aci/policy/pfc.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pfc") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_pfc_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface pfc""" + + # iserver get aci policy interface pfc + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_pfc( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_pfc_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_pfc_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_pfc_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_pfc_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_pfc( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/portsec.py b/menu/get/aci/policy/portsec.py new file mode 100644 index 00000000..de5b81ac --- /dev/null +++ b/menu/get/aci/policy/portsec.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("portsec") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_port_security_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface port_security""" + + # iserver get aci policy interface port_security + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_port_security( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_port_security_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_port_security_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_port_security_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_port_security_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_port_security( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/storm.py b/menu/get/aci/policy/storm.py new file mode 100644 index 00000000..1a1036ba --- /dev/null +++ b/menu/get/aci/policy/storm.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("storm") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_storm_control_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface storm_control""" + + # iserver get aci policy interface storm_control + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_storm_control( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_storm_control_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_storm_control_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_storm_control_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_storm_control_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_storm_control( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/stp.py b/menu/get/aci/policy/stp.py new file mode 100644 index 00000000..28bdd731 --- /dev/null +++ b/menu/get/aci/policy/stp.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("stp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_stp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface stp""" + + # iserver get aci policy interface stp + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_stp( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_stp_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_stp_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_stp_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_stp_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_stp( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/synce.py b/menu/get/aci/policy/synce.py new file mode 100644 index 00000000..ce650e2a --- /dev/null +++ b/menu/get/aci/policy/synce.py @@ -0,0 +1,179 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("synce") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--ref", "ref_policy_name", default='', callback=validations.empty_string_to_none, help="Filter by ref policy name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_synce_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + ref_policy_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface synce""" + + # iserver get aci policy interface synce + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if ref_policy_name is not None: + policy_filter.append( + 'ref_policy_name:%s' % (ref_policy_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_synce( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_synce_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_synce_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_synce_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_synce_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_synce( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/policy/transceiver.py b/menu/get/aci/policy/transceiver.py new file mode 100644 index 00000000..991ebb0a --- /dev/null +++ b/menu/get/aci/policy/transceiver.py @@ -0,0 +1,172 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("transceiver") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "policy_name", default='', callback=validations.empty_string_to_none, help="Filter by policy name") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Filter by pod id") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--unused", is_flag=True, show_default=True, default=False, help="Filter unused") +@click.option("--used", is_flag=True, show_default=True, default=False, help="Filter used") +@click.option("--view", "-v", type=click.Choice(['default', 'usage', 'intf', 'verbose'], case_sensitive=False), multiple=True, show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_policy_transceiver_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + policy_name, + pod_id, + node_name, + unused, + used, + view, + output, + no_cache, + devel + ): + """Get aci policy interface transceiver""" + + # iserver get aci policy interface transceiver + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + if len(view) == 0: + view = ['default'] + + policy_filter = [] + if policy_name is not None: + policy_filter.append( + 'name:%s' % (policy_name) + ) + + if pod_id is not None: + policy_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_name is not None: + policy_filter.append( + 'node:%s' % (node_name) + ) + + if used: + policy_filter.append( + 'used:true' + ) + + if unused: + policy_filter.append( + 'used:false' + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + policies = apic_handler.get_policy_interface_transceiver( + policy_filter=policy_filter, + attachment_info=True + ) + + context_name = apic_handler.set_policy_interface_transceiver_context( + policies + ) + + ctx.busy = False + + if policies is None or len(policies) == 0: + raise NoResultExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + ctx.my_output.json_output(policies) + + if 'default' in view: + aci_output_handler.print_policies_interface_transceiver_summary( + policies + ) + + if 'usage' in view: + aci_output_handler.print_policies_interface_transceiver_usage( + policies + ) + + if 'intf' in view: + aci_output_handler.print_policies_interface_transceiver_interfaces( + policies + ) + + if 'verbose' in view: + for policy in policies: + aci_output_handler.print_policy_interface_transceiver( + policy + ) + + if context_name is not None: + ctx.my_output.default('Context: %s' % (context_name)) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/pool/__init__.py b/menu/get/aci/pool/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/pool/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/pool/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..b27b1aa5 Binary files /dev/null and b/menu/get/aci/pool/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/pool/__pycache__/main.cpython-310.pyc b/menu/get/aci/pool/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4b57bbf1 Binary files /dev/null and b/menu/get/aci/pool/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/pool/__pycache__/vlan.cpython-310.pyc b/menu/get/aci/pool/__pycache__/vlan.cpython-310.pyc new file mode 100644 index 00000000..4f52a8de Binary files /dev/null and b/menu/get/aci/pool/__pycache__/vlan.cpython-310.pyc differ diff --git a/menu/get/aci/pool/main.py b/menu/get/aci/pool/main.py new file mode 100644 index 00000000..18343172 --- /dev/null +++ b/menu/get/aci/pool/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.aci.pool.vlan import get_aci_pool_vlan_command + + +class Failure(Exception): + pass + + +@click.group("pool") +@click.pass_obj +def get_aci_pool_menu(ctx): + """Get aci pool commands""" + + +get_aci_pool_menu.add_command(get_aci_pool_vlan_command) diff --git a/menu/get/aci/pool/vlan.py b/menu/get/aci/pool/vlan.py new file mode 100644 index 00000000..effc98e0 --- /dev/null +++ b/menu/get/aci/pool/vlan.py @@ -0,0 +1,262 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vlan") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "pool_name", default='', callback=validations.empty_string_to_none, help="Filter by pool name") +@click.option("--vlan", "vlan_id", default='', callback=validations.empty_string_to_none, help="Filter by vlan") +@click.option("--domain", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|epg|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_pool_vlan_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pool_name, + vlan_id, + domain_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci pool vlan""" + + # iserver get aci pool vlan + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|epg|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:event,fault,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + pool_vlan_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if pool_name is not None: + pool_vlan_filter.append( + 'name:%s' % (pool_name) + ) + + if vlan_id is not None: + pool_vlan_filter.append( + 'vlan:%s' % (vlan_id) + ) + + if domain_name is not None: + pool_vlan_filter.append( + 'domain:%s' % (domain_name) + ) + + if fault: + pool_vlan_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + vlan_usage_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'state' in view: + vlan_usage_info = True + + if 'epg' in view: + vlan_usage_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + vlans = apic_handler.get_pool_vlans( + pool_vlan_filter=pool_vlan_filter, + vlan_usage_info=vlan_usage_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for vlan in vlans: + if 'eventLog' in vlan: + if vlan['eventLog'] is not None: + event = event + vlan['eventLog'] + + if 'faultRecord' in vlan: + if vlan['faultRecord'] is not None: + fault_record = fault_record + vlan['faultRecord'] + + if 'faultInst' in vlan: + if vlan['faultInst'] is not None: + fault_inst = fault_inst + vlan['faultInst'] + + if 'auditLog' in vlan: + if vlan['auditLog'] is not None: + audit = audit + vlan['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vlans, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vlans) + + if 'state' in view: + aci_output_handler.print_pool_vlans( + vlans, + title=True + ) + + if 'epg' in view: + aci_output_handler.print_pool_vlans_epg( + vlans, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_pool_vlans_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_pool_vlans_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_pool_vlans_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_pool_vlans_audit_logs( + audit, + when=fault_when, + title=True + ) + + if vlans is None or len(vlans) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/__init__.py b/menu/get/aci/proto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/proto/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/proto/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8a6de46b Binary files /dev/null and b/menu/get/aci/proto/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/arp.cpython-310.pyc b/menu/get/aci/proto/__pycache__/arp.cpython-310.pyc new file mode 100644 index 00000000..c73b2f0f Binary files /dev/null and b/menu/get/aci/proto/__pycache__/arp.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/bfd.cpython-310.pyc b/menu/get/aci/proto/__pycache__/bfd.cpython-310.pyc new file mode 100644 index 00000000..7c25b0d3 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/bfd.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/bgp.cpython-310.pyc b/menu/get/aci/proto/__pycache__/bgp.cpython-310.pyc new file mode 100644 index 00000000..4a7e9174 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/bgp.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/cdp.cpython-310.pyc b/menu/get/aci/proto/__pycache__/cdp.cpython-310.pyc new file mode 100644 index 00000000..17ba7dc3 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/cdp.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/hsrp.cpython-310.pyc b/menu/get/aci/proto/__pycache__/hsrp.cpython-310.pyc new file mode 100644 index 00000000..bc5f8070 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/hsrp.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/ipv4.cpython-310.pyc b/menu/get/aci/proto/__pycache__/ipv4.cpython-310.pyc new file mode 100644 index 00000000..8c202fa6 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/ipv4.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/ipv6.cpython-310.pyc b/menu/get/aci/proto/__pycache__/ipv6.cpython-310.pyc new file mode 100644 index 00000000..0feddaa5 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/ipv6.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/isis.cpython-310.pyc b/menu/get/aci/proto/__pycache__/isis.cpython-310.pyc new file mode 100644 index 00000000..2d943328 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/isis.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/lacp.cpython-310.pyc b/menu/get/aci/proto/__pycache__/lacp.cpython-310.pyc new file mode 100644 index 00000000..e864f0a1 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/lacp.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/lldp.cpython-310.pyc b/menu/get/aci/proto/__pycache__/lldp.cpython-310.pyc new file mode 100644 index 00000000..50a3fdea Binary files /dev/null and b/menu/get/aci/proto/__pycache__/lldp.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/main.cpython-310.pyc b/menu/get/aci/proto/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0473ce07 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/proto/__pycache__/nd.cpython-310.pyc b/menu/get/aci/proto/__pycache__/nd.cpython-310.pyc new file mode 100644 index 00000000..464fb137 Binary files /dev/null and b/menu/get/aci/proto/__pycache__/nd.cpython-310.pyc differ diff --git a/menu/get/aci/proto/arp.py b/menu/get/aci/proto/arp.py new file mode 100644 index 00000000..5a6f5708 --- /dev/null +++ b/menu/get/aci/proto/arp.py @@ -0,0 +1,334 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("arp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--vrf", "vrf_name", default='', callback=validations.empty_string_to_none, help="Filter by VRF name") +@click.option("--mac", "mac_address", default='', callback=validations.empty_string_to_none, help="Filter by MAC address") +@click.option("--ip", "ip_address", default='', callback=validations.validate_ip, help="Filter by IP") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by subnet") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['adj'], help="[inst|dom|adj|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_arp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + vrf_name, + mac_address, + ip_address, + ip_subnet, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol arp""" + + # iserver get aci node proto arp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|dom|adj|fault|hfault|event|diag|all', + 'adj', + [ + 'diag:fault,hfault,event' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + arp_domain_filter = [] + hfault_filter = [] + event_filter = [] + + if vrf_name is not None: + arp_domain_filter.append( + 'name:%s' % (vrf_name) + ) + + if mac_address is not None: + arp_domain_filter.append( + 'mac:%s' % (mac_address) + ) + + if len(ip_address) > 0: + arp_domain_filter.append( + 'ip:%s' % (ip_address) + ) + + if len(ip_subnet) > 0: + arp_domain_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if fault: + arp_domain_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + domain_info = False + adjacency_info = False + interface_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + + if 'dom' in view: + domain_info = True + adjacency_info = True + + if 'adj' in view: + domain_info = True + adjacency_info = True + interface_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + proto_infos = [] + instance = [] + domain = [] + adjacency = [] + interface = [] + fault_record = [] + fault_inst = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_arp( + node_info['podId'], + node_info['id'], + arp_domain_filter=arp_domain_filter, + instance_info=instance_info, + domain_info=domain_info, + adjacency_info=adjacency_info, + interface_info=interface_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + if 'instance' in proto_info: + if proto_info['instance'] is not None: + instance.append( + proto_info['instance'] + ) + + if 'domain' in proto_info: + if proto_info['domain'] is not None: + domain = domain + proto_info['domain'] + + if 'interface' in proto_info: + if proto_info['interface'] is not None: + interface = interface + proto_info['interface'] + + if 'adjacency' in proto_info: + if proto_info['adjacency'] is not None: + adjacency = adjacency + proto_info['adjacency'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + if 'faultRecord' in proto_info: + if proto_info['faultRecord'] is not None: + fault_record = fault_record + proto_info['faultRecord'] + + if 'faultInst' in proto_info: + if proto_info['faultInst'] is not None: + fault_inst = fault_inst + proto_info['faultInst'] + + proto_infos.append( + proto_info + ) + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + proto_infos, + indent=4 + ) + ) + return + + ctx.my_output.json_output(proto_infos) + + if 'inst' in view: + aci_output_handler.print_proto_arp_instances( + instance, + title=True + ) + + if 'dom' in view: + aci_output_handler.print_proto_arp_domains( + domain, + title=True + ) + + if 'adj' in view: + aci_output_handler.print_proto_arp_adjacencies( + adjacency, + title=True + ) + + aci_output_handler.print_proto_arp_interface_summary( + interface, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_arp_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_arp_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_arp_event_logs( + event, + when=fault_when, + title=True + ) + + if len(proto_infos) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/bfd.py b/menu/get/aci/proto/bfd.py new file mode 100644 index 00000000..bf99ba95 --- /dev/null +++ b/menu/get/aci/proto/bfd.py @@ -0,0 +1,328 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("bfd") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--id", "session_id", default='', callback=validations.empty_string_to_none, help="Filter by session id") +@click.option("--intf", "interface_id", default='', callback=validations.empty_string_to_none, help="Filter by interface id") +@click.option("--state", "session_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True, help="Filter by session state") +@click.option("--vrf", "vrf_name", default='', callback=validations.empty_string_to_none, help="Filter by VRF name") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by IP address") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by IP subnet") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['session'], help="[inst|session|fault|hfault|event|diag|all|verbose]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_bfd_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + session_id, + interface_id, + session_state, + vrf_name, + ip_address, + ip_subnet, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol bfd""" + + # iserver get aci node proto bfd + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|session|fault|hfault|event|diag|all|verbose', + 'session', + [ + 'diag:fault,hfault,event' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + bfd_filter = [] + hfault_filter = [] + event_filter = [] + + if session_id is not None: + bfd_filter.append( + 'session_id:%s' % (session_id) + ) + + if interface_id is not None: + bfd_filter.append( + 'interface_id:%s' % (interface_id) + ) + + if session_state is not None: + bfd_filter.append( + 'session_state:%s' % (session_state) + ) + + if vrf_name is not None: + bfd_filter.append( + 'vrf:%s' % (vrf_name) + ) + + if len(ip_address) > 0: + bfd_filter.append( + 'ip:%s' % (ip_address) + ) + + if len(ip_subnet) > 0: + bfd_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + sessions = [] + instances = [] + fault_record = [] + fault_inst = [] + event = [] + + instance_info = False + session_info = False + interface_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + session_info = True + interface_info = True + + if 'session' in view: + session_info = True + + if 'fault' in view: + fault_info = True + session_info = True + + if 'hfault' in view: + hfault_info = True + session_info = True + + if 'event' in view: + event_info = True + session_info = True + + if 'verbose' in view: + instance_info = True + session_info = True + interface_info = True + fault_info = True + hfault_info = True + event_info = True + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_bfd( + node_info['podId'], + node_info['id'], + bfd_filter=bfd_filter, + instance_info=instance_info, + session_info=session_info, + interface_info=interface_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + sessions = sessions + proto_info['sessions'] + + instances.append( + proto_info + ) + + for session in sessions: + if 'eventLog' in session: + if session['eventLog'] is not None: + event = event + session['eventLog'] + + if 'faultInst' in session: + if session['faultInst'] is not None: + fault_inst = fault_inst + session['faultInst'] + + if 'faultRecord' in session: + if session['faultRecord'] is not None: + fault_record = fault_record + session['faultRecord'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + instances, + indent=4 + ) + ) + return + + ctx.my_output.json_output(instances) + + if 'inst' in view: + aci_output_handler.print_proto_bfd_instances( + instances + ) + + if 'session' in view: + aci_output_handler.print_proto_bfd_sessions( + sessions, + title=True + ) + + aci_output_handler.print_proto_bfd_sessions_stats( + sessions, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_bfd_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_bfd_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_bfd_event_logs( + event, + when=fault_when, + title=True + ) + + if 'verbose' in view: + for session in sessions: + aci_output_handler.print_proto_bfd_session( + session, + when=fault_when + ) + + if len(instances) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/bgp.py b/menu/get/aci/proto/bgp.py new file mode 100644 index 00000000..03eef17f --- /dev/null +++ b/menu/get/aci/proto/bgp.py @@ -0,0 +1,396 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("bgp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--asn", "bgp_asn", default='', callback=validations.empty_string_to_none, help="Filter by BGP ASN") +@click.option("--vrf", "bgp_vrf", default='', callback=validations.empty_string_to_none, help="Filter by VRF name") +@click.option("--rtr-ip", "rtr_ip_address", default='', callback=validations.validate_ip, help="Filter by BGP Router IP address") +@click.option("--rtr-subnet", "rtr_ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by BGP Router IP subnet") +@click.option("--nbr-type", "nbr_type", type=click.Choice(['any', 'ibgp', 'ebgp'], case_sensitive=False), default='any', show_default=True, help="Filter by BGP neighbor type") +@click.option("--nbr-ip", "nbr_ip_address", default='', callback=validations.validate_ip, help="Filter by BPG Neighbor IP address") +@click.option("--nbr-subnet", "nbr_ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by BPG Neighbor IP subnet") +@click.option("--nbr-state", "nbr_state", type=click.Choice(['any', 'up', 'down'], case_sensitive=False), default='any', show_default=True, help="Filter by BGP neighbor state") +@click.option("--intf", "source_interface", default='', callback=validations.empty_string_to_none, help="Filter by BGP Neighbor source interface") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['nei'], help="[inst|vrf|nei|peer|route|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_bgp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + bgp_asn, + bgp_vrf, + rtr_ip_address, + rtr_ip_subnet, + nbr_type, + nbr_ip_address, + nbr_ip_subnet, + nbr_state, + source_interface, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol bgp""" + + # iserver get aci node proto bgp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|vrf|nei|peer|route|fault|hfault|event|diag|all', + 'nei', + [ + 'diag:fault,hfault,event' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id + ) + if nodes_info is None: + raise ErrorExit + + bgp_filter = [] + hfault_filter = [] + event_filter = [] + + if bgp_asn is not None: + bgp_filter.append( + 'asn:%s' % (bgp_asn) + ) + + if bgp_vrf is not None: + bgp_filter.append( + 'vrf:%s' % (bgp_vrf) + ) + hfault_filter.append( + 'domainNameT:%s' % (bgp_vrf) + ) + event_filter.append( + 'domainNameT:%s' % (bgp_vrf) + ) + + if len(rtr_ip_address) > 0: + bgp_filter.append( + 'rtr-ip:%s' % (rtr_ip_address) + ) + + if len(rtr_ip_subnet) > 0: + bgp_filter.append( + 'rtr-subnet:%s' % (rtr_ip_subnet) + ) + + if len(nbr_type) > 0: + bgp_filter.append( + 'nbr-type:%s' % (nbr_type) + ) + + if len(nbr_ip_address) > 0: + bgp_filter.append( + 'nbr-ip:%s' % (nbr_ip_address) + ) + + if len(nbr_ip_subnet) > 0: + bgp_filter.append( + 'nbr-subnet:%s' % (nbr_ip_subnet) + ) + + if nbr_state is not None: + bgp_filter.append( + 'state:%s' % (nbr_state) + ) + + if source_interface is not None: + bgp_filter.append( + 'interface:%s' % (source_interface) + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + instance_info = False + domain_info = False + neighbor_info = False + stats_info = False + prefix_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + domain_info = True + neighbor_info = True + + if 'vrf' in view: + instance_info = True + domain_info = True + neighbor_info = True + + if 'nei' in view: + instance_info = True + domain_info = True + neighbor_info = True + stats_info = True + + if 'peer' in view: + instance_info = True + domain_info = True + neighbor_info = True + stats_info = True + + if 'route' in view: + instance_info = True + domain_info = True + neighbor_info = True + stats_info = True + prefix_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + proto_infos = [] + instance = [] + domain = [] + neighbor = [] + route = [] + fault_record = [] + fault_inst = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_bgp( + node_info['podId'], + node_info['id'], + bgp_filter=bgp_filter, + instance_info=instance_info, + domain_info=domain_info, + neighbor_info=neighbor_info, + stats_info=stats_info, + prefix_info=prefix_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + proto_infos.append( + proto_info + ) + + if 'instance' in proto_info: + if proto_info['instance'] is not None: + instance.append( + proto_info['instance'] + ) + + if 'domain' in proto_info: + if proto_info['domain'] is not None: + domain = domain + proto_info['domain'] + + if 'neighbor' in proto_info: + if proto_info['neighbor'] is not None: + neighbor = neighbor + proto_info['neighbor'] + + if prefix_info: + for neighbor_info in proto_info['neighbor']: + if 'route' in neighbor_info: + if neighbor_info['route'] is not None: + route = route + neighbor_info['route'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + if 'faultRecord' in proto_info: + if proto_info['faultRecord'] is not None: + fault_record = fault_record + proto_info['faultRecord'] + + if 'faultInst' in proto_info: + if proto_info['faultInst'] is not None: + fault_inst = fault_inst + proto_info['faultInst'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + proto_infos, + indent=4 + ) + ) + return + + ctx.my_output.json_output(proto_infos) + + if 'inst' in view: + aci_output_handler.print_proto_bgp_instances( + instance, + title=True + ) + + if 'vrf' in view: + aci_output_handler.print_proto_bgp_domains( + domain, + title=True + ) + + if 'nei' in view: + aci_output_handler.print_proto_bgp_neighbors( + neighbor, + title=True + ) + + + if 'peer' in view: + aci_output_handler.print_proto_bgp_peers( + neighbor + ) + + if 'route' in view: + aci_output_handler.print_proto_ipv4_routes( + route + ) + + if 'fault' in view: + aci_output_handler.print_proto_bgp_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_bgp_fault_record( + fault_record, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_bgp_event_logs( + event, + title=True + ) + + ctx.my_output.default('Filter: node, role, asn, vrf, rtr-ip, rtr-subnet, type, nbr-type, nbr-ip, nbr-subnet, nbr-state, intf, severity, when', before_newline=True) + ctx.my_output.default('View: inst, vrf, nei (def), peer, route, fault, hfault, event, diag, all') + + if len(proto_infos) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/cdp.py b/menu/get/aci/proto/cdp.py new file mode 100644 index 00000000..06b78f86 --- /dev/null +++ b/menu/get/aci/proto/cdp.py @@ -0,0 +1,249 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("cdp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--sys", "cdp_system", default='', callback=validations.empty_string_to_none, help="Filter by system name") +@click.option("--platform", "cdp_platform", default='', callback=validations.empty_string_to_none, help="Filter by platform name") +@click.option("--cap", "cdp_cap", default='', callback=validations.empty_string_to_none, help="Filter by capabilities") +@click.option("--intf", "cdp_interface", default='', callback=validations.empty_string_to_none, help="Filter by interface name") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['nei'], help="[inst|intf|nei|event|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_cdp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + cdp_system, + cdp_platform, + cdp_cap, + cdp_interface, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol cdp""" + + # iserver get aci node proto cdp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|intf|nei|event|all', + 'nei', + [] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + cdp_filter = [] + event_filter = [] + + if cdp_system is not None: + cdp_filter.append( + 'system:%s' % (cdp_system) + ) + + if cdp_platform is not None: + cdp_filter.append( + 'platform:%s' % (cdp_platform) + ) + + if cdp_cap is not None: + cdp_filter.append( + 'cap:%s' % (cdp_cap) + ) + + if cdp_interface is not None: + cdp_filter.append( + 'interface:%s' % (cdp_interface) + ) + + if fault_when is not None: + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + instance_info = False + nei_info = False + interface_info = False + event_info = False + + if 'inst' in view: + instance_info = True + interface_info = True + nei_info = True + + if 'intf' in view: + interface_info = True + + if 'nei' in view: + nei_info = True + + if 'event' in view: + event_info = True + + instances = [] + interfaces = [] + neighbors = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_cdp( + node_info['podId'], + node_info['id'], + cdp_filter=cdp_filter, + instance_info=instance_info, + nei_info=nei_info, + interface_info=interface_info, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + instances.append( + proto_info + ) + + if 'interfaces' in proto_info: + if proto_info['interfaces'] is not None: + interfaces = interfaces + proto_info['interfaces'] + + if 'neighbors' in proto_info: + if proto_info['neighbors'] is not None: + neighbors = neighbors + proto_info['neighbors'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + instances, + indent=4 + ) + ) + return + + ctx.my_output.json_output(instances) + + if 'inst' in view: + aci_output_handler.print_proto_cdp_instances( + instances, + title=True + ) + + if 'nei' in view: + aci_output_handler.print_proto_cdp_neighbors( + neighbors, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_proto_cdp_interfaces( + interfaces, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_cdp_event_logs( + event, + title=True + ) + + if len(instances) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/hsrp.py b/menu/get/aci/proto/hsrp.py new file mode 100644 index 00000000..167c5ba1 --- /dev/null +++ b/menu/get/aci/proto/hsrp.py @@ -0,0 +1,282 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("hsrp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--vrf", "hsrp_vrf", default='', callback=validations.empty_string_to_none, help="Filter by VRF name") +@click.option("--id", "hsrp_neighbor", default='', callback=validations.empty_string_to_none, help="Filter by neighbor") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['inst'], help="[inst|dom|intf|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_hsrp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + hsrp_vrf, + hsrp_neighbor, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol hsrp""" + + # iserver get aci node proto hsrp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|dom|intf|fault|hfault|event|diag|all', + 'inst', + [ + 'diag:fault,hfault,event' + ] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + hsrp_filter = [] + hfault_filter = [] + event_filter = [] + + if hsrp_neighbor is not None: + hsrp_filter.append( + 'id:%s' % (hsrp_neighbor) + ) + + if hsrp_vrf is not None: + hsrp_filter.append( + 'vrf:%s' % (hsrp_vrf) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + instance_info = False + domain_info = False + interface_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + domain_info = True + interface_info = True + + if 'dom' in view: + domain_info = True + + if 'intf' in view: + interface_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + instances = [] + interfaces = [] + domains = [] + fault_inst = [] + fault_record = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_hsrp( + node_info['podId'], + node_info['id'], + hsrp_filter=hsrp_filter, + instance_info=instance_info, + domain_info=domain_info, + interface_info=interface_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + instances.append( + proto_info + ) + + if 'interfaces' in proto_info: + if proto_info['interfaces'] is not None: + interfaces = interfaces + proto_info['interfaces'] + + if 'domains' in proto_info: + if proto_info['domains'] is not None: + domains = domains + proto_info['domains'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + if 'faultRecord' in proto_info: + if proto_info['faultRecord'] is not None: + fault_record = fault_record + proto_info['faultRecord'] + + if 'faultInst' in proto_info: + if proto_info['faultInst'] is not None: + fault_inst = fault_inst + proto_info['faultInst'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + instances, + indent=4 + ) + ) + return + + ctx.my_output.json_output(instances) + + if 'inst' in view: + aci_output_handler.print_proto_hsrp_instances( + instances, + title=True + ) + + if 'dom' in view: + aci_output_handler.print_proto_hsrp_domains( + domains, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_proto_hsrp_interfaces( + interfaces, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_hsrp_event_logs( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_hsrp_event_logs( + fault_record, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_hsrp_event_logs( + event, + title=True + ) + + if len(instances) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/ipv4.py b/menu/get/aci/proto/ipv4.py new file mode 100644 index 00000000..02845033 --- /dev/null +++ b/menu/get/aci/proto/ipv4.py @@ -0,0 +1,316 @@ +import sys +import json +import traceback +import copy +import threading +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ipv4") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--vrf", "vrf_name", default='', callback=validations.empty_string_to_none, help="VRF") +@click.option("--type", "route_filter", type=click.Choice(['ibgp', 'ebgp', 'bgp', 'static', 'local', 'direct'], case_sensitive=False), multiple=True) +@click.option("--address", "ip_address_filter", default='', callback=validations.validate_ip, help="IP Address filter") +@click.option("--subnet", "ip_subnet_filter", default='', callback=validations.validate_ip_subnet, help="IP Subnet filter") +@click.option("--longer", "longer_prefixes", is_flag=True, show_default=True, default=False, help="Match longer prefixes") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['route'], help="[inst|dom|route|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_ipv4_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + vrf_name, + route_filter, + ip_address_filter, + ip_subnet_filter, + longer_prefixes, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol ipv4""" + + # iserver get aci node proto ipv4 + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|dom|route|fault|hfault|event|diag|all', + 'route', + [ + 'diag:fault,hfault,event' + ] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + ipv4_filter = [] + hfault_filter = [] + event_filter = [] + + if vrf_name is not None: + ipv4_filter.append( + 'vrf:%s' % (vrf_name) + ) + + if len(route_filter) > 0: + for item in route_filter: + ipv4_filter.append( + item + ) + + if ip_address_filter is not None: + if len(ip_address_filter) > 0: + ipv4_filter.append( + 'ip:%s' % (ip_address_filter) + ) + + if ip_subnet_filter is not None: + if len(ip_subnet_filter) > 0: + if longer_prefixes: + ipv4_filter.append( + 'subnet-longer:%s' % (ip_subnet_filter) + ) + else: + ipv4_filter.append( + 'subnet:%s' % (ip_subnet_filter) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + domain_info = False + route_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + domain_info = True + route_info = True + + if 'dom' in view: + domain_info = True + route_info = True + + if 'route' in view: + domain_info = True + route_info = True + + if 'fault' in view: + fault_info = True + domain_info = True + + if 'hfault' in view: + hfault_info = True + domain_info = True + + if 'event' in view: + event_info = True + domain_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + proto_infos = [] + instance = [] + domain = [] + route = [] + fault_record = [] + fault_inst = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_ipv4( + node_info['podId'], + node_info['id'], + ipv4_filter=ipv4_filter, + instance_info=instance_info, + domain_info=domain_info, + route_info=route_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + proto_infos.append( + proto_info + ) + + if 'instance' in proto_info: + if proto_info['instance'] is not None: + instance.append( + proto_info['instance'] + ) + + if 'domain' in proto_info: + if proto_info['domain'] is not None: + domain = domain + proto_info['domain'] + + if 'route' in proto_info: + if proto_info['route'] is not None: + route = route + proto_info['route'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + if 'faultRecord' in proto_info: + if proto_info['faultRecord'] is not None: + fault_record = fault_record + proto_info['faultRecord'] + + if 'faultInst' in proto_info: + if proto_info['faultInst'] is not None: + fault_inst = fault_inst + proto_info['faultInst'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + proto_infos, + indent=4 + ) + ) + return + + ctx.my_output.json_output(proto_infos) + + if 'inst' in view: + aci_output_handler.print_proto_ipv4_instances( + instance, + title=True + ) + + if 'dom' in view: + aci_output_handler.print_proto_ipv4_domains( + domain, + title=True + ) + + if 'route' in view: + aci_output_handler.print_proto_ipv4_routes( + route, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_ipv4_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_ipv4_fault_record( + fault_record, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_ipv4_event_logs( + event, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/ipv6.py b/menu/get/aci/proto/ipv6.py new file mode 100644 index 00000000..95421ade --- /dev/null +++ b/menu/get/aci/proto/ipv6.py @@ -0,0 +1,316 @@ +import sys +import json +import traceback +import copy +import threading +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ipv6") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--vrf", "vrf_name", default='', callback=validations.empty_string_to_none, help="VRF") +@click.option("--type", "route_filter", type=click.Choice(['ibgp', 'ebgp', 'bgp', 'static', 'local', 'direct'], case_sensitive=False), multiple=True) +@click.option("--address", "ip_address_filter", default='', callback=validations.validate_ip, help="IP Address filter") +@click.option("--subnet", "ip_subnet_filter", default='', callback=validations.validate_ip_subnet, help="IP Subnet filter") +@click.option("--longer", "longer_prefixes", is_flag=True, show_default=True, default=False, help="Match longer prefixes") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['route'], help="[inst|dom|route|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_ipv6_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + vrf_name, + route_filter, + ip_address_filter, + ip_subnet_filter, + longer_prefixes, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol ipv6""" + + # iserver get aci node proto ipv6 + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|dom|route|fault|hfault|event|diag|all', + 'route', + [ + 'diag:fault,hfault,event' + ] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + ipv6_filter = [] + hfault_filter = [] + event_filter = [] + + if vrf_name is not None: + ipv6_filter.append( + 'vrf:%s' % (vrf_name) + ) + + if len(route_filter) > 0: + for item in route_filter: + ipv6_filter.append( + item + ) + + if ip_address_filter is not None: + if len(ip_address_filter) > 0: + ipv6_filter.append( + 'ip:%s' % (ip_address_filter) + ) + + if ip_subnet_filter is not None: + if len(ip_subnet_filter) > 0: + if longer_prefixes: + ipv6_filter.append( + 'subnet-longer:%s' % (ip_subnet_filter) + ) + else: + ipv6_filter.append( + 'subnet:%s' % (ip_subnet_filter) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + domain_info = False + route_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + domain_info = True + route_info = True + + if 'dom' in view: + domain_info = True + route_info = True + + if 'route' in view: + domain_info = True + route_info = True + + if 'fault' in view: + fault_info = True + domain_info = True + + if 'hfault' in view: + hfault_info = True + domain_info = True + + if 'event' in view: + event_info = True + domain_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + proto_infos = [] + instance = [] + domain = [] + route = [] + fault_record = [] + fault_inst = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_ipv6( + node_info['podId'], + node_info['id'], + ipv6_filter=ipv6_filter, + instance_info=instance_info, + domain_info=domain_info, + route_info=route_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + proto_infos.append( + proto_info + ) + + if 'instance' in proto_info: + if proto_info['instance'] is not None: + instance.append( + proto_info['instance'] + ) + + if 'domain' in proto_info: + if proto_info['domain'] is not None: + domain = domain + proto_info['domain'] + + if 'route' in proto_info: + if proto_info['route'] is not None: + route = route + proto_info['route'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + if 'faultRecord' in proto_info: + if proto_info['faultRecord'] is not None: + fault_record = fault_record + proto_info['faultRecord'] + + if 'faultInst' in proto_info: + if proto_info['faultInst'] is not None: + fault_inst = fault_inst + proto_info['faultInst'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + proto_infos, + indent=4 + ) + ) + return + + ctx.my_output.json_output(proto_infos) + + if 'inst' in view: + aci_output_handler.print_proto_ipv6_instances( + instance, + title=True + ) + + if 'dom' in view: + aci_output_handler.print_proto_ipv6_domains( + domain, + title=True + ) + + if 'route' in view: + aci_output_handler.print_proto_ipv6_routes( + route, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_ipv6_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_ipv6_fault_record( + fault_record, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_ipv6_event_logs( + event, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/isis.py b/menu/get/aci/proto/isis.py new file mode 100644 index 00000000..efa728f0 --- /dev/null +++ b/menu/get/aci/proto/isis.py @@ -0,0 +1,356 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("isis") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--domain", "domain_name", default='', callback=validations.empty_string_to_none, help="Filter by domain name") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['inst'], help="[inst|intf|lsp|nei|route|tree|tun|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_isis_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + domain_name, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol isis""" + + # iserver get aci node proto isis + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|intf|lsp|nei|route|tree|tun|fault|hfault|event|diag|all', + 'inst', + [ + 'diag:fault,hfault,event' + ] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + isis_domain_filter = [] + hfault_filter = [] + event_filter = [] + + if domain_name is not None: + isis_domain_filter.append( + 'name:%s' % (domain_name) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + domain_info = False + intf_info = False + lsp_info = False + neighbor_info = False + route_info = False + tree_info = False + tunnel_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + domain_info = True + + if 'intf' in view: + instance_info = True + domain_info = True + intf_info = True + + if 'lsp' in view: + instance_info = True + domain_info = True + lsp_info = True + + if 'nei' in view: + instance_info = True + domain_info = True + neighbor_info = True + + if 'route' in view: + instance_info = True + domain_info = True + route_info = True + + if 'tree' in view: + instance_info = True + domain_info = True + tree_info = True + + if 'tunnel' in view: + instance_info = True + domain_info = True + tunnel_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + instances = [] + domains = [] + intf = [] + lsp = [] + neighbor = [] + route = [] + tree = [] + tunnels = [] + fault_record = [] + fault_inst = [] + event = [] + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + for node_info in nodes_info: + node_instance_info = apic_handler.get_protocol_isis( + node_info['podId'], + node_info['id'], + isis_domain_filter=isis_domain_filter, + instance_info=instance_info, + domain_info=domain_info, + interface_info=intf_info, + lsp_info=lsp_info, + neighbor_info=neighbor_info, + route_info=route_info, + tree_info=tree_info, + tunnel_info=tunnel_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if node_instance_info is None: + continue + + instances.append( + node_instance_info + ) + + if domain_info: + domains = domains + node_instance_info['domain'] + + if intf_info: + for domain_info in node_instance_info['domain']: + intf = intf + domain_info['interface'] + + if lsp_info: + for domain_info in node_instance_info['domain']: + lsp = lsp + domain_info['lsp'] + + if neighbor_info: + for domain_info in node_instance_info['domain']: + neighbor = neighbor + domain_info['neighbor'] + + if route_info: + for domain_info in node_instance_info['domain']: + route = route + domain_info['route'] + + if tree_info: + for domain_info in node_instance_info['domain']: + tree = tree + domain_info['tree'] + + if tunnel_info: + for domain_info in node_instance_info['domain']: + tunnels = tunnels + domain_info['tunnel'] + + if 'eventLog' in node_instance_info: + if node_instance_info['eventLog'] is not None: + event = event + node_instance_info['eventLog'] + + if 'faultRecord' in node_instance_info: + if node_instance_info['faultRecord'] is not None: + fault_record = fault_record + node_instance_info['faultRecord'] + + if 'faultInst' in node_instance_info: + if node_instance_info['faultInst'] is not None: + fault_inst = fault_inst + node_instance_info['faultInst'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + instances, + indent=4 + ) + ) + return + + ctx.my_output.json_output(instances) + + if 'inst' in view: + aci_output_handler.print_proto_isis_instances( + instances, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_proto_isis_interfaces( + intf, + title=True + ) + + if 'lsp' in view: + aci_output_handler.print_proto_isis_lsps( + lsp, + title=True + ) + + if 'neighbor' in view: + aci_output_handler.print_proto_isis_neighbors( + neighbor, + title=True + ) + + if 'route' in view: + aci_output_handler.print_proto_isis_routes( + route, + title=True + ) + + if 'tree' in view: + aci_output_handler.print_proto_isis_trees( + tree, + title=True + ) + + if 'tunnel' in view: + aci_output_handler.print_proto_isis_tunnels( + tunnels, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_isis_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_isis_fault_record( + fault_record, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_isis_event_logs( + event, + title=True + ) + + if len(instances) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/lacp.py b/menu/get/aci/proto/lacp.py new file mode 100644 index 00000000..e73ef105 --- /dev/null +++ b/menu/get/aci/proto/lacp.py @@ -0,0 +1,213 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("lacp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['intf'], help="[inst|intf|stats|event|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_lacp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + mac, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol lacp""" + + # iserver get aci node proto lacp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|intf|stats|event|all', + 'intf', + [] + ) + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + event_filter = [] + if fault_when is not None: + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + interface_info = False + event_info = False + + if 'inst' in view: + instance_info = True + interface_info = True + + if 'intf' in view: + instance_info = True + interface_info = True + + if 'stats' in view: + instance_info = True + interface_info = True + + if 'event' in view: + event_info = True + + instances = [] + interfaces = [] + event = [] + + interface_filter = [] + if mac is not None: + interface_filter.append( + 'mac:%s' % (mac) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_lacp( + node_info['podId'], + node_info['id'], + instance_info=instance_info, + interface_info=interface_info, + interface_filter=interface_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + instances.append( + proto_info + ) + + if 'interfaces' in proto_info: + if proto_info['interfaces'] is not None: + interfaces = interfaces + proto_info['interfaces'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + instances, + indent=4 + ) + ) + return + + ctx.my_output.json_output(instances) + + if 'inst' in view: + aci_output_handler.print_proto_lacp_instances( + instances, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_proto_lacp_interfaces( + interfaces, + title=True + ) + + if 'stats' in view: + aci_output_handler.print_proto_lacp_interfaces_stats( + interfaces, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_lacp_event_logs( + event, + title=True + ) + + if len(instances) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/lldp.py b/menu/get/aci/proto/lldp.py new file mode 100644 index 00000000..0c224b38 --- /dev/null +++ b/menu/get/aci/proto/lldp.py @@ -0,0 +1,307 @@ +import sys +import json +import threading +import traceback +import click + +from lib import context +from lib import ip_helper +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("lldp") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--device", default='', callback=validations.empty_string_to_none, help="Filter neighbor by device name") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter neighbor by mac address") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['nei'], help="[inst|nei|stats|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_lldp_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + device, + mac, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol lldp""" + + # iserver get aci node proto lldp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|nei|stats|fault|hfault|event|diag|all', + 'nei', + [ + 'diag:fault,hfault,event' + ] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + context_handler = context.Context(log_id=ctx.run_id) + lldp_context = None + if controller is not None: + lldp_context = context_handler.initialize_apic( + controller['name'] + ) + + adjacency_filter = [] + hfault_filter = [] + event_filter = [] + + if device is not None: + adjacency_filter.append( + 'device:%s' % (device) + ) + + if mac is not None: + adjacency_filter.append( + 'mac:%s' % (mac) + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + stats_info = False + adjacency_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + stats_info = True + adjacency_info = True + + if 'stats' in view: + stats_info = True + + if 'nei' in view: + adjacency_info = True + + if 'fault' in view: + fault_info = True + adjacency_info = True + + if 'hfault' in view: + hfault_info = True + adjacency_info = True + + if 'event' in view: + event_info = True + adjacency_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + proto_infos = [] + instance = [] + stats = [] + adjacency = [] + fault_record = [] + fault_inst = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_lldp( + node_info['podId'], + node_info['id'], + adjacency_filter=adjacency_filter, + instance_info=instance_info, + stats_info=stats_info, + adjacency_info=adjacency_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + proto_infos.append( + proto_info + ) + + if instance_info and proto_info['instance'] is not None: + instance.append( + proto_info['instance'] + ) + + if stats_info and proto_info['stats'] is not None: + stats.append( + proto_info['stats'] + ) + + if adjacency_info and proto_info['adjacency'] is not None: + adjacency = adjacency + proto_info['adjacency'] + lldp_context = apic_handler.add_protocol_lldp_adjacency_context( + lldp_context, + adjacency + ) + + for lldp_adjacency_info in proto_info['adjacency']: + if 'eventLog' in lldp_adjacency_info: + if lldp_adjacency_info['eventLog'] is not None: + event = event + lldp_adjacency_info['eventLog'] + + if 'faultInst' in lldp_adjacency_info: + if lldp_adjacency_info['faultInst'] is not None: + fault_inst = fault_inst + lldp_adjacency_info['faultInst'] + + if 'faultRecord' in lldp_adjacency_info: + if lldp_adjacency_info['faultRecord'] is not None: + fault_record = fault_record + lldp_adjacency_info['faultRecord'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + proto_infos, + indent=4 + ) + ) + return + + ctx.my_output.json_output(proto_infos) + + if 'inst' in view: + aci_output_handler.print_proto_lldp_instance( + instance, + title=True + ) + + if 'stats' in view: + aci_output_handler.print_proto_lldp_instances_stats( + stats, + title=True + ) + + if 'nei' in view: + aci_output_handler.print_lldp_adjacency_endpoints( + adjacency, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_lldp_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_lldp_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_lldp_event_logs( + event, + when=fault_when, + title=True + ) + + if context_handler.is_interface_defined(lldp_context): + success = context_handler.set( + 'lldp', + lldp_context + ) + if success: + ctx.my_output.default('Interface context: lldp') + + if len(instance) == 0 and len(stats) == 0 and len(adjacency) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/proto/main.py b/menu/get/aci/proto/main.py new file mode 100644 index 00000000..24720922 --- /dev/null +++ b/menu/get/aci/proto/main.py @@ -0,0 +1,36 @@ +import click + +from menu.get.aci.proto.arp import get_aci_node_proto_arp_command +from menu.get.aci.proto.bfd import get_aci_node_proto_bfd_command +from menu.get.aci.proto.bgp import get_aci_node_proto_bgp_command +from menu.get.aci.proto.cdp import get_aci_node_proto_cdp_command +from menu.get.aci.proto.hsrp import get_aci_node_proto_hsrp_command +from menu.get.aci.proto.ipv4 import get_aci_node_proto_ipv4_command +from menu.get.aci.proto.ipv6 import get_aci_node_proto_ipv6_command +from menu.get.aci.proto.isis import get_aci_node_proto_isis_command +from menu.get.aci.proto.lacp import get_aci_node_proto_lacp_command +from menu.get.aci.proto.lldp import get_aci_node_proto_lldp_command +from menu.get.aci.proto.nd import get_aci_node_proto_nd_command + + +class Failure(Exception): + pass + + +@click.group("proto") +@click.pass_obj +def get_aci_node_proto_menu(ctx): + """Get aci node protocol commands""" + + +get_aci_node_proto_menu.add_command(get_aci_node_proto_arp_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_bfd_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_bgp_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_cdp_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_hsrp_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_ipv4_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_ipv6_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_isis_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_lacp_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_lldp_command) +get_aci_node_proto_menu.add_command(get_aci_node_proto_nd_command) diff --git a/menu/get/aci/proto/nd.py b/menu/get/aci/proto/nd.py new file mode 100644 index 00000000..d32b60bb --- /dev/null +++ b/menu/get/aci/proto/nd.py @@ -0,0 +1,307 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("nd") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--pod", "pod_id", default='', callback=validations.empty_string_to_none, help="Pod ID") +@click.option("--node", "node_names", multiple=True, help="Node name patterns") +@click.option("--role", "node_role", type=click.Choice(['any', 'leaf', 'spine'], case_sensitive=False), default='any', show_default=True) +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['nei'], help="[inst|dom|nei|intf|fault|hfault|event|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_node_proto_nd_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + pod_id, + node_names, + node_role, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci node protocol nd""" + + # iserver get aci node proto nd + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'inst|dom|nei|intf|fault|hfault|event|diag|all', + 'nei', + [ + 'diag:fault,hfault,event' + ] + ) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + node_role, + pod_id=pod_id, + ) + if nodes_info is None: + raise ErrorExit + + hfault_filter = [] + event_filter = [] + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + + instance_info = False + domain_info = False + neighbor_info = False + interface_info = False + fault_info = False + hfault_info = False + event_info = False + + if 'inst' in view: + instance_info = True + + if 'dom' in view: + instance_info = True + domain_info = True + neighbor_info = True + + if 'nei' in view: + instance_info = True + domain_info = True + neighbor_info = True + interface_info = True + + if 'intf' in view: + instance_info = True + domain_info = True + neighbor_info = True + interface_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + proto_infos = [] + instance = [] + domain = [] + neighbor = [] + interface = [] + fault_record = [] + fault_inst = [] + event = [] + + for node_info in nodes_info: + proto_info = apic_handler.get_protocol_nd( + node_info['podId'], + node_info['id'], + instance_info=instance_info, + domain_info=domain_info, + neighbor_info=neighbor_info, + interface_info=interface_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter + ) + + if proto_info is None: + continue + + proto_infos.append( + proto_info + ) + + if 'instance' in proto_info: + if proto_info['instance'] is not None: + instance.append( + proto_info['instance'] + ) + + if 'domain' in proto_info: + if proto_info['domain'] is not None: + domain = domain + proto_info['domain'] + + if 'interface' in proto_info: + if proto_info['interface'] is not None: + interface = interface + proto_info['interface'] + + if 'neighbor' in proto_info: + if proto_info['neighbor'] is not None: + neighbor = neighbor + proto_info['neighbor'] + + if 'eventLog' in proto_info: + if proto_info['eventLog'] is not None: + event = event + proto_info['eventLog'] + + if 'faultRecord' in proto_info: + if proto_info['faultRecord'] is not None: + fault_record = fault_record + proto_info['faultRecord'] + + if 'faultInst' in proto_info: + if proto_info['faultInst'] is not None: + fault_inst = fault_inst + proto_info['faultInst'] + + event = sorted( + event, + key=lambda i: i['timestamp'] + ) + + fault_inst = sorted( + fault_inst, + key=lambda i: i['timestamp'] + ) + + fault_record = sorted( + fault_record, + key=lambda i: i['timestamp'] + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + proto_infos, + indent=4 + ) + ) + return + + ctx.my_output.json_output(proto_infos) + + if 'inst' in view: + aci_output_handler.print_proto_nd_instances( + instance, + title=True + ) + + if 'dom' in view: + aci_output_handler.print_proto_nd_domains( + domain, + title=True + ) + + if 'nei' in view: + aci_output_handler.print_proto_nd_neighbors( + neighbor, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_proto_nd_interfaces( + interface, + title=True + ) + + aci_output_handler.print_proto_nd_interface_stats( + interface, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_proto_nd_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_proto_nd_fault_record( + fault_record, + title=True + ) + + if 'event' in view: + aci_output_handler.print_proto_nd_event_logs( + event, + title=True + ) + + if len(proto_infos) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/psirt.py b/menu/get/aci/psirt.py new file mode 100644 index 00000000..f9073fe9 --- /dev/null +++ b/menu/get/aci/psirt.py @@ -0,0 +1,164 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output +from lib.psirt import main as psirt +from lib.psirt import output as psirt_output +from lib.psirt import settings + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("psirt") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_any_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_psirt_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + output, + no_cache, + devel + ): + """Get aci psirt""" + + # iserver get aci psirt + + ctx.developer = devel + ctx.output = output + + try: + settings_handler = settings.PsirtSettings(log_id=ctx.run_id) + psirt_settings = settings_handler.get_psirt_settings() + if psirt_settings is None: + ctx.my_output.error('Failed to get psirt api settings') + raise ErrorExit + + if not psirt_settings['enabled']: + ctx.my_output.error('Psirt disabled') + raise ErrorExit + + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handlers = validations.validate_apic_controllers( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handlers is None: + raise ErrorExit + + if len(apic_handlers) == 1: + aci_output_handler.set_apic_off() + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + node_filter = [] + node_filter.append( + 'role:leaf' + ) + + advisories = {} + apic_versions = {} + + for apic_handler in apic_handlers: + apic_nodes = apic_handler['handler'].get_nodes( + node_filter=node_filter + ) + if apic_nodes is None: + continue + + apic_version = None + for node in apic_nodes: + apic_version = node['version'] + if apic_version.startswith('n9000-'): + apic_version = apic_version[6:] + break + + if apic_version is None: + ctx.my_output.error( + 'Failed to get APIC software version' + ) + raise ErrorExit + + apic_versions[apic_handler['name']] = apic_version + + psirt_object_filter = [] + psirt_object_filter.append( + 'product:*aci*' + ) + + psirt_object_filter.append( + 'version:%s' % (apic_version) + ) + + psirt_handler = psirt.Psirt(psirt_settings['key'], psirt_settings['secret'], log_id=ctx.run_id) + advisories[apic_handler['name']] = psirt_handler.get_advisories( + psirt_object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + advisories, + indent=4 + ) + ) + return + + ctx.my_output.json_output(advisories) + + psirt_output_handler = psirt_output.PsirtOutput(log_id=ctx.run_id) + for apic_name in advisories: + ctx.my_output.default('Advisory - Apic: %s version %s' % (apic_name, apic_versions[apic_name]), underline=True, before_newline=True) + psirt_output_handler.print_advisory_version( + advisories[apic_name], + title=False + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/server.py b/menu/get/aci/server.py new file mode 100644 index 00000000..eab10d41 --- /dev/null +++ b/menu/get/aci/server.py @@ -0,0 +1,176 @@ +import sys +import json +import threading +import traceback +import click + +from lib.intersight import compute +from lib.intersight import compute_output +from lib import context + +from menu import defaults +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--node", "node_names", multiple=True, default=['any'], help="Node name patterns") +@click.option("--address", "server_ip", callback=validations.validate_ips, multiple=True, help="Server IP") +@click.option("--view", "-v", default=['state'], help="['state']", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_server_command( + ctx, + iaccount, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + node_names, + server_ip, + view, + output, + no_cache, + devel + ): + """Get server connectivity information""" + + # iserver get aci server + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + + try: + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + node_names, + 'any', + pod_id='' + ) + if nodes_info is None: + raise ErrorExit + + if output != 'json': + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + match_rules = compute_handler.get_mo_match_rules( + ip_filter=server_ip + ) + servers_mo = compute_handler.get_mo( + match_rules=match_rules, + include_rack=True, + include_blade=True + ) + if len(servers_mo) == 0: + ctx.busy = False + ctx.my_output.error('No server found') + raise ErrorExit + + settings = {} + settings['net'] = True + + servers_info = compute_handler.get_info( + servers_mo, + settings, + None, + 0 + ) + + servers_connectivity_info = [] + for server_info in servers_info: + servers_connectivity_info.append( + apic_handler.get_server_connectivity( + server_info, + nodes_info + ) + ) + + context_handler = context.Context(log_id=ctx.run_id) + context_handler.set( + 'phy', + apic_handler.get_context_server_connectivity_interface(servers_connectivity_info) + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + servers_connectivity_info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(servers_connectivity_info) + + for server_connectivity_info in servers_connectivity_info: + compute_output_handler.print_summary_table( + [server_connectivity_info], + title=True + ) + compute_output_handler.print_aci( + server_connectivity_info, + title=True + ) + + ctx.my_output.default('Ctx: phy', before_newline=True) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/system/__init__.py b/menu/get/aci/system/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/aci/system/__pycache__/__init__.cpython-310.pyc b/menu/get/aci/system/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d2fb6095 Binary files /dev/null and b/menu/get/aci/system/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/aci/system/__pycache__/fault.cpython-310.pyc b/menu/get/aci/system/__pycache__/fault.cpython-310.pyc new file mode 100644 index 00000000..7d5bff97 Binary files /dev/null and b/menu/get/aci/system/__pycache__/fault.cpython-310.pyc differ diff --git a/menu/get/aci/system/__pycache__/main.cpython-310.pyc b/menu/get/aci/system/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..9aab88de Binary files /dev/null and b/menu/get/aci/system/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/aci/system/fault.py b/menu/get/aci/system/fault.py new file mode 100644 index 00000000..72147e14 --- /dev/null +++ b/menu/get/aci/system/fault.py @@ -0,0 +1,188 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("fault") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter by severity") +@click.option("--domain", "fault_domain", type=click.Choice(['any', 'access', 'apps', 'ext', 'fw', 'infra', 'mgmt', 'sec', 'tenant'], case_sensitive=False), default='any', show_default=True, help="Filter by domain") +@click.option("--type", "fault_type", type=click.Choice(['any', 'env', 'comm', 'config', 'oper'], case_sensitive=False), default='any', show_default=True, help="Filter by type") +@click.option("--code", "fault_code", default='', callback=validations.empty_string_to_none, help="Filter by code") +@click.option("--cause", "fault_cause", default='', callback=validations.empty_string_to_none, help="Filter by cause") +@click.option("--object", "fault_dn", default='', callback=validations.empty_string_to_none, help="Filter by object") +@click.option("--desc", "fault_description", default='', callback=validations.empty_string_to_none, help="Filter by description") +@click.option("--view", "-v", type=click.Choice(['summary', 'domain', 'type', 'verbose'], case_sensitive=False), multiple=False, default='summary', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_system_fault_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + fault_severity, + fault_domain, + fault_type, + fault_code, + fault_cause, + fault_dn, + fault_description, + view, + output, + no_cache, + devel + ): + """Get aci system fault""" + + # iserver get aci system fault + + ctx.developer = devel + ctx.output = output + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + system_fault_filter = [] + + if fault_severity != 'any': + system_fault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_domain != 'any': + system_fault_filter.append( + 'domain:%s' % (fault_domain) + ) + + if fault_type != 'any': + system_fault_filter.append( + 'type:%s' % (fault_type) + ) + + if fault_code is not None: + system_fault_filter.append( + 'code:%s' % (fault_code) + ) + + if fault_cause is not None: + system_fault_filter.append( + 'cause:%s' % (fault_cause) + ) + + if fault_dn is not None: + system_fault_filter.append( + 'dn:%s' % (fault_dn) + ) + + if fault_description is not None: + system_fault_filter.append( + 'description:%s' % (fault_description) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if view == 'summary': + faults = apic_handler.get_system_faults_summary( + system_fault_filter=system_fault_filter + ) + + if view == 'domain': + faults = apic_handler.get_system_faults_domain_count( + system_fault_filter=system_fault_filter + ) + + if view == 'type': + faults = apic_handler.get_system_faults_type_count( + system_fault_filter=system_fault_filter + ) + + if view == 'verbose': + faults = apic_handler.get_system_faults( + system_fault_filter=system_fault_filter + ) + + ctx.busy = False + + if faults is None or len(faults) == 0: + raise ErrorExit + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + faults, + indent=4 + ) + ) + return + + ctx.my_output.json_output(faults) + + if view == 'summary': + aci_output_handler.print_system_faults_summary( + faults, + title=True + ) + + if view == 'domain': + aci_output_handler.print_system_faults_domain_count( + faults, + title=True + ) + + if view == 'type': + aci_output_handler.print_system_faults_type_count( + faults, + title=True + ) + + if view == 'verbose': + aci_output_handler.print_system_faults( + faults, + title=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/system/main.py b/menu/get/aci/system/main.py new file mode 100644 index 00000000..f863387f --- /dev/null +++ b/menu/get/aci/system/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.aci.system.fault import get_aci_system_fault_command + + +class Failure(Exception): + pass + + +@click.group("system") +@click.pass_obj +def get_aci_system_menu(ctx): + """Get aci system commands""" + + +get_aci_system_menu.add_command(get_aci_system_fault_command) diff --git a/menu/get/aci/tenant.py b/menu/get/aci/tenant.py new file mode 100644 index 00000000..6146c3b4 --- /dev/null +++ b/menu/get/aci/tenant.py @@ -0,0 +1,245 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("tenant") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|count|fault|hfault|event|audit|diag|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_tenant_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci tenant""" + + # iserver get aci tenant + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|count|fault|hfault|event|audit|diag|all', + 'state', + [ + 'diag:event,fault,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + tenant_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + if name is not None: + tenant_filter.append( + 'name:%s' % (name) + ) + + if fault: + tenant_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + count_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'count' in view: + count_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + tenants = apic_handler.get_tenants( + tenant_filter=tenant_filter, + count_info=count_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for tenant in tenants: + if 'eventLog' in tenant: + if tenant['eventLog'] is not None: + event = event + tenant['eventLog'] + + if 'faultRecord' in tenant: + if tenant['faultRecord'] is not None: + fault_record = fault_record + tenant['faultRecord'] + + if 'faultInst' in tenant: + if tenant['faultInst'] is not None: + fault_inst = fault_inst + tenant['faultInst'] + + if 'auditLog' in tenant: + if tenant['auditLog'] is not None: + audit = audit + tenant['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + tenants, + indent=4 + ) + ) + return + + ctx.my_output.json_output(tenants) + + if 'state' in view: + aci_output_handler.print_tenants( + tenants, + title=True + ) + + if 'count' in view: + aci_output_handler.print_tenants_count( + tenants, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_tenants_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_tenants_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_tenants_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_tenants_audit_logs( + audit, + when=fault_when, + title=True + ) + + if tenants is None or len(tenants) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/aci/vrf.py b/menu/get/aci/vrf.py new file mode 100644 index 00000000..54bf3eb4 --- /dev/null +++ b/menu/get/aci/vrf.py @@ -0,0 +1,357 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vrf") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--name", "vrf_name", default='', callback=validations.validate_apic_tenant_name, help="VRF name") +@click.option("--tenant", "tenant_name", default='', callback=validations.empty_string_to_none, help="Tenant name") +@click.option("--pctag", default='', callback=validations.empty_string_to_none, help="Filter by pcTag") +@click.option("--vnid", default='', callback=validations.empty_string_to_none, help="Filter by vnid") +@click.option("--bd", "bd_name", default='', callback=validations.empty_string_to_none, help="Filter by bridge domain name") +@click.option("--epg", "epg_name", default='', callback=validations.empty_string_to_none, help="Filter by epg name") +@click.option("--address", "ip_address", default='', callback=validations.validate_ip, help="Filter by subnet with IP") +@click.option("--subnet", "ip_subnet", default='', callback=validations.validate_ip_subnet, help="Filter by subnet within subnet") +@click.option("--l3out", "l3out_name", default='', callback=validations.empty_string_to_none, help="Filter by l3out name") +@click.option("--fault", "fault", is_flag=True, show_default=True, default=False, help="Filter with faults") +@click.option("--severity", "fault_severity", type=click.Choice(['any', 'critical', 'major', 'minor', 'warning'], case_sensitive=False), default='any', show_default=True, help="Filter faults by severity") +@click.option("--when", "fault_when", default='7d', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--view", "-v", default=['state'], help="[state|route|prop|node|intf|fault|hfault|event|audit|diag|all|verbose]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_aci_vrf_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + vrf_name, + tenant_name, + pctag, + vnid, + bd_name, + epg_name, + ip_address, + ip_subnet, + l3out_name, + fault, + fault_severity, + fault_when, + view, + output, + no_cache, + devel + ): + """Get aci vrfs""" + + # iserver get aci vrfs + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|route|prop|node|intf|fault|hfault|event|audit|diag|all|verbose', + 'state', + [ + 'diag:fault,hfault,event,audit' + ] + ) + if view is None: + sys.exit(1) + + try: + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + no_cache=no_cache + ) + if apic_handler is None: + raise ErrorExit + + vrf_filter = [] + hfault_filter = [] + event_filter = [] + audit_filter = [] + + tenant_filtered = False + if vrf_name is not None: + vrf_filter.append( + 'name:%s' % (vrf_name['name']) + ) + + if vrf_name['tenant'] is not None: + tenant_filtered = True + vrf_filter.append( + 'tenant:%s' % (vrf_name['tenant']) + ) + + if tenant_name is not None: + if tenant_filtered: + ctx.my_output.error( + 'Define tenant in one place' + ) + raise ErrorExit + + vrf_filter.append( + 'tenant:%s' % (tenant_name) + ) + + if bd_name is not None: + vrf_filter.append( + 'bd:%s' % (bd_name) + ) + + if epg_name is not None: + vrf_filter.append( + 'epg:%s' % (epg_name) + ) + + if pctag is not None: + vrf_filter.append( + 'pctag:%s' % (pctag) + ) + + if vnid is not None: + vrf_filter.append( + 'vnid:%s' % (vnid) + ) + + if len(ip_subnet) > 0: + vrf_filter.append( + 'subnet:%s' % (ip_subnet) + ) + + if len(ip_address) > 0: + vrf_filter.append( + 'ip:%s' % (ip_address) + ) + + if l3out_name is not None: + vrf_filter.append( + 'l3out:%s' % (l3out_name) + ) + + if fault: + vrf_filter.append( + 'fault:any' + ) + + if fault_severity != 'any': + hfault_filter.append( + 'severity:%s' % (fault_severity) + ) + + if fault_when is not None: + hfault_filter.append( + 'timestamp:%s' % (fault_when) + ) + event_filter.append( + 'timestamp:%s' % (fault_when) + ) + audit_filter.append( + 'timestamp:%s' % (fault_when) + ) + + bridge_domain_info = True + epg_info = True + l3out_info = True + route_info = False + node_info = False + fault_info = False + hfault_info = False + event_info = False + audit_info = False + + if 'route' in view: + route_info = True + + if 'node' in view: + node_info = True + + if 'intf' in view: + node_info = True + + if 'fault' in view: + fault_info = True + + if 'hfault' in view: + hfault_info = True + + if 'event' in view: + event_info = True + + if 'audit' in view: + audit_info = True + + if 'verbose' in view: + route_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + vrfs = apic_handler.get_vrfs( + vrf_filter=vrf_filter, + bridge_domain_info=bridge_domain_info, + epg_info=epg_info, + l3out_info=l3out_info, + route_info=route_info, + node_info=node_info, + fault_info=fault_info, + hfault_info=hfault_info, + hfault_filter=hfault_filter, + event_info=event_info, + event_filter=event_filter, + audit_info=audit_info, + audit_filter=audit_filter + ) + + event = [] + fault_record = [] + fault_inst = [] + audit = [] + + for vrf in vrfs: + if 'eventLog' in vrf: + if vrf['eventLog'] is not None: + event = event + vrf['eventLog'] + + if 'faultRecord' in vrf: + if vrf['faultRecord'] is not None: + fault_record = fault_record + vrf['faultRecord'] + + if 'faultInst' in vrf: + if vrf['faultInst'] is not None: + fault_inst = fault_inst + vrf['faultInst'] + + if 'auditLog' in vrf: + if vrf['auditLog'] is not None: + audit = audit + vrf['auditLog'] + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vrfs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vrfs) + + if 'state' in view: + aci_output_handler.print_vrfs( + vrfs, + title=True + ) + + if 'prop' in view: + aci_output_handler.print_vrfs_properties( + vrfs, + title=True + ) + + if 'route' in view: + for vrf in vrfs: + aci_output_handler.print_vrf_v4_route( + vrf, + title=True + ) + + if 'node' in view: + aci_output_handler.print_vrfs_node( + vrfs, + title=True + ) + + if 'intf' in view: + aci_output_handler.print_vrfs_interface( + vrfs, + title=True + ) + + if 'fault' in view: + aci_output_handler.print_vrfs_fault_inst( + fault_inst, + title=True + ) + + if 'hfault' in view: + aci_output_handler.print_vrfs_fault_record( + fault_record, + when=fault_when, + title=True + ) + + if 'event' in view: + aci_output_handler.print_vrfs_event_logs( + event, + when=fault_when, + title=True + ) + + if 'audit' in view: + aci_output_handler.print_vrfs_audit_logs( + audit, + when=fault_when, + title=True + ) + + if 'verbose' in view: + aci_output_handler.print_vrfs( + vrfs + ) + for vrf in vrfs: + aci_output_handler.print_vrf(vrf) + + if vrfs is None or len(vrfs) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/chassis.py b/menu/get/chassis.py new file mode 100644 index 00000000..2ba7d602 --- /dev/null +++ b/menu/get/chassis.py @@ -0,0 +1,308 @@ +import json +import sys +import csv +import traceback +import click + +from lib.intersight import settings as intersight_settings +from lib.intersight import chassis +from lib.intersight import chassis_output + +from menu import defaults +from menu import validations + +from progress.bar import Bar + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("chassis") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", "name_filter", multiple=True, help="Select by name") +@click.option("--serial", "serial_filter", multiple=True, help="Select by serial") +@click.option("--model", "model_filter", multiple=True, help="Select by model") +@click.option("--ttl", "user_cache_ttl", default=None, help="Cache TTL") +@click.option("--inventory", "inventory_filename", default=None, help="Inventory CSV filename") +@click.option("--view", "-v", default=['state'], help="[state|adv|alarm|contract|istate|node|fi|io|exp|port|fan|psu|psuc|hw|inv]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_chassis_command( + ctx, + iaccount, + name_filter, + serial_filter, + model_filter, + user_cache_ttl, + inventory_filename, + view, + output, + devel + ): + """Get chassis details""" + + # iserver get is chassis + + ctx.developer = devel + ctx.output = output + if ctx.output == 'default': + ctx.my_output.set_debug() + + view = validations.validate_view( + ctx, + view, + 'state|adv|alarm|contract|istate|node|fi|io|exp|port|net|fan|psu|psuc|hw|inv', + 'state', + [ + 'net:io,fi,port', + 'inv:node,io,exp,fan,psu,inventory', + 'hw:node,io,exp,fan,psu', + 'istate:adv,alarm,contract,state' + ] + ) + if view is None: + sys.exit(1) + + try: + settings_handler = intersight_settings.IntersightSettings( + log_id=ctx.run_id + ) + cache_ttl = settings_handler.get_intersight_cache_ttl() + if user_cache_ttl is not None: + try: + cache_ttl = int(user_cache_ttl) + except BaseException: + cache_ttl = -1 + + if cache_ttl < 0: + ctx.my_output.error('Cache TTL must be gt 0') + raise ErrorExit + + if output not in ['json', 'yaml']: + if cache_ttl is None: + ctx.my_output.default('iaccount %s (cache: off)' % (iaccount)) + else: + if cache_ttl == 0: + ctx.my_output.default('iaccount %s (cache: any)' % (iaccount)) + if cache_ttl > 0: + ctx.my_output.default('iaccount %s (cache: %s seconds)' % (iaccount, cache_ttl)) + + ctx.my_output.default('Select chassis...') + + chassis_handler = chassis.Chassis(iaccount, log_id=ctx.run_id) + + match_rules = chassis_handler.get_mo_match_rules( + name_filter=name_filter, + serial_filter=serial_filter, + model_filter=model_filter + ) + + chassiz_mo = chassis_handler.get_mo( + match_rules=match_rules, + cache_ttl=cache_ttl + ) + + if output not in ['json']: + ctx.my_output.default('Selected chassis: %s' % (len(chassiz_mo))) + + # Collect chassis information + + settings = {} + settings['advisory'] = 'adv' in view + settings['alarm'] = 'alarm' in view + settings['contract'] = 'contract' in view + settings['profile'] = 'state' in view + settings['fan'] = 'fan' in view + settings['fan_control'] = 'fan' in view + settings['psu'] = 'psu' in view + settings['psu_control'] = 'psuc' in view + settings['power_control'] = 'psuc' in view + settings['io'] = 'io' in view or 'port' in view + settings['expander_module'] = 'exp' in view + settings['port'] = 'port' in view + settings['node'] = 'node' in view or 'port' in view + settings['fi'] = 'fi' in view + + if output not in ['json']: + ctx.my_output.default('Collect chassis api objects...') + + chassis_handler.set_cache( + chassiz_mo, + settings, + cache_ttl, + ctx=ctx + ) + + bar_handler = None + if output == 'default': + bar_handler = Bar('Collect chassis information', max=len(chassiz_mo)) + bar_handler.goto(0) + + chassiz_info = chassis_handler.get_info( + chassiz_mo, + settings, + match_rules, + cache_ttl, + prepare_cache=False, + bar_handler=bar_handler + ) + + if output == 'default': + bar_handler.finish() + + # Output section + + chassis_output_handler = chassis_output.ChassisOutput(log_id=ctx.run_id) + + if output == 'json': + ctx.my_output.default(json.dumps(chassiz_info, indent=4)) + ctx.log_prompt = False + return + + if 'inventory' in view: + chassis_output_handler.print_inventory( + chassiz_info, + title=True + ) + + if inventory_filename is not None: + fields = ['Server', 'Server Type', 'Inventory Type', 'Inventory Name', 'Inventory Model', 'Inventory Vendor', 'Inventory Serial', 'Inventory PID'] + rows = [] + + for chassis_info in chassiz_info: + for inventory_info in chassis_info['Inventory']: + row = [] + row.append( + chassis_info['Name'] + ) + row.append( + chassis_info['Type'] + ) + row.append( + inventory_info['Type'] + ) + row.append( + inventory_info['Name'] + ) + row.append( + inventory_info['Model'] + ) + row.append( + inventory_info['Vendor'] + ) + row.append( + inventory_info['Serial'] + ) + row.append( + inventory_info['Pid'] + ) + rows.append( + row + ) + + with open(inventory_filename, 'w', newline='') as file_handler: + write = csv.writer(file_handler) + write.writerow(fields) + for row in rows: + write.writerow(row) + + return + + if 'state' in view: + chassis_output_handler.print_state( + chassiz_info, + title=True + ) + + if 'adv' in view: + chassis_output_handler.print_advisory( + chassiz_info, + title=True + ) + + if 'alarm' in view: + chassis_output_handler.print_chassis_alarm( + chassiz_info, + title=True + ) + + if 'contract' in view: + chassis_output_handler.print_contract( + chassiz_info, + title=True + ) + + if 'node' in view: + chassis_output_handler.print_node( + chassiz_info, + title=True + ) + + if 'io' in view: + chassis_output_handler.print_io_module( + chassiz_info, + title=True + ) + + if 'exp' in view: + chassis_output_handler.print_expander_module( + chassiz_info, + title=True + ) + + if 'port' in view: + chassis_output_handler.print_network_port( + chassiz_info, + title=True + ) + + chassis_output_handler.print_host_port( + chassiz_info, + title=True + ) + + if 'fi' in view: + chassis_output_handler.print_domain( + chassiz_info, + title=True + ) + + if 'fan' in view: + chassis_output_handler.print_fan( + chassiz_info, + title=True + ) + + if 'psuc' in view: + chassis_output_handler.print_psu_control_state_info( + chassiz_info, + title=True + ) + chassis_output_handler.print_power_control_state_info( + chassiz_info, + title=True + ) + + if 'psu' in view: + chassis_output_handler.print_psu( + chassiz_info, + title=True + ) + + ctx.my_output.default('Filter: name, serial, model', before_newline=True) + ctx.my_output.default('View: state (def), adv, alarm, contract, istate, node, fi, io, exp, port, net, fan, psu, psuc, hw, inv') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/cvim/__init__.py b/menu/get/cvim/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/cvim/cluster.py b/menu/get/cvim/cluster.py new file mode 100644 index 00000000..d4956188 --- /dev/null +++ b/menu/get/cvim/cluster.py @@ -0,0 +1,77 @@ +import sys +import threading +import traceback +import click + +from lib.cvim import settings + +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_cvim_cluster( + ctx, + devel + ): + """Get cvim cluster settings""" + + # iserver get cvim cluster + + ctx.developer = devel + + try: + settings_handler = settings.CvimSettings(log_id=ctx.run_id) + clusters = settings_handler.get_cvim_clusters() + + if clusters is None or len(clusters) == 0: + ctx.my_output.default('No cisco vim clusters defined') + return + + default_cluster_name = settings_handler.get_default_cluster() + if default_cluster_name is not None: + for cluster in clusters: + cluster['__Output'] = {} + if cluster['name'] == default_cluster_name: + cluster['__Output']['defaultTick'] = 'Green' + cluster['defaultTick'] = '\u2713' + + order = [ + 'name', + 'defaultTick', + 'openrc', + ] + + headers = [ + 'Cluster Name', + 'Default', + 'Openrc' + ] + + ctx.my_output.my_table( + clusters, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/cvim/main.py b/menu/get/cvim/main.py new file mode 100644 index 00000000..0748bec5 --- /dev/null +++ b/menu/get/cvim/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.cvim.cluster import get_cvim_cluster + + +class Failure(Exception): + pass + + +@click.group("cvim") +@click.pass_obj +def get_cvim_menu(ctx): + """Get cvim commands (alpha)""" + + +get_cvim_menu.add_command(get_cvim_cluster) diff --git a/menu/get/helm/__init__.py b/menu/get/helm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/helm/chart.py b/menu/get/helm/chart.py new file mode 100644 index 00000000..cfec6040 --- /dev/null +++ b/menu/get/helm/chart.py @@ -0,0 +1,148 @@ +import sys +import json +import traceback +import click + +from lib.helm import output as helm_output +from lib.helm import main as helm + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("chart") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by chart name") +@click.option("--view", "-v", default=['state'], help="[state|values|files]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_helm_chart_command( + ctx, + cluster_name, + name, + view, + output, + devel + ): + """Get helm chart""" + + # iserver get helm chart + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|values|files', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name) + if settings is None: + raise ErrorExit + + if 'helm' not in settings: + ctx.my_output.error('Helm not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + helm_handler = helm.Helm( + settings['helm']['ip'], + settings['helm']['username'], + password=settings['helm']['password'], + key_filename=settings['helm']['key_filename'], + log_id=ctx.run_id + ) + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + release_info = False + files_info = False + values_info = False + + if 'state' in view: + release_info = True + + if 'values' in view: + values_info = True + + if 'files' in view: + files_info = True + + charts = helm_handler.get_charts( + chart_filter=object_filter, + release_info=release_info, + values_info=values_info, + files_info=files_info + ) + if charts is None: + ctx.my_output.error('Helm chart get failed') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + charts, + indent=4 + ) + ) + return + + ctx.my_output.json_output(charts) + + output_handler = helm_output.HelmOutput( + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + if 'state' in view: + output_handler.print_charts( + charts, + title=True + ) + + if 'values' in view: + output_handler.print_chart_values( + charts + ) + + if 'files' in view: + output_handler.print_chart_files( + charts, + title=True + ) + + ctx.my_output.default('\nViews: state (def), values, files, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/helm/main.py b/menu/get/helm/main.py new file mode 100644 index 00000000..be91bbbe --- /dev/null +++ b/menu/get/helm/main.py @@ -0,0 +1,18 @@ +import click + +from menu.get.helm.chart import get_helm_chart_command +from menu.get.helm.release import get_helm_release_command + + +class Failure(Exception): + pass + + +@click.group("helm") +@click.pass_obj +def get_helm_menu(ctx): + """Get helm commands""" + + +get_helm_menu.add_command(get_helm_chart_command) +get_helm_menu.add_command(get_helm_release_command) diff --git a/menu/get/helm/release.py b/menu/get/helm/release.py new file mode 100644 index 00000000..4df5ed88 --- /dev/null +++ b/menu/get/helm/release.py @@ -0,0 +1,157 @@ +import sys +import json +import traceback +import click + +from lib.helm import output as helm_output +from lib.helm import main as helm + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("release") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|values|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_helm_release_command( + ctx, + cluster_name, + namespace, + name, + view, + output, + devel + ): + """Get helm release""" + + # iserver get helm release + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|values|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + settings = validations.validate_ocp_cluster_settings(ctx, cluster_name) + if settings is None: + raise ErrorExit + + if 'helm' not in settings: + ctx.my_output.error('Helm not defined for cluster %s' % (settings['name'])) + raise ErrorExit + + helm_handler = helm.Helm( + settings['helm']['ip'], + settings['helm']['username'], + password=settings['helm']['password'], + key_filename=settings['helm']['key_filename'], + log_id=ctx.run_id + ) + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + values_info = False + chart_info = False + day0_info = False + + if 'state' in view: + chart_info = True + + if 'day0' in view: + day0_info = True + + if 'values' in view: + values_info = True + + releases = helm_handler.get_releases( + release_filter=object_filter, + values_info=values_info, + chart_info=chart_info, + day0_info=day0_info + ) + if releases is None: + ctx.my_output.error('Helm release get failed') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + releases, + indent=4 + ) + ) + return + + ctx.my_output.json_output(releases) + + output_handler = helm_output.HelmOutput( + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + if 'state' in view: + output_handler.print_releases( + releases, + title=True + ) + + if 'day0' in view: + output_handler.print_releases_day0( + releases, + title=True + ) + + if 'values' in view: + output_handler.print_release_values( + releases, + title=True + ) + + ctx.my_output.default('\nViews: state (def), values, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/__init__.py b/menu/get/intersight/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/intersight/__pycache__/__init__.cpython-310.pyc b/menu/get/intersight/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..99e05ee3 Binary files /dev/null and b/menu/get/intersight/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/chassis.cpython-310.pyc b/menu/get/intersight/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..18b86cec Binary files /dev/null and b/menu/get/intersight/__pycache__/chassis.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/chassiz.cpython-310.pyc b/menu/get/intersight/__pycache__/chassiz.cpython-310.pyc new file mode 100644 index 00000000..8d342116 Binary files /dev/null and b/menu/get/intersight/__pycache__/chassiz.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/main.cpython-310.pyc b/menu/get/intersight/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..156c2ca2 Binary files /dev/null and b/menu/get/intersight/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/os_config.cpython-310.pyc b/menu/get/intersight/__pycache__/os_config.cpython-310.pyc new file mode 100644 index 00000000..759da124 Binary files /dev/null and b/menu/get/intersight/__pycache__/os_config.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/os_image.cpython-310.pyc b/menu/get/intersight/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..2b0ade7f Binary files /dev/null and b/menu/get/intersight/__pycache__/os_image.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/os_vendor.cpython-310.pyc b/menu/get/intersight/__pycache__/os_vendor.cpython-310.pyc new file mode 100644 index 00000000..d892fdfd Binary files /dev/null and b/menu/get/intersight/__pycache__/os_vendor.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/os_version.cpython-310.pyc b/menu/get/intersight/__pycache__/os_version.cpython-310.pyc new file mode 100644 index 00000000..7e22dc06 Binary files /dev/null and b/menu/get/intersight/__pycache__/os_version.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/scu.cpython-310.pyc b/menu/get/intersight/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..c4854ab2 Binary files /dev/null and b/menu/get/intersight/__pycache__/scu.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/server.cpython-310.pyc b/menu/get/intersight/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..e78d5425 Binary files /dev/null and b/menu/get/intersight/__pycache__/server.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/servers.cpython-310.pyc b/menu/get/intersight/__pycache__/servers.cpython-310.pyc new file mode 100644 index 00000000..b5d7779a Binary files /dev/null and b/menu/get/intersight/__pycache__/servers.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/summary.cpython-310.pyc b/menu/get/intersight/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..c6bac9ab Binary files /dev/null and b/menu/get/intersight/__pycache__/summary.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/workflow.cpython-310.pyc b/menu/get/intersight/__pycache__/workflow.cpython-310.pyc new file mode 100644 index 00000000..37a94857 Binary files /dev/null and b/menu/get/intersight/__pycache__/workflow.cpython-310.pyc differ diff --git a/menu/get/intersight/__pycache__/workflows.cpython-310.pyc b/menu/get/intersight/__pycache__/workflows.cpython-310.pyc new file mode 100644 index 00000000..5f817526 Binary files /dev/null and b/menu/get/intersight/__pycache__/workflows.cpython-310.pyc differ diff --git a/menu/get/intersight/alarm.py b/menu/get/intersight/alarm.py new file mode 100644 index 00000000..a1154dc1 --- /dev/null +++ b/menu/get/intersight/alarm.py @@ -0,0 +1,156 @@ +import json +import sys +import traceback +import click +from webexteamssdk import WebexTeamsAPI + +from lib.intersight.cond_alarm import main as cond_alarm +from lib.intersight import compute_output +from lib.intersight import bot_output +from lib import log_helper + +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("alarm") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--code", "alarm_code", default='', callback=validations.empty_string_to_none, help="Filter by code") +@click.option("--sev", "severity", type=click.Choice(['any', 'crit', 'warn', 'info'], case_sensitive=False), default='any', show_default=True, help="Filter by severity") +@click.option("--when", "alarm_when", default='1y', show_default=True, callback=validations.validate_timestamp_filter, help="Filter faults by timestamp") +@click.option("--new", "only_new", is_flag=True, show_default=True, default=False, help="Only new from last new run") +@click.option("--cleared", "include_cleared", is_flag=True, show_default=True, default=False, help="Show cleared alarms") +@click.option("--limit", default=-1, help="Limit alarms") +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'bot'], case_sensitive=False), default='default', show_default=True) +@click.option("--bot", default='', callback=validations.validate_bot, help="Send result to bot") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_alarm_command( + ctx, + iaccount, + alarm_code, + severity, + alarm_when, + only_new, + include_cleared, + limit, + output, + bot, + devel + ): + """Get alarm""" + + # iserver get is alarm + + ctx.developer = devel + + try: + if output == 'default': + ctx.my_output.default('Get alarms...') + + if output == 'bot' and bot is None: + ctx.my_output.error('Define --bot') + raise ErrorExit + + cond_alarm_handler = cond_alarm.CondAlarm(iaccount, log_id=ctx.run_id) + + cond_alarm_filter = [] + + cond_alarm_filter.append( + 'timestamp:%s' % (alarm_when) + ) + + cond_alarm_filter.append( + 'new:%s' % (only_new) + ) + + cond_alarm_filter.append( + 'cleared:%s' % (include_cleared) + ) + + if alarm_code is not None: + cond_alarm_filter.append( + 'code:%s' % (alarm_code) + ) + + if severity is not None: + cond_alarm_filter.append( + 'severity:%s' % (severity) + ) + + alarms = cond_alarm_handler.get_cond_alarms( + cond_alarm_filter=cond_alarm_filter, + update_moid_cache=only_new + ) + + if alarms is None: + ctx.my_output.error('Failed to get alarms') + raise ErrorExit + + if limit > 0: + alarms = alarms[:limit] + + if output == 'json': + ctx.my_output.default(json.dumps(alarms, indent=4)) + ctx.log_prompt = False + return + + if output == 'default': + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + compute_output_handler.print_alarm(alarms) + + if bot is not None and len(alarms) > 0: + bot_output_handler = bot_output.ComputeBotOutput(log_id=ctx.run_id) + output, html_output = bot_output_handler.print_alarm(alarms) + + users = validations.validate_bot_group(bot['users'], 'intersight.alarm') + if len(users) == 0: + ctx.my_output.error('No bot user found') + raise ErrorExit + + if len(bot['proxies']) == 0: + webex_api_handler = WebexTeamsAPI( + access_token=bot['token'] + ) + else: + webex_api_handler = WebexTeamsAPI( + access_token=bot['token'], + proxies=bot['proxies'] + ) + + log_handler = log_helper.Log(log_id=ctx.run_id) + + files = None + filename = log_handler.bot_output(output, log_id=ctx.run_id) + if filename is not None: + files = [filename] + + output = bot_output_handler.my_output.sanitize_bot_output( + output, + None + ) + + rooms = webex_api_handler.rooms.list() + for room in rooms: + for user in users: + if getattr(room, 'title') == user['title']: + webex_api_handler.messages.create( + roomId=getattr(room, 'id'), + markdown=output, + files=files + ) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/iaccount.py b/menu/get/intersight/iaccount.py new file mode 100644 index 00000000..14a7b64f --- /dev/null +++ b/menu/get/intersight/iaccount.py @@ -0,0 +1,33 @@ +import json +import click + +from lib import iaccount_helper + + +@click.command("iaccount") +@click.pass_obj +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--show-key", is_flag=True, show_default=True, default=False, help="Show key") +def get_intersight_iaccount_command(ctx, output, show_key): + """Get intersight accounts""" + + iaccount_handler = iaccount_helper.IntersightAccount() + accounts = iaccount_handler.get_iaccounts() + + if not show_key: + new_accounts = [] + for account in accounts: + account['keyid'] = '*****' + new_accounts.append(account) + accounts = new_accounts + + if output == 'json': + ctx.my_output.default(json.dumps(accounts, indent=4)) + return + + ctx.my_output.my_table( + accounts, + order=['name', 'keyfile', 'server', 'keyid'], + headers=['iaccount', 'key file', 'server', 'key id'], + table=True + ) diff --git a/menu/get/intersight/main.py b/menu/get/intersight/main.py new file mode 100644 index 00000000..24208cd5 --- /dev/null +++ b/menu/get/intersight/main.py @@ -0,0 +1,34 @@ +import click + +from menu.get.intersight.alarm import get_intersight_alarm_command +from menu.get.intersight.iaccount import get_intersight_iaccount_command +from menu.get.intersight.os_image import get_intersight_os_image_command +from menu.get.intersight.os_vendor import get_intersight_os_vendor_command +from menu.get.intersight.os_version import get_intersight_os_version_command +from menu.get.intersight.os_config import get_intersight_os_config_command +from menu.get.intersight.scu import get_intersight_scu_command +from menu.get.intersight.settings import get_intersight_settings_command +from menu.get.intersight.workflows import get_intersight_workflows_command +from menu.get.intersight.workflow import get_intersight_workflow_command + + +class Failure(Exception): + pass + + +@click.group("is") +@click.pass_obj +def get_intersight_menu(ctx): + """Get intersight commands""" + + +get_intersight_menu.add_command(get_intersight_alarm_command) +get_intersight_menu.add_command(get_intersight_iaccount_command) +get_intersight_menu.add_command(get_intersight_os_image_command) +get_intersight_menu.add_command(get_intersight_os_vendor_command) +get_intersight_menu.add_command(get_intersight_os_version_command) +get_intersight_menu.add_command(get_intersight_os_config_command) +get_intersight_menu.add_command(get_intersight_scu_command) +get_intersight_menu.add_command(get_intersight_settings_command) +get_intersight_menu.add_command(get_intersight_workflows_command) +get_intersight_menu.add_command(get_intersight_workflow_command) diff --git a/menu/get/intersight/os_config.py b/menu/get/intersight/os_config.py new file mode 100644 index 00000000..758a9d2f --- /dev/null +++ b/menu/get/intersight/os_config.py @@ -0,0 +1,75 @@ +import sys +import traceback +import click + +from lib.intersight import hcl_operating_system +from lib.intersight import hcl_operating_system_vendor +from lib.intersight import os_configuration_file +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-config") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--vendor", "vendor_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Vendor Name") +@click.option("--version", "version_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Version Name") +@click.option("--id", "version_id", is_flag=False, show_default=False, default='', type=click.STRING, help="Version ID") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_os_config_command(ctx, iaccount, vendor_name, version_name, version_id, devel): + """Get operating system configuration template""" + + # iserver get is os-config + + ctx.developer = devel + + try: + ctx.my_output.default('Validate input parameters...') + + if vendor_name == '' and version_name == '' and version_id == '': + ctx.my_output.error('Define os version using vendor and version names or version id') + raise ErrorExit + + if version_id == '': + if vendor_name == '' or version_name == '': + ctx.my_output.error('Define os version using vendor and version names or version id') + raise ErrorExit + + if version_id == '': + vendor_handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=ctx.run_id) + vendor_id = vendor_handler.get_moid(vendor_name) + if vendor_id is None: + ctx.my_output.error('Vendor not found: %s' % (vendor_name)) + raise ErrorExit + + version_handler = hcl_operating_system.HclOperatingSystem(iaccount, log_id=ctx.run_id) + version_id = version_handler.get_vendor_version_id(vendor_id, version_name) + if version_id is None: + ctx.my_output.error('Version not found: %s' % (version_name)) + raise ErrorExit + + config_handler = os_configuration_file.OsConfigurationFile(iaccount, log_id=ctx.run_id) + config_files = config_handler.get_file_for_os(version_id) + + if config_files is None: + ctx.my_output.error('No configuration file found') + raise ErrorExit + + for config_file in config_files: + ctx.my_output.default('Configuration file: %s [%s]\n' % (config_file['Name'], config_file['Moid'])) + ctx.my_output.default(config_file['FileContent']) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/os_image.py b/menu/get/intersight/os_image.py new file mode 100644 index 00000000..7d9cf53c --- /dev/null +++ b/menu/get/intersight/os_image.py @@ -0,0 +1,68 @@ +import json +import sys +import traceback +import yaml +import click + +from lib.intersight import os_image +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-image") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml', 'set'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_os_image_command(ctx, iaccount, output, devel): + """Get operating system image""" + + # iserver get is image + + ctx.developer = devel + + try: + image_handler = os_image.OsImage(iaccount, log_id=ctx.run_id) + images = image_handler.get_all() + + if output == 'json': + ctx.my_output.default(json.dumps(images, indent=4)) + ctx.log_prompt = False + return + + if output == 'yaml': + yaml_output = yaml.dump( + images, + default_flow_style=False + ) + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + if output == 'set': + yaml_output = image_handler.get_set_output(images) + if yaml_output is None: + ctx.my_output.error('Failed to get set output type') + raise ErrorExit + + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + image_handler.print(images) + ctx.my_output.json_output(images) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/os_vendor.py b/menu/get/intersight/os_vendor.py new file mode 100644 index 00000000..88b6dbf9 --- /dev/null +++ b/menu/get/intersight/os_vendor.py @@ -0,0 +1,58 @@ +import json +import sys +import traceback +import yaml +import click + +from lib.intersight import hcl_operating_system_vendor +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-vendor") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_os_vendor_command(ctx, iaccount, output, devel): + """Get operating system vendors""" + + # iserver get is os-vendor + + ctx.developer = devel + + try: + handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=ctx.run_id) + vendors = handler.get_all() + ctx.my_output.json_output(vendors) + + if output == 'json': + ctx.my_output.default(json.dumps(vendors, indent=4)) + ctx.log_prompt = False + return + + if output == 'yaml': + yaml_output = yaml.dump( + vendors, + default_flow_style=False + ) + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + handler.print(vendors) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/os_version.py b/menu/get/intersight/os_version.py new file mode 100644 index 00000000..d7ac4241 --- /dev/null +++ b/menu/get/intersight/os_version.py @@ -0,0 +1,69 @@ +import json +import sys +import traceback +import yaml +import click + +from lib.intersight import hcl_operating_system +from lib.intersight import hcl_operating_system_vendor +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-version") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--vendor", "vendor_name", is_flag=False, show_default=False, default='', type=click.STRING, help="Vendor Name") +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_os_version_command(ctx, iaccount, vendor_name, output, devel): + """Get operating system versions""" + + # iserver get is os-version + + ctx.developer = devel + + try: + version_handler = hcl_operating_system.HclOperatingSystem(iaccount, log_id=ctx.run_id) + if vendor_name == '': + versions = version_handler.get_all() + else: + vendor_handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=ctx.run_id) + vendor_attributes = vendor_handler.get_by_name(vendor_name) + if vendor_attributes is None: + ctx.my_output.error('Vendor not found: %s' % (vendor_name)) + raise ErrorExit + versions = version_handler.get_vendor_versions(vendor_attributes['Moid']) + + ctx.my_output.json_output(versions) + + if output == 'json': + ctx.my_output.default(json.dumps(versions, indent=4)) + ctx.log_prompt = False + return + + if output == 'yaml': + yaml_output = yaml.dump( + versions, + default_flow_style=False + ) + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + version_handler.print(versions) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/scu.py b/menu/get/intersight/scu.py new file mode 100644 index 00000000..f3a8bf3b --- /dev/null +++ b/menu/get/intersight/scu.py @@ -0,0 +1,67 @@ +import json +import sys +import traceback +import click +import yaml + +from lib.intersight import scu +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("scu") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml', 'set'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_scu_command(ctx, iaccount, output, devel): + """Get software configuration utilities""" + + # iserver get is scu + + ctx.developer = devel + + try: + scu_handler = scu.SoftwareConfigurationUtility(iaccount, log_id=ctx.run_id) + scus = scu_handler.get_all() + if output == 'json': + ctx.my_output.default(json.dumps(scus, indent=4)) + ctx.log_prompt = False + return + + if output == 'yaml': + yaml_output = yaml.dump( + scus, + default_flow_style=False + ) + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + if output == 'set': + yaml_output = scu_handler.get_set_output(scus) + if yaml_output is None: + ctx.my_output.error('Failed to get set output type') + raise ErrorExit + + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + scu_handler.print(scus) + ctx.my_output.json_output(scus) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/settings.py b/menu/get/intersight/settings.py new file mode 100644 index 00000000..fc7a32a2 --- /dev/null +++ b/menu/get/intersight/settings.py @@ -0,0 +1,15 @@ +import click + +from lib.intersight import settings + + +@click.command("settings") +@click.pass_obj +def get_intersight_settings_command(ctx): + """Get intersight settings""" + + settings_handler = settings.IntersightSettings( + log_id=ctx.run_id + ) + + settings_handler.print_intersight_settings() diff --git a/menu/get/intersight/workflow.py b/menu/get/intersight/workflow.py new file mode 100644 index 00000000..0c60e6c5 --- /dev/null +++ b/menu/get/intersight/workflow.py @@ -0,0 +1,71 @@ +import json +import sys +import traceback +import yaml +import click + +from lib.intersight import workflow_info + +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("workflow") +@click.pass_obj +@click.argument("workflow_id", required=True, type=click.STRING) +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_workflow_command( + ctx, + iaccount, + workflow_id, + output, + devel + ): + """Get workflow""" + + # iserver get is workflow + + ctx.developer = devel + + try: + if output == 'default': + ctx.my_output.default('Get server workflow info...') + + workflow_info_handler = workflow_info.WorkflowInfo(iaccount, log_id=ctx.run_id) + workflow_info_object = workflow_info_handler.get_workflow_info(workflow_id) + if workflow_info_object is None: + ctx.my_output.error('Workflow information collection failed') + raise ErrorExit + + if output == 'json': + ctx.my_output.default(json.dumps(workflow_info_object, indent=4)) + ctx.log_prompt = False + return + + if output == 'yaml': + yaml_output = yaml.dump( + workflow_info_object, + default_flow_style=False + ) + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + workflow_info_handler.print_workflow_info(workflow_info_object) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/intersight/workflows.py b/menu/get/intersight/workflows.py new file mode 100644 index 00000000..4c57c6c0 --- /dev/null +++ b/menu/get/intersight/workflows.py @@ -0,0 +1,170 @@ +import json +import sys +import traceback +import yaml +import click + +from progress.bar import Bar + +from lib.intersight import compute +from lib.intersight import computes_worfklow +from lib.intersight import validations as intersight_validations + +from menu import common +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("workflows") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", multiple=True, help="Select by IP or subnet") +@click.option("--name", "name_filter", multiple=True, callback=intersight_validations.name_filter, help="Select by name") +@click.option("--serial", "serial_filter", multiple=True, callback=intersight_validations.serial_filter, help="Select by serial") +@click.option("--model", "model_filter", multiple=True, callback=intersight_validations.model_filter, help="Select by model") +@click.option("--type", "type_filter", type=click.Choice(['any', 'blade', 'rack'], case_sensitive=False), default='any', show_default=True, help="Select by type") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--failed", "failed_filter", is_flag=True, default=False, help="Filter failed") +@click.option("--completed", "completed_filter", is_flag=True, default=False, help="Filter completed") +@click.option("--power", "power_filter", is_flag=True, default=False, help="Filter power related") +@click.option("--os", "os_filter", is_flag=True, default=False, help="Filter OS related") +@click.option("--fw", "fw_filter", is_flag=True, default=False, help="Filter firmware related") +@click.option("--count", default=-1, show_default=True, help="Last count") +@click.option("--days", default=1, help="Last days") +@click.option("--ttl", "user_cache_ttl", default=None, help="Cache TTL") +@click.option("--order", "sorted_by", type=click.Choice(['server', 'workflow', 'date'], case_sensitive=False), default='date', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json', 'yaml'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_intersight_workflows_command( + ctx, + iaccount, + ip_filter, + name_filter, + serial_filter, + model_filter, + type_filter, + group_filter, + failed_filter, + completed_filter, + power_filter, + os_filter, + fw_filter, + count, + days, + user_cache_ttl, + sorted_by, + output, + devel + ): + """Get workflows""" + + # iserver get is workflows + + ctx.developer = devel + + try: + # default vs. user-defined cache_ttl + cache_ttl = intersight_validations.validate_cache_ttl(user_cache_ttl, log_id=ctx.run_id) + if cache_ttl is not None and cache_ttl < 0: + ctx.my_output.error('Cache TTL must be gt 0') + raise ErrorExit + + # Server details collection settings + + settings = {} + settings['state'] = True + settings['workflow'] = 86400 * days + + if output == 'default': + ctx.my_output.default('Get servers info...') + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + mo_match_rules = compute_handler.get_mo_match_rules( + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=intersight_validations.add_group_filter(serial_filter, group_filter), + model_filter=model_filter + ) + + include_rack = True + include_blade = True + if type_filter == 'rack': + include_blade = False + if type_filter == 'blade': + include_rack = False + + servers_mo = compute_handler.get_mo( + match_rules=mo_match_rules, + include_rack=include_rack, + include_blade=include_blade, + cache_ttl=None + ) + + compute_handler.set_cache( + servers_mo, + settings, + cache_ttl, + ctx=ctx + ) + + bar_handler = None + if output == 'default': + bar_handler = Bar('Collect server information', max=len(servers_mo)) + bar_handler.goto(0) + + match_rules = {} + servers_info = compute_handler.get_info( + servers_mo, + settings, + match_rules, + cache_ttl, + prepare_cache=False, + bar_handler=bar_handler + ) + + workflows_settings = {} + workflows_settings['failed'] = failed_filter + workflows_settings['completed'] = completed_filter + workflows_settings['power'] = power_filter + workflows_settings['os'] = os_filter + workflows_settings['fw'] = fw_filter + workflows_settings['count'] = count + workflows_settings['days'] = days + workflows_settings['sorted'] = sorted_by + + workflows = compute_handler.get_servers_workflows(servers_info, workflows_settings) + if len(workflows) == 0: + ctx.my_output.default('No workflows found', before_newline=True) + return + + if output == 'json': + ctx.my_output.default(json.dumps(workflows, indent=4)) + ctx.log_prompt = False + return + + if output == 'yaml': + yaml_output = yaml.dump( + workflows, + default_flow_style=False + ) + ctx.my_output.default(yaml_output) + ctx.log_prompt = False + return + + compute_output_handler = computes_worfklow.ComputesWorkflow(log_id=ctx.run_id) + compute_output_handler.print_workflows(workflows) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/__init__.py b/menu/get/iwo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/iwo/__pycache__/__init__.cpython-310.pyc b/menu/get/iwo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e77e6bd7 Binary files /dev/null and b/menu/get/iwo/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/action.cpython-310.pyc b/menu/get/iwo/__pycache__/action.cpython-310.pyc new file mode 100644 index 00000000..d9f4a6da Binary files /dev/null and b/menu/get/iwo/__pycache__/action.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/application.cpython-310.pyc b/menu/get/iwo/__pycache__/application.cpython-310.pyc new file mode 100644 index 00000000..d76a5f9b Binary files /dev/null and b/menu/get/iwo/__pycache__/application.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/chassis.cpython-310.pyc b/menu/get/iwo/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..38e93f32 Binary files /dev/null and b/menu/get/iwo/__pycache__/chassis.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/cluster.cpython-310.pyc b/menu/get/iwo/__pycache__/cluster.cpython-310.pyc new file mode 100644 index 00000000..ee3990ce Binary files /dev/null and b/menu/get/iwo/__pycache__/cluster.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/container.cpython-310.pyc b/menu/get/iwo/__pycache__/container.cpython-310.pyc new file mode 100644 index 00000000..38fa6933 Binary files /dev/null and b/menu/get/iwo/__pycache__/container.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/dc.cpython-310.pyc b/menu/get/iwo/__pycache__/dc.cpython-310.pyc new file mode 100644 index 00000000..e0ae1f81 Binary files /dev/null and b/menu/get/iwo/__pycache__/dc.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/dcs.cpython-310.pyc b/menu/get/iwo/__pycache__/dcs.cpython-310.pyc new file mode 100644 index 00000000..c4a69167 Binary files /dev/null and b/menu/get/iwo/__pycache__/dcs.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/disk.cpython-310.pyc b/menu/get/iwo/__pycache__/disk.cpython-310.pyc new file mode 100644 index 00000000..0449739d Binary files /dev/null and b/menu/get/iwo/__pycache__/disk.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/main.cpython-310.pyc b/menu/get/iwo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4bb19973 Binary files /dev/null and b/menu/get/iwo/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/namespace.cpython-310.pyc b/menu/get/iwo/__pycache__/namespace.cpython-310.pyc new file mode 100644 index 00000000..8ce43d36 Binary files /dev/null and b/menu/get/iwo/__pycache__/namespace.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/network.cpython-310.pyc b/menu/get/iwo/__pycache__/network.cpython-310.pyc new file mode 100644 index 00000000..ff6da36d Binary files /dev/null and b/menu/get/iwo/__pycache__/network.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/phy.cpython-310.pyc b/menu/get/iwo/__pycache__/phy.cpython-310.pyc new file mode 100644 index 00000000..601865b5 Binary files /dev/null and b/menu/get/iwo/__pycache__/phy.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/pod.cpython-310.pyc b/menu/get/iwo/__pycache__/pod.cpython-310.pyc new file mode 100644 index 00000000..f1c45021 Binary files /dev/null and b/menu/get/iwo/__pycache__/pod.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/region.cpython-310.pyc b/menu/get/iwo/__pycache__/region.cpython-310.pyc new file mode 100644 index 00000000..b55081b7 Binary files /dev/null and b/menu/get/iwo/__pycache__/region.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/service.cpython-310.pyc b/menu/get/iwo/__pycache__/service.cpython-310.pyc new file mode 100644 index 00000000..c961b7cb Binary files /dev/null and b/menu/get/iwo/__pycache__/service.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/spec.cpython-310.pyc b/menu/get/iwo/__pycache__/spec.cpython-310.pyc new file mode 100644 index 00000000..d32c6e5d Binary files /dev/null and b/menu/get/iwo/__pycache__/spec.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/storage.cpython-310.pyc b/menu/get/iwo/__pycache__/storage.cpython-310.pyc new file mode 100644 index 00000000..7c94b114 Binary files /dev/null and b/menu/get/iwo/__pycache__/storage.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/switch.cpython-310.pyc b/menu/get/iwo/__pycache__/switch.cpython-310.pyc new file mode 100644 index 00000000..88efad90 Binary files /dev/null and b/menu/get/iwo/__pycache__/switch.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/target.cpython-310.pyc b/menu/get/iwo/__pycache__/target.cpython-310.pyc new file mode 100644 index 00000000..d1406494 Binary files /dev/null and b/menu/get/iwo/__pycache__/target.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/targets.cpython-310.pyc b/menu/get/iwo/__pycache__/targets.cpython-310.pyc new file mode 100644 index 00000000..5d97ae1a Binary files /dev/null and b/menu/get/iwo/__pycache__/targets.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/vdc.cpython-310.pyc b/menu/get/iwo/__pycache__/vdc.cpython-310.pyc new file mode 100644 index 00000000..0eb7ee2b Binary files /dev/null and b/menu/get/iwo/__pycache__/vdc.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/vdcs.cpython-310.pyc b/menu/get/iwo/__pycache__/vdcs.cpython-310.pyc new file mode 100644 index 00000000..7bcf20ba Binary files /dev/null and b/menu/get/iwo/__pycache__/vdcs.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/vm.cpython-310.pyc b/menu/get/iwo/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..d5936882 Binary files /dev/null and b/menu/get/iwo/__pycache__/vm.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/vms.cpython-310.pyc b/menu/get/iwo/__pycache__/vms.cpython-310.pyc new file mode 100644 index 00000000..725e8676 Binary files /dev/null and b/menu/get/iwo/__pycache__/vms.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/volume.cpython-310.pyc b/menu/get/iwo/__pycache__/volume.cpython-310.pyc new file mode 100644 index 00000000..9b15c0f9 Binary files /dev/null and b/menu/get/iwo/__pycache__/volume.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/workload.cpython-310.pyc b/menu/get/iwo/__pycache__/workload.cpython-310.pyc new file mode 100644 index 00000000..847b2deb Binary files /dev/null and b/menu/get/iwo/__pycache__/workload.cpython-310.pyc differ diff --git a/menu/get/iwo/__pycache__/zone.cpython-310.pyc b/menu/get/iwo/__pycache__/zone.cpython-310.pyc new file mode 100644 index 00000000..33929b55 Binary files /dev/null and b/menu/get/iwo/__pycache__/zone.cpython-310.pyc differ diff --git a/menu/get/iwo/action.py b/menu/get/iwo/action.py new file mode 100644 index 00000000..3aa7b998 --- /dev/null +++ b/menu/get/iwo/action.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("action") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_action_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo action""" + + # iserver get iwo action + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + actions = iwo_handler.get_actions(related_class='all') + if actions is None: + ctx.busy = False + ctx.my_output.error('Failed to get actions') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + actions, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(actions) + + iwo_handler.print_actions_summary(actions) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/application.py b/menu/get/iwo/application.py new file mode 100644 index 00000000..d22f316b --- /dev/null +++ b/menu/get/iwo/application.py @@ -0,0 +1,169 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("application") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--cluster", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by cluster") +@click.option("--container", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by container") +@click.option("--service", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by service") +@click.option("--stale", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select stale") +@click.option("--inactive", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select inactive") +@click.option("--critical", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select critical") +@click.option("--major", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select major or critical") +@click.option("--minor", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select minor, major or critical") +@click.option("--show-container", is_flag=True, show_default=True, default=False, help="Show application containers") +@click.option("--show-service", is_flag=True, show_default=True, default=False, help="Show application services") +@click.option("--show-actions", is_flag=True, show_default=True, default=False, help="Show application actions") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_application_command( + ctx, + iaccount, + name, + cluster, + container, + service, + stale, + inactive, + critical, + major, + minor, + show_container, + show_service, + show_actions, + output, + verbose, + debug, + devel + ): + """Get iwo application""" + + # iserver get iwo application + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + match_rules = [] + if name is not None: + match_rules.append( + 'name:%s' % (name) + ) + + if cluster is not None: + match_rules.append( + 'cluster:%s' % (cluster) + ) + + if container is not None: + show_container = True + match_rules.append( + 'container:%s' % (container) + ) + + if service is not None: + show_service = True + match_rules.append( + 'service:%s' % (service) + ) + + if stale is not None: + match_rules.append( + 'stale' + ) + + if inactive is not None: + match_rules.append( + 'inactive' + ) + + if critical is not None: + match_rules.append( + 'critical' + ) + + if major is not None: + match_rules.append( + 'major' + ) + + if minor is not None: + match_rules.append( + 'minor' + ) + + resolve_dependencies = False + if show_container or show_service or show_actions: + resolve_dependencies = True + + managed_objects = iwo_handler.get_applications( + resolve_dependencies=resolve_dependencies, + match_rules=match_rules + ) + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get application') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_applications( + managed_objects, + show_service=show_service, + show_container=show_container, + show_actions=show_actions + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/chassis.py b/menu/get/iwo/chassis.py new file mode 100644 index 00000000..ce28c397 --- /dev/null +++ b/menu/get/iwo/chassis.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("chassis") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_chassis_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo chassis""" + + # iserver get iwo chassis + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_chassiss() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get chassis') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_chassiss(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/cluster.py b/menu/get/iwo/cluster.py new file mode 100644 index 00000000..610abe41 --- /dev/null +++ b/menu/get/iwo/cluster.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_cluster_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo cluster""" + + # iserver get iwo cluster + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_clusters() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get cluster') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_clusters(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/container.py b/menu/get/iwo/container.py new file mode 100644 index 00000000..e79ca12f --- /dev/null +++ b/menu/get/iwo/container.py @@ -0,0 +1,169 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("container") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--cluster", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by cluster") +@click.option("--pod", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by pod") +@click.option("--app", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by application") +@click.option("--stale", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select stale") +@click.option("--inactive", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select inactive") +@click.option("--critical", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select critical") +@click.option("--major", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select major or critical") +@click.option("--minor", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select minor, major or critical") +@click.option("--show-pod", is_flag=True, show_default=True, default=False, help="Show container pods") +@click.option("--show-app", is_flag=True, show_default=True, default=False, help="Show container applications") +@click.option("--show-actions", is_flag=True, show_default=True, default=False, help="Show container actions") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_container_command( + ctx, + iaccount, + name, + cluster, + pod, + app, + stale, + inactive, + critical, + major, + minor, + show_pod, + show_app, + show_actions, + output, + verbose, + debug, + devel + ): + """Get iwo container""" + + # iserver get iwo container + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + match_rules = [] + if name is not None: + match_rules.append( + 'name:%s' % (name) + ) + + if cluster is not None: + match_rules.append( + 'cluster:%s' % (cluster) + ) + + if pod is not None: + show_pod = True + match_rules.append( + 'pod:%s' % (pod) + ) + + if app is not None: + show_app = True + match_rules.append( + 'application:%s' % (app) + ) + + if stale is not None: + match_rules.append( + 'stale' + ) + + if inactive is not None: + match_rules.append( + 'inactive' + ) + + if critical is not None: + match_rules.append( + 'critical' + ) + + if major is not None: + match_rules.append( + 'major' + ) + + if minor is not None: + match_rules.append( + 'minor' + ) + + resolve_dependencies = False + if show_pod or show_app or show_actions: + resolve_dependencies = True + + managed_objects = iwo_handler.get_containers( + resolve_dependencies=resolve_dependencies, + match_rules=match_rules + ) + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get container') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_containers( + managed_objects, + show_app=show_app, + show_pod=show_pod, + show_actions=show_actions + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/dc.py b/menu/get/iwo/dc.py new file mode 100644 index 00000000..04866078 --- /dev/null +++ b/menu/get/iwo/dc.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("dc") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_dc_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo data center""" + + # iserver get iwo dc + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + dcs = iwo_handler.get_data_centers() + if dcs is None: + ctx.busy = False + ctx.my_output.error('Failed to get data centers') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + dcs, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(dcs) + + iwo_handler.print_data_centers(dcs) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/disk.py b/menu/get/iwo/disk.py new file mode 100644 index 00000000..aa0cec4b --- /dev/null +++ b/menu/get/iwo/disk.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("disk") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_disk_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo disk""" + + # iserver get iwo disk + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_disks() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get disk') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_disks(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/main.py b/menu/get/iwo/main.py new file mode 100644 index 00000000..244ece2b --- /dev/null +++ b/menu/get/iwo/main.py @@ -0,0 +1,59 @@ +import click + + +from menu.get.iwo.action import get_iwo_action_command +from menu.get.iwo.application import get_iwo_application_command +from menu.get.iwo.chassis import get_iwo_chassis_command +from menu.get.iwo.cluster import get_iwo_cluster_command +from menu.get.iwo.container import get_iwo_container_command +from menu.get.iwo.dc import get_iwo_dc_command +from menu.get.iwo.disk import get_iwo_disk_command +from menu.get.iwo.namespace import get_iwo_namespace_command +from menu.get.iwo.network import get_iwo_network_command +from menu.get.iwo.phy import get_iwo_phy_command +from menu.get.iwo.pod import get_iwo_pod_command +from menu.get.iwo.region import get_iwo_region_command +from menu.get.iwo.service import get_iwo_service_command +from menu.get.iwo.spec import get_iwo_spec_command +from menu.get.iwo.storage import get_iwo_storage_command +from menu.get.iwo.switch import get_iwo_switch_command +from menu.get.iwo.target import get_iwo_target_command +from menu.get.iwo.workload import get_iwo_workload_command +from menu.get.iwo.vdc import get_iwo_vdc_command +from menu.get.iwo.vm import get_iwo_vm_command +from menu.get.iwo.volume import get_iwo_volume_command +from menu.get.iwo.zone import get_iwo_zone_command + + +class Failure(Exception): + pass + + +@click.group("iwo") +@click.pass_obj +def get_iwo_menu(ctx): + """Get iwo commands""" + + +get_iwo_menu.add_command(get_iwo_action_command) +get_iwo_menu.add_command(get_iwo_application_command) +get_iwo_menu.add_command(get_iwo_chassis_command) +get_iwo_menu.add_command(get_iwo_cluster_command) +get_iwo_menu.add_command(get_iwo_container_command) +get_iwo_menu.add_command(get_iwo_dc_command) +get_iwo_menu.add_command(get_iwo_disk_command) +get_iwo_menu.add_command(get_iwo_namespace_command) +get_iwo_menu.add_command(get_iwo_network_command) +get_iwo_menu.add_command(get_iwo_phy_command) +get_iwo_menu.add_command(get_iwo_pod_command) +get_iwo_menu.add_command(get_iwo_region_command) +get_iwo_menu.add_command(get_iwo_service_command) +get_iwo_menu.add_command(get_iwo_spec_command) +get_iwo_menu.add_command(get_iwo_storage_command) +get_iwo_menu.add_command(get_iwo_switch_command) +get_iwo_menu.add_command(get_iwo_target_command) +get_iwo_menu.add_command(get_iwo_workload_command) +get_iwo_menu.add_command(get_iwo_vdc_command) +get_iwo_menu.add_command(get_iwo_vm_command) +get_iwo_menu.add_command(get_iwo_volume_command) +get_iwo_menu.add_command(get_iwo_zone_command) diff --git a/menu/get/iwo/namespace.py b/menu/get/iwo/namespace.py new file mode 100644 index 00000000..4afacee1 --- /dev/null +++ b/menu/get/iwo/namespace.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("namespace") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_namespace_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo namespace""" + + # iserver get iwo namespace + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_namespaces() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get namespace') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_namespaces(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/network.py b/menu/get/iwo/network.py new file mode 100644 index 00000000..b394862e --- /dev/null +++ b/menu/get/iwo/network.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("network") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_network_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo network""" + + # iserver get iwo network + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_networks() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get network') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_networks(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/phy.py b/menu/get/iwo/phy.py new file mode 100644 index 00000000..94519cba --- /dev/null +++ b/menu/get/iwo/phy.py @@ -0,0 +1,178 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("phy") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--vm", "vm_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by vm name") +@click.option("--vdc", "vdc_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by vdc name") +@click.option("--storage", "storage_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by storage name") +@click.option("--stale", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select stale") +@click.option("--inactive", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select inactive") +@click.option("--critical", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select critical") +@click.option("--major", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select major or critical") +@click.option("--minor", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select minor, major or critical") +@click.option("--show-dep", is_flag=True, show_default=True, default=False, help="Show dependencies") +@click.option("--show-vm", is_flag=True, show_default=True, default=False, help="Show virtual machines") +@click.option("--show-vdc", is_flag=True, show_default=True, default=False, help="Show virtual data center") +@click.option("--show-storage", is_flag=True, show_default=True, default=False, help="Show storage") +@click.option("--show-actions", is_flag=True, show_default=True, default=False, help="Show actions") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_phy_command( + ctx, + iaccount, + name, + vm_name, + vdc_name, + storage_name, + stale, + inactive, + critical, + major, + minor, + show_dep, + show_vm, + show_vdc, + show_storage, + show_actions, + output, + verbose, + debug, + devel + ): + """Get iwo physical machine""" + + # iserver get iwo phy + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + match_rules = [] + if name is not None: + match_rules.append( + 'name:%s' % (name) + ) + + if vm_name is not None: + show_vm = True + show_dep = True + match_rules.append( + 'vm:%s' % (vm_name) + ) + + if vdc_name is not None: + show_vdc = True + show_dep = True + match_rules.append( + 'vdc:%s' % (vdc_name) + ) + + if storage_name is not None: + show_storage = True + show_dep = True + match_rules.append( + 'storage:%s' % (storage_name) + ) + + if stale is not None: + match_rules.append( + 'stale' + ) + + if inactive is not None: + match_rules.append( + 'inactive' + ) + + if critical is not None: + match_rules.append( + 'critical' + ) + + if major is not None: + match_rules.append( + 'major' + ) + + if minor is not None: + match_rules.append( + 'minor' + ) + + if show_vm or show_vdc or show_actions or show_storage: + show_dep = True + + phys = iwo_handler.get_physical_machines( + resolve_dependencies=show_dep, + match_rules=match_rules + ) + if phys is None: + ctx.busy = False + ctx.my_output.error('Failed to get physical machines') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + phys, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(phys) + + iwo_handler.print_physical_machines( + phys, + show_dep=show_dep, + show_vm=show_vm, + show_vdc=show_vdc, + show_storage=show_storage, + show_actions=show_actions + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/pod.py b/menu/get/iwo/pod.py new file mode 100644 index 00000000..2928ffd5 --- /dev/null +++ b/menu/get/iwo/pod.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("pod") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_pod_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo pod""" + + # iserver get iwo pod + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_pods() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get pod') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_pods(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/region.py b/menu/get/iwo/region.py new file mode 100644 index 00000000..04eec4d9 --- /dev/null +++ b/menu/get/iwo/region.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("region") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_region_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo region""" + + # iserver get iwo region + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_regions() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get region') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_regions(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/service.py b/menu/get/iwo/service.py new file mode 100644 index 00000000..4a364649 --- /dev/null +++ b/menu/get/iwo/service.py @@ -0,0 +1,158 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("service") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--cluster", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by cluster") +@click.option("--app", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by application") +@click.option("--stale", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select stale") +@click.option("--inactive", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select inactive") +@click.option("--critical", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select critical") +@click.option("--major", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select major or critical") +@click.option("--minor", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select minor, major or critical") +@click.option("--show-app", is_flag=True, show_default=True, default=False, help="Show service applications") +@click.option("--show-actions", is_flag=True, show_default=True, default=False, help="Show service actions") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_service_command( + ctx, + iaccount, + name, + cluster, + app, + stale, + inactive, + critical, + major, + minor, + show_app, + show_actions, + output, + verbose, + debug, + devel + ): + """Get iwo kubernetes service""" + + # iserver get iwo service + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + match_rules = [] + if name is not None: + match_rules.append( + 'name:%s' % (name) + ) + + if cluster is not None: + match_rules.append( + 'cluster:%s' % (cluster) + ) + + if app is not None: + show_app = True + match_rules.append( + 'app:%s' % (app) + ) + + if stale is not None: + match_rules.append( + 'stale' + ) + + if inactive is not None: + match_rules.append( + 'inactive' + ) + + if critical is not None: + match_rules.append( + 'critical' + ) + + if major is not None: + match_rules.append( + 'major' + ) + + if minor is not None: + match_rules.append( + 'minor' + ) + + resolve_dependencies = False + if show_app or show_actions: + resolve_dependencies = True + + managed_objects = iwo_handler.get_services( + resolve_dependencies=resolve_dependencies, + match_rules=match_rules + ) + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get kubernetes service') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_services( + managed_objects, + show_actions=show_actions, + show_app=show_app + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/spec.py b/menu/get/iwo/spec.py new file mode 100644 index 00000000..32b7186d --- /dev/null +++ b/menu/get/iwo/spec.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("spec") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_spec_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo spec""" + + # iserver get iwo spec + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_specs() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get spec') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_specs(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/storage.py b/menu/get/iwo/storage.py new file mode 100644 index 00000000..80319103 --- /dev/null +++ b/menu/get/iwo/storage.py @@ -0,0 +1,166 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("storage") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--vm", "vm_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by vm name") +@click.option("--phy", "phy_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by phy name") +@click.option("--stale", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select stale") +@click.option("--inactive", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select inactive") +@click.option("--critical", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select critical") +@click.option("--major", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select major or critical") +@click.option("--minor", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select minor, major or critical") +@click.option("--show-dep", is_flag=True, show_default=True, default=False, help="Show dependencies") +@click.option("--show-vm", is_flag=True, show_default=True, default=False, help="Show virtual machines") +@click.option("--show-phy", is_flag=True, show_default=True, default=False, help="Show physical machines") +@click.option("--show-actions", is_flag=True, show_default=True, default=False, help="Show actions") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_storage_command( + ctx, + iaccount, + name, + vm_name, + phy_name, + stale, + inactive, + critical, + major, + minor, + show_dep, + show_vm, + show_phy, + show_actions, + output, + verbose, + debug, + devel + ): + """Get iwo storage device""" + + # iserver get iwo storage + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + match_rules = [] + if name is not None: + match_rules.append( + 'name:%s' % (name) + ) + + if vm_name is not None: + show_vm = True + show_dep = True + match_rules.append( + 'vm:%s' % (vm_name) + ) + + if phy_name is not None: + show_phy = True + show_dep = True + match_rules.append( + 'phy:%s' % (phy_name) + ) + + if stale is not None: + match_rules.append( + 'stale' + ) + + if inactive is not None: + match_rules.append( + 'inactive' + ) + + if critical is not None: + match_rules.append( + 'critical' + ) + + if major is not None: + match_rules.append( + 'major' + ) + + if minor is not None: + match_rules.append( + 'minor' + ) + + if show_vm or show_phy or show_actions: + show_dep = True + + storage = iwo_handler.get_storages( + resolve_dependencies=show_dep, + match_rules=match_rules + ) + if storage is None: + ctx.busy = False + ctx.my_output.error('Failed to get storage devices') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + storage, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(storage) + + iwo_handler.print_storages( + storage, + show_dep=show_dep, + show_actions=show_actions, + show_vm=show_vm, + show_phy=show_phy + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/switch.py b/menu/get/iwo/switch.py new file mode 100644 index 00000000..6187e2a7 --- /dev/null +++ b/menu/get/iwo/switch.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("switch") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_switch_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo switch""" + + # iserver get iwo switch + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_switchs() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get switch') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_switchs(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/target.py b/menu/get/iwo/target.py new file mode 100644 index 00000000..b1932b94 --- /dev/null +++ b/menu/get/iwo/target.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("target") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_target_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo target""" + + # iserver get iwo target + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + targets = iwo_handler.get_targets() + if targets is None: + ctx.busy = False + ctx.my_output.error('Failed to get targets') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + targets, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(targets) + + iwo_handler.print_targets(targets) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/vdc.py b/menu/get/iwo/vdc.py new file mode 100644 index 00000000..74e12875 --- /dev/null +++ b/menu/get/iwo/vdc.py @@ -0,0 +1,166 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vdc") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--vm", "vm_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by vm name") +@click.option("--phy", "phy_name", is_flag=False, show_default=True, default='', type=click.STRING, callback=validations.empty_string_to_none, help="Filter by phy name") +@click.option("--stale", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select stale") +@click.option("--inactive", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select inactive") +@click.option("--critical", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select critical") +@click.option("--major", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select major or critical") +@click.option("--minor", is_flag=True, show_default=True, default=False, type=click.STRING, help="Select minor, major or critical") +@click.option("--show-dep", is_flag=True, show_default=True, default=False, help="Show dependencies") +@click.option("--show-vm", is_flag=True, show_default=True, default=False, help="Show virtual machines") +@click.option("--show-phy", is_flag=True, show_default=True, default=False, help="Show physical machines") +@click.option("--show-actions", is_flag=True, show_default=True, default=False, help="Show actions") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_vdc_command( + ctx, + iaccount, + name, + vm_name, + phy_name, + stale, + inactive, + critical, + major, + minor, + show_dep, + show_vm, + show_phy, + show_actions, + output, + verbose, + debug, + devel + ): + """Get iwo virtual data center""" + + # iserver get iwo vdc + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + match_rules = [] + if name is not None: + match_rules.append( + 'name:%s' % (name) + ) + + if vm_name is not None: + show_vm = True + show_dep = True + match_rules.append( + 'vm:%s' % (vm_name) + ) + + if phy_name is not None: + show_phy = True + show_dep = True + match_rules.append( + 'phy:%s' % (phy_name) + ) + + if stale is not None: + match_rules.append( + 'stale' + ) + + if inactive is not None: + match_rules.append( + 'inactive' + ) + + if critical is not None: + match_rules.append( + 'critical' + ) + + if major is not None: + match_rules.append( + 'major' + ) + + if minor is not None: + match_rules.append( + 'minor' + ) + + if show_vm or show_phy or show_actions: + show_dep = True + + vdc = iwo_handler.get_virtual_data_centers( + resolve_dependencies=show_dep, + match_rules=match_rules + ) + if vdc is None: + ctx.busy = False + ctx.my_output.error('Failed to get virtual data centers') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vdc, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(vdc) + + iwo_handler.print_virtual_data_centers( + vdc, + show_dep=show_dep, + show_actions=show_actions, + show_vm=show_vm, + show_phy=show_phy + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/vm.py b/menu/get/iwo/vm.py new file mode 100644 index 00000000..d52b1ebf --- /dev/null +++ b/menu/get/iwo/vm.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import defaults +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_vm_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo vm""" + + # iserver get iwo vm + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + vms = iwo_handler.get_virtual_machines() + if vms is None: + ctx.busy = False + ctx.my_output.error('Failed to get virtual machines') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vms, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(vms) + + iwo_handler.print_virtual_machines(vms) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/volume.py b/menu/get/iwo/volume.py new file mode 100644 index 00000000..2c8882b1 --- /dev/null +++ b/menu/get/iwo/volume.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("volume") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_volume_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo volume""" + + # iserver get iwo volume + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_volumes() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get volume') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_volumes(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/workload.py b/menu/get/iwo/workload.py new file mode 100644 index 00000000..94acea9f --- /dev/null +++ b/menu/get/iwo/workload.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("workload") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_workload_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo workload""" + + # iserver get iwo workload + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_workloads() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get workload') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_workloads(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/iwo/zone.py b/menu/get/iwo/zone.py new file mode 100644 index 00000000..c49ecbc8 --- /dev/null +++ b/menu/get/iwo/zone.py @@ -0,0 +1,85 @@ +import sys +import json +import threading +import traceback +import click + +from lib.iwo import main as iwo + +from menu import validations +from menu import defaults +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("zone") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_iwo_zone_command( + ctx, + iaccount, + output, + verbose, + debug, + devel + ): + """Get iwo zone""" + + # iserver get iwo zone + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + iwo_handler = iwo.Iwo( + iaccount, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + managed_objects = iwo_handler.get_zones() + if managed_objects is None: + ctx.busy = False + ctx.my_output.error('Failed to get zone') + raise ErrorExit + + if output == 'json': + ctx.busy = False + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + managed_objects, + indent=4 + ) + ) + return + + ctx.busy = False + ctx.my_output.json_output(managed_objects) + + iwo_handler.print_zones(managed_objects) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/__init__.py b/menu/get/k8s/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/k8s/am.py b/menu/get/k8s/am.py new file mode 100644 index 00000000..62c56e09 --- /dev/null +++ b/menu/get/k8s/am.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("am") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_am_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s alert manager""" + + # iserver get k8s am + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + alert_managers = k8s_handlers.get_alert_managers( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + alert_managers, + indent=4 + ) + ) + return + + alert_managers = k8s_handlers.get_alert_managers( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + alert_managers, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_alert_managers( + alert_managers, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/amcfg.py b/menu/get/k8s/amcfg.py new file mode 100644 index 00000000..c2026d82 --- /dev/null +++ b/menu/get/k8s/amcfg.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("amcfg") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_amcfg_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s alert manager config""" + + # iserver get k8s amcfg + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + alert_manager_configs = k8s_handlers.get_alert_manager_configs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + alert_manager_configs, + indent=4 + ) + ) + return + + alert_manager_configs = k8s_handlers.get_alert_manager_configs( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + alert_manager_configs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_alert_manager_configs( + alert_manager_configs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/cluster.py b/menu/get/k8s/cluster.py new file mode 100644 index 00000000..42c754fd --- /dev/null +++ b/menu/get/k8s/cluster.py @@ -0,0 +1,114 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import main as k8s +from lib.k8s import settings as k8s_settings +from lib.ocp import settings as ocp_settings +from lib.k8s import output as k8s_output + +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--verify", is_flag=True, show_default=True, default=False, help="Verify api access") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_cluster( + ctx, + verify, + output, + devel + ): + """Get k8s cluster settings""" + + # iserver get k8s cluster + + ctx.developer = devel + ctx.output = output + + try: + k8s_settings_handler = k8s_settings.K8sSettings(log_id=ctx.run_id) + ocp_settings_handler = ocp_settings.OcpSettings(log_id=ctx.run_id) + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + + clusters = k8s_settings_handler.get_k8s_clusters() + + if clusters is None or len(clusters) == 0: + ctx.my_output.default('No kubernetes clusters defined') + return + + default_cluster_name = k8s_settings_handler.get_default_cluster() + for cluster in clusters: + cluster['__Output'] = {} + + if default_cluster_name is not None and cluster['name'] == default_cluster_name: + cluster['__Output']['defaultTick'] = 'Green' + cluster['defaultTick'] = '\u2713' + + for key in ['virtctl', 'helm', 'tools']: + cluster[key] = None + + if cluster['type'] == 'ocp' and cluster['source'] == 'import': + ocp_cluster = ocp_settings_handler.get_ocp_cluster( + cluster['name'] + ) + if ocp_cluster is not None: + for key in ['virtctl', 'helm', 'tools']: + cluster[key] = ocp_cluster[key] + if cluster[key] is not None: + cluster[key]['description'] = '%s@%s' % ( + cluster[key]['username'], + cluster[key]['ip'] + ) + + if verify: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + for cluster in clusters: + cluster['__Output']['apiTick'] = 'Red' + cluster['apiTick'] = '\u2717' + + k8s_handler = k8s.K8s(kubeconfig_filename=cluster['kubeconfig'], cluster_type=cluster['type'], log_id=ctx.run_id) + if k8s_handler.get_api() is not None: + cluster['__Output']['apiTick'] = 'Green' + cluster['apiTick'] = '\u2713' + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + clusters, + indent=4 + ) + ) + return + + ctx.my_output.json_output(clusters) + + k8s_output_handler.print_clusters( + clusters, + title=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/cm.py b/menu/get/k8s/cm.py new file mode 100644 index 00000000..60b21c0f --- /dev/null +++ b/menu/get/k8s/cm.py @@ -0,0 +1,172 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("cm") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--cname", default='', callback=validations.empty_string_to_none, help="Filter by cm name") +@click.option("--cdata", default='', callback=validations.empty_string_to_none, help="Filter by cm data") +@click.option("--view", "-v", default=['state'], help="[state|name|data|pod|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_cm_command( + ctx, + cluster, + namespace, + name, + cname, + cdata, + view, + output, + devel + ): + """Get k8s config map""" + + # iserver get k8s cm + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|name|data|pod|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if cname is not None: + object_filter.append( + 'cm-name:%s' % (cname) + ) + + if cdata is not None: + object_filter.append( + 'cm-data:%s' % (cdata) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + config_maps = k8s_handlers.get_config_maps( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + config_maps, + indent=4 + ) + ) + return + + pod_info = False + if 'pod' in view: + pod_info = True + + config_maps = k8s_handlers.get_config_maps( + object_filter=object_filter, + pod_info=pod_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + config_maps, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_config_maps( + config_maps, + title=True + ) + + if 'name' in view: + k8s_output_handler.print_config_maps_name( + config_maps, + title=True + ) + + if 'data' in view: + k8s_output_handler.print_config_maps_data( + config_maps, + title=True + ) + + if 'pod' in view: + k8s_output_handler.print_config_maps_pod( + config_maps, + title=True + ) + + ctx.my_output.default('Filter: namespace, name, cname, cdata', before_newline=True) + ctx.my_output.default('View: state (def), name, data, pod, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/cni.py b/menu/get/k8s/cni.py new file mode 100644 index 00000000..a9eb9141 --- /dev/null +++ b/menu/get/k8s/cni.py @@ -0,0 +1,123 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("cni") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_cni_command( + ctx, + cluster, + namespace, + name, + output, + devel + ): + """Get k8s volume attachment""" + + # iserver get k8s cni + + ctx.developer = devel + ctx.output = output + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + cnis = k8s_handlers.get_cnis( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + cnis, + indent=4 + ) + ) + return + + cnis = k8s_handlers.get_cnis( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + cnis, + indent=4 + ) + ) + return + + k8s_output_handler.print_cnis( + cnis, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/cquota.py b/menu/get/k8s/cquota.py new file mode 100644 index 00000000..f7bd6f7e --- /dev/null +++ b/menu/get/k8s/cquota.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("cquota") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_cquota_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s cluster quota""" + + # iserver get k8s cquota + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + cluster_quotas = k8s_handlers.get_cluster_quotas( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + cluster_quotas, + indent=4 + ) + ) + return + + cluster_quotas = k8s_handlers.get_cluster_quotas( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + cluster_quotas, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_cluster_quotas( + cluster_quotas, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/crb.py b/menu/get/k8s/crb.py new file mode 100644 index 00000000..56778a08 --- /dev/null +++ b/menu/get/k8s/crb.py @@ -0,0 +1,142 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("crb") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--role", default='', callback=validations.empty_string_to_none, help="Filter by role") +@click.option("--subject", default='', callback=validations.empty_string_to_none, help="Filter by subject") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_crb_command( + ctx, + cluster, + name, + role, + subject, + view, + output, + devel + ): + """Get k8s cluster role bindings""" + + # iserver get k8s crb + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if role is not None: + object_filter.append( + 'role:%s' % (role) + ) + + if subject is not None: + object_filter.append( + 'subject:%s' % (subject) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + crbs = k8s_handlers.get_cluster_role_bindings( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + crbs, + indent=4 + ) + ) + return + + crbs = k8s_handlers.get_cluster_role_bindings( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + crbs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_cluster_role_bindings( + crbs, + title=True + ) + + ctx.my_output.default('Filter: name, role, subject', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/crd.py b/menu/get/k8s/crd.py new file mode 100644 index 00000000..e0e174bf --- /dev/null +++ b/menu/get/k8s/crd.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("crd") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_crd_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s custom resource definition""" + + # iserver get k8s crd + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + custom_resource_definitions = k8s_handlers.get_custom_resource_definitions( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + custom_resource_definitions, + indent=4 + ) + ) + return + + custom_resource_definitions = k8s_handlers.get_custom_resource_definitions( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + custom_resource_definitions, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_custom_resource_definitions( + custom_resource_definitions, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/csv.py b/menu/get/k8s/csv.py new file mode 100644 index 00000000..a1fc18d8 --- /dev/null +++ b/menu/get/k8s/csv.py @@ -0,0 +1,127 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("csv") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_csv_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s cluster service version""" + + # iserver get k8s csv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + cluster_service_versions = k8s_handlers.get_cluster_service_versions( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + cluster_service_versions, + indent=4 + ) + ) + return + + cluster_service_versions = k8s_handlers.get_cluster_service_versions( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + cluster_service_versions, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_cluster_service_versions( + cluster_service_versions, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/dc.py b/menu/get/k8s/dc.py new file mode 100644 index 00000000..a995d3ae --- /dev/null +++ b/menu/get/k8s/dc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("dc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_dc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s deployment config""" + + # iserver get k8s dc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + deployment_configs = k8s_handlers.get_deployment_configs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + deployment_configs, + indent=4 + ) + ) + return + + deployment_configs = k8s_handlers.get_deployment_configs( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + deployment_configs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_deployment_configs( + deployment_configs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/dep.py b/menu/get/k8s/dep.py new file mode 100644 index 00000000..e555023d --- /dev/null +++ b/menu/get/k8s/dep.py @@ -0,0 +1,141 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("dep") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|metadata|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_dep_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s deployment""" + + # iserver get k8s dep + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|metadata|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + deployments = k8s_handlers.get_deployments( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + deployments, + indent=4 + ) + ) + return + + deployments = k8s_handlers.get_deployments( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + deployments, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_deployments( + deployments, + title=True + ) + + if 'metadata' in view: + k8s_output_handler.print_deployments_metadata( + deployments, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), metadata, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ds.py b/menu/get/k8s/ds.py new file mode 100644 index 00000000..4cafcac5 --- /dev/null +++ b/menu/get/k8s/ds.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ds") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ds_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s daemon set""" + + # iserver get k8s ds + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + daemon_sets = k8s_handlers.get_daemon_sets( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + daemon_sets, + indent=4 + ) + ) + return + + daemon_sets = k8s_handlers.get_daemon_sets( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + daemon_sets, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_daemon_sets( + daemon_sets, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/dv.py b/menu/get/k8s/dv.py new file mode 100644 index 00000000..7cf34824 --- /dev/null +++ b/menu/get/k8s/dv.py @@ -0,0 +1,134 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("dv") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_dv_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s data volume (ocp)""" + + # iserver get k8s dv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + dvs = k8s_handlers.get_data_volumes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + dvs, + indent=4 + ) + ) + return + + dvs = k8s_handlers.get_data_volumes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + dvs, + indent=4 + ) + ) + return + + k8s_output_handler.print_data_volumes( + dvs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/eip.py b/menu/get/k8s/eip.py new file mode 100644 index 00000000..eddbe0da --- /dev/null +++ b/menu/get/k8s/eip.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("eip") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_eip_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s egress ip""" + + # iserver get k8s eip + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + egress_ips = k8s_handlers.get_egress_ips( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + egress_ips, + indent=4 + ) + ) + return + + egress_ips = k8s_handlers.get_egress_ips( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + egress_ips, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_egress_ips( + egress_ips, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ep.py b/menu/get/k8s/ep.py new file mode 100644 index 00000000..94efde69 --- /dev/null +++ b/menu/get/k8s/ep.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ep") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ep_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s endpoint""" + + # iserver get k8s ep + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + endpoints = k8s_handlers.get_endpoints( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + endpoints, + indent=4 + ) + ) + return + + endpoints = k8s_handlers.get_endpoints( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + endpoints, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_endpoints( + endpoints, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/erouter.py b/menu/get/k8s/erouter.py new file mode 100644 index 00000000..2c180671 --- /dev/null +++ b/menu/get/k8s/erouter.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("erouter") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_erouter_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s egress router""" + + # iserver get k8s erouter + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + egress_routers = k8s_handlers.get_egress_routers( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + egress_routers, + indent=4 + ) + ) + return + + egress_routers = k8s_handlers.get_egress_routers( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + egress_routers, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_egress_routers( + egress_routers, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ev.py b/menu/get/k8s/ev.py new file mode 100644 index 00000000..150b84d0 --- /dev/null +++ b/menu/get/k8s/ev.py @@ -0,0 +1,149 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ev") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--kind", default='', callback=validations.empty_string_to_none, help="Filter by kind") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--message", default='', callback=validations.empty_string_to_none, help="Filter by message") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ev_command( + ctx, + cluster, + kind, + namespace, + name, + message, + view, + output, + devel + ): + """Get k8s event""" + + # iserver get k8s ev + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if kind is not None: + object_filter.append( + 'kind:%s' % (kind) + ) + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if message is not None: + object_filter.append( + 'message:%s' % (message) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + events = k8s_handlers.get_events( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + events, + indent=4 + ) + ) + return + + events = k8s_handlers.get_events( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + events, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_events( + events, + title=True + ) + + ctx.my_output.default('Filter: namespace, name, kind, message', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ing.py b/menu/get/k8s/ing.py new file mode 100644 index 00000000..1675a836 --- /dev/null +++ b/menu/get/k8s/ing.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ing") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ing_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s ingress""" + + # iserver get k8s ingress + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + ingresses = k8s_handlers.get_ingresses( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + ingresses, + indent=4 + ) + ) + return + + ingresses = k8s_handlers.get_ingresses( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + ingresses, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_ingresses( + ingresses, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/kc.py b/menu/get/k8s/kc.py new file mode 100644 index 00000000..f9cd4c58 --- /dev/null +++ b/menu/get/k8s/kc.py @@ -0,0 +1,90 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import main as k8s +from lib.k8s import settings as k8s_settings +from lib.k8s import output as k8s_output + +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("kc") +@click.pass_obj +@click.option("--verify", is_flag=True, show_default=True, default=False, help="Verify api access") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_kc_command( + ctx, + verify, + output, + devel + ): + """Get k8s kubeconfig""" + + # iserver get k8s kc + + ctx.developer = devel + ctx.output = output + + try: + k8s_settings_handler = k8s_settings.K8sSettings(log_id=ctx.run_id) + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + + clusters_info = k8s_settings_handler.get_clusters_kubeconfig_info() + + if clusters_info is None or len(clusters_info) == 0: + ctx.my_output.default('No kubernetes clusters defined') + return + + if verify: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + for cluster_info in clusters_info: + k8s_handler = k8s.K8s(cluster_info['kubeconfigFilename']) + if k8s_handler.get_api() is not None: + cluster_info['kubeApi'] = True + cluster_info['kubeApiTick'] = '\u2713' + cluster_info['__Output']['kubeApiTick'] = 'Green' + else: + cluster_info['kubeApi'] = False + cluster_info['kubeApiTick'] = '\u2717' + cluster_info['__Output']['kubeApiTick'] = 'Red' + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + clusters_info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(clusters_info) + + k8s_output_handler.print_clusters_kubeconfig( + clusters_info, + title=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/kv.py b/menu/get/k8s/kv.py new file mode 100644 index 00000000..2bcf9902 --- /dev/null +++ b/menu/get/k8s/kv.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("kv") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_kv_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s kubevirt""" + + # iserver get k8s kv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + kubevirts = k8s_handlers.get_kubevirts( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + kubevirts, + indent=4 + ) + ) + return + + kubevirts = k8s_handlers.get_kubevirts( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + kubevirts, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_kubevirts( + kubevirts, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/limit.py b/menu/get/k8s/limit.py new file mode 100644 index 00000000..f7b248bc --- /dev/null +++ b/menu/get/k8s/limit.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("limit") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_limit_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s limit ranges""" + + # iserver get k8s limit + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + limits = k8s_handlers.get_limits( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + limits, + indent=4 + ) + ) + return + + limits = k8s_handlers.get_limits( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + limits, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_limits( + limits, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/main.py b/menu/get/k8s/main.py new file mode 100644 index 00000000..bd05afc2 --- /dev/null +++ b/menu/get/k8s/main.py @@ -0,0 +1,168 @@ +import click + +from menu.get.k8s.am import get_k8s_am_command +from menu.get.k8s.amcfg import get_k8s_amcfg_command +from menu.get.k8s.cluster import get_k8s_cluster +from menu.get.k8s.cm import get_k8s_cm_command +from menu.get.k8s.cni import get_k8s_cni_command +from menu.get.k8s.cquota import get_k8s_cquota_command +from menu.get.k8s.crb import get_k8s_crb_command +from menu.get.k8s.crd import get_k8s_crd_command +from menu.get.k8s.csv import get_k8s_csv_command +from menu.get.k8s.dc import get_k8s_dc_command +from menu.get.k8s.dep import get_k8s_dep_command +from menu.get.k8s.ds import get_k8s_ds_command +from menu.get.k8s.dv import get_k8s_dv_command +from menu.get.k8s.eip import get_k8s_eip_command +from menu.get.k8s.ep import get_k8s_ep_command +from menu.get.k8s.erouter import get_k8s_erouter_command +from menu.get.k8s.ev import get_k8s_ev_command +from menu.get.k8s.ing import get_k8s_ing_command +from menu.get.k8s.kc import get_k8s_kc_command +from menu.get.k8s.kv import get_k8s_kv_command +from menu.get.k8s.limit import get_k8s_limit_command +from menu.get.k8s.mc import get_k8s_mc_command +from menu.get.k8s.mcp import get_k8s_mcp_command +from menu.get.k8s.nad import get_k8s_nad_command +from menu.get.k8s.nnce import get_k8s_nnce_command +from menu.get.k8s.nncp import get_k8s_nncp_command +from menu.get.k8s.nns import get_k8s_nns_command +from menu.get.k8s.node import get_k8s_node_command +from menu.get.k8s.ns import get_k8s_ns_command +from menu.get.k8s.og import get_k8s_og_command +from menu.get.k8s.pc import get_k8s_pc_command +from menu.get.k8s.pmon import get_k8s_pmon_command +from menu.get.k8s.pod import get_k8s_pod_command +from menu.get.k8s.pp import get_k8s_pp_command +from menu.get.k8s.prb import get_k8s_prb_command +from menu.get.k8s.profile import get_k8s_profile_command +from menu.get.k8s.prom import get_k8s_prom_command +from menu.get.k8s.promrule import get_k8s_promrule_command +from menu.get.k8s.pv import get_k8s_pv_command +from menu.get.k8s.pvc import get_k8s_pvc_command +from menu.get.k8s.quota import get_k8s_quota_command +from menu.get.k8s.rb import get_k8s_rb_command +from menu.get.k8s.rc import get_k8s_rc_command +from menu.get.k8s.route import get_k8s_route_command +from menu.get.k8s.rs import get_k8s_rs_command +from menu.get.k8s.ruler import get_k8s_ruler_command +from menu.get.k8s.sa import get_k8s_sa_command +from menu.get.k8s.sc import get_k8s_sc_command +from menu.get.k8s.scc import get_k8s_scc_command +from menu.get.k8s.sec import get_k8s_sec_command +from menu.get.k8s.smon import get_k8s_smon_command +from menu.get.k8s.srn import get_k8s_srn_command +from menu.get.k8s.srnnp import get_k8s_srnnp_command +from menu.get.k8s.srnns import get_k8s_srnns_command +from menu.get.k8s.sts import get_k8s_sts_command +from menu.get.k8s.sub import get_k8s_sub_command +from menu.get.k8s.svc import get_k8s_svc_command +from menu.get.k8s.tuned import get_k8s_tuned_command +from menu.get.k8s.va import get_k8s_va_command +from menu.get.k8s.ver import get_k8s_ver_command +from menu.get.k8s.vm import get_k8s_vm_command +from menu.get.k8s.vmc import get_k8s_vmc_command +from menu.get.k8s.vmcf import get_k8s_vmcf_command +from menu.get.k8s.vmcp import get_k8s_vmcp_command +from menu.get.k8s.vme import get_k8s_vme_command +from menu.get.k8s.vmf import get_k8s_vmf_command +from menu.get.k8s.vmi import get_k8s_vmi_command +from menu.get.k8s.vmim import get_k8s_vmim_command +from menu.get.k8s.vmipr import get_k8s_vmipr_command +from menu.get.k8s.vmirs import get_k8s_vmirs_command +from menu.get.k8s.vmp import get_k8s_vmp_command +from menu.get.k8s.vmr import get_k8s_vmr_command +from menu.get.k8s.vms import get_k8s_vms_command +from menu.get.k8s.vmsc import get_k8s_vmsc_command +from menu.get.k8s.vs import get_k8s_vs_command +from menu.get.k8s.vsc import get_k8s_vsc_command +from menu.get.k8s.vsclass import get_k8s_vsclass_command + + +class Failure(Exception): + pass + + +@click.group("k8s") +@click.pass_obj +def get_k8s_menu(ctx): + """Get k8s commands (alpha)""" + + +get_k8s_menu.add_command(get_k8s_am_command) +get_k8s_menu.add_command(get_k8s_amcfg_command) +get_k8s_menu.add_command(get_k8s_cluster) +get_k8s_menu.add_command(get_k8s_cm_command) +get_k8s_menu.add_command(get_k8s_cni_command) +get_k8s_menu.add_command(get_k8s_cquota_command) +get_k8s_menu.add_command(get_k8s_crb_command) +get_k8s_menu.add_command(get_k8s_crd_command) +get_k8s_menu.add_command(get_k8s_csv_command) +get_k8s_menu.add_command(get_k8s_dc_command) +get_k8s_menu.add_command(get_k8s_dep_command) +get_k8s_menu.add_command(get_k8s_ds_command) +get_k8s_menu.add_command(get_k8s_dv_command) +get_k8s_menu.add_command(get_k8s_eip_command) +get_k8s_menu.add_command(get_k8s_ep_command) +get_k8s_menu.add_command(get_k8s_erouter_command) +get_k8s_menu.add_command(get_k8s_ev_command) +get_k8s_menu.add_command(get_k8s_ing_command) +get_k8s_menu.add_command(get_k8s_kc_command) +get_k8s_menu.add_command(get_k8s_kv_command) +get_k8s_menu.add_command(get_k8s_limit_command) +get_k8s_menu.add_command(get_k8s_mc_command) +get_k8s_menu.add_command(get_k8s_mcp_command) +get_k8s_menu.add_command(get_k8s_nad_command) +get_k8s_menu.add_command(get_k8s_nnce_command) +get_k8s_menu.add_command(get_k8s_nncp_command) +get_k8s_menu.add_command(get_k8s_nns_command) +get_k8s_menu.add_command(get_k8s_node_command) +get_k8s_menu.add_command(get_k8s_ns_command) +get_k8s_menu.add_command(get_k8s_og_command) +get_k8s_menu.add_command(get_k8s_pc_command) +get_k8s_menu.add_command(get_k8s_pmon_command) +get_k8s_menu.add_command(get_k8s_pod_command) +get_k8s_menu.add_command(get_k8s_pp_command) +get_k8s_menu.add_command(get_k8s_prb_command) +get_k8s_menu.add_command(get_k8s_profile_command) +get_k8s_menu.add_command(get_k8s_prom_command) +get_k8s_menu.add_command(get_k8s_promrule_command) +get_k8s_menu.add_command(get_k8s_pv_command) +get_k8s_menu.add_command(get_k8s_pvc_command) +get_k8s_menu.add_command(get_k8s_quota_command) +get_k8s_menu.add_command(get_k8s_rb_command) +get_k8s_menu.add_command(get_k8s_rc_command) +get_k8s_menu.add_command(get_k8s_route_command) +get_k8s_menu.add_command(get_k8s_rs_command) +get_k8s_menu.add_command(get_k8s_ruler_command) +get_k8s_menu.add_command(get_k8s_sa_command) +get_k8s_menu.add_command(get_k8s_sc_command) +get_k8s_menu.add_command(get_k8s_scc_command) +get_k8s_menu.add_command(get_k8s_sec_command) +get_k8s_menu.add_command(get_k8s_smon_command) +get_k8s_menu.add_command(get_k8s_srn_command) +get_k8s_menu.add_command(get_k8s_srnnp_command) +get_k8s_menu.add_command(get_k8s_srnns_command) +get_k8s_menu.add_command(get_k8s_sts_command) +get_k8s_menu.add_command(get_k8s_sub_command) +get_k8s_menu.add_command(get_k8s_svc_command) +get_k8s_menu.add_command(get_k8s_tuned_command) +get_k8s_menu.add_command(get_k8s_va_command) +get_k8s_menu.add_command(get_k8s_ver_command) +get_k8s_menu.add_command(get_k8s_vm_command) +get_k8s_menu.add_command(get_k8s_vmc_command) +get_k8s_menu.add_command(get_k8s_vmcf_command) +get_k8s_menu.add_command(get_k8s_vmcp_command) +get_k8s_menu.add_command(get_k8s_vme_command) +get_k8s_menu.add_command(get_k8s_vmf_command) +get_k8s_menu.add_command(get_k8s_vmi_command) +get_k8s_menu.add_command(get_k8s_vmim_command) +get_k8s_menu.add_command(get_k8s_vmipr_command) +get_k8s_menu.add_command(get_k8s_vmirs_command) +get_k8s_menu.add_command(get_k8s_vmp_command) +get_k8s_menu.add_command(get_k8s_vmr_command) +get_k8s_menu.add_command(get_k8s_vms_command) +get_k8s_menu.add_command(get_k8s_vmsc_command) +get_k8s_menu.add_command(get_k8s_vs_command) +get_k8s_menu.add_command(get_k8s_vsc_command) +get_k8s_menu.add_command(get_k8s_vsclass_command) diff --git a/menu/get/k8s/mc.py b/menu/get/k8s/mc.py new file mode 100644 index 00000000..f17b7bcf --- /dev/null +++ b/menu/get/k8s/mc.py @@ -0,0 +1,184 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("mc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by mc name") +@click.option("--path", "filepath", default='', callback=validations.empty_string_to_none, help="Filter by file path") +@click.option("--systemd", default='', callback=validations.empty_string_to_none, help="Filter by systemd name") +@click.option("--content", default='', callback=validations.empty_string_to_none, help="Filter by content") +@click.option("--view", "-v", default=['state'], help="[state|file|systemd|fcontent|scontent|user|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_mc_command( + ctx, + cluster, + name, + filepath, + systemd, + content, + view, + output, + devel + ): + """Get k8s machine config (ocp)""" + + # iserver get k8s mc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|file|systemd|fcontent|scontent|user|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if filepath is not None: + object_filter.append( + 'path:%s' % (filepath) + ) + + if systemd is not None: + object_filter.append( + 'systemd:%s' % (systemd) + ) + + if content is not None: + object_filter.append( + 'content:%s' % (content) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + machine_configs = k8s_handlers.get_machine_configs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + machine_configs, + indent=4 + ) + ) + return + + machine_configs = k8s_handlers.get_machine_configs( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + machine_configs, + indent=4 + ) + ) + return + + if len(machine_configs) == 0: + ctx.my_output.error( + 'No machine config found matching the search criteria' + ) + raise ErrorExit + + if 'state' in view: + k8s_output_handler.print_machine_configs( + machine_configs, + title=True + ) + + if 'file' in view: + k8s_output_handler.print_machine_configs_file( + machine_configs, + title=True + ) + + if 'fcontent' in view: + k8s_output_handler.print_machine_configs_content_file( + machine_configs, + title=True + ) + + if 'systemd' in view: + k8s_output_handler.print_machine_configs_systemd( + machine_configs, + title=True + ) + + if 'scontent' in view: + k8s_output_handler.print_machine_configs_content_systemd( + machine_configs, + title=True + ) + + if 'user' in view: + k8s_output_handler.print_machine_configs_user( + machine_configs, + title=True + ) + + ctx.my_output.default('Filter: name, path, systemd, content', before_newline=True) + ctx.my_output.default('View: state (def), file, systemd, fcontent, scontent, user, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/mcp.py b/menu/get/k8s/mcp.py new file mode 100644 index 00000000..6855f9ec --- /dev/null +++ b/menu/get/k8s/mcp.py @@ -0,0 +1,139 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("mcp") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|selector|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_mcp_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s machine config pool (ocp)""" + + # iserver get k8s mcp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|selector|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + selector_info = False + if 'selector' in view: + selector_info = True + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + machine_config_pools = k8s_handlers.get_machine_config_pools( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + machine_config_pools, + indent=4 + ) + ) + return + + machine_config_pools = k8s_handlers.get_machine_config_pools( + object_filter=object_filter, + selector_info=selector_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + machine_config_pools, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_machine_config_pools( + machine_config_pools, + title=True + ) + + if 'selector' in view: + k8s_output_handler.print_machine_config_pools_selector( + machine_config_pools, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def), selector, all') + + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/nad.py b/menu/get/k8s/nad.py new file mode 100644 index 00000000..ccdc0c8b --- /dev/null +++ b/menu/get/k8s/nad.py @@ -0,0 +1,134 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("nad") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_nad_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s nad (ocp)""" + + # iserver get k8s nad + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + nads = k8s_handlers.get_nads( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + nads, + indent=4 + ) + ) + return + + nads = k8s_handlers.get_nads( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + nads, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_nads( + nads, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/nnce.py b/menu/get/k8s/nnce.py new file mode 100644 index 00000000..cad8ea40 --- /dev/null +++ b/menu/get/k8s/nnce.py @@ -0,0 +1,128 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("nnce") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_nnce_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s node network configuration enactnent""" + + # iserver get k8s nncp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + enactments = k8s_handlers.get_node_network_configuration_enactments( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + enactments, + indent=4 + ) + ) + return + + enactments = k8s_handlers.get_node_network_configuration_enactments( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + enactments, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_node_network_configuration_enactment( + enactments, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/nncp.py b/menu/get/k8s/nncp.py new file mode 100644 index 00000000..7c0cd949 --- /dev/null +++ b/menu/get/k8s/nncp.py @@ -0,0 +1,128 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("nncp") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_nncp_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s node network configuration policy""" + + # iserver get k8s nncp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + policies = k8s_handlers.get_node_network_configuration_policies( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + policies = k8s_handlers.get_node_network_configuration_policies( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + policies, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_node_network_configuration_policy( + policies, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/nns.py b/menu/get/k8s/nns.py new file mode 100644 index 00000000..dc6b81af --- /dev/null +++ b/menu/get/k8s/nns.py @@ -0,0 +1,191 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("nns") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Include verbose") +@click.option("--view", "-v", default=['all'], help="[dns|route|bond|eth|lb|ovs|vf|vlan|intf|route|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_nns_command( + ctx, + cluster, + name, + verbose, + view, + output, + devel + ): + """Get k8s node network state""" + + # iserver get k8s nncp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'dns|route|bond|eth|lb|ovs|vf|vlan|intf|route|all', + 'all', + [ + 'intf:bond,eth,lb,ovs,vf,vlan' + ] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + states = k8s_handlers.get_node_network_states( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + states, + indent=4 + ) + ) + return + + states = k8s_handlers.get_node_network_states( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + states, + indent=4 + ) + ) + return + + if 'dns' in view: + k8s_output_handler.print_node_network_state_dns( + states, + title=True + ) + + if 'route' in view: + k8s_output_handler.print_node_network_state_route( + states, + title=True + ) + + if 'bond' in view: + k8s_output_handler.print_node_network_state_bond( + states, + ethtool=verbose, + options=verbose, + title=True + ) + + if 'eth' in view: + k8s_output_handler.print_node_network_state_ethernet( + states, + ethtool=verbose, + title=True + ) + + if 'vf' in view: + k8s_output_handler.print_node_network_state_vf( + states, + ethtool=verbose, + title=True + ) + + if 'vlan' in view: + k8s_output_handler.print_node_network_state_vlan( + states, + ethtool=verbose, + title=True + ) + + if 'lb' in view: + k8s_output_handler.print_node_network_state_lb( + states, + ethtool=verbose, + options=verbose, + title=True + ) + + k8s_output_handler.print_node_network_state_lb_interfaces( + states + ) + + if 'ovs' in view: + k8s_output_handler.print_node_network_state_ovs( + states, + ethtool=verbose, + title=True + ) + + k8s_output_handler.print_node_network_state_ovs_interfaces( + states, + ethtool=verbose + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: all (def), dns, route, intf, bond, eth, vlan, vf, lb, ovs') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/node.py b/menu/get/k8s/node.py new file mode 100644 index 00000000..b32e0ef7 --- /dev/null +++ b/menu/get/k8s/node.py @@ -0,0 +1,153 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("node") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--label", default='', callback=validations.empty_string_to_none, help="Filter by label") +@click.option("--view", "-v", default=['state'], help="[state|ver|cap|label|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_node_command( + ctx, + cluster, + name, + label, + view, + output, + devel + ): + """Get k8s node""" + + # iserver get k8s node + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|ver|cap|label|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if label is not None: + object_filter.append( + 'label:%s' % (label) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + nodes = k8s_handlers.get_nodes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + nodes, + indent=4 + ) + ) + return + + nodes = k8s_handlers.get_nodes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + nodes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_nodes_state( + nodes, + title=True + ) + + if 'ver' in view: + k8s_output_handler.print_nodes_version( + nodes, + title=True + ) + + if 'cap' in view: + k8s_output_handler.print_nodes_capacity( + nodes, + title=True + ) + + if 'label' in view: + k8s_output_handler.print_nodes_label( + nodes, + title=True + ) + + ctx.my_output.default('Filter: name, label', before_newline=True) + ctx.my_output.default('View: state (def), ver, cap, label, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ns.py b/menu/get/k8s/ns.py new file mode 100644 index 00000000..026c0366 --- /dev/null +++ b/menu/get/k8s/ns.py @@ -0,0 +1,126 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ns") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ns_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s namespace""" + + # iserver get k8s ns + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + namespaces = k8s_handlers.get_namespaces( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + namespaces, + indent=4 + ) + ) + return + + namespaces = k8s_handlers.get_namespaces( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + namespaces, + indent=4 + ) + ) + return + + k8s_output_handler.print_namespaces( + namespaces, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/og.py b/menu/get/k8s/og.py new file mode 100644 index 00000000..761309c8 --- /dev/null +++ b/menu/get/k8s/og.py @@ -0,0 +1,133 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("og") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|ns|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_og_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s operator group""" + + # iserver get k8s og + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|ns|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + operator_groups = k8s_handlers.get_operator_groups( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + operator_groups, + indent=4 + ) + ) + return + + operator_groups = k8s_handlers.get_operator_groups( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + operator_groups, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_operator_groups( + operator_groups, + title=True + ) + + if 'ns' in view: + k8s_output_handler.print_operator_groups_ns( + operator_groups, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), ns, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/pc.py b/menu/get/k8s/pc.py new file mode 100644 index 00000000..feac8d3b --- /dev/null +++ b/menu/get/k8s/pc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_pc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s priority class""" + + # iserver get k8s pc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + priority_classes = k8s_handlers.get_priority_classes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + priority_classes, + indent=4 + ) + ) + return + + priority_classes = k8s_handlers.get_priority_classes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + priority_classes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_priority_classes( + priority_classes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/pmon.py b/menu/get/k8s/pmon.py new file mode 100644 index 00000000..7d58b569 --- /dev/null +++ b/menu/get/k8s/pmon.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pmon") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_pmon_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s pod monitor""" + + # iserver get k8s pmon + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + pod_monitors = k8s_handlers.get_pod_monitors( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + pod_monitors, + indent=4 + ) + ) + return + + pod_monitors = k8s_handlers.get_pod_monitors( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + pod_monitors, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_pod_monitors( + pod_monitors, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/pod.py b/menu/get/k8s/pod.py new file mode 100644 index 00000000..4d11f6c9 --- /dev/null +++ b/menu/get/k8s/pod.py @@ -0,0 +1,209 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pod") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--owner", default='', callback=validations.empty_string_to_none, help="Filter by owner") +@click.option("--view", "-v", default=['state'], help="[state|metadata|cont|res|svc|env|cm|vol|net|log|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_pod_command( + ctx, + cluster, + namespace, + name, + owner, + view, + output, + devel + ): + """Get k8s pod""" + + # iserver get k8s pod + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|metadata|cont|res|svc|env|cm|vol|net|log|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if owner is not None: + object_filter.append( + 'owner:%s' % (owner) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + pods = k8s_handlers.get_pods( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + pods, + indent=4 + ) + ) + return + + service_info = False + log_info = False + + if 'state' in view: + service_info = True + + if 'svc' in view: + service_info = True + + if 'log' in view: + log_info = True + + pods = k8s_handlers.get_pods( + object_filter=object_filter, + service_info=service_info, + log_info=log_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + pods, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_pods_state( + pods, + title=True + ) + + if 'metadata' in view: + k8s_output_handler.print_pods_metadata( + pods, + title=True + ) + + if 'cont' in view: + k8s_output_handler.print_pods_container( + pods, + title=True + ) + + if 'res' in view: + k8s_output_handler.print_pods_resource( + pods, + title=True + ) + + if 'svc' in view: + k8s_output_handler.print_pods_service( + pods, + title=True + ) + + if 'env' in view: + k8s_output_handler.print_pods_env( + pods, + title=True + ) + + if 'cm' in view: + k8s_output_handler.print_pods_cm( + pods, + title=True + ) + + if 'vol' in view: + k8s_output_handler.print_pods_vol( + pods, + title=True + ) + + if 'net' in view: + k8s_output_handler.print_pods_net( + pods, + title=True + ) + + if 'log' in view: + k8s_output_handler.print_pods_log( + pods, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), metadata, cont, res, svc, env, cm, vol, net, log, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/pp.py b/menu/get/k8s/pp.py new file mode 100644 index 00000000..6d1b017c --- /dev/null +++ b/menu/get/k8s/pp.py @@ -0,0 +1,133 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pp") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by performance profile name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_pp_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s performance profile (ocp)""" + + # iserver get k8s pp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + performance_profiles = k8s_handlers.get_performance_profiles( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + performance_profiles, + indent=4 + ) + ) + return + + performance_profiles = k8s_handlers.get_performance_profiles( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + performance_profiles, + indent=4 + ) + ) + return + + if len(performance_profiles) == 0: + ctx.my_output.error( + 'No performance profile found matching the search criteria' + ) + raise ErrorExit + + if 'state' in view: + k8s_output_handler.print_performance_profiles( + performance_profiles, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/prb.py b/menu/get/k8s/prb.py new file mode 100644 index 00000000..e081b96e --- /dev/null +++ b/menu/get/k8s/prb.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("prb") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_prb_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s probe""" + + # iserver get k8s prb + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + probes = k8s_handlers.get_probes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + probes, + indent=4 + ) + ) + return + + probes = k8s_handlers.get_probes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + probes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_probes( + probes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/profile.py b/menu/get/k8s/profile.py new file mode 100644 index 00000000..06cd7eef --- /dev/null +++ b/menu/get/k8s/profile.py @@ -0,0 +1,146 @@ +import sys +import json +import yaml +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("profile") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|boot|error|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_profile_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s profile (ocp)""" + + # iserver get k8s profile + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|boot|error|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + profiles = k8s_handlers.get_profiles( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + yaml.dump( + profiles + ) + ) + return + + profiles = k8s_handlers.get_profiles( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + profiles, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_profiles( + profiles, + title=True + ) + + if 'boot' in view: + k8s_output_handler.print_profiles_boot( + profiles, + title=True + ) + + if 'error' in view: + k8s_output_handler.print_profiles_error( + profiles, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), boot, error, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/prom.py b/menu/get/k8s/prom.py new file mode 100644 index 00000000..9387d790 --- /dev/null +++ b/menu/get/k8s/prom.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("prom") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_prom_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s prometheus""" + + # iserver get k8s prom + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + prometheuss = k8s_handlers.get_prometheuss( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + prometheuss, + indent=4 + ) + ) + return + + prometheuss = k8s_handlers.get_prometheuss( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + prometheuss, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_prometheuss( + prometheuss, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/promrule.py b/menu/get/k8s/promrule.py new file mode 100644 index 00000000..f55fffe8 --- /dev/null +++ b/menu/get/k8s/promrule.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("promrule") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_promrule_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s prometheus rule""" + + # iserver get k8s promrule + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + prometheus_rules = k8s_handlers.get_prometheus_rules( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + prometheus_rules, + indent=4 + ) + ) + return + + prometheus_rules = k8s_handlers.get_prometheus_rules( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + prometheus_rules, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_prometheus_rules( + prometheus_rules, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/pv.py b/menu/get/k8s/pv.py new file mode 100644 index 00000000..761a0722 --- /dev/null +++ b/menu/get/k8s/pv.py @@ -0,0 +1,126 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pv") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_pv_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s persistent volume""" + + # iserver get k8s pv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + pvs = k8s_handlers.get_pvs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + pvs, + indent=4 + ) + ) + return + + pvs = k8s_handlers.get_pvs( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + pvs, + indent=4 + ) + ) + return + + k8s_output_handler.print_pvs( + pvs, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/pvc.py b/menu/get/k8s/pvc.py new file mode 100644 index 00000000..42968126 --- /dev/null +++ b/menu/get/k8s/pvc.py @@ -0,0 +1,158 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("pvc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|metadata|pv|usage|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_pvc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s persistent volume claim""" + + # iserver get k8s pvc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|metadata|pv|usage|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + pvcs = k8s_handlers.get_pvcs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + pvcs, + indent=4 + ) + ) + return + + usage_info = False + if 'usage' in view: + usage_info = True + + pvcs = k8s_handlers.get_pvcs( + object_filter=object_filter, + usage_info=usage_info, + pv_info=True + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + pvcs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_pvcs( + pvcs, + title=True + ) + + if 'metadata' in view: + k8s_output_handler.print_pvcs_metadata( + pvcs, + title=True + ) + + if 'pv' in view: + k8s_output_handler.print_pvcs_pv( + pvcs, + title=True + ) + + if 'usage' in view: + k8s_output_handler.print_pvcs_usage( + pvcs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), metadata, pv, usage, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/quota.py b/menu/get/k8s/quota.py new file mode 100644 index 00000000..c14527fa --- /dev/null +++ b/menu/get/k8s/quota.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("quota") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_quota_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s resource quota""" + + # iserver get k8s quota + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + resource_quotas = k8s_handlers.get_resource_quotas( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + resource_quotas, + indent=4 + ) + ) + return + + resource_quotas = k8s_handlers.get_resource_quotas( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + resource_quotas, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_resource_quotas( + resource_quotas, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/rb.py b/menu/get/k8s/rb.py new file mode 100644 index 00000000..c0f97b9a --- /dev/null +++ b/menu/get/k8s/rb.py @@ -0,0 +1,142 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("rb") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--subject", default='', callback=validations.empty_string_to_none, help="Filter by subject") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_rb_command( + ctx, + cluster, + namespace, + name, + subject, + view, + output, + devel + ): + """Get k8s role bindings""" + + # iserver get k8s rb + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if subject is not None: + object_filter.append( + 'subject:%s' % (subject) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + crbs = k8s_handlers.get_role_bindings( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + crbs, + indent=4 + ) + ) + return + + crbs = k8s_handlers.get_role_bindings( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + crbs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_role_bindings( + crbs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name, subject', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/rc.py b/menu/get/k8s/rc.py new file mode 100644 index 00000000..1d093159 --- /dev/null +++ b/menu/get/k8s/rc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("rc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_rc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s replication controller""" + + # iserver get k8s rc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + replication_controllers = k8s_handlers.get_replication_controllers( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + replication_controllers, + indent=4 + ) + ) + return + + replication_controllers = k8s_handlers.get_replication_controllers( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + replication_controllers, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_replication_controllers( + replication_controllers, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/route.py b/menu/get/k8s/route.py new file mode 100644 index 00000000..1db57d53 --- /dev/null +++ b/menu/get/k8s/route.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("route") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_route_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s route""" + + # iserver get k8s route + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + routes = k8s_handlers.get_routes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + routes, + indent=4 + ) + ) + return + + routes = k8s_handlers.get_routes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + routes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_routes( + routes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/rs.py b/menu/get/k8s/rs.py new file mode 100644 index 00000000..784d7484 --- /dev/null +++ b/menu/get/k8s/rs.py @@ -0,0 +1,141 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("rs") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|metadata|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_rs_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s replica set""" + + # iserver get k8s rs + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|metadata|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + replica_sets = k8s_handlers.get_replica_sets( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + replica_sets, + indent=4 + ) + ) + return + + replica_sets = k8s_handlers.get_replica_sets( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + replica_sets, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_replica_sets( + replica_sets, + title=True + ) + + if 'metadata' in view: + k8s_output_handler.print_replica_sets_metadata( + replica_sets, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), metadata, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ruler.py b/menu/get/k8s/ruler.py new file mode 100644 index 00000000..3aa4c9fc --- /dev/null +++ b/menu/get/k8s/ruler.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ruler") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ruler_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s thanos ruler""" + + # iserver get k8s ruler + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + thanos_rulers = k8s_handlers.get_thanos_rulers( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + thanos_rulers, + indent=4 + ) + ) + return + + thanos_rulers = k8s_handlers.get_thanos_rulers( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + thanos_rulers, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_thanos_rulers( + thanos_rulers, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/sa.py b/menu/get/k8s/sa.py new file mode 100644 index 00000000..60bd5a42 --- /dev/null +++ b/menu/get/k8s/sa.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sa") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_sa_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s service account""" + + # iserver get k8s sa + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + service_accounts = k8s_handlers.get_service_accounts( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + service_accounts, + indent=4 + ) + ) + return + + service_accounts = k8s_handlers.get_service_accounts( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + service_accounts, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_service_accounts( + service_accounts, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/sc.py b/menu/get/k8s/sc.py new file mode 100644 index 00000000..ea1b56a3 --- /dev/null +++ b/menu/get/k8s/sc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_sc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s storage class""" + + # iserver get k8s sc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + storage_classes = k8s_handlers.get_storage_classes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + storage_classes, + indent=4 + ) + ) + return + + storage_classes = k8s_handlers.get_storage_classes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + storage_classes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_storage_classes( + storage_classes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/scc.py b/menu/get/k8s/scc.py new file mode 100644 index 00000000..09b18c10 --- /dev/null +++ b/menu/get/k8s/scc.py @@ -0,0 +1,128 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("scc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_scc_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s security context constraints""" + + # iserver get k8s scc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + sccs = k8s_handlers.get_security_context_constraints( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + sccs, + indent=4 + ) + ) + return + + sccs = k8s_handlers.get_security_context_constraints( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + sccs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_security_context_constraints( + sccs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/sec.py b/menu/get/k8s/sec.py new file mode 100644 index 00000000..ef30d4e2 --- /dev/null +++ b/menu/get/k8s/sec.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sec") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_sec_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s secret""" + + # iserver get k8s sec + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + secrets = k8s_handlers.get_secrets( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + secrets, + indent=4 + ) + ) + return + + secrets = k8s_handlers.get_secrets( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + secrets, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_secrets( + secrets, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/smon.py b/menu/get/k8s/smon.py new file mode 100644 index 00000000..e9dc277c --- /dev/null +++ b/menu/get/k8s/smon.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("smon") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_smon_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s service monitor""" + + # iserver get k8s smon + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + service_monitors = k8s_handlers.get_service_monitors( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + service_monitors, + indent=4 + ) + ) + return + + service_monitors = k8s_handlers.get_service_monitors( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + service_monitors, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_service_monitors( + service_monitors, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/srn.py b/menu/get/k8s/srn.py new file mode 100644 index 00000000..52f5ac80 --- /dev/null +++ b/menu/get/k8s/srn.py @@ -0,0 +1,126 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("srn") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_srn_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s sriov network""" + + # iserver get k8s srn + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + sriov_networks = k8s_handlers.get_sriov_networks( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + sriov_networks, + indent=4 + ) + ) + return + + sriov_networks = k8s_handlers.get_sriov_networks( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + sriov_networks, + indent=4 + ) + ) + return + + k8s_output_handler.print_sriov_networks( + sriov_networks, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/srnnp.py b/menu/get/k8s/srnnp.py new file mode 100644 index 00000000..fa8b0bdb --- /dev/null +++ b/menu/get/k8s/srnnp.py @@ -0,0 +1,151 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("srnnp") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--resource", default='', callback=validations.empty_string_to_none, help="Filter by resource") +@click.option("--type", "device_type", type=click.Choice(['vfio', 'net', 'any'], case_sensitive=False), default='any', help="Device type") +@click.option("--view", "-v", default=['state'], help="[state|srn|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_srnnp_command( + ctx, + cluster, + name, + resource, + device_type, + view, + output, + devel + ): + """Get k8s sriov network node policy""" + + # iserver get k8s srnnp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|srn|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + sriov_network_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if resource is not None: + object_filter.append( + 'resource:%s' % (resource) + ) + + if device_type != 'any': + object_filter.append( + 'device_type:%s*' % (device_type) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + sriov_network_node_policies = k8s_handlers.get_sriov_network_node_policies( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + sriov_network_node_policies, + indent=4 + ) + ) + return + + sriov_network_node_policies = k8s_handlers.get_sriov_network_node_policies( + object_filter=object_filter, + sriov_network_info=sriov_network_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + sriov_network_node_policies, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_sriov_network_node_policies( + sriov_network_node_policies, + title=True + ) + + if 'srn' in view: + k8s_output_handler.print_sriov_network_node_policies_srn( + sriov_network_node_policies, + title=True + ) + + ctx.my_output.default('Filter: name, resource, type', before_newline=True) + ctx.my_output.default('View: state (def), srn, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/srnns.py b/menu/get/k8s/srnns.py new file mode 100644 index 00000000..7f1950b2 --- /dev/null +++ b/menu/get/k8s/srnns.py @@ -0,0 +1,146 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("srnns") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by node name") +@click.option("--intf", "interface_name", default='', callback=validations.empty_string_to_none, help="Filter by interface name") +@click.option("--view", "-v", default=['state'], help="[state|policy|vf|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_srnns_command( + ctx, + cluster, + node_name, + interface_name, + view, + output, + devel + ): + """Get k8s sriov network node state""" + + # iserver get k8s srnns + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|policy|vf|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if node_name is not None: + object_filter.append( + 'name:%s' % (node_name) + ) + + if interface_name is not None: + object_filter.append( + 'interface:%s' % (interface_name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + sriov_network_node_states = k8s_handlers.get_sriov_network_node_states( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + sriov_network_node_states, + indent=4 + ) + ) + return + + sriov_network_node_states = k8s_handlers.get_sriov_network_node_states( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + sriov_network_node_states, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_sriov_network_nodes_state( + sriov_network_node_states, + title=True + ) + + if 'policy' in view: + k8s_output_handler.print_sriov_network_nodes_state_policy( + sriov_network_node_states, + title=True + ) + + if 'vf' in view: + k8s_output_handler.print_sriov_network_nodes_state_vf( + sriov_network_node_states, + title=True + ) + + ctx.my_output.default('Filter: node, intf', before_newline=True) + ctx.my_output.default('View: state (def), policy, vf, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/sts.py b/menu/get/k8s/sts.py new file mode 100644 index 00000000..6410d5e2 --- /dev/null +++ b/menu/get/k8s/sts.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sts") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_sts_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s stateful set""" + + # iserver get k8s sts + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + stateful_sets = k8s_handlers.get_stateful_sets( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + stateful_sets, + indent=4 + ) + ) + return + + stateful_sets = k8s_handlers.get_stateful_sets( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + stateful_sets, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_stateful_sets( + stateful_sets, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/sub.py b/menu/get/k8s/sub.py new file mode 100644 index 00000000..57cd6d95 --- /dev/null +++ b/menu/get/k8s/sub.py @@ -0,0 +1,127 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sub") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_sub_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get k8s subscription""" + + # iserver get k8s sub + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + subscriptions = k8s_handlers.get_subscriptions( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + subscriptions, + indent=4 + ) + ) + return + + subscriptions = k8s_handlers.get_subscriptions( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + subscriptions, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_subscriptions( + subscriptions, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/svc.py b/menu/get/k8s/svc.py new file mode 100644 index 00000000..64b1f933 --- /dev/null +++ b/menu/get/k8s/svc.py @@ -0,0 +1,207 @@ +import sys +import json +import threading +import traceback +import click + +from lib import ip_helper +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("svc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--type", "-t", "svc_type", type=click.Choice(['NodePort', 'ClusterIP', 'ExternalNane', 'LoadBalancer', 'any'], case_sensitive=False), default='any', show_default=True, help="Filter by type") +@click.option("--cluster-ip", default='', callback=validations.empty_string_to_none, help="Filter by cluster IP") +@click.option("--external-ip", default='', callback=validations.empty_string_to_none, help="Filter by external IP") +@click.option("--port", default='', callback=validations.validate_int_oper, help="Filter by port") +@click.option("--special", default='', callback=validations.empty_string_to_none, help="Filter by special selector") +@click.option("--view", "-v", default=['state'], help="[state|label|pod|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_svc_command( + ctx, + cluster, + namespace, + name, + svc_type, + cluster_ip, + external_ip, + port, + special, + view, + output, + devel + ): + """Get k8s service""" + + # iserver get k8s srv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|label|pod|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if svc_type != 'any': + object_filter.append( + 'type:%s' % (svc_type) + ) + + if cluster_ip is not None: + if ip_helper.is_valid_ipv4_address(cluster_ip): + object_filter.append( + 'cluster-ip:%s' % (cluster_ip) + ) + else: + if ip_helper.is_valid_ipv4_cidr(cluster_ip): + object_filter.append( + 'cluster-subnet:%s' % (cluster_ip) + ) + else: + object_filter.append( + 'cluster-string:%s' % (cluster_ip) + ) + + if external_ip is not None: + if ip_helper.is_valid_ipv4_address(external_ip): + object_filter.append( + 'external-ip:%s' % (external_ip) + ) + else: + if ip_helper.is_valid_ipv4_cidr(external_ip): + object_filter.append( + 'external-subnet:%s' % (external_ip) + ) + else: + object_filter.append( + 'external-string:%s' % (external_ip) + ) + + if len(port) > 0: + object_filter.append( + 'port:%s' % (port) + ) + + if special is not None: + object_filter.append( + 'special:%s' % (special) + ) + + pod_info = False + if 'pod' in view: + pod_info = True + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + services = k8s_handlers.get_services( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + services, + indent=4 + ) + ) + return + + services = k8s_handlers.get_services( + object_filter=object_filter, + pod_info=pod_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + services, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_services( + services, + title=True + ) + + if 'label' in view: + k8s_output_handler.print_services_label( + services, + title=True + ) + + if 'pod' in view: + k8s_output_handler.print_services_pod( + services, + title=True + ) + ctx.my_output.default('Filter: namespace, name, type, cluster-ip, external-ip, port, special', before_newline=True) + ctx.my_output.default('View: state (def), label, pod, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/tuned.py b/menu/get/k8s/tuned.py new file mode 100644 index 00000000..d4116076 --- /dev/null +++ b/menu/get/k8s/tuned.py @@ -0,0 +1,134 @@ +import sys +import json +import yaml +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("tuned") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_tuned_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s tuned (ocp)""" + + # iserver get k8s tuned + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + tuneds = k8s_handlers.get_tuneds( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + yaml.dump( + tuneds + ) + ) + return + + tuneds = k8s_handlers.get_tuneds( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + tuneds, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_tuneds( + tuneds, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/va.py b/menu/get/k8s/va.py new file mode 100644 index 00000000..b36f7cb1 --- /dev/null +++ b/menu/get/k8s/va.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("va") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_va_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s volume attachment""" + + # iserver get k8s va + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + volume_attachments = k8s_handlers.get_volume_attachments( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + volume_attachments, + indent=4 + ) + ) + return + + volume_attachments = k8s_handlers.get_volume_attachments( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + volume_attachments, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_volume_attachments( + volume_attachments, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/ver.py b/menu/get/k8s/ver.py new file mode 100644 index 00000000..d0bbe6d3 --- /dev/null +++ b/menu/get/k8s/ver.py @@ -0,0 +1,123 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("ver") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_ver_command( + ctx, + cluster, + namespace, + name, + output, + devel + ): + """Get k8s volume attachment""" + + # iserver get k8s ver + + ctx.developer = devel + ctx.output = output + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster) + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + versions = k8s_handlers.get_versions( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + versions, + indent=4 + ) + ) + return + + versions = k8s_handlers.get_versions( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + versions, + indent=4 + ) + ) + return + + k8s_output_handler.print_versions( + versions, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vm.py b/menu/get/k8s/vm.py new file mode 100644 index 00000000..a766d9f0 --- /dev/null +++ b/menu/get/k8s/vm.py @@ -0,0 +1,147 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|metadata|dv|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vm_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine""" + + # iserver get k8s vm + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|metadata|dv|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machines = k8s_handlers.get_virtual_machines( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machines, + indent=4 + ) + ) + return + + virtual_machines = k8s_handlers.get_virtual_machines( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machines, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machines( + virtual_machines, + title=True + ) + + if 'metadata' in view: + k8s_output_handler.print_virtual_machines_metadata( + virtual_machines, + title=True + ) + + if 'dv' in view: + k8s_output_handler.print_virtual_machines_dv( + virtual_machines, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), metadata, dv, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmc.py b/menu/get/k8s/vmc.py new file mode 100644 index 00000000..7593cd3d --- /dev/null +++ b/menu/get/k8s/vmc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine clone""" + + # iserver get k8s vmc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_clones = k8s_handlers.get_virtual_machine_clones( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_clones, + indent=4 + ) + ) + return + + virtual_machine_clones = k8s_handlers.get_virtual_machine_clones( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_clones, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_clones( + virtual_machine_clones, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmcf.py b/menu/get/k8s/vmcf.py new file mode 100644 index 00000000..0402003c --- /dev/null +++ b/menu/get/k8s/vmcf.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmcf") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmcf_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine cluster instance types""" + + # iserver get k8s vmcf + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_cluster_itypes = k8s_handlers.get_virtual_machine_cluster_itypes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_cluster_itypes, + indent=4 + ) + ) + return + + virtual_machine_cluster_itypes = k8s_handlers.get_virtual_machine_cluster_itypes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_cluster_itypes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_cluster_itypes( + virtual_machine_cluster_itypes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmcp.py b/menu/get/k8s/vmcp.py new file mode 100644 index 00000000..d1bc58f0 --- /dev/null +++ b/menu/get/k8s/vmcp.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmcp") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmcp_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine cluster preference""" + + # iserver get k8s vmcp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_cluster_prefs = k8s_handlers.get_virtual_machine_cluster_prefs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_cluster_prefs, + indent=4 + ) + ) + return + + virtual_machine_cluster_prefs = k8s_handlers.get_virtual_machine_cluster_prefs( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_cluster_prefs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_cluster_prefs( + virtual_machine_cluster_prefs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vme.py b/menu/get/k8s/vme.py new file mode 100644 index 00000000..d016cdb5 --- /dev/null +++ b/menu/get/k8s/vme.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vme") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vme_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine export""" + + # iserver get k8s vme + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_exports = k8s_handlers.get_virtual_machine_exports( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_exports, + indent=4 + ) + ) + return + + virtual_machine_exports = k8s_handlers.get_virtual_machine_exports( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_exports, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_exports( + virtual_machine_exports, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmf.py b/menu/get/k8s/vmf.py new file mode 100644 index 00000000..03e9b48c --- /dev/null +++ b/menu/get/k8s/vmf.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmf") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmf_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine instance type""" + + # iserver get k8s vmf + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_itypes = k8s_handlers.get_virtual_machine_itypes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_itypes, + indent=4 + ) + ) + return + + virtual_machine_itypes = k8s_handlers.get_virtual_machine_itypes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_itypes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_itypes( + virtual_machine_itypes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmi.py b/menu/get/k8s/vmi.py new file mode 100644 index 00000000..cfd229e9 --- /dev/null +++ b/menu/get/k8s/vmi.py @@ -0,0 +1,171 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmi") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state|metadata|phase|net|svc|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmi_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine instance""" + + # iserver get k8s vmi + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|metadata|phase|net|svc|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + vm_info = False + service_info = False + + if 'state' in view: + vm_info = True + service_info = True + + if 'svc' in view: + service_info = True + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_instances = k8s_handlers.get_virtual_machine_instances( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_instances, + indent=4 + ) + ) + return + + virtual_machine_instances = k8s_handlers.get_virtual_machine_instances( + object_filter=object_filter, + vm_info=vm_info, + service_info=service_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_instances, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_instances( + virtual_machine_instances, + title=True + ) + + if 'metadata' in view: + k8s_output_handler.print_virtual_machine_instances_metadata( + virtual_machine_instances, + title=True + ) + + if 'phase' in view: + k8s_output_handler.print_virtual_machine_instances_phase( + virtual_machine_instances, + title=True + ) + + if 'net' in view: + k8s_output_handler.print_virtual_machine_instances_interface( + virtual_machine_instances, + title=True + ) + + if 'svc' in view: + k8s_output_handler.print_virtual_machine_instances_service( + virtual_machine_instances, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def), metadata, phase, net, svc, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmim.py b/menu/get/k8s/vmim.py new file mode 100644 index 00000000..1da536f4 --- /dev/null +++ b/menu/get/k8s/vmim.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmim") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmim_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine instance migration""" + + # iserver get k8s vmim + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_migrations = k8s_handlers.get_virtual_machine_migrations( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_migrations, + indent=4 + ) + ) + return + + virtual_machine_migrations = k8s_handlers.get_virtual_machine_migrations( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_migrations, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_migrations( + virtual_machine_migrations, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmipr.py b/menu/get/k8s/vmipr.py new file mode 100644 index 00000000..a627fd60 --- /dev/null +++ b/menu/get/k8s/vmipr.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmipr") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmipr_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine instance preset""" + + # iserver get k8s vmipr + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_presets = k8s_handlers.get_virtual_machine_presets( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_presets, + indent=4 + ) + ) + return + + virtual_machine_presets = k8s_handlers.get_virtual_machine_presets( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_presets, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_presets( + virtual_machine_presets, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmirs.py b/menu/get/k8s/vmirs.py new file mode 100644 index 00000000..a000afd9 --- /dev/null +++ b/menu/get/k8s/vmirs.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmirs") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmirs_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine instance replica set""" + + # iserver get k8s vmirs + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_replica_sets = k8s_handlers.get_virtual_machine_replica_sets( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_replica_sets, + indent=4 + ) + ) + return + + virtual_machine_replica_sets = k8s_handlers.get_virtual_machine_replica_sets( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_replica_sets, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_replica_sets( + virtual_machine_replica_sets, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmp.py b/menu/get/k8s/vmp.py new file mode 100644 index 00000000..c24c9203 --- /dev/null +++ b/menu/get/k8s/vmp.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmp") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmp_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine preference""" + + # iserver get k8s vmp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_prefs = k8s_handlers.get_virtual_machine_prefs( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_prefs, + indent=4 + ) + ) + return + + virtual_machine_prefs = k8s_handlers.get_virtual_machine_prefs( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_prefs, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_prefs( + virtual_machine_prefs, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmr.py b/menu/get/k8s/vmr.py new file mode 100644 index 00000000..d371a3cd --- /dev/null +++ b/menu/get/k8s/vmr.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmr") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmr_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine restore""" + + # iserver get k8s quota + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_restores = k8s_handlers.get_virtual_machine_restores( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_restores, + indent=4 + ) + ) + return + + virtual_machine_restores = k8s_handlers.get_virtual_machine_restores( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_restores, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_restores( + virtual_machine_restores, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vms.py b/menu/get/k8s/vms.py new file mode 100644 index 00000000..432fda04 --- /dev/null +++ b/menu/get/k8s/vms.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vms") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vms_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine snapshot""" + + # iserver get k8s quota + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_snapshots = k8s_handlers.get_virtual_machine_snapshots( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_snapshots, + indent=4 + ) + ) + return + + virtual_machine_snapshots = k8s_handlers.get_virtual_machine_snapshots( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_snapshots, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_snapshots( + virtual_machine_snapshots, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vmsc.py b/menu/get/k8s/vmsc.py new file mode 100644 index 00000000..bcf01e13 --- /dev/null +++ b/menu/get/k8s/vmsc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmsc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vmsc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s virtual machine snapshot content""" + + # iserver get k8s vmsc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + virtual_machine_snapshot_contents = k8s_handlers.get_virtual_machine_snapshot_contents( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_snapshot_contents, + indent=4 + ) + ) + return + + virtual_machine_snapshot_contents = k8s_handlers.get_virtual_machine_snapshot_contents( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_snapshot_contents, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_virtual_machine_snapshot_contents( + virtual_machine_snapshot_contents, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vs.py b/menu/get/k8s/vs.py new file mode 100644 index 00000000..f3eac3e2 --- /dev/null +++ b/menu/get/k8s/vs.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vs") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vs_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s volume snapshot""" + + # iserver get k8s vs + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + volume_snapshots = k8s_handlers.get_volume_snapshots( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + volume_snapshots, + indent=4 + ) + ) + return + + volume_snapshots = k8s_handlers.get_volume_snapshots( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + volume_snapshots, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_volume_snapshots( + volume_snapshots, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vsc.py b/menu/get/k8s/vsc.py new file mode 100644 index 00000000..f16d1852 --- /dev/null +++ b/menu/get/k8s/vsc.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vsc") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vsc_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s volume snapshot content""" + + # iserver get k8s vsc + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + volume_snapshot_contents = k8s_handlers.get_volume_snapshot_contents( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + volume_snapshot_contents, + indent=4 + ) + ) + return + + volume_snapshot_contents = k8s_handlers.get_volume_snapshot_contents( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + volume_snapshot_contents, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_volume_snapshot_contents( + volume_snapshot_contents, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/k8s/vsclass.py b/menu/get/k8s/vsclass.py new file mode 100644 index 00000000..afa9de56 --- /dev/null +++ b/menu/get/k8s/vsclass.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.k8s import output as k8s_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vsclass") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_k8s_vsclass_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get k8s volume snapshot class""" + + # iserver get k8s vsclass + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + k8s_output_handler = k8s_output.K8sOutput(log_id=ctx.run_id) + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if k8s_handlers.get_api() is None: + ctx.busy = False + ctx.my_output.error( + 'Connection to kubernetes cluster failed' + ) + raise ErrorExit + + if output == 'mo': + volume_snapshot_classes = k8s_handlers.get_volume_snapshot_classes( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + volume_snapshot_classes, + indent=4 + ) + ) + return + + volume_snapshot_classes = k8s_handlers.get_volume_snapshot_classes( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + volume_snapshot_classes, + indent=4 + ) + ) + return + + if 'state' in view: + k8s_output_handler.print_volume_snapshot_classes( + volume_snapshot_classes, + title=True + ) + + ctx.my_output.default('Filter: namespace, name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/kv/__init__.py b/menu/get/kv/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/kv/main.py b/menu/get/kv/main.py new file mode 100644 index 00000000..01aef513 --- /dev/null +++ b/menu/get/kv/main.py @@ -0,0 +1,18 @@ +import click + +from menu.get.kv.vm import get_kubevirt_vm_command +from menu.get.kv.vmi import get_kubevirt_vmi_command + + +class Failure(Exception): + pass + + +@click.group("kv") +@click.pass_obj +def get_kv_menu(ctx): + """Get kubevirt commands (alpha)""" + + +get_kv_menu.add_command(get_kubevirt_vm_command) +get_kv_menu.add_command(get_kubevirt_vmi_command) diff --git a/menu/get/kv/vm.py b/menu/get/kv/vm.py new file mode 100644 index 00000000..74e81534 --- /dev/null +++ b/menu/get/kv/vm.py @@ -0,0 +1,125 @@ +import sys +import json +import threading +import traceback +import click + +from lib.kubevirt import output as kubevirt_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_kubevirt_vm_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get kubevirt virtual machine""" + + # iserver get kv vm + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + kubevirt_output_handler = kubevirt_output.KubevirtOutput(log_id=ctx.run_id) + kubevirt_handlers = validations.validate_kubevirt_name(ctx, cluster) + if kubevirt_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if output == 'mo': + virtual_machines = kubevirt_handlers.get_virtual_machines( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machines, + indent=4 + ) + ) + return + + virtual_machines = kubevirt_handlers.get_virtual_machines( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machines, + indent=4 + ) + ) + return + + if 'state' in view: + kubevirt_output_handler.print_virtual_machines( + virtual_machines, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/kv/vmi.py b/menu/get/kv/vmi.py new file mode 100644 index 00000000..ba72793a --- /dev/null +++ b/menu/get/kv/vmi.py @@ -0,0 +1,125 @@ +import sys +import json +import threading +import traceback +import click + +from lib.kubevirt import output as kubevirt_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vmi") +@click.pass_obj +@click.option("--cluster", default='', help="Kubernetes cluster name") +@click.option("--namespace", default='', callback=validations.empty_string_to_none, help="Filter by namespace") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'mo', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_kubevirt_vmi_command( + ctx, + cluster, + namespace, + name, + view, + output, + devel + ): + """Get kubevirt virtual machine instance""" + + # iserver get kv vmi + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + kubevirt_output_handler = kubevirt_output.KubevirtOutput(log_id=ctx.run_id) + kubevirt_handlers = validations.validate_kubevirt_name(ctx, cluster) + if kubevirt_handlers is None: + raise ErrorExit + + object_filter = [] + + if namespace is not None: + object_filter.append( + 'namespace:%s' % (namespace) + ) + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json', 'mo']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if output == 'mo': + virtual_machine_instances = kubevirt_handlers.get_virtual_machine_instances( + object_filter=object_filter, + return_mo=True + ) + ctx.my_output.default( + json.dumps( + virtual_machine_instances, + indent=4 + ) + ) + return + + virtual_machine_instances = kubevirt_handlers.get_virtual_machine_instances( + object_filter=object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + virtual_machine_instances, + indent=4 + ) + ) + return + + if 'state' in view: + kubevirt_output_handler.print_virtual_machine_instances( + virtual_machine_instances, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/linux/__init__.py b/menu/get/linux/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/linux/bond.py b/menu/get/linux/bond.py new file mode 100644 index 00000000..565dabb9 --- /dev/null +++ b/menu/get/linux/bond.py @@ -0,0 +1,226 @@ +import sys +import json +import threading +import traceback +import click + +from lib import ip_helper +from lib.linux import output as linux_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("bond") +@click.pass_obj +@click.option("--server", multiple=True, help="Linux server name") +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--nexus", "nexus", default='', callback=validations.validate_nexus_any_name, help="Nexus name") +@click.option("--view", "-v", default=['state'], help="[state|member|aci|nexus|all]", show_default=True, multiple=True) +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_linux_bond_command( + ctx, + server, + controller, + nexus, + view, + no_cache, + output, + devel + ): + """Get linux bond state""" + + # iserver get linux bond + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|member|aci|nexus|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + if 'aci' in view and controller is None: + ctx.my_output.default( + '[WARNING] Define APIC for aci view' + ) + + if 'nexus' in view and len(nexus) == 0: + ctx.my_output.default( + '[WARNING] Define nexus devices for nexus view' + ) + + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + linux_handlers = validations.validate_linux_names( + ctx, + server, + no_cache=no_cache + ) + if linux_handlers is None: + raise ErrorExit + + if 'aci' in view and controller is not None: + apic_handler = validations.validate_apic_controller( + ctx, + controller, + '', + '', + '', + '', + no_cache=True, + show_selected=False + ) + if apic_handler is None: + raise ErrorExit + + nodes_info = validations.validate_apic_node_names( + ctx, + apic_handler, + ['any'], + 'any', + pod_id='' + ) + if nodes_info is None: + raise ErrorExit + + if 'nexus' in view and len(nexus) > 0: + nexus_handlers = validations.validate_nexus_devices( + ctx, + nexus, + '', + '', + '' + ) + if nexus_handlers is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + bonds = [] + for linux_handler in linux_handlers: + server_bond_info = linux_handler.get_bond() + if server_bond_info is not None: + bonds = bonds + server_bond_info + + if 'aci' in view and controller is not None: + mac_address = [] + for bond in bonds: + for member in bond['member']: + mac_address.append( + member['mac'] + ) + + aci_lacp_infos = apic_handler.get_macs_lacp( + mac_address, + nodes_info + ) + if aci_lacp_infos is not None: + for aci_lacp_info in aci_lacp_infos: + aci_lacp_info['server'] = '--' + aci_lacp_info['interface'] = '--' + for bond in bonds: + for member in bond['member']: + if ip_helper.is_mac_equal(aci_lacp_info['adjacency']['sysId'], member['mac']): + aci_lacp_info['server'] = bond['server'] + aci_lacp_info['interface'] = member['name'] + + + if 'nexus' in view and len(nexus) > 0: + mac_address = [] + for bond in bonds: + for member in bond['member']: + mac_address.append( + member['mac'] + ) + + nexus_lacp_infos = [] + for nexus_handler in nexus_handlers: + nexus_lacp_info = nexus_handler['handler'].get_macs_lacp( + mac_address + ) + if nexus_lacp_info is not None: + for lacp_info in nexus_lacp_info: + lacp_info['server'] = '--' + lacp_info['interface'] = '--' + for port in lacp_info['port']: + for bond in bonds: + for member in bond['member']: + if ip_helper.is_mac_equal(port['partner_mac'], member['mac']): + lacp_info['server'] = bond['server'] + lacp_info['interface'] = member['name'] + + nexus_lacp_infos = nexus_lacp_infos + nexus_lacp_info + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + bond, + indent=4 + ) + ) + return + + ctx.my_output.json_output(bonds) + + if 'state' in view: + linux_output_handler.print_linux_bond( + bonds, + title=True + ) + + if 'member' in view: + linux_output_handler.print_linux_bond_member( + bonds, + title=True + ) + + if 'aci' in view and controller is not None: + linux_output_handler.print_linux_bond_aci( + aci_lacp_infos, + title=True + ) + + if 'nexus' in view and len(nexus) > 0: + linux_output_handler.print_linux_bond_nexus( + nexus_lacp_infos, + title=True + ) + + ctx.my_output.default('\nViews: state (def), member, aci, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/linux/boot.py b/menu/get/linux/boot.py new file mode 100644 index 00000000..c0a46eab --- /dev/null +++ b/menu/get/linux/boot.py @@ -0,0 +1,90 @@ +import sys +import json +import threading +import traceback +import click + +from lib.linux import output as linux_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("boot") +@click.pass_obj +@click.option("--server", default='', callback=validations.empty_string_to_none, help="Linux server name") +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_linux_boot_command( + ctx, + server, + no_cache, + output, + devel + ): + """Get linux boot /proc/cmdline settings""" + + # iserver get linux boot + + ctx.developer = devel + ctx.output = output + + try: + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + linux_handler = validations.validate_linux_name( + ctx, + server, + no_cache=no_cache + ) + if linux_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + boot = linux_handler.get_boot() + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + boot, + indent=4 + ) + ) + return + + ctx.my_output.json_output(boot) + + linux_output_handler.print_linux_boot( + boot + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/linux/hp.py b/menu/get/linux/hp.py new file mode 100644 index 00000000..d9aafa99 --- /dev/null +++ b/menu/get/linux/hp.py @@ -0,0 +1,106 @@ +import sys +import json +import threading +import traceback +import click + +from lib.linux import output as linux_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("hp") +@click.pass_obj +@click.option("--server", multiple=True, help="Linux server name") +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_linux_hp_command( + ctx, + server, + no_cache, + output, + devel + ): + """Get linux huge pages settings""" + + # iserver get linux hp + + ctx.developer = devel + ctx.output = output + + try: + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + linux_handlers = validations.validate_linux_names( + ctx, + server, + no_cache=no_cache + ) + if linux_handlers is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + for linux_handler in linux_handlers: + if not linux_handler.ssh_handler.is_ssh(): + ctx.busy = False + ctx.my_output.error( + 'Linux server connection failed: %s' % (linux_handler.server_display_name) + ) + raise ErrorExit + + huge_pages = [] + for linux_handler in linux_handlers: + item = {} + item['name'] = linux_handler.server_name + item['hp'] = linux_handler.get_huge_pages() + huge_pages.append( + item + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + huge_pages, + indent=4 + ) + ) + return + + ctx.my_output.json_output(huge_pages) + + linux_output_handler.print_linux_huge_pages( + huge_pages, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/linux/main.py b/menu/get/linux/main.py new file mode 100644 index 00000000..cacbf7a2 --- /dev/null +++ b/menu/get/linux/main.py @@ -0,0 +1,24 @@ +import click + +from menu.get.linux.bond import get_linux_bond_command +from menu.get.linux.boot import get_linux_boot_command +from menu.get.linux.hp import get_linux_hp_command +from menu.get.linux.server import get_linux_server_command +from menu.get.linux.sysctl import get_linux_sysctl_command + + +class Failure(Exception): + pass + + +@click.group("linux") +@click.pass_obj +def get_linux_menu(ctx): + """Get linux commands""" + + +get_linux_menu.add_command(get_linux_bond_command) +get_linux_menu.add_command(get_linux_boot_command) +get_linux_menu.add_command(get_linux_hp_command) +get_linux_menu.add_command(get_linux_server_command) +get_linux_menu.add_command(get_linux_sysctl_command) diff --git a/menu/get/linux/server.py b/menu/get/linux/server.py new file mode 100644 index 00000000..e359a427 --- /dev/null +++ b/menu/get/linux/server.py @@ -0,0 +1,56 @@ +import sys +import traceback +import click + +from lib.linux import settings +from lib.linux import output as linux_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_linux_server_command( + ctx, + show_password, + output, + devel + ): + """Get linux servers""" + + # iserver get linux server + + ctx.developer = devel + ctx.output = output + + try: + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + settings_handler = settings.LinuxSettings(log_id=ctx.run_id) + + servers = settings_handler.get_linux_servers() + if servers is None: + ctx.my_output.error('Failed to get linux servers') + raise ErrorExit + + linux_output_handler.print_linux_servers( + servers, + show_password=show_password + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/linux/sysctl.py b/menu/get/linux/sysctl.py new file mode 100644 index 00000000..e826c74b --- /dev/null +++ b/menu/get/linux/sysctl.py @@ -0,0 +1,123 @@ +import sys +import json +import threading +import traceback +import click + +from lib.linux import output as linux_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sysctl") +@click.pass_obj +@click.option("--server", default='', callback=validations.empty_string_to_none, help="Linux server name") +@click.option("--key", default='', callback=validations.empty_string_to_none, help="Filter by parameter name") +@click.option("--diff", "candidate_diff_servers", multiple=True, default=[], help="Diff server name") +@click.option("--no-cache", "no_cache", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_linux_sysctl_command( + ctx, + server, + key, + candidate_diff_servers, + no_cache, + output, + devel + ): + """Get linux sysctl parameters""" + + # iserver get linux sysctl + + ctx.developer = devel + ctx.output = output + + try: + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + linux_handler = validations.validate_linux_name( + ctx, + server, + no_cache=no_cache + ) + if linux_handler is None: + raise ErrorExit + + diff_handlers = {} + diff_servers = [] + if len(candidate_diff_servers) > 0: + for candidate_diff_server in candidate_diff_servers: + diff_handler = validations.validate_linux_name( + ctx, + candidate_diff_server, + no_cache=no_cache + ) + if diff_handler is None: + raise ErrorExit + + diff_handlers[diff_handler.server_name] = diff_handler + diff_servers.append( + diff_handler.server_name + ) + + sysctl_filter = [] + if key is not None: + sysctl_filter.append( + 'key:%s' % (key) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + sysctl = linux_handler.get_sysctl(sysctl_filter=sysctl_filter) + diff_sysctl = {} + for diff_server in diff_servers: + diff_sysctl[diff_server] = diff_handlers[diff_server].get_sysctl(sysctl_filter=sysctl_filter) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + sysctl, + indent=4 + ) + ) + return + + ctx.my_output.json_output(sysctl) + + linux_output_handler.print_linux_sysctl( + sysctl, + diff_servers, + diff_sysctl, + title=True + ) + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/main.py b/menu/get/main.py new file mode 100644 index 00000000..ea5508ab --- /dev/null +++ b/menu/get/main.py @@ -0,0 +1,54 @@ +import click + +from menu.get.aci.main import get_aci_menu +from menu.get.chassis import get_chassis_command +from menu.get.cvim.main import get_cvim_menu +from menu.get.helm.main import get_helm_menu +from menu.get.intersight.main import get_intersight_menu +from menu.get.iwo.main import get_iwo_menu +from menu.get.k8s.main import get_k8s_menu +from menu.get.kv.main import get_kv_menu +from menu.get.linux.main import get_linux_menu +from menu.get.nc.main import get_nc_menu +from menu.get.nx.main import get_nx_menu +from menu.get.nso.main import get_nso_menu +from menu.get.ocp.main import get_ocp_menu +from menu.get.openshift.main import get_openshift_menu +from menu.get.osp.main import get_osp_menu +from menu.get.psirt import get_psirt_command +from menu.get.redfish.main import get_redfish_menu +from menu.get.server import get_server_command +from menu.get.ucsm.main import get_ucsm_menu +from menu.get.vc.main import get_vc_menu + + +class Failure(Exception): + pass + + +@click.group("get") +@click.pass_obj +def get_menu(ctx): + """Get commands""" + + +get_menu.add_command(get_aci_menu) +get_menu.add_command(get_chassis_command) +get_menu.add_command(get_cvim_menu) +get_menu.add_command(get_helm_menu) +get_menu.add_command(get_intersight_menu) +get_menu.add_command(get_iwo_menu) +get_menu.add_command(get_k8s_menu) +get_menu.add_command(get_kv_menu) +get_menu.add_command(get_linux_menu) +get_menu.add_command(get_nc_menu) +get_menu.add_command(get_nx_menu) +get_menu.add_command(get_nso_menu) +get_menu.add_command(get_ocp_menu) +get_menu.add_command(get_openshift_menu) +get_menu.add_command(get_osp_menu) +get_menu.add_command(get_psirt_command) +get_menu.add_command(get_redfish_menu) +get_menu.add_command(get_server_command) +get_menu.add_command(get_ucsm_menu) +get_menu.add_command(get_vc_menu) diff --git a/menu/get/nc/__init__.py b/menu/get/nc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/nc/main.py b/menu/get/nc/main.py new file mode 100644 index 00000000..782946b9 --- /dev/null +++ b/menu/get/nc/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.nc.notif import get_nc_notif_command + + +class Failure(Exception): + pass + + +@click.group("nc") +@click.pass_obj +def get_nc_menu(ctx): + """Get netconf commands""" + + +get_nc_menu.add_command(get_nc_notif_command) diff --git a/menu/get/nc/notif.py b/menu/get/nc/notif.py new file mode 100644 index 00000000..5f4678f9 --- /dev/null +++ b/menu/get/nc/notif.py @@ -0,0 +1,76 @@ +import sys +import json +import threading +import traceback +import click + +from lib.netconf import notification + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("notif") +@click.pass_obj +@click.option("--ip", "netconf_ip", default='', callback=validations.validate_ip, help="Netconf IP") +@click.option("--username", "netconf_username", default='', help="Netconf Username") +@click.option("--password", "netconf_password", default='', help="Netconf Password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nc_notif_command( + ctx, + netconf_ip, + netconf_username, + netconf_password, + devel + ): + """Get netconf notification""" + + # iserver get vc vms + + ctx.developer = devel + ctx.output = 'default' + + try: + netconf_ip = '10.58.28.230' + netconf_port = 2022 + netconf_username = 'admin' + netconf_password = 'admin' + + notif_handler = notification.NetconfNotification( + netconf_ip, + netconf_port, + netconf_username, + netconf_password, + log_id=ctx.run_id + ) + + if not notif_handler.is_working(): + ctx.my_output.error('Netconf connection failed') + raise ErrorExit + + ctx.my_output.default('Netconf connection working') + + stream = 'ncs-events' + if not notif_handler.is_stream(stream): + ctx.my_output.error('Stream connection failed: %s' % (stream)) + raise ErrorExit + + ctx.my_output.default('Stream working: %s' % (stream)) + + notif_handler.get_notifications(stream) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/__init__.py b/menu/get/nso/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/nso/__pycache__/__init__.cpython-310.pyc b/menu/get/nso/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..447a6511 Binary files /dev/null and b/menu/get/nso/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/nso/__pycache__/main.cpython-310.pyc b/menu/get/nso/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..4c769777 Binary files /dev/null and b/menu/get/nso/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/nso/__pycache__/ncs.cpython-310.pyc b/menu/get/nso/__pycache__/ncs.cpython-310.pyc new file mode 100644 index 00000000..fe18bc4b Binary files /dev/null and b/menu/get/nso/__pycache__/ncs.cpython-310.pyc differ diff --git a/menu/get/nso/__pycache__/vnfd.cpython-310.pyc b/menu/get/nso/__pycache__/vnfd.cpython-310.pyc new file mode 100644 index 00000000..ff64b93b Binary files /dev/null and b/menu/get/nso/__pycache__/vnfd.cpython-310.pyc differ diff --git a/menu/get/nso/cnfd.py b/menu/get/nso/cnfd.py new file mode 100644 index 00000000..188941c4 --- /dev/null +++ b/menu/get/nso/cnfd.py @@ -0,0 +1,147 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nso import output as nso_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cnfd") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--name", "cnfd_name", default='', help="Filter by CNFD name") +@click.option("--chart", "chart_name", default='', help="Filter by chart name") +@click.option("--version", "chart_version", default='', help="Filter by chart version") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_cnfd_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + restconf_disabled, + cnfd_name, + chart_name, + chart_version, + view, + output, + devel + ): + """Get nso cnfd""" + + # iserver get cnfd + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nso_output_handler = nso_output.NsoOutput( + verbose=False, + debug=devel, + log_id=ctx.run_id + ) + nso_handler = validations.validate_nso( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled + ) + if nso_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + + if cnfd_name is not None: + object_filter.append( + 'name:%s' % (cnfd_name) + ) + + if chart_name is not None: + object_filter.append( + 'chart:%s' % (chart_name) + ) + + if chart_version is not None: + object_filter.append( + 'version:%s' % (chart_version) + ) + + cnfds = nso_handler.get_cnfm_cnfds( + object_filter=object_filter, + cnfi_info=True + ) + + ctx.busy = False + + if cnfds is None: + ctx.my_output.error( + 'Failed to CNFD' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + cnfds, + indent=4 + ) + ) + return + + ctx.my_output.json_output(cnfds) + + if 'state' in view: + nso_output_handler.print_cnfm_cnfds( + cnfds, + title=True + ) + + ctx.my_output.default('\nViews: state (def)') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/cnfi.py b/menu/get/nso/cnfi.py new file mode 100644 index 00000000..de27b215 --- /dev/null +++ b/menu/get/nso/cnfi.py @@ -0,0 +1,222 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nso import output as nso_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cnfi") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--name", "cnfi_name", default='', help="Filter by CNFI name") +@click.option("--view", "-v", default=['state'], help="[state|ready|plan|device|result|pod|dep|rs|svc|vmi|k8s|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_cnfi_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + restconf_disabled, + cnfi_name, + view, + output, + devel + ): + """Get nso cnfi""" + + # iserver get cnfi + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|ready|plan|device|result|pod|dep|rs|svc|vmi|k8s|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nso_output_handler = nso_output.NsoOutput( + verbose=False, + debug=devel, + log_id=ctx.run_id + ) + nso_handler = validations.validate_nso( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled + ) + if nso_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + + if cnfi_name is not None: + object_filter.append( + 'name:%s' % (cnfi_name) + ) + + plan_info = False + device_info = False + result_info = False + + if 'state' in view: + plan_info = True + device_info = True + result_info = True + + if 'ready' in view: + plan_info = True + + if 'plan' in view: + plan_info = True + + if 'device' in view: + device_info = True + + if 'result' in view: + result_info = True + + if 'pod' in view: + result_info = True + + if 'dep' in view: + result_info = True + + if 'rs' in view: + result_info = True + + if 'svc' in view: + result_info = True + + if 'vmi' in view: + result_info = True + + if 'k8s' in view: + result_info = True + + cnfis = nso_handler.get_cnfm_cnfis( + object_filter=object_filter, + plan_info=plan_info, + result_info=result_info, + device_info=device_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + cnfis, + indent=4 + ) + ) + return + + ctx.my_output.json_output(cnfis) + + if 'state' in view: + nso_output_handler.print_cnfm_cnfis( + cnfis, + title=True + ) + + if 'ready' in view: + nso_output_handler.print_cnfm_cnfis_ready( + cnfis, + title=True + ) + + if 'plan' in view: + nso_output_handler.print_cnfm_cnfis_plan( + cnfis, + title=True + ) + + if 'result' in view: + nso_output_handler.print_cnfm_cnfis_result( + cnfis, + title=True + ) + + if 'rs' in view or 'k8s' in view: + nso_output_handler.print_cnfm_cnfis_rs( + cnfis, + title=True + ) + + if 'dep' in view or 'k8s' in view: + nso_output_handler.print_cnfm_cnfis_dep( + cnfis, + title=True + ) + + if 'pod' in view or 'k8s' in view: + nso_output_handler.print_cnfm_cnfis_pod( + cnfis, + title=True + ) + + if 'vmi' in view or 'k8s' in view: + nso_output_handler.print_cnfm_cnfis_vmi( + cnfis, + title=True + ) + + if 'svc' in view or 'k8s' in view: + nso_output_handler.print_cnfm_cnfis_svc( + cnfis, + title=True + ) + + if 'device' in view: + nso_output_handler.print_cnfm_cnfis_device( + cnfis, + title=True + ) + + ctx.my_output.default('\nViews: state (def), ready, plan, device, result, pod, dep, rs, svc, vmi, k8s, all') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/cnfm.py b/menu/get/nso/cnfm.py new file mode 100644 index 00000000..1613715d --- /dev/null +++ b/menu/get/nso/cnfm.py @@ -0,0 +1,149 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nso import output as nso_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cnfm") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--name", "cnfm_name", default='', callback=validations.empty_string_to_none, help="Filter by cnfm name") +@click.option("--view", "-v", default=['state'], help="[state|cluster|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_cnfm_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + restconf_disabled, + cnfm_name, + view, + output, + devel + ): + """Get nso cnfm""" + + # iserver get nso cnfm + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|cluster|device|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nso_output_handler = nso_output.NsoOutput( + verbose=False, + debug=devel, + log_id=ctx.run_id + ) + nso_handler = validations.validate_nso( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled + ) + if nso_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + + if cnfm_name is not None: + object_filter.append( + 'name:%s' % (cnfm_name) + ) + + cnfi_info = False + device_info = False + + if 'state' in view: + cnfi_info = True + device_info = True + + if 'cluster' in view: + cnfi_info = True + + devices = nso_handler.get_cnfm_devices( + object_filter=object_filter, + cnfi_info=cnfi_info, + device_info=device_info + ) + + ctx.busy = False + + if devices is None: + ctx.my_output.error('Failed to get cnfm device information') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + devices, + indent=4 + ) + ) + return + + ctx.my_output.json_output(devices) + + if 'state' in view: + nso_output_handler.print_cnfm_state( + devices, + title=True + ) + + if 'cluster' in view: + nso_output_handler.print_cnfm_clusters( + devices, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def), cluster, all') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/device.py b/menu/get/nso/device.py new file mode 100644 index 00000000..f0fe2cdc --- /dev/null +++ b/menu/get/nso/device.py @@ -0,0 +1,134 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nso import output as nso_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("device") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--name", "device_name", default='', callback=validations.empty_string_to_none, help="Filter by device name") +@click.option("--type", "device_type", default='', callback=validations.empty_string_to_none, help="Filter by device type") +@click.option("--view", "-v", default=['state'], help="[state|sync]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_device_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + restconf_disabled, + device_name, + device_type, + view, + output, + devel + ): + """Get nso device""" + + # iserver get nso device + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|sync', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nso_output_handler = nso_output.NsoOutput( + verbose=False, + debug=devel, + log_id=ctx.run_id + ) + nso_handler = validations.validate_nso( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled + ) + if nso_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + + if device_name is not None: + object_filter.append( + 'name:%s' % (device_name) + ) + + if device_type is not None: + object_filter.append( + 'type:%s' % (device_type) + ) + + sync_info = False + if 'sync' in view: + sync_info = True + + devices = nso_handler.get_devices( + object_filter=object_filter, + sync_info=sync_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + devices, + indent=4 + ) + ) + return + + if 'state' in view or 'sync' in view: + nso_output_handler.print_devices( + devices, + title=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/main.py b/menu/get/nso/main.py new file mode 100644 index 00000000..295315eb --- /dev/null +++ b/menu/get/nso/main.py @@ -0,0 +1,26 @@ +import click + +from menu.get.nso.cnfd import get_nso_cnfd_command +from menu.get.nso.cnfi import get_nso_cnfi_command +from menu.get.nso.cnfm import get_nso_cnfm_command +from menu.get.nso.device import get_nso_device_command +from menu.get.nso.ncs import get_nso_ncs_command +from menu.get.nso.nfvo.main import get_nso_nfvo_menu + + +class Failure(Exception): + pass + + +@click.group("nso") +@click.pass_obj +def get_nso_menu(ctx): + """Get nso commands""" + + +get_nso_menu.add_command(get_nso_cnfd_command) +get_nso_menu.add_command(get_nso_cnfi_command) +get_nso_menu.add_command(get_nso_cnfm_command) +get_nso_menu.add_command(get_nso_device_command) +get_nso_menu.add_command(get_nso_ncs_command) +get_nso_menu.add_command(get_nso_nfvo_menu) diff --git a/menu/get/nso/ncs.py b/menu/get/nso/ncs.py new file mode 100644 index 00000000..e0344bdd --- /dev/null +++ b/menu/get/nso/ncs.py @@ -0,0 +1,51 @@ +import sys +import traceback +import click + +from lib.nso import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ncs") +@click.pass_obj +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_ncs_command( + ctx, + show_password, + devel + ): + """Get ncs instances""" + + # iserver get aci controller + + ctx.developer = devel + + try: + settings_handler = settings.NsoSettings(log_id=ctx.run_id) + + ncss = settings_handler.get_nso_ncss() + if ncss is None: + ctx.my_output.error('Failed to get NSCs') + raise ErrorExit + + settings_handler.print_nso_ncss( + ncss, + show_password=show_password + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/nfvo/__init__.py b/menu/get/nso/nfvo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/nso/nfvo/__pycache__/__init__.cpython-310.pyc b/menu/get/nso/nfvo/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..332ab485 Binary files /dev/null and b/menu/get/nso/nfvo/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/nso/nfvo/__pycache__/main.cpython-310.pyc b/menu/get/nso/nfvo/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..001fb8a7 Binary files /dev/null and b/menu/get/nso/nfvo/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/nso/nfvo/__pycache__/vnfd.cpython-310.pyc b/menu/get/nso/nfvo/__pycache__/vnfd.cpython-310.pyc new file mode 100644 index 00000000..869c74f4 Binary files /dev/null and b/menu/get/nso/nfvo/__pycache__/vnfd.cpython-310.pyc differ diff --git a/menu/get/nso/nfvo/__pycache__/vnfi.cpython-310.pyc b/menu/get/nso/nfvo/__pycache__/vnfi.cpython-310.pyc new file mode 100644 index 00000000..fc752267 Binary files /dev/null and b/menu/get/nso/nfvo/__pycache__/vnfi.cpython-310.pyc differ diff --git a/menu/get/nso/nfvo/main.py b/menu/get/nso/nfvo/main.py new file mode 100644 index 00000000..ad114692 --- /dev/null +++ b/menu/get/nso/nfvo/main.py @@ -0,0 +1,18 @@ +import click + +from menu.get.nso.nfvo.vnfd import get_nso_nfvo_vnfd_command +from menu.get.nso.nfvo.vnfi import get_nso_nfvo_vnfi_command + + +class Failure(Exception): + pass + + +@click.group("nfvo") +@click.pass_obj +def get_nso_nfvo_menu(ctx): + """Get nso nfvo commands""" + + +get_nso_nfvo_menu.add_command(get_nso_nfvo_vnfd_command) +get_nso_nfvo_menu.add_command(get_nso_nfvo_vnfi_command) diff --git a/menu/get/nso/nfvo/vnfd.py b/menu/get/nso/nfvo/vnfd.py new file mode 100644 index 00000000..c5cef8b4 --- /dev/null +++ b/menu/get/nso/nfvo/vnfd.py @@ -0,0 +1,136 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nso import output as nso_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vnfd") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--nfvo", type=click.Choice(['3.x', 'etsi:4.x'], case_sensitive=False), default='etsi:4.x', show_default=True, help="NFVO Version") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--id", "vnfd_id", default='', callback=validations.empty_string_to_none, help="VNFD name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_nfvo_vnfd_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + nfvo, + restconf_disabled, + vnfd_id, + output, + devel + ): + """Get nso nfvo vnfd""" + + # iserver get nso nfvo vnfd + + ctx.developer = devel + ctx.output = output + + try: + nso_output_handler = nso_output.NsoOutput( + verbose=False, + debug=devel, + log_id=ctx.run_id + ) + nso_handler = validations.validate_nso_nfvo( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo + ) + if nso_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if vnfd_id is None: + vnfds = nso_handler.nfvo_handler.get_vnfds() + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vnfds, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vnfds) + + nso_output_handler.print_vnfds( + vnfds + ) + + else: + vnfd = nso_handler.nfvo_handler.get_vnfd( + vnfd_id=vnfd_id + ) + + ctx.busy = False + + if vnfd is None: + ctx.my_output.error( + 'VNFD %s not found' % (vnfd_id) + ) + raise ErrorExit + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vnfd, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vnfd) + + ctx.my_output.default( + vnfd + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nso/nfvo/vnfi.py b/menu/get/nso/nfvo/vnfi.py new file mode 100644 index 00000000..6afeeb32 --- /dev/null +++ b/menu/get/nso/nfvo/vnfi.py @@ -0,0 +1,148 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vnfi") +@click.pass_obj +@click.option("--ncs", "ncs_name", default='', callback=validations.validate_ncs_name, help="NSO name") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--ip", "ncs_ip", default='', callback=validations.validate_ip, help="NSO IP") +@click.option("--port", "ncs_port", default=8080, help="NSO Port") +@click.option("--username", "ncs_username", default='', help="NSO Username") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--password", "ncs_password", default='', help="NSO Password") +@click.option("--nfvo", "nfvo_version", type=click.Choice(['3.x', '4.x'], case_sensitive=False), default='4.x', show_default=True, help="NFVO Version") +@click.option("--etsi", "nfvo_etsi", is_flag=True, show_default=True, default=False, help="NFVO ETSI") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--name", "vnfi_name", default='', callback=validations.empty_string_to_none, help="VNFD name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nso_nfvo_vnfi_command( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + nfvo_version, + nfvo_etsi, + restconf_disabled, + vnfi_name, + output, + verbose, + devel + ): + """Get nso nfvo vnfi""" + + # iserver get nso nfvo vnfi + + ctx.developer = devel + ctx.output = output + + try: + nso_handler = validations.validate_nso_ncs( + ctx, + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo_version, + nfvo_etsi + ) + if nso_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + if vnfi_name is None: + vnfis = nso_handler.get_vnfis_info() + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vnfis, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vnfis) + + nso_handler.print_vnfis( + vnfis + ) + + else: + if output == 'json': + vnfi = nso_handler.get_vnfi( + vnfi_name, + output_format='json' + ) + + if output == 'default': + vnfi = nso_handler.get_vnfi( + vnfi_name, + output_format='xml' + ) + + ctx.busy = False + + if vnfi is None: + ctx.my_output.error( + 'VNF-INFO %s not found' % (vnfi_name) + ) + raise ErrorExit + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vnfi, + indent=4 + ) + ) + return + + ctx.my_output.default( + vnfi + ) + + plan = nso_handler.get_vnfi_plan(vnfi_name) + if plan is None: + ctx.my_output.default('WARNING: No plan found') + return + + nso_handler.print_vnfi_plan(plan) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/__init__.py b/menu/get/nx/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/nx/config.py b/menu/get/nx/config.py new file mode 100644 index 00000000..aa863511 --- /dev/null +++ b/menu/get/nx/config.py @@ -0,0 +1,123 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nexus import settings as nexus_settings +from lib.nexus import output as nexus_output +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("config") +@click.pass_obj +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--cache", "user_cache", type=click.Choice(['follow', 'on', 'off'], case_sensitive=False), default='follow', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_config_command( + ctx, + device, + device_ip, + device_username, + device_password, + view, + user_cache, + output, + devel + ): + """Get config""" + + # iserver get nx ver + + ctx.my_output.default('Placeholder') + if True: + return + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + if user_cache == 'on': + cache_enabled = True + if user_cache == 'off': + cache_enabled = False + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + nexus_output_handler = nexus_output.NexusOutput(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + configs = [] + + for device_handler in device_handlers: + device_configs = device_handler['handler'].get_configs() + if device_configs is not None: + configs = configs + device_configs + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + configs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(configs) + + nexus_output_handler.print_configs( + configs, + title=True + ) + + ctx.my_output.default('Filter: --', before_newline=True) + ctx.my_output.default('View: state (def)') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/device.py b/menu/get/nx/device.py new file mode 100644 index 00000000..b6dd1a78 --- /dev/null +++ b/menu/get/nx/device.py @@ -0,0 +1,51 @@ +import sys +import traceback +import click + +from lib.nexus import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("device") +@click.pass_obj +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_device_command( + ctx, + show_password, + devel + ): + """Get nx devices""" + + # iserver get nx device + + ctx.developer = devel + + try: + settings_handler = settings.NexusSettings(log_id=ctx.run_id) + + switches = settings_handler.get_nexus_devices() + if switches is None: + ctx.my_output.error('Failed to get Nexus devices') + raise ErrorExit + + settings_handler.print_nexus_devices( + switches, + show_password=show_password + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/lacp.py b/menu/get/nx/lacp.py new file mode 100644 index 00000000..59e2c56f --- /dev/null +++ b/menu/get/nx/lacp.py @@ -0,0 +1,130 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nexus import settings as nexus_settings +from lib.nexus import output as nexus_output +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("lacp") +@click.pass_obj +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--mac", "nbr_mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--cache", "user_cache", type=click.Choice(['follow', 'on', 'off'], case_sensitive=False), default='follow', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_lacp_command( + ctx, + device, + device_ip, + device_username, + device_password, + nbr_mac, + view, + user_cache, + output, + devel + ): + """Get lacp neighbor""" + + # iserver get nx lacp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + if user_cache == 'on': + cache_enabled = True + if user_cache == 'off': + cache_enabled = False + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + nexus_output_handler = nexus_output.NexusOutput(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + if nbr_mac is not None: + object_filter.append( + 'mac:%s' % (nbr_mac) + ) + + neighbors = [] + + for device_handler in device_handlers: + device_neighbors = device_handler['handler'].get_lacps( + object_filter=object_filter + ) + if device_neighbors is not None: + neighbors = neighbors + device_neighbors + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + neighbors, + indent=4 + ) + ) + return + + ctx.my_output.json_output(neighbors) + + if 'state' in view: + nexus_output_handler.print_lacps( + neighbors, + title=True + ) + + ctx.my_output.default('Filter: mac', before_newline=True) + ctx.my_output.default('View: state (def)') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/lldp.py b/menu/get/nx/lldp.py new file mode 100644 index 00000000..30324005 --- /dev/null +++ b/menu/get/nx/lldp.py @@ -0,0 +1,137 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nexus import settings as nexus_settings +from lib.nexus import output as nexus_output +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("lldp") +@click.pass_obj +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--id", "nbr_id", default='', callback=validations.empty_string_to_none, help="Filter neighbor by device id") +@click.option("--mac", "nbr_mac", default='', callback=validations.empty_string_to_none, help="Filter neighbor by mac address") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--cache", "user_cache", type=click.Choice(['follow', 'on', 'off'], case_sensitive=False), default='follow', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_lldp_command( + ctx, + device, + device_ip, + device_username, + device_password, + nbr_id, + nbr_mac, + view, + user_cache, + output, + devel + ): + """Get lldp neighbor""" + + # iserver get nx lldp + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + if user_cache == 'on': + cache_enabled = True + if user_cache == 'off': + cache_enabled = False + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + nexus_output_handler = nexus_output.NexusOutput(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + if nbr_id is not None: + object_filter.append( + 'id:%s' % (nbr_id) + ) + + if nbr_mac is not None: + object_filter.append( + 'mac:%s' % (nbr_mac) + ) + + neighbors = [] + + for device_handler in device_handlers: + device_neighbors = device_handler['handler'].get_lldps( + object_filter=object_filter + ) + if device_neighbors is not None: + neighbors = neighbors + device_neighbors + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + neighbors, + indent=4 + ) + ) + return + + ctx.my_output.json_output(neighbors) + + if 'state' in view: + nexus_output_handler.print_lldps( + neighbors, + title=True + ) + + ctx.my_output.default('Filter: id, mac', before_newline=True) + ctx.my_output.default('View: state (def)') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/mac.py b/menu/get/nx/mac.py new file mode 100644 index 00000000..a511f971 --- /dev/null +++ b/menu/get/nx/mac.py @@ -0,0 +1,137 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nexus import settings as nexus_settings +from lib.nexus import output as nexus_output +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("mac") +@click.pass_obj +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--vlan", default='', callback=validations.empty_string_to_none, help="Filter by vlan") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--cache", "user_cache", type=click.Choice(['follow', 'on', 'off'], case_sensitive=False), default='follow', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_mac_command( + ctx, + device, + device_ip, + device_username, + device_password, + mac, + vlan, + view, + user_cache, + output, + devel + ): + """Get mac address table mac""" + + # iserver get nx mac + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + if user_cache == 'on': + cache_enabled = True + if user_cache == 'off': + cache_enabled = False + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + nexus_output_handler = nexus_output.NexusOutput(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + if mac is not None: + object_filter.append( + 'mac:%s' % (mac) + ) + + if vlan is not None: + object_filter.append( + 'vlan:%s' % (vlan) + ) + + macs = [] + + for device_handler in device_handlers: + device_macs = device_handler['handler'].get_macs( + object_filter=object_filter + ) + if device_macs is not None: + macs = macs + device_macs + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + macs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(macs) + + if 'state' in view: + nexus_output_handler.print_macs( + macs, + title=True + ) + + ctx.my_output.default('Filter: mac, vlan', before_newline=True) + ctx.my_output.default('View: state (def)') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/main.py b/menu/get/nx/main.py new file mode 100644 index 00000000..413945dc --- /dev/null +++ b/menu/get/nx/main.py @@ -0,0 +1,30 @@ +import click + +from menu.get.nx.config import get_nx_config_command +from menu.get.nx.device import get_nx_device_command +from menu.get.nx.lacp import get_nx_lacp_command +from menu.get.nx.lldp import get_nx_lldp_command +from menu.get.nx.mac import get_nx_mac_command +from menu.get.nx.psirt import get_nx_psirt_command +from menu.get.nx.server import get_nx_server_command +from menu.get.nx.ver import get_nx_ver_command + + +class Failure(Exception): + pass + + +@click.group("nx") +@click.pass_obj +def get_nx_menu(ctx): + """Get nexus commands""" + + +get_nx_menu.add_command(get_nx_config_command) +get_nx_menu.add_command(get_nx_device_command) +get_nx_menu.add_command(get_nx_lacp_command) +get_nx_menu.add_command(get_nx_lldp_command) +get_nx_menu.add_command(get_nx_mac_command) +get_nx_menu.add_command(get_nx_psirt_command) +get_nx_menu.add_command(get_nx_server_command) +get_nx_menu.add_command(get_nx_ver_command) diff --git a/menu/get/nx/psirt.py b/menu/get/nx/psirt.py new file mode 100644 index 00000000..fae3d6f3 --- /dev/null +++ b/menu/get/nx/psirt.py @@ -0,0 +1,155 @@ +import sys +import json +import threading +import traceback +import click + +from lib.aci import output as aci_output +from lib.psirt import main as psirt +from lib.psirt import output as psirt_output +from lib.psirt import settings +from lib.nexus import settings as nexus_settings + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("psirt") +@click.pass_obj +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_psirt_command( + ctx, + device, + device_ip, + device_username, + device_password, + view, + output, + devel + ): + """Get nx psirt""" + + # iserver get nx psirt + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + settings_handler = settings.PsirtSettings(log_id=ctx.run_id) + psirt_settings = settings_handler.get_psirt_settings() + if psirt_settings is None: + ctx.my_output.error('Failed to get psirt api settings') + raise ErrorExit + + if not psirt_settings['enabled']: + ctx.my_output.error('Psirt disabled') + raise ErrorExit + + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + advisories = {} + node_versions = {} + + for device_handler in device_handlers: + device_versions = device_handler['handler'].get_versions() + + if len(device_versions) != 1: + continue + + device_version = device_versions[0]['nxos_ver_str'] + node_versions[device_handler['name']] = device_version + + psirt_object_filter = [] + psirt_object_filter.append( + 'product:*nx-os*' + ) + + psirt_object_filter.append( + 'version:%s' % (device_version) + ) + + psirt_handler = psirt.Psirt(psirt_settings['key'], psirt_settings['secret'], log_id=ctx.run_id) + advisories[device_handler['name']] = psirt_handler.get_advisories( + psirt_object_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + advisories, + indent=4 + ) + ) + return + + ctx.my_output.json_output(advisories) + + psirt_output_handler = psirt_output.PsirtOutput(log_id=ctx.run_id) + for device_name in advisories: + ctx.my_output.default('Advisory - Apic: %s version %s' % (device_name, node_versions[device_name]), underline=True, before_newline=True) + psirt_output_handler.print_advisory_version( + advisories[device_name], + title=False + ) + + ctx.my_output.default('Filter: --', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/server.py b/menu/get/nx/server.py new file mode 100644 index 00000000..6e84d6e3 --- /dev/null +++ b/menu/get/nx/server.py @@ -0,0 +1,157 @@ +import sys +import json +import threading +import traceback +import click + +from lib.intersight import compute +from lib.intersight import compute_output +from lib.nexus import settings as nexus_settings + +from menu import defaults +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--address", "server_ip", callback=validations.validate_ip, help="Server IP") +@click.option("--view", "-v", default=['all'], help="[lacp|lldp|mac|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_server_command( + ctx, + iaccount, + device, + device_ip, + device_username, + device_password, + server_ip, + view, + output, + devel + ): + """Get server information""" + + # iserver get nx xd server + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'lacp|lldp|mac|all', + 'all', + [] + ) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + if output != 'json': + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + match_rules = compute_handler.get_mo_match_rules( + ip_filter=[server_ip] + ) + servers_mo = compute_handler.get_mo( + match_rules=match_rules, + include_rack=True, + include_blade=True + ) + if len(servers_mo) == 0: + ctx.busy = False + ctx.my_output.error('Server not found') + raise ErrorExit + + if len(servers_mo) > 1: + ctx.busy = False + ctx.my_output.error('Multiple servers found') + raise ErrorExit + + settings = {} + settings['net'] = True + + servers_info = compute_handler.get_info( + servers_mo, + settings, + None, + 0 + ) + server_info = servers_info[0] + for device_handler in device_handlers: + server_info = device_handler['handler'].get_server_connectivity( + server_info + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + server_info['MacAddressInfo'], + indent=4 + ) + ) + return + + ctx.my_output.json_output(server_info['MacAddressInfo']) + + compute_output_handler.print_summary_table( + [server_info], + title=True + ) + + compute_output_handler.print_nx( + server_info, + title=True + ) + + ctx.my_output.default('Filter: --', before_newline=True) + ctx.my_output.default('View: lacp, lldp, mac, all (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/nx/ver.py b/menu/get/nx/ver.py new file mode 100644 index 00000000..2453dac2 --- /dev/null +++ b/menu/get/nx/ver.py @@ -0,0 +1,122 @@ +import sys +import json +import threading +import traceback +import click + +from lib.nexus import settings as nexus_settings +from lib.nexus import output as nexus_output +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ver") +@click.pass_obj +@click.option("--device", "device", default='', callback=validations.validate_nexus_any_name, help="Device name") +@click.option("--ip", "device_ip", default='', callback=validations.validate_ip, help="Device IP") +@click.option("--username", "device_username", default='', help="Device Username") +@click.option("--password", "device_password", default='', help="Device Password") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--cache", "user_cache", type=click.Choice(['follow', 'on', 'off'], case_sensitive=False), default='follow', show_default=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_nx_ver_command( + ctx, + device, + device_ip, + device_username, + device_password, + view, + user_cache, + output, + devel + ): + """Get version""" + + # iserver get nx ver + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + cache_enabled = nexus_settings_handler.is_nexus_cache_enabled() + if user_cache == 'on': + cache_enabled = True + if user_cache == 'off': + cache_enabled = False + + device_handlers = validations.validate_nexus_devices( + ctx, + device, + device_ip, + device_username, + device_password, + cache_enabled=cache_enabled + ) + if device_handlers is None: + raise ErrorExit + + nexus_output_handler = nexus_output.NexusOutput(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + versions = [] + + for device_handler in device_handlers: + device_versions = device_handler['handler'].get_versions( + object_filter=object_filter + ) + if device_versions is not None: + versions = versions + device_versions + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + versions, + indent=4 + ) + ) + return + + ctx.my_output.json_output(versions) + + nexus_output_handler.print_versions( + versions, + title=True + ) + + ctx.my_output.default('Filter: --', before_newline=True) + ctx.my_output.default('View: state (def)') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ocp/__init__.py b/menu/get/ocp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/ocp/__pycache__/__init__.cpython-310.pyc b/menu/get/ocp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d8afe41e Binary files /dev/null and b/menu/get/ocp/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/cluster.cpython-310.pyc b/menu/get/ocp/__pycache__/cluster.cpython-310.pyc new file mode 100644 index 00000000..750b691c Binary files /dev/null and b/menu/get/ocp/__pycache__/cluster.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/installer.cpython-310.pyc b/menu/get/ocp/__pycache__/installer.cpython-310.pyc new file mode 100644 index 00000000..c6948429 Binary files /dev/null and b/menu/get/ocp/__pycache__/installer.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/kc.cpython-310.pyc b/menu/get/ocp/__pycache__/kc.cpython-310.pyc new file mode 100644 index 00000000..3c476af8 Binary files /dev/null and b/menu/get/ocp/__pycache__/kc.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/main.cpython-310.pyc b/menu/get/ocp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..dddc0355 Binary files /dev/null and b/menu/get/ocp/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/node.cpython-310.pyc b/menu/get/ocp/__pycache__/node.cpython-310.pyc new file mode 100644 index 00000000..4df1825c Binary files /dev/null and b/menu/get/ocp/__pycache__/node.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/vcenter.cpython-310.pyc b/menu/get/ocp/__pycache__/vcenter.cpython-310.pyc new file mode 100644 index 00000000..f9413790 Binary files /dev/null and b/menu/get/ocp/__pycache__/vcenter.cpython-310.pyc differ diff --git a/menu/get/ocp/__pycache__/vm.cpython-310.pyc b/menu/get/ocp/__pycache__/vm.cpython-310.pyc new file mode 100644 index 00000000..0219d0c6 Binary files /dev/null and b/menu/get/ocp/__pycache__/vm.cpython-310.pyc differ diff --git a/menu/get/ocp/chrony.py b/menu/get/ocp/chrony.py new file mode 100644 index 00000000..3fd827b7 --- /dev/null +++ b/menu/get/ocp/chrony.py @@ -0,0 +1,70 @@ +import sys +import traceback +import threading +import click + +from lib.ocp import output as ocp_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("chrony") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ocp_chrony_command( + ctx, + cluster_name, + output, + devel + ): + """Get ocp chrony state""" + + # iserver get ocp chrony + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster_name, cluster_type='ocp', silent=True) + if k8s_handlers is None: + raise ErrorExit + + ocp_output_handler = ocp_output.OcpOutput(log_id=ctx.run_id) + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + info = ocp_handler.get_ocp_chrony_info( + mcp=True, + config=True, + state=True + ) + ctx.busy = False + ocp_output_handler.print_ocp_chrony_info(info) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ocp/cpolicy.py b/menu/get/ocp/cpolicy.py new file mode 100644 index 00000000..12ca6c86 --- /dev/null +++ b/menu/get/ocp/cpolicy.py @@ -0,0 +1,67 @@ +import sys +import traceback +import threading +import click + +from lib.ocp import output as ocp_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cpolicy") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ocp_cpolicy_command( + ctx, + cluster_name, + output, + devel + ): + """Get ocp container policy""" + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster_name, cluster_type='ocp', silent=True) + if k8s_handlers is None: + raise ErrorExit + + ocp_output_handler = ocp_output.OcpOutput(log_id=ctx.run_id) + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + info = ocp_handler.get_ocp_container_policy_info( + mcp=True, + config=True + ) + ctx.busy = False + ocp_output_handler.print_ocp_container_policy_info(info) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ocp/main.py b/menu/get/ocp/main.py new file mode 100644 index 00000000..96d087f7 --- /dev/null +++ b/menu/get/ocp/main.py @@ -0,0 +1,24 @@ +import click + +from menu.get.ocp.chrony import get_ocp_chrony_command +from menu.get.ocp.cpolicy import get_ocp_cpolicy_command +from menu.get.ocp.node import get_ocp_node_command +from menu.get.ocp.ssh import get_ocp_ssh_command +from menu.get.ocp.vm import get_ocp_vm_command + + +class Failure(Exception): + pass + + +@click.group("ocp") +@click.pass_obj +def get_ocp_menu(ctx): + """Get ocp commands""" + + +get_ocp_menu.add_command(get_ocp_chrony_command) +get_ocp_menu.add_command(get_ocp_cpolicy_command) +get_ocp_menu.add_command(get_ocp_node_command) +get_ocp_menu.add_command(get_ocp_ssh_command) +get_ocp_menu.add_command(get_ocp_vm_command) diff --git a/menu/get/ocp/node.py b/menu/get/ocp/node.py new file mode 100644 index 00000000..73f729fc --- /dev/null +++ b/menu/get/ocp/node.py @@ -0,0 +1,183 @@ +import sys +import json +import traceback +import threading +import click + +from lib.ocp import settings +from lib.ocp import output as ocp_output +from lib.ocp import main as ocp + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("node") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster name") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster node name") +@click.option("--role", "node_role", type=click.Choice(['any', 'master', 'worker'], case_sensitive=False), default='any', show_default=True) +@click.option("--label", default='', callback=validations.empty_string_to_none, help="Filter by node label") +@click.option("--view", "-v", type=click.Choice(['default', 'version', 'label', 'sriov', 'sriov-phy', 'sriov-policy', 'sriov-network', 'sriov-vf', 'all'], case_sensitive=False), multiple=False, default='default') +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ocp_node_command( + ctx, + cluster_name, + node_name, + node_role, + label, + view, + output, + devel + ): + """Get ocp node""" + + # iserver get ocp node + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + ocp_output_handler = ocp_output.OcpOutput(log_id=ctx.run_id) + settings_handler = settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None: + cluster_name = settings_handler.get_default_cluster() + if cluster_name is not None and output == 'default': + ctx.my_output.default('Cluster: %s' % (cluster_name)) + + cluster_filter = [] + + if cluster_name is not None: + cluster_filter.append( + 'name:%s' % (cluster_name) + ) + + clusters = settings_handler.get_ocp_clusters( + cluster_filter=cluster_filter + ) + + if clusters is None or len(clusters) == 0: + ctx.busy = False + raise ErrorExit + + nodes = [] + + node_filter = [] + + if node_name is not None: + node_filter.append( + 'name:%s' % (node_name) + ) + + if node_role != 'any': + if node_role == 'master': + node_filter.append( + 'master:true' + ) + if node_role == 'worker': + node_filter.append( + 'worker:true' + ) + + if label is not None: + node_filter.append( + 'label:%s' % (label) + ) + + sriov_phy_info = False + sriov_policy_info = False + sriov_network_info = False + sriov_vf_info = False + + if view in ['sriov', 'all']: + sriov_phy_info = True + sriov_policy_info = True + sriov_network_info = True + sriov_vf_info = True + + if view == 'sriov-phy': + sriov_phy_info = True + + if view == 'sriov-policy': + sriov_policy_info = True + + if view == 'sriov-network': + sriov_network_info = True + + if view == 'sriov-vf': + sriov_vf_info = True + + for cluster_settings in clusters: + cluster_handler = ocp.Ocp( + cluster_settings['name'], + log_id=ctx.run_id + ) + cluster_nodes_info = cluster_handler.get_ocp_nodes( + node_filter=node_filter, + sriov_phy_info=sriov_phy_info, + sriov_policy_info=sriov_policy_info, + sriov_network_info=sriov_network_info, + sriov_vf_info=sriov_vf_info + ) + if cluster_nodes_info is not None: + nodes = nodes + cluster_nodes_info + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + nodes, + indent=4 + ) + ) + return + + ctx.my_output.json_output(nodes) + + if view in ['default', 'all']: + pass + + if view in ['version', 'all']: + pass + + if view in ['label', 'all']: + pass + + if view in ['sriov-phy', 'sriov', 'all']: + ocp_output_handler.print_ocp_nodes_sriov_phy(nodes, title=True) + + if view in ['sriov-policy', 'sriov', 'all']: + ocp_output_handler.print_ocp_nodes_sriov_policy(nodes, title=True) + + if view in ['sriov-network', 'sriov', 'all']: + ocp_output_handler.print_ocp_nodes_sriov_network(nodes, title=True) + + if view in ['sriov-vf', 'sriov', 'all']: + ocp_output_handler.print_ocp_nodes_sriov_vf(nodes, title=True) + + ctx.busy = False + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ocp/ssh.py b/menu/get/ocp/ssh.py new file mode 100644 index 00000000..f33b5e3a --- /dev/null +++ b/menu/get/ocp/ssh.py @@ -0,0 +1,66 @@ +import sys +import traceback +import threading +import click + +from lib.ocp import output as ocp_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ssh") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ocp_ssh_command( + ctx, + cluster_name, + output, + devel + ): + """Get ocp nodes ssh access""" + + # iserver get ocp ssh + + ctx.developer = devel + ctx.output = output + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + k8s_handlers = validations.validate_kubernetes_name(ctx, cluster_name, cluster_type='ocp') + if k8s_handlers is None: + raise ErrorExit + + ocp_output_handler = ocp_output.OcpOutput(log_id=ctx.run_id) + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + keys = ocp_handler.get_ocp_ssh_authorized_keys() + ctx.busy = False + ocp_output_handler.print_ocp_ssh_authorized_keys(keys) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ocp/vm.py b/menu/get/ocp/vm.py new file mode 100644 index 00000000..ba67147e --- /dev/null +++ b/menu/get/ocp/vm.py @@ -0,0 +1,199 @@ +import sys +import json +import traceback +import threading +import click + +from lib.ocp import output as ocp_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Cluster name") +@click.option("--node", "node_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster node name") +@click.option("--namespace", "vm_namespace", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine namespace") +@click.option("--name", "vm_name", default='', callback=validations.validate_ocp_namespace_name, help="Filter by virtual machine name") +@click.option("--mac", "mac_address_filter", default='', callback=validations.empty_string_to_none, help="MAC filter") +@click.option("--sriov", type=click.Choice(['any', 'enabled', 'disabled'], case_sensitive=False), default='any', show_default=True, help="Filter by sriov capabilities") +@click.option("--fabric", "fabric_hint", callback=validations.validate_fabric, multiple=True, help="Fabric hint") +@click.option("--view", "-v", type=click.Choice(['default', 'intf', 'sriov', 'fabric', 'bgp', 'net', 'disk', 'csi', 'service', 'all'], case_sensitive=False), multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ocp_vm_command( + ctx, + cluster_name, + node_name, + vm_namespace, + vm_name, + mac_address_filter, + sriov, + fabric_hint, + view, + output, + devel + ): + """Get ocp vm""" + + # iserver get ocp vm + + ctx.developer = devel + ctx.output = output + if len(view) == 0: + view = ['default'] + + try: + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + ocp_output_handler = ocp_output.OcpOutput(log_id=ctx.run_id) + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + # ctx.busy = False + # response = ocp_handler.k8s_handler.get_virtual_machine_instances() + # print(response) + + vm_filter = [] + namespace_filtered = False + + if vm_name is not None: + vm_filter.append( + 'name:%s' % (vm_name['name']) + ) + + if vm_name['namespace'] is not None: + namespace_filtered = True + vm_filter.append( + 'namespace:%s' % (vm_name['namespace']) + ) + + if vm_namespace is not None: + if namespace_filtered: + ctx.my_output.error( + 'Define namespace filter in one place' + ) + raise ErrorExit + + vm_filter.append( + 'namespace:%s' % (vm_namespace) + ) + + if node_name is not None: + vm_filter.append( + 'node:%s' % (node_name) + ) + + if sriov != 'any': + vm_filter.append( + 'sriov:%s' % (sriov) + ) + + if mac_address_filter is not None: + vm_filter.append( + 'mac:%s' % (mac_address_filter) + ) + + csi_info = False + if 'csi' in view or 'all' in view: + csi_info = True + + sriov_info = False + if 'sriov' in view or 'net' in view or 'all' in view: + sriov_info = True + + fabric_info = False + if 'fabric' in view or 'net' in view or 'all' in view: + if fabric_hint is None: + if 'all' not in view: + ctx.my_output.error('Provide --fabric hint') + raise ErrorExit + if output != 'json': + ctx.my_output.default('[INFO] Provide --fabric hint for fabric and bgp information') + else: + fabric_info = True + + bgp_info = False + if 'bgp' in view or 'net' in view or 'all' in view: + if fabric_hint is None: + if 'all' not in view: + ctx.my_output.error('Provide --fabric hint') + raise ErrorExit + else: + bgp_info = True + + vms = ocp_handler.get_ocp_vms( + vm_filter=vm_filter, + csi_info=csi_info, + sriov_info=sriov_info, + fabric_info=fabric_info, + bgp_info=bgp_info, + fabric_hint=fabric_hint + ) + + ctx.busy = False + + if vms is None: + raise ErrorExit + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vms, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vms) + + if 'all' in view or 'default' in view: + ocp_output_handler.print_ocp_vms(vms, title=True) + + if 'all' in view or 'disk' in view: + ocp_output_handler.print_ocp_vms_disk(vms, title=True) + + if 'all' in view or 'csi' in view: + ocp_output_handler.print_ocp_vms_csi(vms, title=True) + + if 'all' in view or 'service' in view: + ocp_output_handler.print_ocp_vms_service(vms, title=True) + + if 'all' in view or 'intf' in view or 'net' in view: + ocp_output_handler.print_ocp_vms_intf(vms, title=True) + + if 'all' in view or 'sriov' in view or 'net' in view: + ocp_output_handler.print_ocp_vms_sriov(vms, title=True) + + if fabric_info: + if 'all' in view or 'fabric' in view or 'net' in view: + ocp_output_handler.print_ocp_vms_fabric(vms, title=True) + + if bgp_info: + if 'all' in view or 'bgp' in view or 'net' in view: + ocp_output_handler.print_ocp_vms_bgp(vms, title=True) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/openshift/__init__.py b/menu/get/openshift/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/openshift/ai/__init__.py b/menu/get/openshift/ai/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/openshift/ai/cluster.py b/menu/get/openshift/ai/cluster.py new file mode 100644 index 00000000..b8c45a6d --- /dev/null +++ b/menu/get/openshift/ai/cluster.py @@ -0,0 +1,145 @@ +import sys +import traceback +import json +import threading +import click + +from lib.openshift import console +from lib.openshift import output as openshift_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by cluster name") +@click.option("--view", "-v", default=['state'], help="[state|verbose]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_openshift_ai_cluster_command( + ctx, + name, + view, + output, + devel + ): + """Get openshift assisted installer clusters""" + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|verbose', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + openshift_output_handler = openshift_output.OpenshiftOutput(log_id=ctx.run_id) + console_handler = console.Console(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + subscriptions = console_handler.get_accounts_mgmt_subscription_mo() + if subscriptions is None: + ctx.my_output.error('Failed to get subscriptions') + raise ErrorExit + + cluster_ids = [] + for subscription in subscriptions: + cluster_ids.append( + subscription['cluster_id'] + ) + + config_info = False + credentials_info = False + infra_info = False + manifest_info = False + kubeconfig_info = False + + if 'verbose' in view: + config_info = True + credentials_info = True + infra_info = True + manifest_info = True + kubeconfig_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if len(cluster_ids) > 0: + object_filter.append( + 'ids:%s' % (','.join(cluster_ids)) + ) + + clusters = console_handler.get_assisted_install_clusters( + assisted_install_cluster_filter=object_filter, + config_info=config_info, + credentials_info=credentials_info, + infra_info=infra_info, + manifest_info=manifest_info, + kubeconfig_info=kubeconfig_info + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + clusters, + indent=4 + ) + ) + return + + ctx.my_output.json_output(clusters) + + if 'state' in view: + openshift_output_handler.print_assisted_install_clusters_state(clusters, title=True) + + if 'verbose' in view: + for cluster in clusters: + openshift_output_handler.print_assisted_install_cluster(cluster) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def), verbose') + + # print(json.dumps(response, indent=4)) + # print(json.dumps(json.loads(response[0]['validations_info']), indent=4)) + + # cluster_id = '2069d759-cbc3-42e5-9b3a-3bc7b395a738' + # response = console_handler.get_assisted_install_cluster_install_config_mo(cluster_id) + # print(json.dumps(response, indent=4)) + + # response = console_handler.get_assisted_install_infra_mo() + # print(response) + + # response = console_handler.get_assisted_install_manifest_mo(cluster_id) + # print(response) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/openshift/ai/main.py b/menu/get/openshift/ai/main.py new file mode 100644 index 00000000..e58df201 --- /dev/null +++ b/menu/get/openshift/ai/main.py @@ -0,0 +1,18 @@ +import click + +from menu.get.openshift.ai.cluster import get_openshift_ai_cluster_command +from menu.get.openshift.ai.version import get_openshift_ai_version_command + + +class Failure(Exception): + pass + + +@click.group("ai") +@click.pass_obj +def get_openshift_ai_menu(ctx): + """Get openshift assisted installer commands""" + + +get_openshift_ai_menu.add_command(get_openshift_ai_cluster_command) +get_openshift_ai_menu.add_command(get_openshift_ai_version_command) diff --git a/menu/get/openshift/ai/version.py b/menu/get/openshift/ai/version.py new file mode 100644 index 00000000..6e030f8b --- /dev/null +++ b/menu/get/openshift/ai/version.py @@ -0,0 +1,72 @@ +import sys +import traceback +import json +import threading +import click + +from lib.openshift import console +from lib.openshift import output as openshift_output + +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("version") +@click.pass_obj +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_openshift_ai_version_command( + ctx, + output, + devel + ): + """Get openshift assisted installer supported versions""" + + ctx.developer = devel + ctx.output = output + + try: + openshift_output_handler = openshift_output.OpenshiftOutput(log_id=ctx.run_id) + console_handler = console.Console(log_id=ctx.run_id) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + versions = console_handler.get_assisted_install_versions() + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps( + versions, + indent=4 + ) + ) + return + + ctx.my_output.json_output(versions) + + openshift_output_handler.print_assisted_install_versions( + versions['openshift'], + title=True + ) + + ctx.my_output.default('The latest production version: %s' % (console_handler.get_assisted_install_versions_latest())) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/openshift/main.py b/menu/get/openshift/main.py new file mode 100644 index 00000000..717263fe --- /dev/null +++ b/menu/get/openshift/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.openshift.ai.main import get_openshift_ai_menu + + +class Failure(Exception): + pass + + +@click.group("openshift") +@click.pass_obj +def get_openshift_menu(ctx): + """Get rh openshift api commands""" + + +get_openshift_menu.add_command(get_openshift_ai_menu) diff --git a/menu/get/osp/__init__.py b/menu/get/osp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/osp/az.py b/menu/get/osp/az.py new file mode 100644 index 00000000..39978edd --- /dev/null +++ b/menu/get/osp/az.py @@ -0,0 +1,135 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("az") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by az name") +@click.option("--hv", "hypervisor", default='', callback=validations.empty_string_to_none, help="Filter by hypervisor") +@click.option("--view", "-v", default=['state'], help="[state|hv|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_az_command( + ctx, + cluster, + name, + hypervisor, + view, + output, + devel + ): + """Get osp availability zone""" + + # iserver get osp az + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|hv|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + hv_info = False + + if 'hv' in view: + hv_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if hypervisor is not None: + object_filter.append( + 'hv:%s' % (hypervisor) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + availability_zones = osp_handlers.get_availability_zones( + object_filter=object_filter, + hv_info=hv_info + ) + + ctx.busy = False + + if availability_zones is None: + ctx.my_output.error( + 'Failed to get availability zones' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + availability_zones, + indent=4 + ) + ) + return + + ctx.my_output.json_output(availability_zones) + + if 'state' in view: + osp_output_handler.print_availability_zones( + availability_zones, + title=True + ) + + if 'hv' in view: + osp_output_handler.print_availability_zones_hv( + availability_zones, + title=True + ) + + ctx.my_output.default('Filter: name, hv', before_newline=True) + ctx.my_output.default('View: state (def), hv, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/cluster.py b/menu/get/osp/cluster.py new file mode 100644 index 00000000..08adbfbc --- /dev/null +++ b/menu/get/osp/cluster.py @@ -0,0 +1,102 @@ +import sys +import threading +import traceback +import click + +from lib.osp import main as openstack +from lib.osp import settings + +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cluster") +@click.pass_obj +@click.option("--verify", is_flag=True, show_default=True, default=False, help="Verify api access") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_cluster( + ctx, + verify, + devel + ): + """Get osp cluster settings""" + + # iserver get osp cluster + + ctx.developer = devel + + try: + settings_handler = settings.OspSettings(log_id=ctx.run_id) + clusters = settings_handler.get_openstack_clusters() + + if clusters is None or len(clusters) == 0: + ctx.my_output.default('No openstack clusters defined') + return + + default_cluster_name = settings_handler.get_default_cluster() + if default_cluster_name is not None: + for cluster in clusters: + cluster['__Output'] = {} + if cluster['name'] == default_cluster_name: + cluster['__Output']['defaultTick'] = 'Green' + cluster['defaultTick'] = '\u2713' + + if verify: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + for cluster in clusters: + cluster['__Output'] = {} + cluster['__Output']['apiTick'] = 'Red' + cluster['apiTick'] = '\u2717' + + k8s_handler = openstack.Osp(openrc_filename=cluster['openrc'], cluster_type=cluster['type'], log_id=ctx.run_id) + if k8s_handler.get_api() is not None: + cluster['__Output']['apiTick'] = 'Green' + cluster['apiTick'] = '\u2713' + + ctx.busy = False + + order = [ + 'name', + 'defaultTick', + 'type', + 'openrc', + ] + + headers = [ + 'Cluster Name', + 'Default', + 'Type', + 'Openrc' + ] + + if verify: + order.append('apiTick') + headers.append('API') + + ctx.my_output.my_table( + clusters, + order=order, + headers=headers, + allow_order_subkeys=True, + underline=True, + row_separator=False, + table=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/fip.py b/menu/get/osp/fip.py new file mode 100644 index 00000000..1153e78d --- /dev/null +++ b/menu/get/osp/fip.py @@ -0,0 +1,191 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("fip") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--floating", "floating_ip", default='', callback=validations.validate_ip_subnet, help="Filter by floating ip address") +@click.option("--fixed", "fixed_ip", default='', callback=validations.validate_ip_subnet, help="Filter by fixed ip address") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--router", default='', callback=validations.empty_string_to_none, help="Filter by router name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--floating-net", "floating_net", default='', callback=validations.empty_string_to_none, help="Filter by floating network name") +@click.option("--fixed-net", "fixed_net", default='', callback=validations.empty_string_to_none, help="Filter by fixed network name") +@click.option("--vm", "vm_name", default='', callback=validations.empty_string_to_none, help="Filter by vm name") +@click.option("--view", "-v", default=['state'], help="[state|id|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_fip_command( + ctx, + cluster, + floating_ip, + fixed_ip, + mac, + router, + tenant, + floating_net, + fixed_net, + vm_name, + view, + output, + devel + ): + """Get osp floating ip""" + + # iserver get osp fip + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + network_info = False + router_info = False + port_info = False + + if 'state' in view: + tenant_info = True + network_info = True + router_info = True + port_info = True + + object_filter = [] + + if len(floating_ip) > 0: + object_filter.append( + 'floating-ip:%s' % (floating_ip) + ) + + if len(fixed_ip) > 0: + object_filter.append( + 'fixed-ip:%s' % (fixed_ip) + ) + + if mac is not None: + object_filter.append( + 'mac:%s' % (mac) + ) + + if router is not None: + router_info = True + object_filter.append( + 'router:%s' % (router) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant:%s' % (tenant) + ) + + if floating_net is not None: + network_info = True + object_filter.append( + 'floating-network:%s' % (floating_net) + ) + + if fixed_net is not None: + port_info = True + object_filter.append( + 'fixed-network:%s' % (fixed_net) + ) + + if vm_name is not None: + port_info = True + object_filter.append( + 'vm:%s' % (vm_name) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + fips = osp_handlers.get_floating_ips( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + router_info=router_info, + port_info=port_info + ) + + ctx.busy = False + + if fips is None: + ctx.my_output.error( + 'Failed to get floating ips' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + fips, + indent=4 + ) + ) + return + + ctx.my_output.json_output(fips) + + if 'state' in view: + osp_output_handler.print_floating_ips( + fips, + title=True + ) + + if 'id' in view: + osp_output_handler.print_floating_ips_id( + fips, + title=True + ) + + ctx.my_output.default('Filter: floating, fixed, mac, router, tenant, floating-net, fixed-net, vm', before_newline=True) + ctx.my_output.default('View: state (def), id, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/flv.py b/menu/get/osp/flv.py new file mode 100644 index 00000000..986187c7 --- /dev/null +++ b/menu/get/osp/flv.py @@ -0,0 +1,163 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("flv") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by flavor name") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine name") +@click.option("--key", "key", default='', callback=validations.empty_string_to_none, help="Filter by key") +@click.option("--value", "value", default='', callback=validations.empty_string_to_none, help="Filter by value") +@click.option("--view", "-v", default=['state'], help="[state|key|vm|id|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_flv_command( + ctx, + cluster, + name, + virtual_machine, + key, + value, + view, + output, + devel + ): + """Get osp flavor""" + + # iserver get osp flv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|key|vm|id|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + keys_info = False + vm_info = False + + if 'key' in view: + keys_info = True + + if 'vm' in view: + vm_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if virtual_machine is not None: + vm_info = True + object_filter.append( + 'vm:%s' % (virtual_machine) + ) + + if key is not None: + keys_info = True + object_filter.append( + 'key:%s' % (key) + ) + + if value is not None: + keys_info = True + object_filter.append( + 'value:%s' % (value) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + flavors = osp_handlers.get_flavors( + object_filter=object_filter, + keys_info=keys_info, + vm_info=vm_info + ) + + ctx.busy = False + + if flavors is None: + ctx.my_output.error( + 'Failed to get flavors' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + flavors, + indent=4 + ) + ) + return + + ctx.my_output.json_output(flavors) + + if 'state' in view or 'key' in view: + osp_output_handler.print_flavors( + flavors, + title=True + ) + + if 'id' in view: + osp_output_handler.print_flavors_id( + flavors, + title=True + ) + + if 'vm' in view: + osp_output_handler.print_flavors_vm( + flavors, + title=True + ) + + ctx.my_output.default('Filter: name, vm, key, value', before_newline=True) + ctx.my_output.default('View: state (def), id, key, vm, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/hv.py b/menu/get/osp/hv.py new file mode 100644 index 00000000..ad49a3b8 --- /dev/null +++ b/menu/get/osp/hv.py @@ -0,0 +1,137 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("hv") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--address", default='', callback=validations.validate_ip_subnet, help="Filter by ip address") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine") +@click.option("--view", "-v", default=['state'], help="[state|vm|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_hv_command( + ctx, + cluster, + name, + address, + virtual_machine, + view, + output, + devel + ): + """Get osp hypervisor""" + + # iserver get osp hv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|vm|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + vm_info = False + + if 'vm' in view: + vm_info = True + + object_filter = [] + + if name is not None: + object_filter.append('name:%s' % (name)) + + if len(address) > 0: + object_filter.append('address:%s' % (address)) + + if virtual_machine is not None: + vm_info = True + object_filter.append('vm:%s' % (virtual_machine)) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + hvs = osp_handlers.get_hypervisors( + object_filter=object_filter, + vm_info=vm_info + ) + + ctx.busy = False + + if hvs is None: + ctx.my_output.error( + 'Failed to get hypervisors' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + hvs, + indent=4 + ) + ) + return + + ctx.my_output.json_output(hvs) + + if 'state' in view: + osp_output_handler.print_hypervisors( + hvs, + title=True + ) + + if 'vm' in view: + osp_output_handler.print_hypervisors_vm( + hvs, + title=True + ) + + ctx.my_output.default('Filter: name, address, vm', before_newline=True) + ctx.my_output.default('View: state (def), vm, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/img.py b/menu/get/osp/img.py new file mode 100644 index 00000000..d5d428f0 --- /dev/null +++ b/menu/get/osp/img.py @@ -0,0 +1,143 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("img") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by image name") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine name") +@click.option("--file", "filename", default='', callback=validations.empty_string_to_none, help="Download selected image to file") +@click.option("--view", "-v", default=['state'], help="[state|id|vm|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_img_command( + ctx, + cluster, + name, + virtual_machine, + filename, + view, + output, + devel + ): + """Get osp image""" + + # iserver get osp img + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|vm|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + vm_info = False + if 'vm' in view: + vm_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if virtual_machine is not None: + vm_info = True + object_filter.append( + 'vm:%s' % (virtual_machine) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + images = osp_handlers.get_images( + object_filter=object_filter, + vm_info=vm_info + ) + + ctx.busy = False + + if images is None: + ctx.my_output.error( + 'Failed to get images' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + images, + indent=4 + ) + ) + return + + ctx.my_output.json_output(images) + + if 'state' in view: + osp_output_handler.print_images( + images, + title=True + ) + + if 'id' in view: + osp_output_handler.print_images_id( + images, + title=True + ) + + if 'vm' in view: + osp_output_handler.print_images_vm( + images, + title=True + ) + + ctx.my_output.default('Filter: name, vm', before_newline=True) + ctx.my_output.default('View: state (def), id, vm, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/main.py b/menu/get/osp/main.py new file mode 100644 index 00000000..216a9484 --- /dev/null +++ b/menu/get/osp/main.py @@ -0,0 +1,50 @@ +import click + +from menu.get.osp.az import get_osp_az_command +from menu.get.osp.cluster import get_osp_cluster +from menu.get.osp.fip import get_osp_fip_command +from menu.get.osp.flv import get_osp_flv_command +from menu.get.osp.hv import get_osp_hv_command +from menu.get.osp.img import get_osp_img_command +from menu.get.osp.net import get_osp_net_command +from menu.get.osp.port import get_osp_port_command +from menu.get.osp.quota import get_osp_quota_command +from menu.get.osp.role import get_osp_role_command +from menu.get.osp.rtr import get_osp_rtr_command +from menu.get.osp.sg import get_osp_sg_command +from menu.get.osp.snap import get_osp_snap_command +from menu.get.osp.sub import get_osp_sub_command +from menu.get.osp.tenant import get_osp_tenant_command +from menu.get.osp.user import get_osp_user_command +from menu.get.osp.vm import get_osp_vm_command +from menu.get.osp.vol import get_osp_vol_command + + +class Failure(Exception): + pass + + +@click.group("osp") +@click.pass_obj +def get_osp_menu(ctx): + """Get osp commands""" + + +get_osp_menu.add_command(get_osp_az_command) +get_osp_menu.add_command(get_osp_cluster) +get_osp_menu.add_command(get_osp_fip_command) +get_osp_menu.add_command(get_osp_flv_command) +get_osp_menu.add_command(get_osp_hv_command) +get_osp_menu.add_command(get_osp_img_command) +get_osp_menu.add_command(get_osp_net_command) +get_osp_menu.add_command(get_osp_port_command) +get_osp_menu.add_command(get_osp_quota_command) +get_osp_menu.add_command(get_osp_role_command) +get_osp_menu.add_command(get_osp_rtr_command) +get_osp_menu.add_command(get_osp_sg_command) +get_osp_menu.add_command(get_osp_snap_command) +get_osp_menu.add_command(get_osp_sub_command) +get_osp_menu.add_command(get_osp_tenant_command) +get_osp_menu.add_command(get_osp_user_command) +get_osp_menu.add_command(get_osp_vm_command) +get_osp_menu.add_command(get_osp_vol_command) diff --git a/menu/get/osp/net.py b/menu/get/osp/net.py new file mode 100644 index 00000000..ac56d773 --- /dev/null +++ b/menu/get/osp/net.py @@ -0,0 +1,210 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("net") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by network name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--ext", "external", is_flag=True, show_default=True, default=False, help="Filter external network") +@click.option("--address", default='', callback=validations.validate_ip, help="Filter by ip address") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by port mac address") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine") +@click.option("--hv", "hypervisor", default='', callback=validations.empty_string_to_none, help="Filter by hypervisor") +@click.option("--vlan", default='', callback=validations.empty_string_to_none, help="Filter by vlan") +@click.option("--view", "-v", default=['state'], help="[state|id|port|phy|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_net_command( + ctx, + cluster, + name, + tenant, + external, + address, + mac, + virtual_machine, + hypervisor, + vlan, + view, + output, + devel + ): + """Get osp network""" + + # iserver get osp net + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|port|phy|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + port_info = False + subnet_info = False + router_info = False + + if 'state' in view: + tenant_info = True + subnet_info = True + router_info = True + + if 'port' in view: + tenant_info = True + subnet_info = True + port_info = True + + if 'phy' in view: + tenant_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (tenant) + ) + + if external: + object_filter.append( + 'external:true' + ) + + if address is not None and len(address) > 0: + subnet_info = True + object_filter.append( + 'address:%s' % (address) + ) + + if mac is not None: + port_info = True + object_filter.append( + 'mac:%s' % (mac) + ) + + if virtual_machine is not None: + port_info = True + object_filter.append( + 'vm_name:%s' % (virtual_machine) + ) + + if hypervisor is not None: + port_info = True + object_filter.append( + 'hv:%s' % (hypervisor) + ) + + if vlan is not None: + object_filter.append( + 'vlan:%s' % (vlan) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + networks = osp_handlers.get_networks( + object_filter=object_filter, + tenant_info=tenant_info, + subnet_info=subnet_info, + port_info=port_info, + router_info=router_info + ) + + ctx.busy = False + + if networks is None: + ctx.my_output.error( + 'Failed to get networks' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + networks, + indent=4 + ) + ) + return + + ctx.my_output.json_output(networks) + + if 'state' in view: + osp_output_handler.print_networks( + networks, + title=True + ) + + if 'id' in view: + osp_output_handler.print_networks_id( + networks, + title=True + ) + + if 'port' in view: + osp_output_handler.print_networks_port( + networks, + title=True + ) + + if 'phy' in view: + osp_output_handler.print_networks_phy( + networks, + title=True + ) + + ctx.my_output.default('Filter: name, tenant, address, mac, vm, hv, vlan', before_newline=True) + ctx.my_output.default('View: state (def), id, port, phy, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/port.py b/menu/get/osp/port.py new file mode 100644 index 00000000..1bd14040 --- /dev/null +++ b/menu/get/osp/port.py @@ -0,0 +1,235 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("port") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by port name") +@click.option("--state", type=click.Choice(['active', 'down', 'any'], case_sensitive=False), default='any', show_default=True) +@click.option("--type", "port_type", type=click.Choice(['compute', 'dhcp', 'floating', 'gateway', 'ha', 'any'], case_sensitive=False), default='any', show_default=True) +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--net", "network", default='', callback=validations.empty_string_to_none, help="Filter by network name") +@click.option("--subnet", "subnet", default='', callback=validations.empty_string_to_none, help="Filter by subnet name") +@click.option("--address", default='', callback=validations.validate_ip_subnet, help="Filter by ip address") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--hv", "hypervisor", default='', callback=validations.empty_string_to_none, help="Filter by hypervisor") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine") +@click.option("--sg", "security_group", default='', callback=validations.empty_string_to_none, help="Filter by security group") +@click.option("--view", "-v", default=['state'], help="[state|id|sec|hv|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_port_command( + ctx, + cluster, + name, + state, + port_type, + tenant, + network, + subnet, + address, + mac, + hypervisor, + virtual_machine, + security_group, + view, + output, + devel + ): + """Get osp port""" + + # iserver get osp port + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|sec|hv|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + network_info = False + subnet_info = False + security_info = False + vm_info = False + fip_info = False + + if 'state' in view: + tenant_info = True + network_info = True + subnet_info = True + fip_info = True + + if 'sec' in view: + security_info = True + vm_info = True + + if 'hv' in view: + vm_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if state != 'any': + object_filter.append( + 'state:%s' % (state) + ) + + if port_type != 'any': + object_filter.append( + 'type:%s' % (port_type) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (tenant) + ) + + if network is not None: + network_info = True + object_filter.append( + 'network_name:%s' % (network) + ) + + if subnet is not None: + subnet_info = True + object_filter.append( + 'subnet_name:%s' % (subnet) + ) + + if address is not None: + object_filter.append( + 'address:%s' % (address) + ) + + if mac is not None: + object_filter.append( + 'mac:%s' % (mac) + ) + + if hypervisor is not None: + object_filter.append( + 'hv:%s' % (hypervisor) + ) + + if virtual_machine is not None: + vm_info = True + object_filter.append( + 'vm_name:%s' % (virtual_machine) + ) + + if security_group is not None: + security_info = True + object_filter.append( + 'sg:%s' % (security_group) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + ports = osp_handlers.get_ports( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + subnet_info=subnet_info, + security_info=security_info, + vm_info=vm_info, + fip_info=fip_info + ) + + ctx.busy = False + + if ports is None: + ctx.my_output.error( + 'Failed to get ports' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + ports, + indent=4 + ) + ) + return + + ctx.my_output.json_output(ports) + + if 'state' in view: + osp_output_handler.print_ports( + ports, + title=True + ) + + if 'id' in view: + osp_output_handler.print_ports_id( + ports, + title=True + ) + + if 'sec' in view: + osp_output_handler.print_ports_security( + ports, + title=True + ) + + if 'hv' in view: + osp_output_handler.print_ports_hv( + ports, + title=True + ) + + ctx.my_output.default('Filter: name, state, type, tenant, net, subnet, address, mac, hv, vm, sg', before_newline=True) + ctx.my_output.default('View: state (def), id, sec, hv, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/quota.py b/menu/get/osp/quota.py new file mode 100644 index 00000000..e26754c7 --- /dev/null +++ b/menu/get/osp/quota.py @@ -0,0 +1,123 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("quota") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_quota_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get osp quota""" + + # iserver get osp quota + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + + if 'state' in view: + tenant_info = True + + object_filter = [] + + if name is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (name) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + quotas = osp_handlers.get_quotas( + object_filter=object_filter, + tenant_info=tenant_info + ) + + ctx.busy = False + + if quotas is None: + ctx.my_output.error( + 'Failed to get quotas' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + quotas, + indent=4 + ) + ) + return + + ctx.my_output.json_output(quotas) + + if 'state' in view: + osp_output_handler.print_quotas( + quotas, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/role.py b/menu/get/osp/role.py new file mode 100644 index 00000000..fbeac5a9 --- /dev/null +++ b/menu/get/osp/role.py @@ -0,0 +1,109 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("role") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_role_command( + ctx, + cluster, + view, + output, + devel + ): + """Get osp role""" + + # iserver get osp role + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + object_filter = [] + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + roles = osp_handlers.get_roles( + object_filter=object_filter + ) + + ctx.busy = False + + if roles is None: + ctx.my_output.error( + 'Failed to get roles' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + roles, + indent=4 + ) + ) + return + + ctx.my_output.json_output(roles) + + if 'state' in view: + osp_output_handler.print_roles( + roles, + title=True + ) + + ctx.my_output.default('Filter: --', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/rtr.py b/menu/get/osp/rtr.py new file mode 100644 index 00000000..e89f2ad5 --- /dev/null +++ b/menu/get/osp/rtr.py @@ -0,0 +1,146 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("rtr") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by router name") +@click.option("--view", "-v", default=['state'], help="[state|id|port|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_rtr_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get osp router""" + + # iserver get osp rtr + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|port|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + network_info = False + subnet_info = False + port_info = False + + if 'state' in view: + tenant_info = True + network_info = True + subnet_info = True + + if 'port' in view: + tenant_info = True + port_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + routers = osp_handlers.get_routers( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + subnet_info=subnet_info, + port_info=port_info + ) + + ctx.busy = False + + if routers is None: + ctx.my_output.error( + 'Failed to get routers' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + routers, + indent=4 + ) + ) + return + + ctx.my_output.json_output(routers) + + if 'state' in view: + osp_output_handler.print_routers( + routers, + title=True + ) + + if 'id' in view: + osp_output_handler.print_routers_id( + routers, + title=True + ) + + if 'port' in view: + osp_output_handler.print_routers_port( + routers, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def), id, port, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/sg.py b/menu/get/osp/sg.py new file mode 100644 index 00000000..a1e8e3e7 --- /dev/null +++ b/menu/get/osp/sg.py @@ -0,0 +1,186 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sg") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by port mac address") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine") +@click.option("--view", "-v", default=['state'], help="[state|id|rule|port|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_sg_command( + ctx, + cluster, + name, + tenant, + mac, + virtual_machine, + view, + output, + devel + ): + """Get osp security group""" + + # iserver get osp sg + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|rule|port|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + rule_info = False + port_info = False + + if 'state' in view: + tenant_info = True + + if 'id' in view: + rule_info = True + + if 'rule' in view: + tenant_info = True + rule_info = True + + if 'port' in view: + tenant_info = True + rule_info = True + port_info = True + + object_filter = [] + + if name is not None: + if len(name.split('/')) == 2: + (tenant, name) = name.split('/') + + tenant_info = True + object_filter.append( + 'name:%s' % (name) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (tenant) + ) + + if mac is not None: + tenant_info = True + port_info = True + object_filter.append( + 'mac:%s' % (mac) + ) + + if virtual_machine is not None: + tenant_info = True + port_info = True + object_filter.append( + 'vm_name:%s' % (virtual_machine) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + security_groups = osp_handlers.get_security_groups( + object_filter=object_filter, + tenant_info=tenant_info, + rule_info=rule_info, + port_info=port_info + ) + + ctx.busy = False + + if security_groups is None: + ctx.my_output.error( + 'Failed to get security groups' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + security_groups, + indent=4 + ) + ) + return + + ctx.my_output.json_output(security_groups) + + if 'state' in view: + osp_output_handler.print_security_groups( + security_groups, + title=True + ) + + if 'id' in view: + osp_output_handler.print_security_groups_id( + security_groups, + title=True + ) + + if 'rule' in view: + osp_output_handler.print_security_groups_rule( + security_groups, + title=True + ) + + if 'port' in view: + osp_output_handler.print_security_groups_port( + security_groups, + title=True + ) + + ctx.my_output.default('Filter: name, tenant, mac, vm', before_newline=True) + ctx.my_output.default('View: state (def), id, rule, port, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/snap.py b/menu/get/osp/snap.py new file mode 100644 index 00000000..5fcb6e15 --- /dev/null +++ b/menu/get/osp/snap.py @@ -0,0 +1,147 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("snap") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by snapshot name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--vol", default='', callback=validations.empty_string_to_none, help="Filter by volume name") +@click.option("--view", "-v", default=['state'], help="[state|id|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_snap_command( + ctx, + cluster, + name, + tenant, + vol, + view, + output, + devel + ): + """Get osp snapshot""" + + # iserver get osp snap + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + volume_info = False + + if 'state' in view: + tenant_info = True + volume_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (tenant) + ) + + if vol is not None: + volume_info = True + object_filter.append( + 'volume_name:%s' % (vol) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + snapshots = osp_handlers.get_snapshots( + object_filter=object_filter, + tenant_info=tenant_info, + volume_info=volume_info + ) + + ctx.busy = False + + if snapshots is None: + ctx.my_output.error( + 'Failed to get snapshots' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + snapshots, + indent=4 + ) + ) + return + + ctx.my_output.json_output(snapshots) + + if 'state' in view: + osp_output_handler.print_snapshots( + snapshots, + title=True + ) + + if 'id' in view: + osp_output_handler.print_snapshots_id( + snapshots, + title=True + ) + + ctx.my_output.default('Filter: name, tenant, vol', before_newline=True) + ctx.my_output.default('View: state (def), id, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/sub.py b/menu/get/osp/sub.py new file mode 100644 index 00000000..4cd46d20 --- /dev/null +++ b/menu/get/osp/sub.py @@ -0,0 +1,183 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("sub") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by subnet name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--address", default='', callback=validations.validate_ip, help="Filter by ip address") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine") +@click.option("--hv", "hypervisor", default='', callback=validations.empty_string_to_none, help="Filter by hypervisor") +@click.option("--view", "-v", default=['state'], help="[state|id|port|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_sub_command( + ctx, + cluster, + name, + tenant, + address, + mac, + virtual_machine, + hypervisor, + view, + output, + devel + ): + """Get osp subnet""" + + # iserver get osp sub + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|port|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + network_info = False + port_info = False + + if 'state' in view: + tenant_info = True + network_info = True + + if 'port' in view: + tenant_info = True + network_info = True + port_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (tenant) + ) + + if address is not None and len(address) > 0: + object_filter.append( + 'address:%s' % (address) + ) + + if mac is not None: + port_info = True + object_filter.append( + 'mac:%s' % (mac) + ) + + if virtual_machine is not None: + port_info = True + object_filter.append( + 'vm_name:%s' % (virtual_machine) + ) + + if hypervisor is not None: + port_info = True + object_filter.append( + 'hv:%s' % (hypervisor) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + subnets = osp_handlers.get_subnets( + object_filter=object_filter, + tenant_info=tenant_info, + network_info=network_info, + port_info=port_info + ) + + ctx.busy = False + + if subnets is None: + ctx.my_output.error( + 'Failed to get subnets' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + subnets, + indent=4 + ) + ) + return + + ctx.my_output.json_output(subnets) + + if 'state' in view: + osp_output_handler.print_subnets( + subnets, + title=True + ) + + if 'id' in view: + osp_output_handler.print_subnets_id( + subnets, + title=True + ) + + if 'port' in view: + osp_output_handler.print_subnets_port( + subnets, + title=True + ) + + ctx.my_output.default('Filter: name, tenant, address, mac, vm, hv', before_newline=True) + ctx.my_output.default('View: state (def), id, port, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/tenant.py b/menu/get/osp/tenant.py new file mode 100644 index 00000000..79e5e1aa --- /dev/null +++ b/menu/get/osp/tenant.py @@ -0,0 +1,109 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("tenant") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_tenant_command( + ctx, + cluster, + view, + output, + devel + ): + """Get osp tenant""" + + # iserver get osp tenant + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + object_filter = [] + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + tenants = osp_handlers.get_tenants( + object_filter=object_filter + ) + + ctx.busy = False + + if tenants is None: + ctx.my_output.error( + 'Failed to get tenants' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + tenants, + indent=4 + ) + ) + return + + ctx.my_output.json_output(tenants) + + if 'state' in view: + osp_output_handler.print_tenants( + tenants, + title=True + ) + + ctx.my_output.default('Filter: --', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/user.py b/menu/get/osp/user.py new file mode 100644 index 00000000..2aa36e9a --- /dev/null +++ b/menu/get/osp/user.py @@ -0,0 +1,125 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("user") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--view", "-v", default=['state'], help="[state]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_user_command( + ctx, + cluster, + name, + view, + output, + devel + ): + """Get osp user""" + + # iserver get osp user + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + role_info = False + + if 'state' in view: + tenant_info = True + role_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + users = osp_handlers.get_users( + object_filter=object_filter, + tenant_info=tenant_info, + role_info=role_info + ) + + ctx.busy = False + + if users is None: + ctx.my_output.error( + 'Failed to get users' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + users, + indent=4 + ) + ) + return + + ctx.my_output.json_output(users) + + if 'state' in view: + osp_output_handler.print_users( + users, + title=True + ) + + ctx.my_output.default('Filter: name', before_newline=True) + ctx.my_output.default('View: state (def)') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/vm.py b/menu/get/osp/vm.py new file mode 100644 index 00000000..0a1c722a --- /dev/null +++ b/menu/get/osp/vm.py @@ -0,0 +1,264 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vm") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant") +@click.option("--img", "image", default='', callback=validations.empty_string_to_none, help="Filter by image") +@click.option("--flv", "flavor", default='', callback=validations.empty_string_to_none, help="Filter by flavor") +@click.option("--net", "network", default='', callback=validations.empty_string_to_none, help="Filter by network") +@click.option("--address", default='', callback=validations.validate_ip_subnet, help="Filter by ip address") +@click.option("--mac", default='', callback=validations.empty_string_to_none, help="Filter by mac address") +@click.option("--hv", "hypervisor", default='', callback=validations.empty_string_to_none, help="Filter by hypervisor") +@click.option("--view", "-v", default=['state'], help="[state|id|net|sec|console|logs|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_vm_command( + ctx, + cluster, + name, + tenant, + image, + flavor, + network, + address, + mac, + hypervisor, + view, + output, + devel + ): + """Get osp virtual machine""" + + # iserver get osp vm + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|net|sec|console|logs|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + flavor_info = False + image_info = False + volume_info = False + network_info = False + subnet_info = False + port_info = False + security_info = False + console_info = False + logs_info = False + + object_filter = [] + + if name is not None: + if len(name.split('/')) == 2: + (tenant, name) = name.split('/') + object_filter.append('name:%s' % (name)) + + if tenant is not None: + tenant_info = True + object_filter.append('tenant_name:%s' % (tenant)) + + if image is not None: + image_info = True + object_filter.append('image_name:%s' % (image)) + + if flavor is not None: + flavor_info = True + object_filter.append('flavor_name:%s' % (flavor)) + + if network is not None: + object_filter.append('network_name:%s' % (network)) + + if len(address) > 0: + network_info = True + subnet_info = True + object_filter.append('address:%s' % (address)) + + if mac is not None: + network_info = True + subnet_info = True + object_filter.append('mac:%s' % (mac)) + + if hypervisor is not None: + object_filter.append('hypervisor:%s' % (hypervisor)) + + if 'state' in view: + tenant_info = True + flavor_info = True + image_info = True + volume_info = True + + if 'net' in view: + tenant_info = True + network_info = True + subnet_info = True + + if 'sec' in view: + tenant_info = True + network_info = True + subnet_info = True + port_info = True + security_info = True + + if 'console' in view: + tenant_info = True + console_info = True + + if 'logs' in view: + logs_info = True + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + vms = osp_handlers.get_virtual_machines( + object_filter=object_filter, + tenant_info=tenant_info, + flavor_info=flavor_info, + image_info=image_info, + volume_info=volume_info, + network_info=network_info, + subnet_info=subnet_info, + port_info=port_info, + security_info=security_info, + console_info=console_info, + logs_info=logs_info + ) + + if 'sec' in view: + security_group_names = [] + for vm_info in vms: + for interface_info in vm_info['interface']: + for security_group_name in interface_info['port_info']['security_group_names']: + if security_group_name not in security_group_names: + security_group_names.append( + security_group_name + ) + + if len(security_group_names) == 0: + security_groups = [] + + if len(security_group_names) > 0: + object_filter = [] + object_filter.append( + 'names:%s' % (','.join(security_group_names)) + ) + + security_groups = osp_handlers.get_security_groups( + object_filter=object_filter, + tenant_info=True, + rule_info=True, + port_info=False + ) + + ctx.busy = False + + if vms is None: + ctx.my_output.error( + 'Failed to get virtual machines' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + vms, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vms) + + if 'state' in view: + osp_output_handler.print_virtual_machines( + vms, + title=True + ) + + if 'id' in view: + osp_output_handler.print_virtual_machines_id( + vms, + title=True + ) + + if 'net' in view: + osp_output_handler.print_virtual_machines_net( + vms, + title=True + ) + + if 'sec' in view: + osp_output_handler.print_virtual_machines_sec( + vms, + title=True + ) + + osp_output_handler.print_security_groups_rule( + security_groups, + title=True + ) + + if 'console' in view: + osp_output_handler.print_virtual_machines_console( + vms, + title=True + ) + + if 'logs' in view: + osp_output_handler.print_virtual_machines_logs( + vms + ) + + ctx.my_output.default('Filter: name, tenant, img, flv, net, address, mac, hv', before_newline=True) + ctx.my_output.default('View: state (def), id, net, sec, console, logs, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/osp/vol.py b/menu/get/osp/vol.py new file mode 100644 index 00000000..6f97062e --- /dev/null +++ b/menu/get/osp/vol.py @@ -0,0 +1,155 @@ +import sys +import json +import threading +import traceback +import click + +from lib.osp import output as osp_output + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("vol") +@click.pass_obj +@click.option("--cluster", default='', help="Openstack cluster name") +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Filter by name") +@click.option("--tenant", default='', callback=validations.empty_string_to_none, help="Filter by tenant name") +@click.option("--hv", "hypervisor", default='', callback=validations.empty_string_to_none, help="Filter by hypervisor") +@click.option("--vm", "virtual_machine", default='', callback=validations.empty_string_to_none, help="Filter by virtual machine") +@click.option("--view", "-v", default=['state'], help="[state|id|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_osp_vol_command( + ctx, + cluster, + name, + tenant, + hypervisor, + virtual_machine, + view, + output, + devel + ): + """Get osp volume""" + + # iserver get osp vol + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'state|id|all', + 'state', + [] + ) + if view is None: + sys.exit(1) + + try: + osp_output_handler = osp_output.OspOutput(log_id=ctx.run_id) + osp_handlers = validations.validate_osp_name(ctx, cluster) + if osp_handlers is None: + raise ErrorExit + + tenant_info = False + vm_info = False + + if 'state' in view: + tenant_info = True + vm_info = True + + object_filter = [] + + if name is not None: + object_filter.append( + 'name:%s' % (name) + ) + + if tenant is not None: + tenant_info = True + object_filter.append( + 'tenant_name:%s' % (tenant) + ) + + if hypervisor is not None: + vm_info = True + object_filter.append( + 'hv:%s' % (hypervisor) + ) + + if virtual_machine is not None: + vm_info = True + object_filter.append( + 'vm_name:%s' % (virtual_machine) + ) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + volumes = osp_handlers.get_volumes( + object_filter=object_filter, + tenant_info=tenant_info, + vm_info=vm_info + ) + + ctx.busy = False + + if volumes is None: + ctx.my_output.error( + 'Failed to get volumes' + ) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + volumes, + indent=4 + ) + ) + return + + ctx.my_output.json_output(volumes) + + if 'state' in view: + osp_output_handler.print_volumes( + volumes, + title=True + ) + + if 'id' in view: + osp_output_handler.print_volumes_id( + volumes, + title=True + ) + + ctx.my_output.default('Filter: name, tenant, hv, vm', before_newline=True) + ctx.my_output.default('View: state (def), id, all') + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/psirt.py b/menu/get/psirt.py new file mode 100644 index 00000000..c7ab8203 --- /dev/null +++ b/menu/get/psirt.py @@ -0,0 +1,249 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + +from lib.psirt import main as psirt +from lib.psirt import output as psirt_output +from lib.psirt import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +class NoResultExit(Exception): + pass + + +@click.command("psirt") +@click.pass_obj +@click.option("--sev", "severity", type=click.Choice(['any', 'crit', 'high', 'med', 'low', 'info'], case_sensitive=False), default='any', show_default=True) +@click.option("--bug", default='', callback=validations.empty_string_to_none, help="Filter by bug") +@click.option("--cve", default='', callback=validations.empty_string_to_none, help="Filter by cve") +@click.option("--cwe", default='', callback=validations.empty_string_to_none, help="Filter by cwe") +@click.option("--prod", "product", default='', callback=validations.empty_string_to_none, help="Filter by product name") +@click.option("--ver", "version", default='', callback=validations.empty_string_to_none, help="Filter by product version") +@click.option("--added", type=click.INT, default=-1, show_default=True) +@click.option("--updated", type=click.INT, default=365, show_default=True) +@click.option("--limit", "-l", "output_limit", type=click.INT, default=25, show_default=True) +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--view", "-v", default=['list'], help="[list|url|sum|ver|prod|settings|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_psirt_command( + ctx, + severity, + bug, + cve, + cwe, + product, + version, + added, + updated, + output_limit, + show_password, + view, + output, + devel + ): + """Get psirt advisory""" + + # iserver get psirt adv + + ctx.developer = devel + ctx.output = output + view = validations.validate_view( + ctx, + view, + 'list|url|sum|ver|prod|settings|all', + 'list', + [] + ) + if view is None: + sys.exit(1) + + try: + settings_handler = settings.PsirtSettings(log_id=ctx.run_id) + psirt_settings = settings_handler.get_psirt_settings() + if psirt_settings is None: + ctx.my_output.error('Failed to get psirt api settings') + raise ErrorExit + + advisories = [] + if 'list' in view or 'url' in view or 'sum' in view or 'ver' in view or 'prod' in view: + (key, secret) = settings_handler.get_psirt_credentials() + if key is None or secret is None: + ctx.my_output.error( + 'Define psirt api key/secret' + ) + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + object_filter = [] + + if severity != 'any': + object_filter.append( + 'severity:%s' % (severity) + ) + + if bug is not None: + object_filter.append( + 'bug:%s' % (bug) + ) + + if cve is not None: + object_filter.append( + 'cve:%s' % (cve) + ) + + if cwe is not None: + object_filter.append( + 'cwe:%s' % (cwe) + ) + + if product is not None: + object_filter.append( + 'product:%s' % (product) + ) + + if version is not None: + object_filter.append( + 'version:%s' % (version) + ) + + if added > 0: + object_filter.append( + 'added:%s' % (added) + ) + + if updated > 0: + object_filter.append( + 'updated:%s' % (updated) + ) + + psirt_handler = psirt.Psirt(key, secret, log_id=ctx.run_id) + advisories = psirt_handler.get_advisories( + object_filter + ) + + ctx.busy = False + + if advisories is None: + ctx.my_output.error('Failed to get advisories') + raise ErrorExit + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + advisories, + indent=4 + ) + ) + return + + ctx.my_output.json_output(advisories) + + output_handler = psirt_output.PsirtOutput(log_id=ctx.run_id) + + if 'settings' in view: + output_handler.print_psirt_settings( + psirt_settings, + show_password=show_password + ) + + if 'list' in view and 'ver' not in view: + if output_limit > 0: + output_handler.print_advisory( + advisories[:output_limit], + title=True + ) + else: + output_handler.print_advisory( + advisories, + title=True + ) + + if 'ver' in view: + if output_limit > 0: + output_handler.print_advisory_version( + advisories[:output_limit], + title=True + ) + else: + output_handler.print_advisory_version( + advisories, + title=True + ) + + if 'url' in view: + if output_limit > 0: + output_handler.print_advisory_url( + advisories[:output_limit], + title=True + ) + else: + output_handler.print_advisory_url( + advisories, + title=True + ) + + if 'sum' in view: + if output_limit > 0: + output_handler.print_advisory_summary( + advisories[:output_limit], + title=True + ) + else: + output_handler.print_advisory_summary( + advisories, + title=True + ) + + if 'prod' in view: + if output_limit > 0: + output_handler.print_advisory_product( + advisories[:output_limit], + title=True, + product_filter=product + ) + else: + output_handler.print_advisory_product( + advisories, + title=True, + product_filter=product + ) + + if output_limit > 0 and len(advisories) >= output_limit: + ctx.my_output.default('Output limited to %s entries' % (output_limit), before_newline=True) + + ctx.my_output.default('Filter: sev, bug, cve, cwe, prod, ver, added, updated', before_newline=True) + ctx.my_output.default('View: list (def), url, sum, ver, all') + + if advisories is None or len(advisories) == 0: + raise NoResultExit + + except NoResultExit: + ctx.busy = False + sys.exit(666) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/redfish/__init__.py b/menu/get/redfish/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/redfish/__pycache__/__init__.cpython-310.pyc b/menu/get/redfish/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d976fb8d Binary files /dev/null and b/menu/get/redfish/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/access.cpython-310.pyc b/menu/get/redfish/__pycache__/access.cpython-310.pyc new file mode 100644 index 00000000..d47fe67e Binary files /dev/null and b/menu/get/redfish/__pycache__/access.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/adhoc.cpython-310.pyc b/menu/get/redfish/__pycache__/adhoc.cpython-310.pyc new file mode 100644 index 00000000..639c2ba0 Binary files /dev/null and b/menu/get/redfish/__pycache__/adhoc.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/cache.cpython-310.pyc b/menu/get/redfish/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..6eed4092 Binary files /dev/null and b/menu/get/redfish/__pycache__/cache.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/configuration.cpython-310.pyc b/menu/get/redfish/__pycache__/configuration.cpython-310.pyc new file mode 100644 index 00000000..2a40a67b Binary files /dev/null and b/menu/get/redfish/__pycache__/configuration.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/endpoint.cpython-310.pyc b/menu/get/redfish/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..936cbf8d Binary files /dev/null and b/menu/get/redfish/__pycache__/endpoint.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/fi.cpython-310.pyc b/menu/get/redfish/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..6e60a725 Binary files /dev/null and b/menu/get/redfish/__pycache__/fi.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/main.cpython-310.pyc b/menu/get/redfish/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..1c8e2ba8 Binary files /dev/null and b/menu/get/redfish/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/server.cpython-310.pyc b/menu/get/redfish/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..724b76af Binary files /dev/null and b/menu/get/redfish/__pycache__/server.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/servers.cpython-310.pyc b/menu/get/redfish/__pycache__/servers.cpython-310.pyc new file mode 100644 index 00000000..a6113c98 Binary files /dev/null and b/menu/get/redfish/__pycache__/servers.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/settings.cpython-310.pyc b/menu/get/redfish/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..c5ba4f44 Binary files /dev/null and b/menu/get/redfish/__pycache__/settings.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/summary.cpython-310.pyc b/menu/get/redfish/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..a14878cc Binary files /dev/null and b/menu/get/redfish/__pycache__/summary.cpython-310.pyc differ diff --git a/menu/get/redfish/__pycache__/ucsc.cpython-310.pyc b/menu/get/redfish/__pycache__/ucsc.cpython-310.pyc new file mode 100644 index 00000000..fc22bd90 Binary files /dev/null and b/menu/get/redfish/__pycache__/ucsc.cpython-310.pyc differ diff --git a/menu/get/redfish/cache.py b/menu/get/redfish/cache.py new file mode 100644 index 00000000..c30d9f17 --- /dev/null +++ b/menu/get/redfish/cache.py @@ -0,0 +1,49 @@ +import sys +import traceback +import click + +from lib.redfish import cache +from lib.redfish import output as redfish_output +from lib.redfish import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cache") +@click.pass_obj +def get_redfish_cache_command(ctx): + """Get redfish cache""" + + # iserver get redfish cache + + try: + output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + + settings_handler = settings.RedfishSettings() + redfish_settings = settings_handler.get_redfish_settings() + output_handler.print_redfish_settings(redfish_settings) + + cache_handler = cache.RedfishCache() + info = cache_handler.get_redfish_cache_list() + if info is None: + ctx.my_output.error('Cache list not found') + raise ErrorExit + + output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + output_handler.print_redfish_cache( + info, + title=True + ) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/redfish/endpoint.py b/menu/get/redfish/endpoint.py new file mode 100644 index 00000000..569cdeb5 --- /dev/null +++ b/menu/get/redfish/endpoint.py @@ -0,0 +1,116 @@ +import sys +import json +import traceback +import click + +from progress.bar import Bar + +from lib.redfish import endpoint_settings +from lib.redfish import output as redfish_output + +from menu import common +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("endpoint") +@click.pass_obj +@click.option("--type", "endpoint_type", type=click.Choice(['any', 'standard', 'ucsc', 'fi', 'dell', 'hpe'], case_sensitive=False), default='any', help="Redfish endpoint type") +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip_subnet, help="Redfish management IP") +@click.option("--serial", "serial_number", default='', help="Endpoint serial number") +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--verify", is_flag=True, show_default=True, default=False, help="Verify endpoint") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_redfish_endpoint_command( + ctx, + endpoint_type, + endpoint_ip, + serial_number, + show_password, + verify, + output, + devel + ): + """Get redfish endpoints""" + + # iserver get redfish endpoint + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings(log_id=ctx.run_id) + endpoints = endpoint_settings_handler.get_redfish_endpoints_settings( + endpoint_type=endpoint_type, + endpoint_ip=endpoint_ip, + serial_number=serial_number, + include=['identity'] + ) + + if verify and len(endpoints) > 0: + if output == 'default': + bar_handler = Bar('Progress', max=len(endpoints)) + bar_handler.goto(0) + + for item in endpoints: + item['endpoint']['verified'] = endpoint_settings_handler.verify_redfish_endpoint_authentication( + item['endpoint_id'] + ) + if output == 'default': + bar_handler.next() + + if output == 'default': + bar_handler.finish() + + if not show_password: + for item in endpoints: + item['endpoint']['password'] = '******' + + if output == 'json': + ctx.my_output.default( + json.dumps( + endpoints, + indent=4 + ) + ) + return + + ctx.my_output.json_output(endpoints) + + if len(endpoints) == 0: + ctx.my_output.default('No redfish endpoints found') + return + + output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + output_handler.print_redfish_endpoint_settings( + endpoints, + verify=verify + ) + + if verify: + authenticated = 0 + for item in endpoints: + if item['endpoint']['verified']: + authenticated = authenticated + 1 + + ctx.my_output.default('\nAuthenticated: %s/%s' % ( + authenticated, + len(endpoints) + )) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/redfish/main.py b/menu/get/redfish/main.py new file mode 100644 index 00000000..a60f4ef3 --- /dev/null +++ b/menu/get/redfish/main.py @@ -0,0 +1,22 @@ +import click + +from menu.get.redfish.cache import get_redfish_cache_command +from menu.get.redfish.endpoint import get_redfish_endpoint_command +from menu.get.redfish.template import get_redfish_template_command +from menu.get.redfish.uri import get_redfish_uri_command + + +class Failure(Exception): + pass + + +@click.group("redfish") +@click.pass_obj +def get_redfish_menu(ctx): + """Get redfish commands""" + + +get_redfish_menu.add_command(get_redfish_cache_command) +get_redfish_menu.add_command(get_redfish_endpoint_command) +get_redfish_menu.add_command(get_redfish_template_command) +get_redfish_menu.add_command(get_redfish_uri_command) diff --git a/menu/get/redfish/template.py b/menu/get/redfish/template.py new file mode 100644 index 00000000..db4a9d32 --- /dev/null +++ b/menu/get/redfish/template.py @@ -0,0 +1,430 @@ +import sys +import json +import threading +import traceback +import click + +from lib.redfish import endpoint +from lib.redfish import endpoint_settings +from lib.redfish import output as redfish_output +from lib import ip_helper + +from menu import common +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("template") +@click.pass_obj +@click.option("--type", "endpoint_type", type=click.Choice(['ucsc', 'fi', 'hpe', 'dell'], case_sensitive=False), default='ucsc', help="Redfish endpoint type") +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--port", "endpoint_port", default=443, help="Redfish management TCP port") +@click.option("--username", default='', help="Redfish username") +@click.option("--password", default='', help="Redfish password") +@click.option("--inventory-type", default='', help="FI Inventory Type") +@click.option("--inventory-id", default='', help="FI Inventory Id") +@click.option("--cache", "cache_name", callback=validations.empty_string_to_none, default='', help="Cache name") +@click.option("--ttl", "cache_ttl", default=600, help="Cache TTL") +@click.option("--view", "-v", default=['identity'], help="[access|account|bios|cpu|endpoint|fan|gpu|hw|identity|mem|net|pci|power|psu|role|storage|thermal|all]", show_default=True, multiple=True) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_redfish_template_command( + ctx, + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + inventory_type, + inventory_id, + cache_name, + cache_ttl, + view, + output, + devel + ): + """Get redfish template""" + + # iserver get redfish template + + ctx.developer = devel + view = validations.validate_view( + ctx, + view, + 'access|account|bios|cpu|endpoint|fan|gpu|hw|identity|mem|net|pci|power|psu|role|storage|thermal|all', + 'identity', + [ + 'access:account,role', + 'hw:cpu,fan,gpu,mem,net,pci,psu,storage', + 'endpoint:endpoint' + ] + ) + if view is None: + sys.exit(1) + + try: + common.flags_fixup(ctx, False, False, False) + + if cache_name is None: + if len(endpoint_ip) == 0: + endpoint_ip = input('Redfish endpoint IP address: ') + if not ip_helper.is_valid_ipv4_address(endpoint_ip): + ctx.my_output.error('IPv4 address invalid') + raise ErrorExit + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + + endpoint_id = endpoint_settings_handler.get_endpoint_id_with_ip( + endpoint_ip + ) + if endpoint_id is None: + ctx.my_output.default('Endpoint not found in internal redfish database. Provide full access details.') + system_id = None + + endpoint_port = input('Redfish endpoint port [def. 443]: ') + if len(endpoint_port) == 0: + endpoint_port = 443 + else: + try: + endpoint_port = int(endpoint_port) + except BaseException: + ctx.my_output.error('Port (int) value expected') + endpoint_port = None + + if endpoint_port is None: + raise ErrorExit + + username = input('Redfish authentication username: ') + if len(username) == 0: + raise ErrorExit + + password = input('Redfish authentication password: ') + if len(password) == 0: + raise ErrorExit + + handler_endpoint_type = input('Endpoint type [ucsc, fi, dell, hp]: ') + if len(handler_endpoint_type) == 0 or handler_endpoint_type not in ['ucsc', 'fi', 'dell', 'hp']: + raise ErrorExit + + if handler_endpoint_type == 'fi': + inventory_type = input('Inventory type: ') + if len(inventory_type) == 0: + raise ErrorExit + + inventory_id = input('Inventory id: ') + if len(inventory_id) == 0: + raise ErrorExit + + redfish_settings = None + else: + redfish_settings = endpoint_settings_handler.get_redfish_endpoint_settings(endpoint_id) + if redfish_settings is None: + ctx.my_output.default('Selected server in internal redfish database and is not configured with Redfish access') + raise ErrorExit + + ctx.my_output.default('Endpoint found in internal redfish database.') + + if redfish_settings['endpoint']['type'] == 'generic': + ctx.my_output.error( + 'Endpoint properties template not supported on generic endpoint type' + ) + raise ErrorExit + + system_id = endpoint_id + handler_endpoint_type = redfish_settings['endpoint']['type'] + endpoint_ip = redfish_settings['endpoint']['ip'] + endpoint_port = redfish_settings['endpoint']['port'] + + update_requested = False + if len(username) == 0: + username = redfish_settings['endpoint']['username'] + else: + update_requested = True + if len(password) == 0: + password = redfish_settings['endpoint']['password'] + else: + update_requested = True + if len(inventory_type) == 0: + inventory_type = redfish_settings['endpoint']['inventory_type'] + else: + update_requested = True + if len(inventory_id) == 0: + inventory_id = redfish_settings['endpoint']['inventory_id'] + else: + update_requested = True + + + if update_requested: + ctx.my_output.default('Update redfish endpoint settings?') + if common.get_confirmation(): + redfish_endpoint_settings = {} + redfish_endpoint_settings['type'] = handler_endpoint_type + redfish_endpoint_settings['ip'] = endpoint_ip + redfish_endpoint_settings['port'] = endpoint_port + redfish_endpoint_settings['username'] = username + redfish_endpoint_settings['password'] = password + redfish_endpoint_settings['inventory_type'] = inventory_type + redfish_endpoint_settings['inventory_id'] = inventory_id + + success = endpoint_settings_handler.set_redfish_endpoint_access( + redfish_endpoint_settings, + endpoint_id + ) + if success: + ctx.my_output.default('Updated') + redfish_settings = endpoint_settings_handler.get_redfish_endpoint_settings(endpoint_id) + if redfish_settings is None: + ctx.my_output.default('Something went wrong after update...') + raise ErrorExit + else: + ctx.my_output.error('Update failed') + + if cache_name is not None: + system_id = None + handler_endpoint_type = 'cache' + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + redfish_handler = endpoint.RedfishEndpoint( + handler_endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + system_id=system_id, + cache_name=cache_name, + get_timeout=120, + auto_connect=False, + ssl_verify=False, + log_id=ctx.run_id + ) + + if endpoint_type == 'fi': + redfish_handler.endpoint_handler.set_inventory( + inventory_type, + inventory_id + ) + + template_properties = {} + for properties_template_name in view: + if properties_template_name in ['endpoint']: + continue + + if properties_template_name == 'inventory': + if endpoint_type == 'fi': + template_properties[properties_template_name] = redfish_handler.endpoint_handler.get_inventory() + + continue + + template_properties[properties_template_name] = redfish_handler.endpoint_handler.get_template_properties( + properties_template_name, + cache_key=system_id, + cache_ttl=cache_ttl + ) + if template_properties[properties_template_name] is None: + ctx.my_output.error( + 'Failed to get template %s' % (properties_template_name) + ) + raise ErrorExit + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps(template_properties, indent=4) + ) + return + + ctx.my_output.json_output(template_properties) + + output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + + if 'identity' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'identity', + template_properties['identity'], + title=True + ) + + if endpoint_type == 'hpe': + output_handler.print_hpe_properties( + 'identity', + template_properties['identity'] + ) + + if endpoint_type == 'dell': + output_handler.print_dell_properties( + 'identity', + template_properties['identity'] + ) + + if 'endpoint' in view: + if redfish_settings is not None: + ctx.my_output.default( + json.dumps(redfish_settings, indent=4) + ) + + return + + if 'account' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'account', + template_properties['account'], + title=True + ) + + if 'role' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'role', + template_properties['role'], + title=True + ) + + if 'bios' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'bios', + template_properties['bios'], + title=True + ) + + if 'cpu' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'cpu', + template_properties['cpu'], + title=True + ) + + if 'gpu' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'gpu', + template_properties['gpu'], + title=True + ) + + if 'mem' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'mem', + template_properties['mem'], + title=True + ) + + if 'storage' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'storage', + template_properties['storage'], + title=True + ) + + if endpoint_type == 'hpe': + output_handler.print_hpe_properties( + 'storage', + template_properties['storage'] + ) + + if endpoint_type == 'dell': + output_handler.print_dell_properties( + 'storage', + template_properties['storage'] + ) + + if 'net' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'net', + template_properties['net'], + title=True + ) + + if 'pci' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'pci', + template_properties['pci'], + title=True + ) + + if 'fan' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'fan', + template_properties['fan'], + title=True + ) + + if 'psu' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'psu', + template_properties['psu'], + title=True + ) + + if 'power' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'power', + template_properties['power'] + ) + + if endpoint_type == 'hpe': + output_handler.print_hpe_properties( + 'power', + template_properties['power'] + ) + + if endpoint_type == 'dell': + output_handler.print_dell_properties( + 'power', + template_properties['power'] + ) + + if 'thermal' in view: + if endpoint_type == 'ucsc': + output_handler.print_ucsc_properties( + 'thermal', + template_properties['thermal'], + title=True + ) + + if endpoint_type == 'hpe': + output_handler.print_hpe_properties( + 'thermal', + template_properties['thermal'] + ) + + if endpoint_type == 'dell': + output_handler.print_dell_properties( + 'thermal', + template_properties['thermal'] + ) + + ctx.my_output.default('View: access, account, bios, cpu, fan, gpu, hw, identity (def), mem, net, pci, power, psu, role, storage, thermal, all', before_newline=True) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/redfish/uri.py b/menu/get/redfish/uri.py new file mode 100644 index 00000000..a590aed1 --- /dev/null +++ b/menu/get/redfish/uri.py @@ -0,0 +1,437 @@ +import sys +import json +import threading +import traceback +import click + +from lib.redfish import endpoint +from lib.redfish import endpoint_settings +from lib.redfish import output as redfish_output +from lib import ip_helper + +from menu import common +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("uri") +@click.pass_obj +@click.option("--type", "endpoint_type", type=click.Choice(['standard', 'ucsc', 'fi', 'dell', 'hpe'], case_sensitive=False), default='standard', help="Redfish endpoint type") +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--port", "endpoint_port", default=443, help="Redfish management TCP port") +@click.option("--username", default='', help="Redfish username") +@click.option("--password", default='', help="Redfish password") +@click.option("--inventory-type", default='', help="FI Inventory Type") +@click.option("--inventory-id", default='', help="FI Inventory Id") +@click.option("--uri", "redfish_path", default='/', callback=validations.validate_redfish_path, help="Redfish resource uri") +@click.option("--property", "redfish_properties", multiple=True, help="Select redfish properties within resource") +@click.option("--key", "key_filter", multiple=True, help="Filter keys") +@click.option("--value", "value_filter", multiple=True, help="Filter values") +@click.option("--description", is_flag=True, show_default=True, default=False, help="Description properties only") +@click.option("--children", is_flag=True, show_default=True, default=False, help="Children only") +@click.option("--oem", is_flag=True, show_default=True, default=False, help="Oem only") +@click.option("--action", is_flag=True, show_default=True, default=False, help="Action only") +@click.option("--deep", is_flag=True, show_default=True, default=False, help="Recursive iteration") +@click.option("--no-exclusions", is_flag=True, show_default=True, default=False, help="No uri exclusions in deep search") +@click.option("--max", "tree_max_execution_time", is_flag=False, type=click.INT, default=120, help="Max execution time in seconds") +@click.option("--timeout", "get_timeout", is_flag=False, show_default=True, default=10, type=click.INT, help="Get uri timeout") +@click.option("--cache", "cache_name", callback=validations.empty_string_to_none, default='', help="Cache name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_redfish_uri_command( + ctx, + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + inventory_type, + inventory_id, + redfish_path, + redfish_properties, + key_filter, + value_filter, + description, + children, + oem, + action, + deep, + no_exclusions, + tree_max_execution_time, + get_timeout, + cache_name, + output, + devel + ): + """Get redfish uri resources""" + + # iserver get redfish uri + + ctx.developer = devel + + try: + common.flags_fixup(ctx, False, False, False) + + if cache_name is None: + if len(endpoint_ip) == 0: + endpoint_ip = input('Redfish endpoint IP address: ') + if not ip_helper.is_valid_ipv4_address(endpoint_ip): + ctx.my_output.error('IPv4 address invalid') + raise ErrorExit + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + + endpoint_id = endpoint_settings_handler.get_endpoint_id_with_ip( + endpoint_ip + ) + if endpoint_id is None: + ctx.my_output.default('Endpoint not found in internal redfish database. Provide full access details.') + system_id = None + + endpoint_port = input('Redfish endpoint port [def. 443]: ') + if len(endpoint_port) == 0: + endpoint_port = 443 + else: + try: + endpoint_port = int(endpoint_port) + except BaseException: + ctx.my_output.error('Port (int) value expected') + endpoint_port = None + + if endpoint_port is None: + raise ErrorExit + + username = input('Redfish authentication username: ') + if len(username) == 0: + raise ErrorExit + + password = input('Redfish authentication password: ') + if len(password) == 0: + raise ErrorExit + + handler_endpoint_type = input('Endpoint type [ucsc, fi, dell, hp]: ') + if len(handler_endpoint_type) == 0 or handler_endpoint_type not in ['ucsc', 'fi', 'dell', 'hp']: + raise ErrorExit + + if handler_endpoint_type == 'fi': + inventory_type = input('Inventory type: ') + if len(inventory_type) == 0: + raise ErrorExit + + inventory_id = input('Inventory id: ') + if len(inventory_id) == 0: + raise ErrorExit + + redfish_settings = None + else: + redfish_settings = endpoint_settings_handler.get_redfish_endpoint_settings(endpoint_id) + if redfish_settings is None: + ctx.my_output.default('Selected server in internal redfish database and is not configured with Redfish access') + raise ErrorExit + + ctx.my_output.default('Endpoint found in internal redfish database.') + + if redfish_settings['endpoint']['type'] == 'generic': + ctx.my_output.error( + 'Endpoint properties template not supported on generic endpoint type' + ) + raise ErrorExit + + system_id = endpoint_id + handler_endpoint_type = redfish_settings['endpoint']['type'] + endpoint_ip = redfish_settings['endpoint']['ip'] + endpoint_port = redfish_settings['endpoint']['port'] + + update_requested = False + if len(username) == 0: + username = redfish_settings['endpoint']['username'] + else: + update_requested = True + if len(password) == 0: + password = redfish_settings['endpoint']['password'] + else: + update_requested = True + if len(inventory_type) == 0: + inventory_type = redfish_settings['endpoint']['inventory_type'] + else: + update_requested = True + if len(inventory_id) == 0: + inventory_id = redfish_settings['endpoint']['inventory_id'] + else: + update_requested = True + + + if update_requested: + ctx.my_output.default('Update redfish endpoint settings?') + if common.get_confirmation(): + redfish_endpoint_settings = {} + redfish_endpoint_settings['type'] = handler_endpoint_type + redfish_endpoint_settings['ip'] = endpoint_ip + redfish_endpoint_settings['port'] = endpoint_port + redfish_endpoint_settings['username'] = username + redfish_endpoint_settings['password'] = password + redfish_endpoint_settings['inventory_type'] = inventory_type + redfish_endpoint_settings['inventory_id'] = inventory_id + + success = endpoint_settings_handler.set_redfish_endpoint_access( + redfish_endpoint_settings, + endpoint_id + ) + if success: + ctx.my_output.default('Updated') + redfish_settings = endpoint_settings_handler.get_redfish_endpoint_settings(endpoint_id) + if redfish_settings is None: + ctx.my_output.default('Something went wrong after update...') + raise ErrorExit + else: + ctx.my_output.error('Update failed') + + if cache_name is not None: + system_id = None + handler_endpoint_type = 'cache' + + ctx.my_output.default('Requested URI: %s' % (redfish_path)) + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + redfish_handler = endpoint.RedfishEndpoint( + handler_endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + system_id=system_id, + cache_name=cache_name, + get_timeout=get_timeout, + auto_connect=True, + ssl_verify=False, + deep_search_exlusions=not no_exclusions, + tree_max_execution_time=tree_max_execution_time, + log_id=ctx.run_id + ) + + if endpoint_type == 'fi': + redfish_handler.endpoint_handler.set_inventory( + inventory_type, + inventory_id + ) + + if not redfish_handler.is_connected(): + ctx.busy = False + ctx.my_output.error( + 'Redfish access failed' + ) + raise ErrorExit + + output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + + # --children option handler with optional --deep + if children: + children_paths = redfish_handler.get_children( + redfish_path, + deep + ) + + ctx.busy = False + + if children is None: + ctx.my_output.error( + 'Children collection failed: %s' % (redfish_path) + ) + raise ErrorExit + + output_handler.print_children( + redfish_handler.endpoint_handler.path_fixup(redfish_path), + children_paths, + deep, + output + ) + + return + + # --description option handler with optional --deep + if description: + description_tree = redfish_handler.get_descriptions( + redfish_path, + deep + ) + + ctx.busy = False + + if description_tree is None: + ctx.my_output.error( + 'Description collection failed: %s' % (redfish_path) + ) + raise ErrorExit + + output_handler.print_tree( + description_tree, + output + ) + + return + + # --action option handler with optional --deep + if action: + action_tree = redfish_handler.get_action( + redfish_path, + deep + ) + + ctx.busy = False + + if action_tree is None: + ctx.my_output.error( + 'Action collection failed: %s' % (redfish_path) + ) + raise ErrorExit + + output_handler.print_tree( + action_tree, + output + ) + + return + + # --oem option handler with optional --deep + if oem: + oem_tree = redfish_handler.get_oem( + redfish_path, + deep + ) + + ctx.busy = False + + if oem_tree is None: + ctx.my_output.error( + 'Oem collection failed: %s' % (redfish_path) + ) + raise ErrorExit + + output_handler.print_tree( + oem_tree, + output + ) + + return + + # --key option handler with optional --deep + if len(key_filter) > 0: + key_tree = redfish_handler.get_keys( + redfish_path, + deep, + key_filter + ) + + ctx.busy = False + + if key_tree is None: + ctx.my_output.error( + 'Oem collection failed: %s' % (redfish_path) + ) + raise ErrorExit + + output_handler.print_tree( + key_tree, + output + ) + + return + + # --value option handler with optional --deep + if len(value_filter) > 0: + key_tree = redfish_handler.get_values( + redfish_path, + deep, + value_filter + ) + + ctx.busy = False + + if key_tree is None: + ctx.my_output.error( + 'Value collection failed: %s' % (redfish_path) + ) + raise ErrorExit + + output_handler.print_tree( + key_tree, + output + ) + + return + + # --path with deep + if deep: + tree = redfish_handler.get_tree( + redfish_path + ) + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps(tree, indent=4) + ) + + if output == 'default': + ctx.my_output.default('') + for uri in tree: + if tree[uri] is not None: + ctx.my_output.default(uri, underline=True) + ctx.my_output.default(json.dumps(tree[uri], indent=4)) + ctx.my_output.default('') + + return + + # --path and optional property selection + properties = redfish_handler.get_properties( + redfish_path, + redfish_properties + ) + if properties is None: + ctx.busy = False + ctx.my_output.error( + 'Redfish call failed: %s' % (redfish_path) + ) + raise ErrorExit + + ctx.busy = False + + if output == 'json': + ctx.my_output.default( + json.dumps(properties, indent=4) + ) + + if output == 'default': + ctx.my_output.default('') + ctx.my_output.default( + redfish_handler.endpoint_handler.path_fixup( + redfish_path + ), + underline=True + ) + ctx.my_output.default( + json.dumps(properties, indent=4) + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/server.py b/menu/get/server.py new file mode 100644 index 00000000..b7daff20 --- /dev/null +++ b/menu/get/server.py @@ -0,0 +1,676 @@ +import json +import sys +import traceback +import click + +from progress.bar import Bar + +from lib.intersight import compute +from lib.intersight import computes_summary +from lib.intersight import compute_output +from lib.intersight import chassis +from lib.intersight import validations as intersight_validations +from lib.vc import vcenter +from lib.vc import settings as vc_settings +from lib import my_servers_helper +from lib import context + +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", multiple=True, help="Select by IP or subnet") +@click.option("--name", "name_filter", multiple=True, callback=intersight_validations.name_filter, help="Select by name") +@click.option("--serial", "serial_filter", multiple=True, callback=intersight_validations.serial_filter, help="Select by serial") +@click.option("--model", "model_filter", multiple=True, callback=intersight_validations.model_filter, help="Select by model") +@click.option("--type", "type_filter", type=click.Choice(['any', 'blade', 'rack'], case_sensitive=False), default='any', show_default=True, help="Select by type") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--tag", "tag_filter", multiple=True, callback=intersight_validations.tag_filter, help="Tag filter") +@click.option("--led", "locator_filter", type=click.Choice(['any', 'on', 'off'], case_sensitive=False), default='any', show_default=True, help="Filter by locator led state") +@click.option("--power", "power_filter", type=click.Choice(['any', 'on', 'off'], case_sensitive=False), default='any', show_default=True, help="Filter by power state") +@click.option("--alarm", "alarm_filter", type=click.Choice(['any', 'info', 'warn', 'crit'], case_sensitive=False), default='any', show_default=True, help="Filter by alarm severity") +@click.option("--mode", "mode_filter", type=click.Choice(['any', 'imm', 'ucsm'], case_sensitive=False), default='any', show_default=True, help="Filter by management mode") +@click.option("--disc", "disconnected", is_flag=True, default=False, help="Filter disconnected") +@click.option("--cname", "cname_filter", default='', help="Chassis name loose match filter") +@click.option("--cmodel", "cmodel_filter", default='', help="Chassis model loose match filter") +@click.option("--cserial", "cserial_filter", default='', callback=validations.validate_filter_serials, help="Chassis serial strict match filter") +@click.option("--cpu", "cpu_filter", multiple=True, callback=intersight_validations.cpu_filter, help="CPU filter") +@click.option("--gpu", "gpu_filter", multiple=True, callback=intersight_validations.gpu_filter, help="GPU filter") +@click.option("--mem", "memory_filter", multiple=True, callback=intersight_validations.memory_filter, help="Memory filter") +@click.option("--pci", "pci_filter", multiple=True, callback=intersight_validations.pci_filter, help="PCI filter") +@click.option("--mac", "mac_filter", multiple=True, help="MAC address filter") +@click.option("--sc", "sc_filter", multiple=True, callback=intersight_validations.sc_filter, help="Storage controller filter") +@click.option("--pd", "pd_filter", multiple=True, callback=intersight_validations.pd_filter, help="Physical disk filter") +@click.option("--vd", "vd_filter", multiple=True, callback=intersight_validations.vd_filter, help="Virtual drive filter") +@click.option("--fan", "fan_filter", multiple=True, callback=intersight_validations.fan_filter, help="Fan filter") +@click.option("--psu", "psu_filter", multiple=True, callback=intersight_validations.psu_filter, help="Psu filter") +@click.option("--vc", "vcenter_name", default='', help="vCenter name") +@click.option("--view", "-v", default=['state'], help="[state|adv|alarm|board|boot|connector|contract|cpu|env|fan|fanm|fw|gpu|hcl|hw|inv|istate|kvm|lic|mem|net|pci|power|profile|psu|sc|pd|vd|storage|sw|thermal|tpm|workflow|vc|summary]", show_default=True, multiple=True) +@click.option("--days", default=0, type=click.INT, help="Last days workflows") +@click.option("--ttl", "user_cache_ttl", default=None, help="Cache TTL") +@click.option("--inventory", "inventory_filename", default=None, help="Inventory CSV filename") +@click.option("--set", "set_group", default='', callback=validations.validate_group_oper, help="Set as group") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_server_command( + ctx, + iaccount, + ip_filter, + name_filter, + serial_filter, + model_filter, + type_filter, + group_filter, + tag_filter, + locator_filter, + power_filter, + alarm_filter, + mode_filter, + disconnected, + cname_filter, + cmodel_filter, + cserial_filter, + cpu_filter, + gpu_filter, + memory_filter, + pci_filter, + mac_filter, + sc_filter, + pd_filter, + vd_filter, + fan_filter, + psu_filter, + vcenter_name, + view, + days, + user_cache_ttl, + inventory_filename, + set_group, + output, + devel + ): + """Get server details""" + + # iserver get is server + + ctx.developer = devel + ctx.output = output + if ctx.output == 'default': + ctx.my_output.set_debug() + + view = validations.validate_view( + ctx, + view, + 'state|adv|alarm|board|boot|connector|contract|cpu|env|fan|fanm|fw|gpu|hcl|hw|inv|istate|kvm|lic|mem|net|pci|power|profile|psu|sc|pd|vd|storage|sw|thermal|tpm|workflow|vc|summary', + 'state', + [ + 'hw:state,board,cpu,fan,gpu,mem,pci,net,psu,storage,tpm', + 'inv:board,chassis,cpu,fan,gpu,mem,pci,net,psu,storage,tpm,inventory', + 'sw:fw,boot,kvm', + 'env:power,thermal', + 'istate:adv,alarm,connector,contract,hcl,lic,profile,workflow' + ] + ) + if view is None: + sys.exit(1) + + if 'summary' in view and len(view) > 1: + ctx.my_output.error( + 'Summary view should be the only view defined' + ) + sys.exit(1) + + try: + # default vs. user-defined cache_ttl + cache_ttl = intersight_validations.validate_cache_ttl(user_cache_ttl, log_id=ctx.run_id) + if cache_ttl is not None and cache_ttl < 0: + ctx.my_output.error('Cache TTL must be gt 0') + raise ErrorExit + + # Server details collection settings + + settings = {} + settings['alarm'] = 'alarm' in view or alarm_filter != 'any' + settings['advisory'] = 'adv' in view + settings['board'] = 'board' in view or 'tpm' in view + settings['boot'] = 'boot' in view + settings['connector'] = 'connector' in view or 'state' in view + settings['contract'] = 'contract' in view + settings['cpu'] = 'cpu' in view or cpu_filter['info'] + settings['fan'] = 'fan' in view or 'fanm' in view or fan_filter['info'] + settings['fw'] = 'fw' in view + settings['gpu'] = 'gpu' in view or gpu_filter['info'] + settings['hcl'] = 'hcl' in view + settings['inventory'] = 'inventory' in view + settings['locator'] = 'state' in view or locator_filter != 'any' + settings['memory'] = 'mem' in view or memory_filter['info'] + settings['net'] = 'net' in view or len(mac_filter) > 0 + settings['pci'] = 'pci' in view or 'gpu' in view or pci_filter['info'] or gpu_filter['info'] + settings['power'] = 'power' in view + settings['profile'] = 'profile' in view + settings['psu'] = 'psu' in view or psu_filter['info'] + settings['state'] = 'state' in view or locator_filter != 'any' or power_filter != 'any' + settings['storage'] = 'storage' in view or 'sc' in view or 'pd' in view or 'vd' in view or sc_filter['info'] or pd_filter['info'] or vd_filter['info'] + settings['thermal'] = 'thermal' in view + settings['tpm'] = 'tpm' in view + settings['workflow'] = None + if 'workflow' in view or 'state' in view: + if days > 0: + settings['workflow'] = 86400 * days + + # Server filtering options incl. chassis filtering (early exit if no chassis matching criteria) + + match_rules = {} + match_rules['locator'] = locator_filter + match_rules['power'] = power_filter + match_rules['alarms'] = alarm_filter + match_rules['ucsm'] = False + if mode_filter == 'ucsm': + match_rules['ucsm'] = True + match_rules['imm'] = False + if mode_filter == 'imm': + match_rules['imm'] = True + match_rules['disconnected'] = disconnected + match_rules['cpu'] = cpu_filter + match_rules['gpu'] = gpu_filter + match_rules['memory'] = memory_filter + match_rules['pci'] = pci_filter + match_rules['mac'] = mac_filter + match_rules['sc'] = sc_filter + match_rules['pd'] = pd_filter + match_rules['vd'] = vd_filter + match_rules['fan'] = fan_filter + match_rules['psu'] = psu_filter + match_rules['ancestor'] = [] + + if len(cname_filter) > 0 or len(cserial_filter) > 0 or len(cmodel_filter) > 0: + cmatch_rules = {} + cmatch_rules['name'] = cname_filter + cmatch_rules['serial'] = ','.join(cserial_filter) + cmatch_rules['model'] = cmodel_filter + + chassis_handler = chassis.Chassis(iaccount, log_id=ctx.run_id) + + chassiz_mo = chassis_handler.get_mo( + match_rules=cmatch_rules, + cache_ttl=cache_ttl + ) + if chassiz_mo is None or len(chassiz_mo) == 0: + ctx.my_output.error('No chassis found') + return + + for chassis_mo in chassiz_mo: + match_rules['ancestor'].append( + chassis_mo['Moid'] + ) + + # Runtime information + + if output not in ['json']: + if cache_ttl is None: + ctx.my_output.default('iaccount %s (cache: off)' % (iaccount)) + else: + if cache_ttl == 0: + ctx.my_output.default('iaccount %s (cache: any)' % (iaccount)) + if cache_ttl > 0: + ctx.my_output.default('iaccount %s (cache: %s seconds)' % (iaccount, cache_ttl)) + + ctx.my_output.default('Select servers...') + + # Collect servers mo using basic filtering criteria and expansion based on settings. No cache used + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + mo_match_rules = compute_handler.get_mo_match_rules( + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=intersight_validations.add_group_filter(serial_filter, group_filter), + model_filter=model_filter, + tag_filter=tag_filter + ) + + include_rack = True + include_blade = True + if type_filter == 'rack': + include_blade = False + if type_filter == 'blade': + include_rack = False + + rack_expand = [] + blade_expand = [] + if settings['pci']: + rack_expand.append('PciDevices') + blade_expand.append('PciDevices') + blade_expand.append('PciNodes') + if settings['psu']: + rack_expand.append('Psus') + if settings['fan']: + rack_expand.append('Fanmodules') + if settings['locator']: + rack_expand.append('LocatorLed') + blade_expand.append('LocatorLed') + if settings['state']: + rack_expand.append('RegisteredDevice') + blade_expand.append('RegisteredDevice') + + servers_mo = compute_handler.get_mo( + match_rules=mo_match_rules, + include_rack=include_rack, + rack_expand=rack_expand, + include_blade=include_blade, + blade_expand=blade_expand, + cache_ttl=None + ) + + if output not in ['json']: + ctx.my_output.default('Selected servers: %s' % (len(servers_mo))) + + if len(servers_mo) == 0: + return + + # Collect chassis information. No cache used + + chassiz_info = None + if 'chassis' in view: + chassiz_moid = [] + for server_mo in servers_mo: + if server_mo['ObjectType'] == 'compute.Blade': + if server_mo['EquipmentChassis']['Moid'] not in chassiz_moid: + chassiz_moid.append( + server_mo['EquipmentChassis']['Moid'] + ) + + chassiz_info = [] + if len(chassiz_moid) > 0: + if output not in ['json']: + ctx.my_output.default('Collect chassis api objects...') + + chassis_handler = chassis.Chassis(iaccount, log_id=ctx.run_id) + cmatch_rules = chassis_handler.get_mo_match_rules( + moid_filter=','.join(chassiz_moid) + ) + chassiz_mo = chassis_handler.get_mo( + match_rules=cmatch_rules, + cache_ttl=None + ) + if chassiz_mo is not None and len(chassiz_mo) > 0: + chassis_settings = {} + chassis_settings['node'] = True + chassis_settings['io'] = True + chassis_settings['expander_module'] = True + chassis_settings['fan'] = True + chassis_settings['psu'] = True + + bar_handler = None + if output == 'default': + bar_handler = Bar('Collect chassis information', max=len(chassiz_mo)) + bar_handler.goto(0) + + chassiz_info = chassis_handler.get_info( + chassiz_mo, + chassis_settings, + [], + cache_ttl, + bar_handler=bar_handler + ) + + if output == 'default': + bar_handler.finish() + + # Collect server information + + if output not in ['json']: + ctx.my_output.default('Collect server api objects...') + + compute_handler.set_cache( + servers_mo, + settings, + cache_ttl, + ctx=ctx + ) + + bar_handler = None + if output == 'default': + bar_handler = Bar('Collect server information', max=len(servers_mo)) + bar_handler.goto(0) + + servers_info = compute_handler.get_info( + servers_mo, + settings, + match_rules, + cache_ttl, + prepare_cache=False, + bar_handler=bar_handler + ) + + if output == 'default': + bar_handler.finish() + + if len(vcenter_name) > 0: + vc_settings_handler = vc_settings.VcSettings(log_id=ctx.run_id) + vcenter_settings = vc_settings_handler.get_vc_instance(vcenter_name) + if vcenter_settings is None: + ctx.my_output.error('vcenter not found: %s' % (vcenter_name)) + raise ErrorExit + + vc_handler = vcenter.Vcenter( + vcenter_settings['ip'], + vcenter_settings['username'], + vcenter_settings['password'], + port=vcenter_settings['port'], + log_id=ctx.run_id + ) + + ctx.my_output.default('Get vcenter hosts...') + + vc_hosts = vc_handler.get_hosts_summary() + if vc_hosts is None: + ctx.my_output.error('No vcenter hosts found') + raise ErrorExit + + vc_vms = vc_handler.get_vms() + if vc_vms is None: + ctx.my_output.error('No vcenter virtual machines found') + raise ErrorExit + + # Output section + + is_rack = False + is_blade = False + for server_info in servers_info: + if server_info['Type'] == 'Blade': + is_blade = True + if server_info['Type'] == 'Rack': + is_rack = True + + if 'summary' in view: + summary_handler = computes_summary.ComputesSummary(settings, log_id=ctx.run_id) + summary = summary_handler.get_summary(servers_info) + if output == 'json': + ctx.my_output.default(json.dumps(summary, indent=4)) + ctx.log_prompt = False + return + + ctx.my_output.default('') + ctx.my_output.json_output(summary) + summary_handler.print_summary(summary) + return + + if output == 'json': + ctx.my_output.default(json.dumps(servers_info, indent=4)) + ctx.log_prompt = False + return + + ctx.my_output.json_output(servers_info) + + ctx.my_output.default('') + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + if 'inventory' in view: + compute_output_handler.print_inventory( + servers_info, + chassiz_info, + title=True + ) + + if inventory_filename is not None: + compute_output_handler.print_inventory_csv( + servers_info, + chassiz_info, + inventory_filename + ) + + return + + if 'state' in view: + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + # hw:board,cpu,fan,gpu,mem,pci,net,psu,state,storage,tpm + + if 'board' in view: + compute_output_handler.print_board( + servers_info, + title=True + ) + + if 'cpu' in view: + compute_output_handler.print_cpu( + servers_info, + title=True + ) + + if 'gpu' in view: + compute_output_handler.print_gpu( + servers_info, + title=True + ) + + if 'mem' in view: + compute_output_handler.print_memory( + servers_info, + title=True + ) + + if 'storage' in view or 'sc' in view: + compute_output_handler.print_storage_controllers( + servers_info, + title=True + ) + + if 'storage' in view or 'pd' in view: + compute_output_handler.print_physical_disks( + servers_info, + title=True + ) + + if 'storage' in view or 'vd' in view: + compute_output_handler.print_virtual_drives( + servers_info, + title=True + ) + + if 'net' in view: + if is_rack: + compute_output_handler.print_cimc( + servers_info, + title=True + ) + + compute_output_handler.print_net( + servers_info, + title=True + ) + + if 'pci' in view: + compute_output_handler.print_pci( + servers_info, + title=True + ) + + if is_blade: + compute_output_handler.print_pci_node( + servers_info, + title=True + ) + + if 'fanm' in view: + if is_rack: + compute_output_handler.print_fan_module( + servers_info, + title=True + ) + + if 'fan' in view: + if is_rack: + compute_output_handler.print_fan( + servers_info, + title=True + ) + + if 'psu' in view: + if is_rack: + compute_output_handler.print_psu( + servers_info, + title=True + ) + + if 'tpm' in view: + compute_output_handler.print_tpm( + servers_info, + title=True + ) + + # sw:fw,boot,kvm + + if 'fw' in view: + compute_output_handler.print_firmware( + servers_info, + title=True + ) + + if 'boot' in view: + compute_output_handler.print_boot( + servers_info, + title=True + ) + + if 'kvm' in view: + compute_output_handler.print_kvm( + servers_info, + title=True + ) + + # env:power,thermal + + if 'power' in view: + compute_output_handler.print_power( + servers_info, + title=True + ) + + if 'thermal' in view: + compute_output_handler.print_thermal( + servers_info, + title=True + ) + + # istate:adv,alarm,connector,contract,hcl,lic,profile,workflow + + if 'adv' in view: + compute_output_handler.print_advisory( + servers_info, + title=True + ) + + if 'alarm' in view: + compute_output_handler.print_server_alarm( + servers_info, + title=True + ) + + if 'connector' in view: + compute_output_handler.print_connector( + servers_info, + title=True + ) + + if 'contract' in view: + compute_output_handler.print_contract( + servers_info, + title=True + ) + + if 'hcl' in view: + compute_output_handler.print_hcl( + servers_info, + title=True + ) + + if 'lic' in view: + compute_output_handler.print_license( + servers_info, + title=True + ) + + if 'profile' in view: + compute_output_handler.print_profile( + servers_info, + title=True + ) + + if 'workflow' in view: + compute_output_handler.print_workflows( + servers_info, + title=True + ) + + if 'vc' in view: + compute_output_handler.print_vc_vms( + servers_info, + vc_hosts, + vc_vms, + title=True + ) + + # Set group operation handling + + if set_group is not None: + my_servers_handler = my_servers_helper.MyServers() + if set_group['oper'] == 'add': + if my_servers_handler.add_group_servers(set_group['group'], servers_info): + ctx.my_output.default('Servers added to group: %s' % (set_group['group'])) + return + + ctx.my_output.error('Failed to add servers to group: %s' % (set_group['group'])) + raise ErrorExit + + if set_group['oper'] == 'del': + if my_servers_handler.del_group_servers(set_group['group'], servers_info): + ctx.my_output.default('Servers removed from group: %s' % (set_group['group'])) + return + + ctx.my_output.error('Failed to add servers to group: %s' % (set_group['group'])) + raise ErrorExit + + if my_servers_handler.set_group_servers(set_group['group'], servers_info): + ctx.my_output.default('Group configured with selected servers: %s' % (set_group['group'])) + return + + ctx.my_output.error('Failed to configure group with selected servers: %s' % (set_group['group'])) + raise ErrorExit + + context_handler = context.Context(log_id=ctx.run_id) + context_handler.set( + 'mac', + compute_handler.get_context_mac(servers_info) + ) + context_handler.set( + 'ip', + compute_handler.get_context_ip(servers_info) + ) + + ctx.my_output.default('Filter: ip, name, serial, model, type, group, led, power, alarm, mode', before_newline=True) + ctx.my_output.default(' disc, cname, cmodel, cserial, cpu, gpu, mem, pci, mac, sc, pd, vd, fan, psu') + ctx.my_output.default('View: state (def), adv, alarm, board, boot, connector, contract, cpu, env, fan, fw, gpu, hcl, hw, inv, istate') + ctx.my_output.default(' kvm, lic, mem, net, pci, power, profile, psu, sc, pd, vd, storage, sw, thermal, tpm, workflow, summary') + ctx.my_output.default('Ctx: ip, mac') + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/__init__.py b/menu/get/ucsm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/ucsm/__pycache__/__init__.cpython-310.pyc b/menu/get/ucsm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d8c0be02 Binary files /dev/null and b/menu/get/ucsm/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/blade.cpython-310.pyc b/menu/get/ucsm/__pycache__/blade.cpython-310.pyc new file mode 100644 index 00000000..0bd335d5 Binary files /dev/null and b/menu/get/ucsm/__pycache__/blade.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/blades.cpython-310.pyc b/menu/get/ucsm/__pycache__/blades.cpython-310.pyc new file mode 100644 index 00000000..44643f82 Binary files /dev/null and b/menu/get/ucsm/__pycache__/blades.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/chassis.cpython-310.pyc b/menu/get/ucsm/__pycache__/chassis.cpython-310.pyc new file mode 100644 index 00000000..e55b7eee Binary files /dev/null and b/menu/get/ucsm/__pycache__/chassis.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/chassiz.cpython-310.pyc b/menu/get/ucsm/__pycache__/chassiz.cpython-310.pyc new file mode 100644 index 00000000..3018dd5f Binary files /dev/null and b/menu/get/ucsm/__pycache__/chassiz.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/endpoint.cpython-310.pyc b/menu/get/ucsm/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..f7a1d196 Binary files /dev/null and b/menu/get/ucsm/__pycache__/endpoint.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/inventory.cpython-310.pyc b/menu/get/ucsm/__pycache__/inventory.cpython-310.pyc new file mode 100644 index 00000000..c1ab6d5b Binary files /dev/null and b/menu/get/ucsm/__pycache__/inventory.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/main.cpython-310.pyc b/menu/get/ucsm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..db2cae85 Binary files /dev/null and b/menu/get/ucsm/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/manager.cpython-310.pyc b/menu/get/ucsm/__pycache__/manager.cpython-310.pyc new file mode 100644 index 00000000..939eeef7 Binary files /dev/null and b/menu/get/ucsm/__pycache__/manager.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/query.cpython-310.pyc b/menu/get/ucsm/__pycache__/query.cpython-310.pyc new file mode 100644 index 00000000..d81f082c Binary files /dev/null and b/menu/get/ucsm/__pycache__/query.cpython-310.pyc differ diff --git a/menu/get/ucsm/__pycache__/server.cpython-310.pyc b/menu/get/ucsm/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..e14496f4 Binary files /dev/null and b/menu/get/ucsm/__pycache__/server.cpython-310.pyc differ diff --git a/menu/get/ucsm/blade.py b/menu/get/ucsm/blade.py new file mode 100644 index 00000000..209c592f --- /dev/null +++ b/menu/get/ucsm/blade.py @@ -0,0 +1,135 @@ +import sys +import json +import traceback +import click + +from lib.ucsm import manager + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("blade") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--chassis-id", "chassis_id", default='', help="Chassis Id") +@click.option("--chassis-serial", "chassis_serial", default='', help="Chassis serial number") +@click.option("--blade-id", "blade_id", default='', help="Blade Id") +@click.option("--blade-serial", "blade_serial", default='', help="Blade serial number") +@click.option("--power", is_flag=True, show_default=True, default=False, help="Power state information") +@click.option("--thermal", is_flag=True, show_default=True, default=False, help="Thermal state information") +@click.option("--env", is_flag=True, show_default=True, default=False, help="Environmental state information") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_blade_command( + ctx, + ucsm, + chassis_id, + chassis_serial, + blade_id, + blade_serial, + power, + thermal, + env, + output, + devel + ): + """Get ucsm blade""" + + # iserver get ucsm blade + + ctx.developer = devel + + try: + if blade_serial == '': + if chassis_id == '' and chassis_serial == '': + ctx.my_output.error('Select chassis by id or serial') + raise ErrorExit + + if chassis_id != '' and chassis_serial != '': + ctx.my_output.error('Select chassis by id or serial') + raise ErrorExit + + if blade_id != '' and blade_serial != '': + ctx.my_output.error('Select blade by id or serial') + raise ErrorExit + + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + if blade_serial != '': + blade_info = ucsm_handler.get_blade( + blade_serial=blade_serial, + power=power + ) + if blade_info is None: + ctx.my_output.error('Failed to find blade with serial: %s' % (blade_serial)) + raise ErrorExit + + if blade_serial == '': + if chassis_id == '': + chassis_id = ucsm_handler.get_chassis_id( + chassis_serial=chassis_serial + ) + if chassis_id is None: + ctx.my_output.error('Failed to find chassis with serial: %s' % (chassis_serial)) + raise ErrorExit + + if not ucsm_handler.is_chassis_id(chassis_id): + ctx.my_output.error('Failed to find chassis with id: %s' % (chassis_id)) + raise ErrorExit + + if env: + power = True + thermal = True + + blade_info = ucsm_handler.get_blade( + chassis_id=chassis_id, + blade_id=blade_id, + power=power, + thermal=thermal + ) + if blade_info is None: + ctx.my_output.error('Failed to find blade with id: %s' % (blade_id)) + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + blade_info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(blade_info) + + ucsm_handler.print_blade( + blade_info, + power=power, + thermal=thermal + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/blades.py b/menu/get/ucsm/blades.py new file mode 100644 index 00000000..3741bad3 --- /dev/null +++ b/menu/get/ucsm/blades.py @@ -0,0 +1,120 @@ +import sys +import json +import traceback +import click + +from lib.ucsm import manager +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("blades") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--chassis-id", "chassis_id", default='', help="Chassis Id") +@click.option("--chassis-serial", "chassis_serial", default='', help="Chassis serial number") +@click.option("--power", is_flag=True, show_default=True, default=False, help="Power state information") +@click.option("--thermal", is_flag=True, show_default=True, default=False, help="Thermal state information") +@click.option("--env", is_flag=True, show_default=True, default=False, help="Environmental state information") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_blades_command( + ctx, + ucsm, + chassis_id, + chassis_serial, + power, + thermal, + env, + output, + devel + ): + """Get ucsm blades""" + + # iserver get ucsm blades + + ctx.developer = devel + + try: + if chassis_id == '' and chassis_serial == '': + ctx.my_output.error('Select chassis by id or serial') + raise ErrorExit + + if chassis_id != '' and chassis_serial != '': + ctx.my_output.error('Select chassis by id or serial') + raise ErrorExit + + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + if chassis_id == '': + chassis_id = ucsm_handler.get_chassis_id( + chassis_serial=chassis_serial + ) + if chassis_id is None: + ctx.my_output.error('Failed to find chassis with serial: %s' % (chassis_serial)) + raise ErrorExit + + if not ucsm_handler.is_chassis_id(chassis_id): + ctx.my_output.error('Failed to find chassis with id: %s' % (chassis_id)) + raise ErrorExit + + chassis_rn = ucsm_handler.get_chassis_property(chassis_id, 'rn') + if chassis_rn is None: + ctx.my_output.error('Failed to find chassis name: %s' % (chassis_id)) + raise ErrorExit + + if env: + power = True + thermal = True + + blades_info = ucsm_handler.get_blades( + chassis_rn=chassis_rn, + power=power, + thermal=thermal + ) + if blades_info is None: + ctx.my_output.error('Failed to get blades info') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + blades_info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(blades_info) + + ucsm_handler.print_blades( + blades_info, + power=power, + thermal=thermal, + include_chassis_id=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/chassis.py b/menu/get/ucsm/chassis.py new file mode 100644 index 00000000..f604dd2b --- /dev/null +++ b/menu/get/ucsm/chassis.py @@ -0,0 +1,119 @@ +import sys +import json +import traceback +import click + +from lib.ucsm import manager + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("chassis") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--chassis-id", "chassis_id", default='', help="Chassis Id") +@click.option("--chassis-serial", "chassis_serial", default='', help="Chassis serial number") +@click.option("--blade", is_flag=True, show_default=True, default=False, help="Blade information") +@click.option("--power", is_flag=True, show_default=True, default=False, help="Power state information") +@click.option("--thermal", is_flag=True, show_default=True, default=False, help="Thermal state information") +@click.option("--env", is_flag=True, show_default=True, default=False, help="Environmental state information") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_chassis_command( + ctx, + ucsm, + chassis_id, + chassis_serial, + blade, + power, + thermal, + env, + output, + devel + ): + """Get ucsm chassis""" + + # iserver get ucsm chassis + + ctx.developer = devel + + try: + if chassis_id == '' and chassis_serial == '': + ctx.my_output.error('Select chassis by id or serial') + raise ErrorExit + + if chassis_id != '' and chassis_serial != '': + ctx.my_output.error('Select chassis by id or serial') + raise ErrorExit + + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + if chassis_id == '': + chassis_id = ucsm_handler.get_chassis_id( + chassis_serial=chassis_serial + ) + if chassis_id is None: + ctx.my_output.error('Failed to find chassis with serial: %s' % (chassis_serial)) + raise ErrorExit + + if not ucsm_handler.is_chassis_id(chassis_id): + ctx.my_output.error('Failed to find chassis with id: %s' % (chassis_id)) + raise ErrorExit + + if env: + power = True + thermal = True + + chassis_info = ucsm_handler.get_chassis( + chassis_id, + blade=blade, + power=power, + thermal=thermal + ) + if chassis_info is None: + ctx.my_output.error('Failed to get chassis info') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + chassis_info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(chassis_info) + + ucsm_handler.print_chassis( + chassis_info, + blade=blade, + power=power, + thermal=thermal + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/chassiz.py b/menu/get/ucsm/chassiz.py new file mode 100644 index 00000000..18a11fff --- /dev/null +++ b/menu/get/ucsm/chassiz.py @@ -0,0 +1,94 @@ +import sys +import json +import traceback +import click + +from lib.ucsm import manager + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("chassiz") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--blade", is_flag=True, show_default=True, default=False, help="Blade information") +@click.option("--power", is_flag=True, show_default=True, default=False, help="Power state information") +@click.option("--thermal", is_flag=True, show_default=True, default=False, help="Thermal state information") +@click.option("--env", is_flag=True, show_default=True, default=False, help="Environmental state information") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_chassiz_command( + ctx, + ucsm, + blade, + power, + thermal, + env, + output, + devel + ): + """Get ucsm chassiz""" + + # iserver get ucsm chassiz + + ctx.developer = devel + + try: + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + if env: + power = True + thermal = True + + chassiz_info = ucsm_handler.get_chassiz( + blade=blade, + power=power, + thermal=thermal + ) + if chassiz_info is None: + ctx.my_output.error('Chassis info get failed') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + chassiz_info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(chassiz_info) + + ucsm_handler.print_chassiz( + chassiz_info, + blade=blade, + power=power, + thermal=thermal + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/inventory.py b/menu/get/ucsm/inventory.py new file mode 100644 index 00000000..b525a31b --- /dev/null +++ b/menu/get/ucsm/inventory.py @@ -0,0 +1,75 @@ +import sys +import json +import traceback +import click + +from lib.ucsm import manager + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("inventory") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_inventory_command( + ctx, + ucsm, + output, + devel + ): + """Get ucsm inventory""" + + # iserver get ucsm inventory + + ctx.developer = devel + + try: + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + inventory = ucsm_handler.get_inventory() + if inventory is None: + ctx.my_output.error('Inventory info get failed') + raise ErrorExit + + if output == 'json': + ctx.my_output.default( + json.dumps( + inventory, + indent=4 + ) + ) + return + + ctx.my_output.json_output(inventory) + + ucsm_handler.print_inventory( + inventory + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/main.py b/menu/get/ucsm/main.py new file mode 100644 index 00000000..3327f92f --- /dev/null +++ b/menu/get/ucsm/main.py @@ -0,0 +1,28 @@ +import click + +from menu.get.ucsm.inventory import get_ucsm_inventory_command +from menu.get.ucsm.chassis import get_ucsm_chassis_command +from menu.get.ucsm.chassiz import get_ucsm_chassiz_command +from menu.get.ucsm.blades import get_ucsm_blades_command +from menu.get.ucsm.blade import get_ucsm_blade_command +from menu.get.ucsm.manager import get_ucsm_manager_command +from menu.get.ucsm.query import get_ucsm_query_command + + +class Failure(Exception): + pass + + +@click.group("ucsm") +@click.pass_obj +def get_ucsm_menu(ctx): + """Get ucsm commands""" + + +get_ucsm_menu.add_command(get_ucsm_inventory_command) +get_ucsm_menu.add_command(get_ucsm_chassis_command) +get_ucsm_menu.add_command(get_ucsm_chassiz_command) +get_ucsm_menu.add_command(get_ucsm_blades_command) +get_ucsm_menu.add_command(get_ucsm_blade_command) +get_ucsm_menu.add_command(get_ucsm_manager_command) +get_ucsm_menu.add_command(get_ucsm_query_command) diff --git a/menu/get/ucsm/manager.py b/menu/get/ucsm/manager.py new file mode 100644 index 00000000..8e3dbb4f --- /dev/null +++ b/menu/get/ucsm/manager.py @@ -0,0 +1,51 @@ +import sys +import traceback +import click + +from lib.ucsm import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("manager") +@click.pass_obj +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_manager_command( + ctx, + show_password, + devel + ): + """Get ucsm managers""" + + # iserver get ucsm manager + + ctx.developer = devel + + try: + settings_handler = settings.UcsmSettings(log_id=ctx.run_id) + + managers = settings_handler.get_ucsm_managers() + if managers is None: + ctx.my_output.error('Failed to get UCSM managers') + raise ErrorExit + + settings_handler.print_ucsm_managers( + managers, + show_password=show_password + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/ucsm/query.py b/menu/get/ucsm/query.py new file mode 100644 index 00000000..f9d677ba --- /dev/null +++ b/menu/get/ucsm/query.py @@ -0,0 +1,72 @@ +import sys +import json +import traceback +import click + +from lib.ucsm import manager + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("query") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--class-id", "class_id", default='', help="Class Id") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_ucsm_query_command( + ctx, + ucsm, + class_id, + devel + ): + """Get ucsm api query""" + + # iserver get ucsm query + + ctx.developer = devel + + try: + if len(class_id) == 0: + ctx.my_output.error('Define class id') + raise ErrorExit + + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + response = ucsm_handler.query_classid( + class_id + ) + if response is None: + ctx.my_output.error('Failed to get class id: %s' % (class_id)) + raise ErrorExit + + if isinstance(response, list): + for item in response: + ctx.my_output.default(str(item)) + else: + ctx.my_output.default(str(item)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/vc/__init__.py b/menu/get/vc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/vc/__pycache__/__init__.cpython-310.pyc b/menu/get/vc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..ebcfa1dd Binary files /dev/null and b/menu/get/vc/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/vc/__pycache__/hosts.cpython-310.pyc b/menu/get/vc/__pycache__/hosts.cpython-310.pyc new file mode 100644 index 00000000..f2a58036 Binary files /dev/null and b/menu/get/vc/__pycache__/hosts.cpython-310.pyc differ diff --git a/menu/get/vc/__pycache__/instance.cpython-310.pyc b/menu/get/vc/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..8730f373 Binary files /dev/null and b/menu/get/vc/__pycache__/instance.cpython-310.pyc differ diff --git a/menu/get/vc/__pycache__/main.cpython-310.pyc b/menu/get/vc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e0f92fa6 Binary files /dev/null and b/menu/get/vc/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/vc/__pycache__/vms.cpython-310.pyc b/menu/get/vc/__pycache__/vms.cpython-310.pyc new file mode 100644 index 00000000..d69dca60 Binary files /dev/null and b/menu/get/vc/__pycache__/vms.cpython-310.pyc differ diff --git a/menu/get/vc/host/__init__.py b/menu/get/vc/host/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/get/vc/host/__pycache__/__init__.cpython-310.pyc b/menu/get/vc/host/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..28a7ae57 Binary files /dev/null and b/menu/get/vc/host/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/get/vc/host/__pycache__/main.cpython-310.pyc b/menu/get/vc/host/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..96b2a607 Binary files /dev/null and b/menu/get/vc/host/__pycache__/main.cpython-310.pyc differ diff --git a/menu/get/vc/host/__pycache__/net.cpython-310.pyc b/menu/get/vc/host/__pycache__/net.cpython-310.pyc new file mode 100644 index 00000000..888f5db2 Binary files /dev/null and b/menu/get/vc/host/__pycache__/net.cpython-310.pyc differ diff --git a/menu/get/vc/host/__pycache__/pnet.cpython-310.pyc b/menu/get/vc/host/__pycache__/pnet.cpython-310.pyc new file mode 100644 index 00000000..217fed1e Binary files /dev/null and b/menu/get/vc/host/__pycache__/pnet.cpython-310.pyc differ diff --git a/menu/get/vc/host/main.py b/menu/get/vc/host/main.py new file mode 100644 index 00000000..ed3dab0b --- /dev/null +++ b/menu/get/vc/host/main.py @@ -0,0 +1,16 @@ +import click + +from menu.get.vc.host.pnet import get_vc_host_pnet_command + + +class Failure(Exception): + pass + + +@click.group("host") +@click.pass_obj +def get_vc_host_menu(ctx): + """Get vcenter host commands""" + + +get_vc_host_menu.add_command(get_vc_host_pnet_command) diff --git a/menu/get/vc/host/pnet.py b/menu/get/vc/host/pnet.py new file mode 100644 index 00000000..fa4c77cb --- /dev/null +++ b/menu/get/vc/host/pnet.py @@ -0,0 +1,115 @@ +import sys +import json +import threading +import traceback +import click + +from lib.xd import vc2fabric + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("pnet") +@click.pass_obj +@click.option("--vc", "vcenter", default='', callback=validations.validate_vc_name, help="vCenter name") +@click.option("--ip", "vcenter_ip", default='', callback=validations.validate_ip, help="vCenter IP") +@click.option("--username", "vcenter_username", default='', help="vCenter Username") +@click.option("--password", "vcenter_password", default='', help="vCenter Password") +@click.option("--name", default='', help="Host name") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_vc_host_pnet_command( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password, + name, + output, + devel + ): + """Get vc host net""" + + # iserver get vc host net + + ctx.developer = devel + ctx.output = output + + try: + if len(name) == 0: + ctx.my_output.error( + 'Define vcenter host name' + ) + raise ErrorExit + + vc_handler = validations.validate_vcenter( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password + ) + if vc_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + hosts_obj = vc_handler.get_hosts_by_name(name, strict=False) + if len(hosts_obj) is None or len(hosts_obj) == 0: + ctx.busy = False + ctx.my_output.error( + 'Host not found' + ) + raise ErrorExit + + if len(hosts_obj) > 1: + ctx.busy = False + ctx.my_output.error( + 'Be more precise...' + ) + for host_obj in hosts_obj: + ctx.my_output.default('- %s' % (host_obj.name)) + + raise ErrorExit + + ctx.busy = False + + info = vc_handler.get_host_networking( + hosts_obj[0] + ) + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + info, + indent=4 + ) + ) + return + + ctx.my_output.json_output(info) + + vc_handler.print_host_phy_networking( + info + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/vc/hosts.py b/menu/get/vc/hosts.py new file mode 100644 index 00000000..4a689cc7 --- /dev/null +++ b/menu/get/vc/hosts.py @@ -0,0 +1,98 @@ +import sys +import json +import threading +import traceback +import click + +from lib.xd import vc2fabric + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("hosts") +@click.pass_obj +@click.option("--vc", "vcenter", default='', callback=validations.validate_vc_name, help="vCenter name") +@click.option("--ip", "vcenter_ip", default='', callback=validations.validate_ip, help="vCenter IP") +@click.option("--username", "vcenter_username", default='', help="vCenter Username") +@click.option("--password", "vcenter_password", default='', help="vCenter Password") +@click.option("--name", "host_name_filter", default='', help="Host name loose match filter") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_vc_hosts_command( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password, + host_name_filter, + output, + devel + ): + """Get vc hosts""" + + # iserver get vc hosts + + ctx.developer = devel + ctx.output = output + + try: + vc_handler = validations.validate_vcenter( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password + ) + if vc_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + host_filter = [] + if len(host_name_filter) > 0: + host_filter.append( + 'name:%s' % (host_name_filter) + ) + + hosts = vc_handler.get_hosts_summary( + host_filter=host_filter + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + hosts, + indent=4 + ) + ) + return + + ctx.my_output.json_output(hosts) + + vc_handler.print_hosts_summary( + hosts, + title=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/vc/instance.py b/menu/get/vc/instance.py new file mode 100644 index 00000000..ff71a432 --- /dev/null +++ b/menu/get/vc/instance.py @@ -0,0 +1,51 @@ +import sys +import traceback +import click + +from lib.vc import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("instance") +@click.pass_obj +@click.option("--show-password", is_flag=True, show_default=True, default=False, help="Show password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_vc_instance_command( + ctx, + show_password, + devel + ): + """Get vcenter instances""" + + # iserver get vc instance + + ctx.developer = devel + + try: + settings_handler = settings.VcSettings(log_id=ctx.run_id) + + instances = settings_handler.get_vc_instances() + if instances is None: + ctx.my_output.error('Failed to get vcenter instances') + raise ErrorExit + + settings_handler.print_vc_instances( + instances, + show_password=show_password + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/get/vc/main.py b/menu/get/vc/main.py new file mode 100644 index 00000000..23e35c34 --- /dev/null +++ b/menu/get/vc/main.py @@ -0,0 +1,22 @@ +import click + +from menu.get.vc.instance import get_vc_instance_command +from menu.get.vc.host.main import get_vc_host_menu +from menu.get.vc.hosts import get_vc_hosts_command +from menu.get.vc.vms import get_vc_vms_command + + +class Failure(Exception): + pass + + +@click.group("vc") +@click.pass_obj +def get_vc_menu(ctx): + """Get vcenter commands""" + + +get_vc_menu.add_command(get_vc_instance_command) +get_vc_menu.add_command(get_vc_host_menu) +get_vc_menu.add_command(get_vc_hosts_command) +get_vc_menu.add_command(get_vc_vms_command) diff --git a/menu/get/vc/vms.py b/menu/get/vc/vms.py new file mode 100644 index 00000000..593078ef --- /dev/null +++ b/menu/get/vc/vms.py @@ -0,0 +1,128 @@ +import sys +import json +import threading +import traceback +import click + +from lib.xd import vc2fabric + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("vms") +@click.pass_obj +@click.option("--vc", "vcenter", default='', callback=validations.validate_vc_name, help="vCenter name") +@click.option("--ip", "vcenter_ip", default='', callback=validations.validate_ip, help="vCenter IP") +@click.option("--username", "vcenter_username", default='', help="vCenter Username") +@click.option("--password", "vcenter_password", default='', help="vCenter Password") +@click.option("--name", "vm_name_filter", default='', help="VM name loose match filter") +@click.option("--host", "host_filter", default='', help="Host loose match filter") +@click.option("--net", is_flag=True, show_default=True, default=False, help="Show network details") +@click.option("--fabric", is_flag=True, show_default=True, default=False, help="Show fabric details") +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def get_vc_vms_command( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password, + vm_name_filter, + host_filter, + net, + fabric, + output, + devel + ): + """Get vc vms""" + + # iserver get vc vms + + ctx.developer = devel + ctx.output = output + if fabric: + net = False + + try: + vc_handler = validations.validate_vcenter( + ctx, + vcenter, + vcenter_ip, + vcenter_username, + vcenter_password + ) + if vc_handler is None: + raise ErrorExit + + if output not in ['json']: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + vm_filter = [] + if len(vm_name_filter) > 0: + vm_filter.append( + 'name:%s' % (vm_name_filter) + ) + + if len(host_filter) > 0: + vm_filter.append( + 'host:%s' % (host_filter) + ) + + vms = vc_handler.get_vms( + vm_filter=vm_filter + ) + + if fabric: + vms = vc2fabric.add_vms_fabric_connections( + vms, + log_id=ctx.run_id + ) + + ctx.busy = False + + if output == 'json': + ctx.log_prompt = False + ctx.my_output.default( + json.dumps( + vms, + indent=4 + ) + ) + return + + ctx.my_output.json_output(vms) + + if fabric: + vc_handler.print_vms_fabric( + vms + ) + + if net: + vc_handler.print_vms_net( + vms + ) + + if not fabric and not net: + vc_handler.print_vms( + vms, + title=True + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/main.py b/menu/main.py new file mode 100644 index 00000000..04e51e87 --- /dev/null +++ b/menu/main.py @@ -0,0 +1,196 @@ +import json +import os +import sys +import uuid +import time +import subprocess +import click + +from menu.create.main import create_menu +from menu.delete.main import delete_menu +from menu.get.main import get_menu +from menu.set.main import set_menu +from menu.settings.main import settings_menu +from menu.utils.main import utils_menu + +from lib import output_helper +from lib import log_helper +from lib import settings_helper + +COMMAND = None + + +class MyCliContext(): + def __init__(self, user_command): + self.run_id = str(uuid.uuid4()).rsplit('-', maxsplit=1)[-1] + + self.my_output = output_helper.OutputHelper(log_id=self.run_id) + self.my_output.initialize() + + self.developer = False + self.output = 'default' + self.busy = False + self.start_time = int(time.time() * 1000) + + self.log = log_helper.Log(log_id=self.run_id) + self.log.initialize() + self.log.set_command(user_command) + self.log_prompt = True + + my_settings = settings_helper.Settings() + self.defaults = {} + self.defaults['iaccount'] = my_settings.get_setting('iaccount', default=None) + + +def print_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + if getattr(sys, 'frozen', False): + bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__))) + version_filename = os.path.abspath(os.path.join(bundle_dir, 'version')) + else: + bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__))) + main_dir = os.path.dirname(bundle_dir) + version_filename = os.path.abspath(os.path.join(main_dir, 'version')) + + try: + with open(version_filename, 'r', encoding='utf-8') as file_handler: + version = file_handler.read() + + except BaseException: + version = 'unknown' + + click.echo('Version %s' % (version)) + click.echo('Project: https://wwwin-github.cisco.com/emear-telcocloud/iserver') + ctx.exit() + + +def check_isctl(): + try: + command = 'isctl version' + with subprocess.Popen( + args=command, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + shell=True, + env=os.environ + ) as process: + output, error = process.communicate() + if process.returncode == 0: + return True, output.decode('utf-8') + return False, 'isctl command execution failed' + except BaseException: + return False, 'Exception in running isctl command' + + +def check_isctl_version(output, min_required): + try: + version_index = output.split(' ')[2].split('.') + min_required_index = min_required.split('.') + + if len(version_index) != len(min_required_index): + return False + + # pylint: disable=consider-using-enumerate + for index in range(0, len(version_index)): + if version_index[index] < min_required_index[index]: + return False + + except BaseException: + return False + + return True + + +def check_isctl_option(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + success, reason = check_isctl() + if success: + click.echo('[SUCCESS] isctl found') + click.echo(reason) + else: + click.echo('[ERROR] %s' % (reason)) + + ctx.exit() + + +@click.pass_obj +def _on_close(ctx): + log_handler = log_helper.Log(log_id=ctx.run_id) + + duration = int(time.time() * 1000) - ctx.start_time + + log_analyzis = log_handler.analyze(duration) + ctx.my_output.duration(json.dumps(log_analyzis, indent=4)) + + all_logs = log_handler.get_logs() + + if ctx.developer: + ctx.my_output.default('\nDeveloper output\n') + ctx.my_output.default(json.dumps(log_analyzis, indent=4)) + ctx.my_output.my_logs(all_logs, stream='default') + else: + ctx.my_output.devel(json.dumps(log_analyzis, indent=4)) + ctx.my_output.my_logs(all_logs, stream='devel') + + command = log_handler.get_command() + error_exit = False + clean_logs = True + if command is not None: + no_log = False + for item in ['utils devel cli']: + if item in command: + no_log = True + + if not no_log: + if ctx.log_prompt: + if log_analyzis['cache_hits'] > 0: + print('\nInfo: finished in %s ms and logs saved in %s incl. cache hits' % (duration, ctx.log.logs_directory)) + else: + print('\nInfo: finished in %s ms and logs saved in %s' % (duration, ctx.log.logs_directory)) + + if ctx.log.is_log('error'): + print( + '%s: errors found in %s' % ( + ctx.my_output.add_color('Warning', 'Red'), + ctx.log.get_log_filename('error') + ) + ) + error_exit = True + + clean_logs = False + + if clean_logs: + log_handler.clean() + + if error_exit: + sys.exit(1) + + +@click.group("main") +@click.option('--version', is_flag=True, callback=print_version, + expose_value=False, is_eager=True) +@click.option('--check-isctl', is_flag=True, callback=check_isctl_option, + expose_value=False, is_eager=True) +@click.pass_context +def cli(ctx): + """iServer CLI""" + ctx.obj = MyCliContext(COMMAND) + ctx.call_on_close(_on_close) + + +cli.add_command(create_menu) +cli.add_command(get_menu) +cli.add_command(delete_menu) +cli.add_command(set_menu) +cli.add_command(settings_menu) +cli.add_command(utils_menu) + + +def run(user_input): + global COMMAND + COMMAND = user_input + cli(None) diff --git a/menu/progress.py b/menu/progress.py new file mode 100644 index 00000000..692fb4c1 --- /dev/null +++ b/menu/progress.py @@ -0,0 +1,22 @@ +import sys +import time + + +def spinning_cursor(): + while 1: + for cursor in '|/-\\': + yield cursor + + +def spinner_task(ctx, newline=True): + delay = 0.1 + spinner = spinning_cursor() + while ctx.busy: + sys.stdout.write(next(spinner)) + sys.stdout.flush() + time.sleep(delay) + sys.stdout.write('\b') + sys.stdout.flush() + if newline: + sys.stdout.write('\n') + sys.stdout.flush() diff --git a/menu/set/__init__.py b/menu/set/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/__pycache__/__init__.cpython-310.pyc b/menu/set/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f40deab9 Binary files /dev/null and b/menu/set/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/__pycache__/main.cpython-310.pyc b/menu/set/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e79d72e4 Binary files /dev/null and b/menu/set/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/__pycache__/os_image.cpython-310.pyc b/menu/set/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..d7392524 Binary files /dev/null and b/menu/set/__pycache__/os_image.cpython-310.pyc differ diff --git a/menu/set/__pycache__/scu.cpython-310.pyc b/menu/set/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..d3060ff5 Binary files /dev/null and b/menu/set/__pycache__/scu.cpython-310.pyc differ diff --git a/menu/set/aci/__init__.py b/menu/set/aci/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/aci/__pycache__/__init__.cpython-310.pyc b/menu/set/aci/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c8714117 Binary files /dev/null and b/menu/set/aci/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/aci/__pycache__/cache.cpython-310.pyc b/menu/set/aci/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..f077adf0 Binary files /dev/null and b/menu/set/aci/__pycache__/cache.cpython-310.pyc differ diff --git a/menu/set/aci/__pycache__/controller.cpython-310.pyc b/menu/set/aci/__pycache__/controller.cpython-310.pyc new file mode 100644 index 00000000..a33a16bc Binary files /dev/null and b/menu/set/aci/__pycache__/controller.cpython-310.pyc differ diff --git a/menu/set/aci/__pycache__/main.cpython-310.pyc b/menu/set/aci/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..29153321 Binary files /dev/null and b/menu/set/aci/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/aci/__pycache__/mode.cpython-310.pyc b/menu/set/aci/__pycache__/mode.cpython-310.pyc new file mode 100644 index 00000000..307f8dee Binary files /dev/null and b/menu/set/aci/__pycache__/mode.cpython-310.pyc differ diff --git a/menu/set/aci/cache.py b/menu/set/aci/cache.py new file mode 100644 index 00000000..2931ac05 --- /dev/null +++ b/menu/set/aci/cache.py @@ -0,0 +1,129 @@ +import sys +import traceback +import click + +from menu import common +from menu import validations + +from lib.aci import apic +from lib.aci import cache +from lib.aci import settings +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cache") +@click.pass_obj +@click.option("--apic", "name", default='', callback=validations.empty_string_to_none, help="APIC specific settings") +@click.option("--on", "cache_on", is_flag=True, show_default=True, default=False, help="Set cache on") +@click.option("--off", "cache_off", is_flag=True, show_default=True, default=False, help="Set cache off") +@click.option("--ttl", "cache_ttl", default=0, type=click.INT, help="Set cache ttl in seconds") +@click.option("--populate", "cache_populate", is_flag=True, show_default=True, default=False, help="Populate cache") +@click.option("--clear", "cache_clear", is_flag=True, show_default=True, default=False, help="Clear cache") +def set_aci_cache_command( + ctx, + name, + cache_on, + cache_off, + cache_ttl, + cache_populate, + cache_clear + ): + """Set aci cache""" + + # iserver set aci cache + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + if cache_on and cache_off: + ctx.my_output.error('Select either --on or --off') + raise ErrorExit + + if cache_populate and cache_clear: + ctx.my_output.error('Select either --populte or --clear') + raise ErrorExit + + settings_handler = settings.ApicSettings(log_id=ctx.run_id) + if name is None: + apic_names = settings_handler.get_apic_controller_names() + if len(apic_names) == 0: + ctx.my_output.error('No api controllers defined') + raise ErrorExit + else: + if settings_handler.get_apic_controller(name) is None: + ctx.my_output.error('Unknown apic name: %s' % (name)) + raise ErrorExit + apic_names = [name] + + if cache_on: + for apic_name in apic_names: + if not settings_handler.set_apic_cache_on(apic_name=apic_name): + ctx.my_output.error('Failed to set cache on: %s' % (apic_name)) + raise ErrorExit + ctx.my_output.default('Cache enabled: %s' % (apic_name)) + + if cache_off: + for apic_name in apic_names: + if not settings_handler.set_apic_cache_off(apic_name=apic_name): + ctx.my_output.error('Failed to set cache off: %s' % (apic_name)) + raise ErrorExit + ctx.my_output.default('Cache disabled: %s' % (apic_name)) + + if cache_ttl > 0: + for apic_name in apic_names: + if not settings_handler.set_apic_cache_ttl(cache_ttl, apic_name=apic_name): + ctx.my_output.error('Failed to set cache ttl: %s' % (apic_name)) + raise ErrorExit + ctx.my_output.default('Cache ttl set to %s seconds: %s' % (cache_ttl, apic_name)) + + if cache_clear: + for apic_name in apic_names: + cache_handler = cache.Cache( + apic_name + ) + if not cache_handler.clear_cache(bar_enabled=True): + ctx.my_output.error('Failed to clear cache: %s' % (apic_name)) + raise ErrorExit + ctx.my_output.default('Cache cleared: %s' % (apic_name)) + + if cache_populate: + for apic_name in apic_names: + controller = settings_handler.get_apic_controller(apic_name) + apic_handler = apic.Apic( + controller['ip'], + controller['port'], + controller['username'], + controller['password'], + apic_name=apic_name, + log_id=ctx.run_id + ) + apic_handler.get_mos(bar_enabled=True) + + if len(apic_names) == 1: + controllers = [settings_handler.get_apic_controller(apic_name)] + else: + controllers = settings_handler.get_apic_controllers() + + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + aci_output_handler.print_apic_controllers( + controllers, + show_password=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/aci/controller.py b/menu/set/aci/controller.py new file mode 100644 index 00000000..639f8790 --- /dev/null +++ b/menu/set/aci/controller.py @@ -0,0 +1,105 @@ +import sys +import traceback +import click + +from menu import common + +from lib.aci import apic +from lib.aci import settings +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("controller") +@click.pass_obj +@click.option("--name", "apic_name", default='', help="APIC name") +@click.option("--ip", "apic_ip", default='', help="APIC IP/FQDN") +@click.option("--port", "apic_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "apic_username", default='', help="APIC username") +@click.option("--password", "apic_password", default='', help="APIC password") +@click.option("--domain", "apic_domain", default='', help="Administrative domain") +@click.option("--verify", is_flag=True, show_default=True, default=False, help="Verify authenticaition") +def set_aci_controller_command( + ctx, + apic_name, + apic_ip, + apic_port, + apic_username, + apic_password, + apic_domain, + verify + ): + """Set aci controller access details""" + + # iserver set aci controller + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + if len(apic_name) == 0: + ctx.my_output.error('Define apic entry name') + raise ErrorExit + + if len(apic_ip) == 0: + ctx.my_output.error('Define apic ip address') + raise ErrorExit + + if len(apic_username) == 0: + ctx.my_output.error('Define apic username') + raise ErrorExit + + if len(apic_password) == 0: + ctx.my_output.error('Define apic password') + raise ErrorExit + + if verify: + apic_handler = apic.Apic( + apic_ip, + apic_port, + apic_username, + apic_password, + log_id=ctx.run_id + ) + if not apic_handler.is_connected(): + ctx.my_output.error('Failed to connect to APIC') + raise ErrorExit + + ctx.my_output.default('APIC authentication successful') + + settings_handler = settings.ApicSettings(log_id=ctx.run_id) + success = settings_handler.set_apic_controller( + apic_name, + apic_ip, + apic_port, + apic_username, + apic_password, + domain=apic_domain + ) + if not success: + ctx.my_output.error('Failed to define apic entry') + raise ErrorExit + + controller = settings_handler.get_apic_controller(apic_name) + + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + aci_output_handler.print_apic_controllers( + [controller], + show_password=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/aci/main.py b/menu/set/aci/main.py new file mode 100644 index 00000000..9ad9890d --- /dev/null +++ b/menu/set/aci/main.py @@ -0,0 +1,22 @@ +import click + +from menu.set.aci.cache import set_aci_cache_command +from menu.set.aci.controller import set_aci_controller_command +from menu.set.aci.mode import set_aci_mode_command +from menu.set.aci.ws import set_aci_ws_command + + +class Failure(Exception): + pass + + +@click.group("aci") +@click.pass_obj +def set_aci_menu(ctx): + """Set aci commands""" + + +set_aci_menu.add_command(set_aci_cache_command) +set_aci_menu.add_command(set_aci_controller_command) +set_aci_menu.add_command(set_aci_mode_command) +set_aci_menu.add_command(set_aci_ws_command) diff --git a/menu/set/aci/mode.py b/menu/set/aci/mode.py new file mode 100644 index 00000000..bb69bc7d --- /dev/null +++ b/menu/set/aci/mode.py @@ -0,0 +1,82 @@ +import sys +import traceback +import click + +from menu import common +from menu import validations + +from lib.aci import settings +from lib.aci import output as aci_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("mode") +@click.pass_obj +@click.option("--apic", "apic_name", default='', callback=validations.empty_string_to_none, help="APIC specific settings") +@click.option("--online", "online_mode", is_flag=True, show_default=True, default=False, help="Set online mode") +@click.option("--offline", "offline_mode", is_flag=True, show_default=True, default=False, help="Set offline mode") +def set_aci_mode_command( + ctx, + apic_name, + online_mode, + offline_mode + ): + """Set aci mode""" + + # iserver set aci mode + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + settings_handler = settings.ApicSettings(log_id=ctx.run_id) + + if apic_name is not None: + if settings_handler.get_apic_controller(apic_name) is None: + ctx.my_output.error('Unknown apic name: %s' % (apic_name)) + raise ErrorExit + + if not online_mode and not offline_mode: + ctx.my_output.error('Select either --online or --offline') + raise ErrorExit + + if online_mode and offline_mode: + ctx.my_output.error('Select either --online or --offline') + raise ErrorExit + + if online_mode: + if not settings_handler.set_apic_mode_online(apic_name=apic_name): + ctx.my_output.error('Failed to set online mode') + raise ErrorExit + + if offline_mode: + if not settings_handler.set_apic_mode_offline(apic_name=apic_name): + ctx.my_output.error('Failed to set offline mode') + raise ErrorExit + + if apic_name is None: + controllers = settings_handler.get_apic_controllers() + else: + controllers = [settings_handler.get_apic_controller(apic_name)] + + aci_output_handler = aci_output.ApicOutput(log_id=ctx.run_id) + aci_output_handler.print_apic_controllers( + controllers, + show_password=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/aci/ws.py b/menu/set/aci/ws.py new file mode 100644 index 00000000..716ee963 --- /dev/null +++ b/menu/set/aci/ws.py @@ -0,0 +1,81 @@ +import sys +import traceback +import click + +from menu import common +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ws") +@click.pass_obj +@click.option("--apic", "controller", default='', callback=validations.validate_apic_name, help="APIC name") +@click.option("--ip", "controller_ip", default='', callback=validations.validate_ip, help="APIC IP") +@click.option("--port", "controller_port", default=443, show_default=True, help="APIC Port") +@click.option("--username", "controller_username", default='', help="APIC Username") +@click.option("--password", "controller_password", default='', help="APIC Password") +@click.option("--mo", "managed_objects", default=[], multiple=True, help="Managed objects") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def set_aci_ws_command( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + managed_objects, + debug + ): + """Set aci websocket""" + + # iserver set aci ws + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + if len(managed_objects) == 0: + ctx.my_output.error( + 'Define at least one managed object' + ) + ctx.my_output.default('Example:') + ctx.my_output.default('- /api/class/fvTenant') + ctx.my_output.default('- /api/node/class/faultInst') + ctx.my_output.default('- /api/node/class/faultDelegate') + raise ErrorExit + + apic_handler = validations.validate_apic_controller( + ctx, + controller, + controller_ip, + controller_port, + controller_username, + controller_password, + debug=debug + ) + if apic_handler is None: + raise ErrorExit + + apic_handler.ws_run( + managed_objects + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except KeyboardInterrupt: + ctx.busy = False + sys.exit(0) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/cvim/__init__.py b/menu/set/cvim/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/cvim/main.py b/menu/set/cvim/main.py new file mode 100644 index 00000000..075b9885 --- /dev/null +++ b/menu/set/cvim/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.cvim.openrc import set_cvim_openrc + + +class Failure(Exception): + pass + + +@click.group("cvim") +@click.pass_obj +def set_cvim_menu(ctx): + """Cisco vim actions and settings""" + + +set_cvim_menu.add_command(set_cvim_openrc) diff --git a/menu/set/cvim/openrc.py b/menu/set/cvim/openrc.py new file mode 100644 index 00000000..6c3a67f1 --- /dev/null +++ b/menu/set/cvim/openrc.py @@ -0,0 +1,78 @@ +import os +import sys +import traceback +import click + +from lib.k8s import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("openrc") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="K8s cluster name") +@click.option("--file", "openrc_filename", default='', help="Kubeconfig filename") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_cvim_openrc( + ctx, + cluster_name, + openrc_filename, + devel + ): + """Set k8s cvim settings""" + + # iserver set k8s cvim + + ctx.developer = devel + + try: + if len(cluster_name) == 0: + ctx.my_output.error('Define k8s cluster name') + raise ErrorExit + + if len(openrc_filename) == 0: + ctx.my_output.error('Define openrc filename') + raise ErrorExit + + if not os.path.isfile(openrc_filename): + ctx.my_output.error('Kubeconfig file not found') + raise ErrorExit + + settings_handler = settings.K8sSettings(log_id=ctx.run_id) + + cluster = settings_handler.get_k8s_cluster( + cluster_name + ) + + if cluster is not None: + if cluster['source'] != 'user': + ctx.my_output.error( + 'Cluster %s cannot be modified' % (cluster_name) + ) + raise ErrorExit + + success = settings_handler.set_k8s_cluster( + cluster_name, + openrc_filename, + cluster_type='standard' + ) + if not success: + ctx.my_output.error('Failed to set cluster') + raise ErrorExit + + ctx.my_output.default('Kubernetes cluster set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/k8s/__init__.py b/menu/set/k8s/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/k8s/kc.py b/menu/set/k8s/kc.py new file mode 100644 index 00000000..4097de3a --- /dev/null +++ b/menu/set/k8s/kc.py @@ -0,0 +1,78 @@ +import os +import sys +import traceback +import click + +from lib.k8s import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("kc") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="K8s cluster name") +@click.option("--file", "kubeconfig_filename", default='', help="Kubeconfig filename") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_k8s_kc( + ctx, + cluster_name, + kubeconfig_filename, + devel + ): + """Set k8s kc settings""" + + # iserver set k8s kc + + ctx.developer = devel + + try: + if len(cluster_name) == 0: + ctx.my_output.error('Define k8s cluster name') + raise ErrorExit + + if len(kubeconfig_filename) == 0: + ctx.my_output.error('Define kubeconfig filename') + raise ErrorExit + + if not os.path.isfile(kubeconfig_filename): + ctx.my_output.error('Kubeconfig file not found') + raise ErrorExit + + settings_handler = settings.K8sSettings(log_id=ctx.run_id) + + cluster = settings_handler.get_k8s_cluster( + cluster_name + ) + + if cluster is not None: + if cluster['source'] != 'user': + ctx.my_output.error( + 'Cluster %s cannot be modified' % (cluster_name) + ) + raise ErrorExit + + success = settings_handler.set_k8s_cluster( + cluster_name, + kubeconfig_filename, + cluster_type='standard' + ) + if not success: + ctx.my_output.error('Failed to set cluster') + raise ErrorExit + + ctx.my_output.default('Kubernetes cluster set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/k8s/main.py b/menu/set/k8s/main.py new file mode 100644 index 00000000..7a9b9dae --- /dev/null +++ b/menu/set/k8s/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.k8s.kc import set_k8s_kc + + +class Failure(Exception): + pass + + +@click.group("k8s") +@click.pass_obj +def set_k8s_menu(ctx): + """K8s actions and settings""" + + +set_k8s_menu.add_command(set_k8s_kc) diff --git a/menu/set/linux/__init__.py b/menu/set/linux/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/linux/main.py b/menu/set/linux/main.py new file mode 100644 index 00000000..dc5282dc --- /dev/null +++ b/menu/set/linux/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.linux.server import set_linux_server_command + + +class Failure(Exception): + pass + + +@click.group("linux") +@click.pass_obj +def set_linux_menu(ctx): + """Set linux commands""" + + +set_linux_menu.add_command(set_linux_server_command) diff --git a/menu/set/linux/server.py b/menu/set/linux/server.py new file mode 100644 index 00000000..81f9343e --- /dev/null +++ b/menu/set/linux/server.py @@ -0,0 +1,84 @@ +import sys +import traceback +import click + +from menu import validations + +from lib.linux import settings +from lib.linux import output as linux_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--name", default='', callback=validations.empty_string_to_none, help="Linux name") +@click.option("--ip", "linux_ip", default='', callback=validations.empty_string_to_none, help="IP/FQDN") +@click.option("--username", default='', callback=validations.empty_string_to_none, help="Username") +@click.option("--password", default='', callback=validations.empty_string_to_none, help="Password") +@click.option("--key", default='', callback=validations.validate_optional_file, help="SSH public key") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_linux_server_command( + ctx, + name, + linux_ip, + username, + password, + key, + devel + ): + """Set linux server access details""" + + # iserver set linux server + + ctx.developer = devel + ctx.output = 'default' + + try: + if name is None: + ctx.my_output.error('Define linux server entry name') + raise ErrorExit + + if linux_ip is None: + ctx.my_output.error('Define linux server ip address') + raise ErrorExit + + if username is None: + ctx.my_output.error('Define username') + raise ErrorExit + + if password is None and key is None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + if password is not None and key is not None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + linux_output_handler = linux_output.LinuxOutput(log_id=ctx.run_id) + settings_handler = settings.LinuxSettings(log_id=ctx.run_id) + + if not settings_handler.set_linux_server(name, linux_ip, username, password=password, key_filename=key): + ctx.my_output.error('Failed to set linux server entry') + raise ErrorExit + + servers = settings_handler.get_linux_servers() + linux_output_handler.print_linux_servers( + servers, + show_password=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/main.py b/menu/set/main.py new file mode 100644 index 00000000..bfb9a64d --- /dev/null +++ b/menu/set/main.py @@ -0,0 +1,40 @@ +import click + +from menu.set.aci.main import set_aci_menu +from menu.set.cvim.main import set_cvim_menu +from menu.set.k8s.main import set_k8s_menu +from menu.set.linux.main import set_linux_menu +from menu.set.nx.main import set_nx_menu +from menu.set.nso.main import set_nso_menu +from menu.set.ocp.main import set_ocp_menu +from menu.set.osp.main import set_osp_menu +from menu.set.psirt import set_psirt_command +from menu.set.redfish.main import set_redfish_menu +from menu.set.server.main import set_server_menu +from menu.set.ucsm.main import set_ucsm_menu +from menu.set.vc.main import set_vc_menu + + +class Failure(Exception): + pass + + +@click.group("set") +@click.pass_obj +def set_menu(ctx): + """Actions and Settings""" + + +set_menu.add_command(set_aci_menu) +set_menu.add_command(set_cvim_menu) +set_menu.add_command(set_k8s_menu) +set_menu.add_command(set_linux_menu) +set_menu.add_command(set_nx_menu) +set_menu.add_command(set_nso_menu) +set_menu.add_command(set_ocp_menu) +set_menu.add_command(set_osp_menu) +set_menu.add_command(set_psirt_command) +set_menu.add_command(set_redfish_menu) +set_menu.add_command(set_server_menu) +set_menu.add_command(set_ucsm_menu) +set_menu.add_command(set_vc_menu) diff --git a/menu/set/nso/__init__.py b/menu/set/nso/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/nso/__pycache__/__init__.cpython-310.pyc b/menu/set/nso/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c8714117 Binary files /dev/null and b/menu/set/nso/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/nso/__pycache__/controller.cpython-310.pyc b/menu/set/nso/__pycache__/controller.cpython-310.pyc new file mode 100644 index 00000000..94bb20eb Binary files /dev/null and b/menu/set/nso/__pycache__/controller.cpython-310.pyc differ diff --git a/menu/set/nso/__pycache__/main.cpython-310.pyc b/menu/set/nso/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..eee27291 Binary files /dev/null and b/menu/set/nso/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/nso/__pycache__/ncs.cpython-310.pyc b/menu/set/nso/__pycache__/ncs.cpython-310.pyc new file mode 100644 index 00000000..3b85b4f2 Binary files /dev/null and b/menu/set/nso/__pycache__/ncs.cpython-310.pyc differ diff --git a/menu/set/nso/main.py b/menu/set/nso/main.py new file mode 100644 index 00000000..43d98396 --- /dev/null +++ b/menu/set/nso/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.nso.ncs import set_nso_ncs_command + + +class Failure(Exception): + pass + + +@click.group("nso") +@click.pass_obj +def set_nso_menu(ctx): + """Set nso commands""" + + +set_nso_menu.add_command(set_nso_ncs_command) diff --git a/menu/set/nso/ncs.py b/menu/set/nso/ncs.py new file mode 100644 index 00000000..85fe3746 --- /dev/null +++ b/menu/set/nso/ncs.py @@ -0,0 +1,110 @@ +import sys +import traceback +import click + +from menu import common + +from lib.nso import settings +from lib.nso import main as nso + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ncs") +@click.pass_obj +@click.option("--name", "ncs_name", default='', help="NCS name") +@click.option("--ip", "ncs_ip", default='', help="NCS IP/FQDN") +@click.option("--username", "ncs_username", default='', help="NCS username") +@click.option("--password", "ncs_password", default='', help="NCS password") +@click.option("--port", "ncs_port", default=8080, help="NCS REST API Port") +@click.option("--nfvo", "nfvo_version", type=click.Choice(['none', '3.x', '4.x'], case_sensitive=False), default='none', show_default=True, help="NFVO Version") +@click.option("--protocol", "ncs_protocol", type=click.Choice(['http', 'https'], case_sensitive=False), default='http', show_default=True, help="Protocol") +@click.option("--restconf_disabled", is_flag=True, show_default=True, default=False, help="Restconf") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_nso_ncs_command( + ctx, + ncs_name, + ncs_ip, + ncs_username, + ncs_password, + ncs_port, + nfvo_version, + ncs_protocol, + restconf_disabled, + devel + ): + """Set nso ncs access details""" + + # iserver set nso ncs + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if len(ncs_name) == 0: + ctx.my_output.error('Define ncs entry name') + raise ErrorExit + + if len(ncs_ip) == 0: + ctx.my_output.error('Define ncs ip address') + raise ErrorExit + + if len(ncs_username) == 0: + ctx.my_output.error('Define ncs username') + raise ErrorExit + + if len(ncs_password) == 0: + ctx.my_output.error('Define ncs password') + raise ErrorExit + + if nfvo_version == 'none': + nfvo_version = None + + nso_handler = nso.Nso( + ncs_protocol, + ncs_ip, + ncs_port, + username=ncs_username, + password=ncs_password, + restconf_enabled=not restconf_disabled, + nfvo=nfvo_version, + log_id=ctx.run_id + ) + + if not nso_handler.is_connected(): + ctx.my_output.error('Failed to connect to NCS') + raise ErrorExit + + ctx.my_output.default('NCS authentication successful') + + settings_handler = settings.NsoSettings(log_id=ctx.run_id) + success = settings_handler.set_nso_ncs( + ncs_name, + ncs_protocol, + ncs_ip, + ncs_port, + ncs_username, + ncs_password, + not restconf_disabled, + nfvo_version + ) + if not success: + ctx.my_output.error('Failed to define ncs entry') + raise ErrorExit + + ctx.my_output.default('NCS entry created: %s' % (ncs_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/nx/__init__.py b/menu/set/nx/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/nx/device.py b/menu/set/nx/device.py new file mode 100644 index 00000000..9ad80fbe --- /dev/null +++ b/menu/set/nx/device.py @@ -0,0 +1,97 @@ +import sys +import traceback +import click + +from menu import common + +from lib.nexus import nxapi +from lib.nexus import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("device") +@click.pass_obj +@click.option("--name", "nexus_name", default='', help="Nexus device name") +@click.option("--ip", "nexus_ip", default='', help="Nexus device IP/FQDN") +@click.option("--username", "nexus_username", default='', help="Nexus device username") +@click.option("--password", "nexus_password", default='', help="Nexus device password") +@click.option("--domain", "nexus_domain", default='', help="Administrative domain") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_nx_device_command( + ctx, + nexus_name, + nexus_ip, + nexus_username, + nexus_password, + nexus_domain, + devel + ): + """Set nexus device access details""" + + # iserver set nx device + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if len(nexus_name) == 0: + ctx.my_output.error('Define nexus entry name') + raise ErrorExit + + if len(nexus_ip) == 0: + ctx.my_output.error('Define nexus ip address') + raise ErrorExit + + if len(nexus_username) == 0: + ctx.my_output.error('Define nexus username') + raise ErrorExit + + if len(nexus_password) == 0: + ctx.my_output.error('Define nexus password') + raise ErrorExit + + nexus_handler = nxapi.NxApi( + nexus_ip, + nexus_username, + nexus_password, + name=nexus_name, + log_id=ctx.run_id + ) + + nexus_handler.connect() + if nexus_handler.is_connected(): + ctx.my_output.default('Nexus device authentication successful') + else: + ctx.my_output.error('Failed to connect to Nexus device. Continue?') + if not common.get_confirmation(): + raise ErrorExit + + settings_handler = settings.NexusSettings(log_id=ctx.run_id) + success = settings_handler.set_nexus_device( + nexus_name, + nexus_ip, + nexus_username, + nexus_password, + domain=nexus_domain + ) + if not success: + ctx.my_output.error('Failed to define nexus entry') + raise ErrorExit + + ctx.my_output.default('Nexus device entry created: %s' % (nexus_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/nx/main.py b/menu/set/nx/main.py new file mode 100644 index 00000000..a3730e7d --- /dev/null +++ b/menu/set/nx/main.py @@ -0,0 +1,18 @@ +import click + +from menu.set.nx.device import set_nx_device_command +from menu.set.nx.ws import set_nx_ws_command + + +class Failure(Exception): + pass + + +@click.group("nx") +@click.pass_obj +def set_nx_menu(ctx): + """Set nexus commands""" + + +set_nx_menu.add_command(set_nx_device_command) +set_nx_menu.add_command(set_nx_ws_command) diff --git a/menu/set/nx/ws.py b/menu/set/nx/ws.py new file mode 100644 index 00000000..d51e3d59 --- /dev/null +++ b/menu/set/nx/ws.py @@ -0,0 +1,78 @@ +import sys +import traceback +import click + +from menu import common +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ws") +@click.pass_obj +@click.option("--switch", "switch", default='', callback=validations.validate_nexus_name, help="Switch name") +@click.option("--ip", "switch_ip", default='', callback=validations.validate_ip, help="Switch IP") +@click.option("--username", "switch_username", default='', help="Switch Username") +@click.option("--password", "switch_password", default='', help="Switch Password") +@click.option("--mo", "managed_objects", default=[], multiple=True, help="Managed objects") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug mode") +def set_nx_ws_command( + ctx, + switch, + switch_ip, + switch_username, + switch_password, + managed_objects, + debug + ): + """Set aci websocket""" + + # iserver set aci ws + + ctx.developer = False + common.flags_fixup(ctx, False, False, False) + + try: + if len(managed_objects) == 0: + ctx.my_output.error( + 'Define at least one managed object' + ) + ctx.my_output.default('Example:') + ctx.my_output.default('- /api/class/fvTenant') + ctx.my_output.default('- /api/node/class/faultInst') + ctx.my_output.default('- /api/node/class/faultDelegate') + raise ErrorExit + + nexus_handler = validations.validate_nexus_switch( + ctx, + switch, + switch_ip, + switch_username, + switch_password, + debug=debug + ) + if nexus_handler is None: + raise ErrorExit + + nexus_handler.ws_run( + managed_objects + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except KeyboardInterrupt: + ctx.busy = False + sys.exit(0) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/__init__.py b/menu/set/ocp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/ocp/__pycache__/__init__.cpython-310.pyc b/menu/set/ocp/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..63306a65 Binary files /dev/null and b/menu/set/ocp/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/ocp/__pycache__/kubeconfig.cpython-310.pyc b/menu/set/ocp/__pycache__/kubeconfig.cpython-310.pyc new file mode 100644 index 00000000..156bd27b Binary files /dev/null and b/menu/set/ocp/__pycache__/kubeconfig.cpython-310.pyc differ diff --git a/menu/set/ocp/__pycache__/main.cpython-310.pyc b/menu/set/ocp/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..965d486e Binary files /dev/null and b/menu/set/ocp/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/ocp/cluster/__init__.py b/menu/set/ocp/cluster/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/ocp/cluster/__pycache__/__init__.cpython-310.pyc b/menu/set/ocp/cluster/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..e58bbab2 Binary files /dev/null and b/menu/set/ocp/cluster/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/ocp/cluster/__pycache__/main.cpython-310.pyc b/menu/set/ocp/cluster/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..e3046c31 Binary files /dev/null and b/menu/set/ocp/cluster/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/ocp/cluster/__pycache__/nestedhv.cpython-310.pyc b/menu/set/ocp/cluster/__pycache__/nestedhv.cpython-310.pyc new file mode 100644 index 00000000..a598c3d5 Binary files /dev/null and b/menu/set/ocp/cluster/__pycache__/nestedhv.cpython-310.pyc differ diff --git a/menu/set/ocp/cluster/main.py b/menu/set/ocp/cluster/main.py new file mode 100644 index 00000000..af299916 --- /dev/null +++ b/menu/set/ocp/cluster/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.ocp.cluster.nestedhv import set_ocp_cluster_nestedhv + + +class Failure(Exception): + pass + + +@click.group("cluster") +@click.pass_obj +def set_ocp_cluster_menu(ctx): + """OCP Cluster Actions and Settings""" + + +set_ocp_cluster_menu.add_command(set_ocp_cluster_nestedhv) diff --git a/menu/set/ocp/cluster/nestedhv.py b/menu/set/ocp/cluster/nestedhv.py new file mode 100644 index 00000000..91cecda3 --- /dev/null +++ b/menu/set/ocp/cluster/nestedhv.py @@ -0,0 +1,64 @@ +import sys +import traceback +import click + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("nestedhv") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--disabled", is_flag=True, show_default=True, default=False, help="Disable nested hv") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_cluster_nestedhv( + ctx, + cluster_name, + disabled, + verbose, + debug, + devel + ): + """Set ocp cluster nestedhv""" + + # iserver set ocp cluster nestedhv + + ctx.developer = devel + + try: + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + worker_node_names = ocp_handler.get_worker_nodes_name() + if worker_node_names is None: + ctx.my_output.error('No worker nodes found') + raise ErrorExit + + for worker_node_name in worker_node_names: + ctx.my_output.default('Worker node: %s' % (worker_node_name), underline=True, before_newline=True) + if not ocp_handler.set_ocp_node_nestedhv(worker_node_name, enabled=not disabled): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/helm.py b/menu/set/ocp/helm.py new file mode 100644 index 00000000..f07eb1f2 --- /dev/null +++ b/menu/set/ocp/helm.py @@ -0,0 +1,94 @@ +import os +import sys +import traceback +import click + +from lib.ocp import settings + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("helm") +@click.pass_obj +@click.option("--cluster", "cluster_name", callback=validations.empty_string_to_none, help="OCP cluster name") +@click.option("--ip", "linux_ip", default='', callback=validations.empty_string_to_none, help="IP/FQDN") +@click.option("--username", default='', callback=validations.empty_string_to_none, help="Username") +@click.option("--password", default='', callback=validations.empty_string_to_none, help="Password") +@click.option("--key", default='', callback=validations.validate_optional_file, help="SSH public key") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_helm( + ctx, + cluster_name, + linux_ip, + username, + password, + key, + devel + ): + """Set ocp cluster helm""" + + # iserver set ocp helm + + ctx.developer = devel + + try: + settings_handler = settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None: + cluster_name = settings_handler.get_default_cluster() + if cluster_name is None: + ctx.my_output.error('Define OCP cluster name') + raise ErrorExit + + if linux_ip is None: + ctx.my_output.error('Define linux server ip address') + raise ErrorExit + + if username is None: + ctx.my_output.error('Define username') + raise ErrorExit + + if password is None and key is None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + if password is not None and key is not None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + cluster_settings = settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if cluster_settings is None: + ctx.my_output.error('Cluster not found') + raise ErrorExit + + cluster_settings['helm'] = {} + cluster_settings['helm']['ip'] = linux_ip + cluster_settings['helm']['username'] = username + cluster_settings['helm']['password'] = password + cluster_settings['helm']['key_filename'] = key + + success = settings_handler.set_ocp_cluster( + cluster_settings + ) + if not success: + ctx.my_output.error('Failed to update ocp cluster kubeconfig') + raise ErrorExit + + ctx.my_output.default('OCP cluster helm set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/kc.py b/menu/set/ocp/kc.py new file mode 100644 index 00000000..a3dc9b4d --- /dev/null +++ b/menu/set/ocp/kc.py @@ -0,0 +1,83 @@ +import os +import sys +import traceback +import click + +from lib.ocp import settings + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("kc") +@click.pass_obj +@click.option("--cluster", "cluster_name", callback=validations.empty_string_to_none, help="OCP cluster name") +@click.option("--file", "kubeconfig_filename", callback=validations.empty_string_to_none, help="Kubeconfig filename") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_kubeconfig( + ctx, + cluster_name, + kubeconfig_filename, + devel + ): + """Set ocp cluster kubeconfig""" + + # iserver set ocp kc + + ctx.developer = devel + + try: + settings_handler = settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None: + cluster_name = settings_handler.get_default_cluster() + if cluster_name is None: + ctx.my_output.error('Define OCP cluster name') + raise ErrorExit + + if kubeconfig_filename is None: + ctx.my_output.error('Define OCP kubeconfig filename') + raise ErrorExit + + if not os.path.isfile(kubeconfig_filename): + ctx.my_output.error('Kubeconfig file not found') + raise ErrorExit + + cluster_settings = settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if cluster_settings is None: + success = settings_handler.create_ocp_cluster( + cluster_name, + kubeconfig_filename + ) + if not success: + ctx.my_output.error('Failed to create ocp cluster kubeconfig') + raise ErrorExit + + ctx.my_output.default('OCP cluster kubeconfig created: %s' % (cluster_name)) + + else: + success = settings_handler.set_ocp_cluster_kubeconfig( + cluster_name, + kubeconfig_filename + ) + if not success: + ctx.my_output.error('Failed to update ocp cluster kubeconfig') + raise ErrorExit + + ctx.my_output.default('OCP cluster kubeconfig set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/main.py b/menu/set/ocp/main.py new file mode 100644 index 00000000..2bae9257 --- /dev/null +++ b/menu/set/ocp/main.py @@ -0,0 +1,30 @@ +import click + +from menu.set.ocp.cluster.main import set_ocp_cluster_menu +from menu.set.ocp.helm import set_ocp_helm +from menu.set.ocp.kc import set_ocp_kubeconfig +from menu.set.ocp.node.main import set_ocp_node_menu +from menu.set.ocp.ssh import set_ocp_ssh_command +from menu.set.ocp.tools import set_ocp_tools +from menu.set.ocp.virtctl import set_ocp_virtctl +from menu.set.ocp.vm.main import set_ocp_vm_menu + + +class Failure(Exception): + pass + + +@click.group("ocp") +@click.pass_obj +def set_ocp_menu(ctx): + """OCP Actions and Settings""" + + +set_ocp_menu.add_command(set_ocp_cluster_menu) +set_ocp_menu.add_command(set_ocp_helm) +set_ocp_menu.add_command(set_ocp_kubeconfig) +set_ocp_menu.add_command(set_ocp_node_menu) +set_ocp_menu.add_command(set_ocp_ssh_command) +set_ocp_menu.add_command(set_ocp_tools) +set_ocp_menu.add_command(set_ocp_virtctl) +set_ocp_menu.add_command(set_ocp_vm_menu) diff --git a/menu/set/ocp/node/__init__.py b/menu/set/ocp/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/ocp/node/__pycache__/__init__.cpython-310.pyc b/menu/set/ocp/node/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c569057c Binary files /dev/null and b/menu/set/ocp/node/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/ocp/node/__pycache__/down.cpython-310.pyc b/menu/set/ocp/node/__pycache__/down.cpython-310.pyc new file mode 100644 index 00000000..01358839 Binary files /dev/null and b/menu/set/ocp/node/__pycache__/down.cpython-310.pyc differ diff --git a/menu/set/ocp/node/__pycache__/main.cpython-310.pyc b/menu/set/ocp/node/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..42dea46e Binary files /dev/null and b/menu/set/ocp/node/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/ocp/node/__pycache__/nestedhv.cpython-310.pyc b/menu/set/ocp/node/__pycache__/nestedhv.cpython-310.pyc new file mode 100644 index 00000000..df20091c Binary files /dev/null and b/menu/set/ocp/node/__pycache__/nestedhv.cpython-310.pyc differ diff --git a/menu/set/ocp/node/__pycache__/restart.cpython-310.pyc b/menu/set/ocp/node/__pycache__/restart.cpython-310.pyc new file mode 100644 index 00000000..3f134ffc Binary files /dev/null and b/menu/set/ocp/node/__pycache__/restart.cpython-310.pyc differ diff --git a/menu/set/ocp/node/__pycache__/up.cpython-310.pyc b/menu/set/ocp/node/__pycache__/up.cpython-310.pyc new file mode 100644 index 00000000..368a39d1 Binary files /dev/null and b/menu/set/ocp/node/__pycache__/up.cpython-310.pyc differ diff --git a/menu/set/ocp/node/down.py b/menu/set/ocp/node/down.py new file mode 100644 index 00000000..87f82b2b --- /dev/null +++ b/menu/set/ocp/node/down.py @@ -0,0 +1,65 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("down") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--node", "node_name", default='', help="OCP cluster node name") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="No wait") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_node_down( + ctx, + cluster_name, + node_name, + no_wait, + verbose, + debug, + devel + ): + """Set ocp cluster node down""" + + # iserver set ocp node down + + ctx.developer = devel + + try: + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + if not validations.validate_ocp_node(ctx, ocp_handler, node_name): + raise ErrorExit + + if not ocp_handler.set_ocp_node_down(node_name, wait=not no_wait): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/node/main.py b/menu/set/ocp/node/main.py new file mode 100644 index 00000000..f937d49b --- /dev/null +++ b/menu/set/ocp/node/main.py @@ -0,0 +1,22 @@ +import click + +from menu.set.ocp.node.down import set_ocp_node_down +from menu.set.ocp.node.nestedhv import set_ocp_node_nestedhv +from menu.set.ocp.node.restart import set_ocp_node_restart +from menu.set.ocp.node.up import set_ocp_node_up + + +class Failure(Exception): + pass + + +@click.group("node") +@click.pass_obj +def set_ocp_node_menu(ctx): + """OCP Node Actions and Settings""" + + +set_ocp_node_menu.add_command(set_ocp_node_down) +set_ocp_node_menu.add_command(set_ocp_node_nestedhv) +set_ocp_node_menu.add_command(set_ocp_node_restart) +set_ocp_node_menu.add_command(set_ocp_node_up) diff --git a/menu/set/ocp/node/nestedhv.py b/menu/set/ocp/node/nestedhv.py new file mode 100644 index 00000000..884a793f --- /dev/null +++ b/menu/set/ocp/node/nestedhv.py @@ -0,0 +1,62 @@ +import sys +import traceback +import click + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("nestedhv") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--node", "node_name", default='', help="OCP cluster node name") +@click.option("--disabled", is_flag=True, show_default=True, default=False, help="Disable nested hv") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_node_nestedhv( + ctx, + cluster_name, + node_name, + disabled, + verbose, + debug, + devel + ): + """Set ocp cluster node nestedhv""" + + # iserver set ocp node nestedhv + + ctx.developer = devel + + try: + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + if not validations.validate_ocp_node(ctx, ocp_handler, node_name): + raise ErrorExit + + if not ocp_handler.set_ocp_node_nestedhv(node_name, enabled=not disabled): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/node/restart.py b/menu/set/ocp/node/restart.py new file mode 100644 index 00000000..3abaa80c --- /dev/null +++ b/menu/set/ocp/node/restart.py @@ -0,0 +1,66 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("restart") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--node", "node_name", default='', help="OCP cluster node name") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_node_restart( + ctx, + cluster_name, + node_name, + verbose, + debug, + devel + ): + """Set ocp cluster node restart""" + + # iserver set ocp node restart + + ctx.developer = devel + + try: + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + if not validations.validate_ocp_node(ctx, ocp_handler, node_name): + raise ErrorExit + + if not ocp_handler.set_ocp_node_down(node_name, wait=True): + raise ErrorExit + + if not ocp_handler.set_ocp_node_up(node_name, wait=True): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/node/up.py b/menu/set/ocp/node/up.py new file mode 100644 index 00000000..d59fd925 --- /dev/null +++ b/menu/set/ocp/node/up.py @@ -0,0 +1,65 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("up") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--node", "node_name", default='', help="OCP cluster node name") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="No wait") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_node_up( + ctx, + cluster_name, + node_name, + no_wait, + verbose, + debug, + devel + ): + """Set ocp cluster node up""" + + # iserver set ocp node up + + ctx.developer = devel + + try: + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + if not validations.validate_ocp_node(ctx, ocp_handler, node_name): + raise ErrorExit + + if not ocp_handler.set_ocp_node_up(node_name, wait=not no_wait): + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/ssh.py b/menu/set/ocp/ssh.py new file mode 100644 index 00000000..78685b21 --- /dev/null +++ b/menu/set/ocp/ssh.py @@ -0,0 +1,114 @@ +import sys +import traceback +import click + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("ssh") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="Filter by cluster name") +@click.option("--role", "node_role", type=click.Choice(['any', 'master', 'worker'], case_sensitive=False), default='any', show_default=True) +@click.option("--action", type=click.Choice(['add', 'del'], case_sensitive=False)) +@click.option("--file", "filename", default='', callback=validations.validate_optional_file, help="SSH public key to be added") +@click.option("--key", default='', help="SSH public key search pattern to be removed") +@click.option("--no-wait", "no_wait", is_flag=True, show_default=True, default=False, help="No-wait for mcp update") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_ssh_command( + ctx, + cluster_name, + node_role, + action, + filename, + key, + no_wait, + devel + ): + """Set ocp ssh authorized keys""" + + # iserver set ocp ssh + + ctx.developer = devel + ctx.output = 'default' + + try: + if action is None or action not in ['add', 'del']: + ctx.my_output.error('--action add|del required') + raise ErrorExit + + if action == 'add': + if filename is None: + ctx.my_output.error('Filename with ssh public key required') + raise ErrorExit + + if action == 'del': + if len(key) == 0: + ctx.my_output.error('SSH public key search pattern required') + raise ErrorExit + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name + ) + if ocp_handler is None: + raise ErrorExit + + ctx.my_output.default('Checking machine config pools...') + machine_config_pools = ocp_handler.k8s_handler.get_machine_config_pools() + + if not ocp_handler.k8s_handler.is_machine_config_pools_ready(machine_config_pools=machine_config_pools): + ctx.my_output.error('Machine config pools are not ready for new configuration') + raise ErrorExit + + ctx.my_output.default('Machine config pools ready for new configuration') + + if action == 'add': + machine_configs = ocp_handler.add_ocp_ssh_authorized_key( + filename, + node_role + ) + + if action == 'del': + machine_configs = ocp_handler.delete_ocp_ssh_authorized_key( + key, + node_role + ) + + if machine_configs is None: + ctx.my_output.error( + 'Failed to set ssh authorized key' + ) + raise ErrorExit + + if len(machine_configs) == 0: + ctx.my_output.default('Completed (no change)') + + if len(machine_configs) > 0: + ctx.my_output.default('Completed with machine configs modified') + for machine_config in machine_configs: + ctx.my_output.default('- %s' % (machine_config)) + + if no_wait: + return + + if not ocp_handler.k8s_handler.wait_machine_config_pool_update(machine_config_pools, machine_configs, output_handler=ctx.my_output): + raise ErrorExit + + ctx.my_output.default('Completed') + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/tools.py b/menu/set/ocp/tools.py new file mode 100644 index 00000000..9b5be297 --- /dev/null +++ b/menu/set/ocp/tools.py @@ -0,0 +1,94 @@ +import os +import sys +import traceback +import click + +from lib.ocp import settings + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("tools") +@click.pass_obj +@click.option("--cluster", "cluster_name", callback=validations.empty_string_to_none, help="OCP cluster name") +@click.option("--ip", "linux_ip", default='', callback=validations.empty_string_to_none, help="IP/FQDN") +@click.option("--username", default='', callback=validations.empty_string_to_none, help="Username") +@click.option("--password", default='', callback=validations.empty_string_to_none, help="Password") +@click.option("--key", default='', callback=validations.validate_optional_file, help="SSH public key") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_tools( + ctx, + cluster_name, + linux_ip, + username, + password, + key, + devel + ): + """Set ocp cluster tools""" + + # iserver set ocp tools + + ctx.developer = devel + + try: + settings_handler = settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None: + cluster_name = settings_handler.get_default_cluster() + if cluster_name is None: + ctx.my_output.error('Define OCP cluster name') + raise ErrorExit + + if linux_ip is None: + ctx.my_output.error('Define linux server ip address') + raise ErrorExit + + if username is None: + ctx.my_output.error('Define username') + raise ErrorExit + + if password is None and key is None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + if password is not None and key is not None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + cluster_settings = settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if cluster_settings is None: + ctx.my_output.error('Cluster not found') + raise ErrorExit + + cluster_settings['tools'] = {} + cluster_settings['tools']['ip'] = linux_ip + cluster_settings['tools']['username'] = username + cluster_settings['tools']['password'] = password + cluster_settings['tools']['key_filename'] = key + + success = settings_handler.set_ocp_cluster( + cluster_settings + ) + if not success: + ctx.my_output.error('Failed to update ocp cluster kubeconfig') + raise ErrorExit + + ctx.my_output.default('OCP cluster tools set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/virtctl.py b/menu/set/ocp/virtctl.py new file mode 100644 index 00000000..2762f7e6 --- /dev/null +++ b/menu/set/ocp/virtctl.py @@ -0,0 +1,94 @@ +import os +import sys +import traceback +import click + +from lib.ocp import settings + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("virtctl") +@click.pass_obj +@click.option("--cluster", "cluster_name", callback=validations.empty_string_to_none, help="OCP cluster name") +@click.option("--ip", "linux_ip", default='', callback=validations.empty_string_to_none, help="IP/FQDN") +@click.option("--username", default='', callback=validations.empty_string_to_none, help="Username") +@click.option("--password", default='', callback=validations.empty_string_to_none, help="Password") +@click.option("--key", default='', callback=validations.validate_optional_file, help="SSH public key") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_virtctl( + ctx, + cluster_name, + linux_ip, + username, + password, + key, + devel + ): + """Set ocp cluster virtctl""" + + # iserver set ocp virtctl + + ctx.developer = devel + + try: + settings_handler = settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None: + cluster_name = settings_handler.get_default_cluster() + if cluster_name is None: + ctx.my_output.error('Define OCP cluster name') + raise ErrorExit + + if linux_ip is None: + ctx.my_output.error('Define linux server ip address') + raise ErrorExit + + if username is None: + ctx.my_output.error('Define username') + raise ErrorExit + + if password is None and key is None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + if password is not None and key is not None: + ctx.my_output.error('Define password or public key') + raise ErrorExit + + cluster_settings = settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if cluster_settings is None: + ctx.my_output.error('Cluster not found') + raise ErrorExit + + cluster_settings['virtctl'] = {} + cluster_settings['virtctl']['ip'] = linux_ip + cluster_settings['virtctl']['username'] = username + cluster_settings['virtctl']['password'] = password + cluster_settings['virtctl']['key_filename'] = key + + success = settings_handler.set_ocp_cluster( + cluster_settings + ) + if not success: + ctx.my_output.error('Failed to update ocp cluster kubeconfig') + raise ErrorExit + + ctx.my_output.default('OCP cluster virtctl set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/vm/__init__.py b/menu/set/ocp/vm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/ocp/vm/__pycache__/__init__.cpython-310.pyc b/menu/set/ocp/vm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c569057c Binary files /dev/null and b/menu/set/ocp/vm/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/ocp/vm/__pycache__/down.cpython-310.pyc b/menu/set/ocp/vm/__pycache__/down.cpython-310.pyc new file mode 100644 index 00000000..56dfd00e Binary files /dev/null and b/menu/set/ocp/vm/__pycache__/down.cpython-310.pyc differ diff --git a/menu/set/ocp/vm/__pycache__/main.cpython-310.pyc b/menu/set/ocp/vm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..a8df9283 Binary files /dev/null and b/menu/set/ocp/vm/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/ocp/vm/__pycache__/nestedhv.cpython-310.pyc b/menu/set/ocp/vm/__pycache__/nestedhv.cpython-310.pyc new file mode 100644 index 00000000..df20091c Binary files /dev/null and b/menu/set/ocp/vm/__pycache__/nestedhv.cpython-310.pyc differ diff --git a/menu/set/ocp/vm/__pycache__/restart.cpython-310.pyc b/menu/set/ocp/vm/__pycache__/restart.cpython-310.pyc new file mode 100644 index 00000000..4631385a Binary files /dev/null and b/menu/set/ocp/vm/__pycache__/restart.cpython-310.pyc differ diff --git a/menu/set/ocp/vm/__pycache__/up.cpython-310.pyc b/menu/set/ocp/vm/__pycache__/up.cpython-310.pyc new file mode 100644 index 00000000..c542a716 Binary files /dev/null and b/menu/set/ocp/vm/__pycache__/up.cpython-310.pyc differ diff --git a/menu/set/ocp/vm/down.py b/menu/set/ocp/vm/down.py new file mode 100644 index 00000000..9903ad60 --- /dev/null +++ b/menu/set/ocp/vm/down.py @@ -0,0 +1,93 @@ +import sys +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("down") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--name", "vm_name", default='', help="Virtual machine name") +@click.option("--namespace", is_flag=False, show_default=False, default='', type=click.STRING, help="Namespace") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="No wait") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_vm_down( + ctx, + cluster_name, + vm_name, + namespace, + no_wait, + verbose, + debug, + devel + ): + """Set ocp cluster vm down""" + + # iserver set ocp vm down + + ctx.developer = devel + + try: + if len(vm_name) == 0: + ctx.my_output.error('Define VM name') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + namespace = validations.validate_ocp_vm_namespace( + ctx, + ocp_handler, + namespace, + vm_name + ) + if namespace is None: + raise ErrorExit + + if not ocp_handler.is_ocp_vmi_mo(namespace, vm_name): + ctx.my_output.default('Virtual machine already down') + return + + ctx.my_output.default('Stop virtual machine...') + if not ocp_handler.stop_ocp_vm(namespace, vm_name): + ctx.my_output.error('Virtual machine stop failed') + raise ErrorExit + + ctx.my_output.default('Virtual machine stopped') + + if not no_wait: + ctx.my_output.default('Wait for virtual machine stopped...') + if not ocp_handler.wait_ocp_vm_stopped(namespace, vm_name): + ctx.my_output.error('Timed out') + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/vm/main.py b/menu/set/ocp/vm/main.py new file mode 100644 index 00000000..21fefcc7 --- /dev/null +++ b/menu/set/ocp/vm/main.py @@ -0,0 +1,20 @@ +import click + +from menu.set.ocp.vm.down import set_ocp_vm_down +from menu.set.ocp.vm.restart import set_ocp_vm_restart +from menu.set.ocp.vm.up import set_ocp_vm_up + + +class Failure(Exception): + pass + + +@click.group("vm") +@click.pass_obj +def set_ocp_vm_menu(ctx): + """OCP Virtual Machine Actions and Settings""" + + +set_ocp_vm_menu.add_command(set_ocp_vm_down) +set_ocp_vm_menu.add_command(set_ocp_vm_restart) +set_ocp_vm_menu.add_command(set_ocp_vm_up) diff --git a/menu/set/ocp/vm/restart.py b/menu/set/ocp/vm/restart.py new file mode 100644 index 00000000..a92c6f60 --- /dev/null +++ b/menu/set/ocp/vm/restart.py @@ -0,0 +1,100 @@ +import sys +import time +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("restart") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--name", "vm_name", default='', help="Virtual machine name") +@click.option("--namespace", is_flag=False, show_default=False, default='', type=click.STRING, help="Namespace") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="No wait") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_vm_restart( + ctx, + cluster_name, + vm_name, + namespace, + no_wait, + verbose, + debug, + devel + ): + """Set ocp cluster vm restart""" + + # iserver set ocp vm restart + + ctx.developer = devel + + try: + if len(vm_name) == 0: + ctx.my_output.error('Define VM name') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + namespace = validations.validate_ocp_vm_namespace( + ctx, + ocp_handler, + namespace, + vm_name + ) + if namespace is None: + raise ErrorExit + + if not ocp_handler.is_ocp_vmi_mo(namespace, vm_name): + ctx.my_output.default('Starting virtual machine...') + if not ocp_handler.start_ocp_vm(namespace, vm_name): + ctx.my_output.error('Virtual machine start failed') + raise ErrorExit + + ctx.my_output.default('Virtual machine started') + + else: + ctx.my_output.default('Restarting virtual machine...') + if not ocp_handler.restart_ocp_vm(namespace, vm_name): + ctx.my_output.error('Virtual machine start failed') + raise ErrorExit + + ctx.my_output.default('Virtual machine restarted') + + if not no_wait: + ctx.my_output.default('Wait for virtual machine running...') + time.sleep(15) + if not ocp_handler.wait_ocp_vm_running(namespace, vm_name): + ctx.my_output.error('Timed out') + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ocp/vm/up.py b/menu/set/ocp/vm/up.py new file mode 100644 index 00000000..e224b916 --- /dev/null +++ b/menu/set/ocp/vm/up.py @@ -0,0 +1,94 @@ +import sys +import json +import threading +import traceback +import click + +from menu import validations +from menu import progress + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("up") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', help="OCP cluster name") +@click.option("--name", "vm_name", default='', help="Virtual machine name") +@click.option("--namespace", is_flag=False, show_default=False, default='', type=click.STRING, help="Namespace") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="No wait") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ocp_vm_up( + ctx, + cluster_name, + vm_name, + namespace, + no_wait, + verbose, + debug, + devel + ): + """Set ocp cluster vm up""" + + # iserver set ocp vm up + + ctx.developer = devel + + try: + if len(vm_name) == 0: + ctx.my_output.error('Define VM name') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + ocp_handler = validations.validate_ocp_cluster( + ctx, + cluster_name, + verbose=verbose, + debug=debug + ) + if ocp_handler is None: + raise ErrorExit + + namespace = validations.validate_ocp_vm_namespace( + ctx, + ocp_handler, + namespace, + vm_name + ) + if namespace is None: + raise ErrorExit + + if ocp_handler.is_ocp_vmi_mo(namespace, vm_name): + ctx.my_output.default('Virtual machine already up') + return + + ctx.my_output.default('Starting virtual machine...') + if not ocp_handler.start_ocp_vm(namespace, vm_name): + ctx.my_output.error('Virtual machine start failed') + raise ErrorExit + + ctx.my_output.default('Virtual machine started') + + if not no_wait: + ctx.my_output.default('Wait for virtual machine running...') + if not ocp_handler.wait_ocp_vm_running(namespace, vm_name): + ctx.my_output.error('Timed out') + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/osp/__init__.py b/menu/set/osp/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/osp/main.py b/menu/set/osp/main.py new file mode 100644 index 00000000..4be8fb1f --- /dev/null +++ b/menu/set/osp/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.osp.openrc import set_osp_openrc + + +class Failure(Exception): + pass + + +@click.group("osp") +@click.pass_obj +def set_osp_menu(ctx): + """Openstack actions and settings""" + + +set_osp_menu.add_command(set_osp_openrc) diff --git a/menu/set/osp/openrc.py b/menu/set/osp/openrc.py new file mode 100644 index 00000000..e9051976 --- /dev/null +++ b/menu/set/osp/openrc.py @@ -0,0 +1,88 @@ +import os +import sys +import traceback +import click + +from lib.osp import settings + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("openrc") +@click.pass_obj +@click.option("--cluster", "cluster_name", default='', callback=validations.empty_string_to_none, help="K8s cluster name") +@click.option("--file", "openrc_filename", default='', callback=validations.empty_string_to_none, help="Kubeconfig filename") +@click.option("--cert", "cert_filename", default='', callback=validations.empty_string_to_none, help="Certificate filename") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_osp_openrc( + ctx, + cluster_name, + openrc_filename, + cert_filename, + devel + ): + """Set openstack cluster openrc""" + + # iserver set osp openrc + + ctx.developer = devel + + try: + if cluster_name is None: + ctx.my_output.error('Define openstack cluster name') + raise ErrorExit + + if openrc_filename is None: + ctx.my_output.error('Define openrc filename') + raise ErrorExit + + if not os.path.isfile(openrc_filename): + ctx.my_output.error('Openrc file not found') + raise ErrorExit + + if cert_filename is not None: + if not os.path.isfile(cert_filename): + ctx.my_output.error('Certificate file not found') + raise ErrorExit + + settings_handler = settings.OspSettings(log_id=ctx.run_id) + + cluster = settings_handler.get_openstack_cluster( + cluster_name + ) + + if cluster is not None: + if cluster['source'] != 'user': + ctx.my_output.error( + 'Cluster %s cannot be modified' % (cluster_name) + ) + raise ErrorExit + + success = settings_handler.set_openstack_cluster( + cluster_name, + openrc_filename, + cluster_type='standard', + cert_filename=cert_filename + ) + if not success: + ctx.my_output.error('Failed to set openstack cluster') + raise ErrorExit + + ctx.my_output.default('Openstack cluster set: %s' % (cluster_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/psirt.py b/menu/set/psirt.py new file mode 100644 index 00000000..2e3c5a2e --- /dev/null +++ b/menu/set/psirt.py @@ -0,0 +1,93 @@ +import sys +import traceback +import click + +from lib.psirt import settings +from lib.psirt import output as psirt_output + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("psirt") +@click.pass_obj +@click.option("--key", default='', callback=validations.empty_string_to_none, help="API key") +@click.option("--secret", default='', callback=validations.empty_string_to_none, help="API secret") +@click.option("--cache", default='', callback=validations.empty_string_to_none, help="Cache on|off") +@click.option("--ttl", default=0, type=click.INT, help="Cache TTL") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_psirt_command( + ctx, + key, + secret, + cache, + ttl, + devel + ): + """Set psirt api settings""" + + # iserver set psirt + + ctx.developer = devel + + try: + settings_handler = settings.PsirtSettings(log_id=ctx.run_id) + + if key is not None and secret is not None: + success = settings_handler.set_psirt_credentials( + key, + secret + ) + if not success: + ctx.my_output.error('Failed to set psirt api') + raise ErrorExit + ctx.my_output.default('Psirt api access configured') + + if cache.lower() == 'on': + success = settings_handler.set_cache_on() + if not success: + ctx.my_output.error('Failed to enable cache') + raise ErrorExit + ctx.my_output.default('Cache enabled') + + if cache.lower() == 'off': + success = settings_handler.set_cache_off() + if not success: + ctx.my_output.error('Failed to disable cache') + raise ErrorExit + ctx.my_output.default('Cache disabled') + + if ttl > 0: + success = settings_handler.set_cache_ttl(ttl) + if not success: + ctx.my_output.error('Failed to set cache ttl') + raise ErrorExit + ctx.my_output.default('Cache ttl set') + + psirt_settings = settings_handler.get_psirt_settings() + if psirt_settings is None: + ctx.my_output.error('Failed to get psirt api settings') + raise ErrorExit + + output_handler = psirt_output.PsirtOutput(log_id=ctx.run_id) + + output_handler.print_psirt_settings( + psirt_settings, + show_password=False + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/redfish/__init__.py b/menu/set/redfish/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/redfish/__pycache__/__init__.cpython-310.pyc b/menu/set/redfish/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d976fb8d Binary files /dev/null and b/menu/set/redfish/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/adhoc.cpython-310.pyc b/menu/set/redfish/__pycache__/adhoc.cpython-310.pyc new file mode 100644 index 00000000..639c2ba0 Binary files /dev/null and b/menu/set/redfish/__pycache__/adhoc.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/cache.cpython-310.pyc b/menu/set/redfish/__pycache__/cache.cpython-310.pyc new file mode 100644 index 00000000..1a7d5a3a Binary files /dev/null and b/menu/set/redfish/__pycache__/cache.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/configuration.cpython-310.pyc b/menu/set/redfish/__pycache__/configuration.cpython-310.pyc new file mode 100644 index 00000000..85969d77 Binary files /dev/null and b/menu/set/redfish/__pycache__/configuration.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/endpoint.cpython-310.pyc b/menu/set/redfish/__pycache__/endpoint.cpython-310.pyc new file mode 100644 index 00000000..1bb4a35c Binary files /dev/null and b/menu/set/redfish/__pycache__/endpoint.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/fi.cpython-310.pyc b/menu/set/redfish/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..757016ee Binary files /dev/null and b/menu/set/redfish/__pycache__/fi.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/main.cpython-310.pyc b/menu/set/redfish/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..eae2f850 Binary files /dev/null and b/menu/set/redfish/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/server.cpython-310.pyc b/menu/set/redfish/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..d9272452 Binary files /dev/null and b/menu/set/redfish/__pycache__/server.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/servers.cpython-310.pyc b/menu/set/redfish/__pycache__/servers.cpython-310.pyc new file mode 100644 index 00000000..80c83e90 Binary files /dev/null and b/menu/set/redfish/__pycache__/servers.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/settings.cpython-310.pyc b/menu/set/redfish/__pycache__/settings.cpython-310.pyc new file mode 100644 index 00000000..97615799 Binary files /dev/null and b/menu/set/redfish/__pycache__/settings.cpython-310.pyc differ diff --git a/menu/set/redfish/__pycache__/ucsc.cpython-310.pyc b/menu/set/redfish/__pycache__/ucsc.cpython-310.pyc new file mode 100644 index 00000000..fc22bd90 Binary files /dev/null and b/menu/set/redfish/__pycache__/ucsc.cpython-310.pyc differ diff --git a/menu/set/redfish/access/__init__.py b/menu/set/redfish/access/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/redfish/access/__pycache__/__init__.cpython-310.pyc b/menu/set/redfish/access/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..db51647a Binary files /dev/null and b/menu/set/redfish/access/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/redfish/access/__pycache__/fi.cpython-310.pyc b/menu/set/redfish/access/__pycache__/fi.cpython-310.pyc new file mode 100644 index 00000000..72acfcfc Binary files /dev/null and b/menu/set/redfish/access/__pycache__/fi.cpython-310.pyc differ diff --git a/menu/set/redfish/access/__pycache__/main.cpython-310.pyc b/menu/set/redfish/access/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..c2845778 Binary files /dev/null and b/menu/set/redfish/access/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/redfish/access/__pycache__/server.cpython-310.pyc b/menu/set/redfish/access/__pycache__/server.cpython-310.pyc new file mode 100644 index 00000000..7edecbd1 Binary files /dev/null and b/menu/set/redfish/access/__pycache__/server.cpython-310.pyc differ diff --git a/menu/set/redfish/access/__pycache__/servers.cpython-310.pyc b/menu/set/redfish/access/__pycache__/servers.cpython-310.pyc new file mode 100644 index 00000000..4bbb2385 Binary files /dev/null and b/menu/set/redfish/access/__pycache__/servers.cpython-310.pyc differ diff --git a/menu/set/redfish/access/fi.py b/menu/set/redfish/access/fi.py new file mode 100644 index 00000000..89c8a3af --- /dev/null +++ b/menu/set/redfish/access/fi.py @@ -0,0 +1,197 @@ +import sys +import threading +import traceback +import click + +from progress.bar import Bar + +from lib.redfish import endpoint +from lib.redfish import endpoint_settings + +from menu import common +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("fi") +@click.pass_obj +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Fabric Interconnect IP") +@click.option("--port", "endpoint_port", default=443, help="Redfish port") +@click.option("--username", default='', help="Redfish username") +@click.option("--password", default='', help="Redfish password") +@click.option("--ssl_verify", is_flag=True, default=False, help="SSL verify") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_redfish_access_fi_command( + ctx, + endpoint_ip, + endpoint_port, + username, + password, + ssl_verify, + devel + ): + """Set redfish access for FI-Attached systems""" + + # iserver set redfish endpoint + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + endpoint_type = 'fi' + try: + if endpoint_ip == '': + ctx.my_output.error('Define endpoint IP address') + raise ErrorExit + + if username == '': + ctx.my_output.error('Define Redfish access username') + raise ErrorExit + + if password == '': + ctx.my_output.error('Define Redfish access password') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + redfish_handler = endpoint.RedfishEndpoint( + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + get_timeout=30, + ssl_verify=ssl_verify, + log_id=ctx.run_id, + verbose=False, + debug=False + ) + + if not redfish_handler.is_connected(): + ctx.busy = False + ctx.my_output.error( + 'Redfish access failed' + ) + raise ErrorExit + + ctx.busy = False + + ctx.my_output.default('\nRedfish authentication successful') + + redfish_handler.endpoint_handler.set_inventory( + '', + '' + ) + inventory = redfish_handler.endpoint_handler.get_inventory() + if inventory is None: + ctx.my_output.error('Failed to get fabric interconnect inventory') + raise ErrorExit + + redfish_handler.endpoint_handler.print_inventory(inventory) + ctx.my_output.default('') + if not common.get_confirmation(): + return + + failed = [] + + bar_handler = Bar('Chassis', max=len(inventory['chassis'])) + bar_handler.goto(0) + for item in inventory['chassis']: + redfish_handler.endpoint_handler.set_inventory( + 'Chassis', + item['Iom1'] + ) + + identity = redfish_handler.endpoint_handler.get_template_identity_chassis_properties() + if identity is None: + failed.append( + dict( + type='Chassis', + serial=item['Serial'] + ) + ) + bar_handler.next() + continue + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + success = endpoint_settings_handler.set_redfish_endpoint_settings( + redfish_handler.endpoint_handler.get_endpoint_configuration(), + identity + ) + if not success: + failed.append( + dict( + type='Chassis', + serial=item['Serial'] + ) + ) + + bar_handler.next() + + bar_handler.finish() + + bar_handler = Bar('Server', max=len(inventory['servers'])) + bar_handler.goto(0) + for item in inventory['servers']: + redfish_handler.endpoint_handler.set_inventory( + 'Server', + item['Name'] + ) + + identity = redfish_handler.endpoint_handler.get_template_identity_server_properties() + if identity is None: + failed.append( + dict( + type='Server', + serial=item['Serial'] + ) + ) + bar_handler.next() + continue + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + success = endpoint_settings_handler.set_redfish_endpoint_settings( + redfish_handler.endpoint_handler.get_endpoint_configuration(), + identity + ) + if not success: + failed.append( + dict( + type='Server', + serial=item['Serial'] + ) + ) + + bar_handler.next() + + bar_handler.finish() + + if len(failed) == 0: + ctx.my_output.default('All FI-attached redfish endpoints settings saved') + return + + ctx.my_output.default('') + ctx.my_output.error('Not all FI-attached redfish endpoints settings saved') + for item in failed: + ctx.my_output.default('- Inventory Type [%s] Serial [%s]' % (item['type'], item['serial'])) + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/redfish/access/main.py b/menu/set/redfish/access/main.py new file mode 100644 index 00000000..4f777de7 --- /dev/null +++ b/menu/set/redfish/access/main.py @@ -0,0 +1,18 @@ +import click + +from menu.set.redfish.access.fi import set_redfish_access_fi_command +from menu.set.redfish.access.server import set_redfish_access_server_command + + +class Failure(Exception): + pass + + +@click.group("access") +@click.pass_obj +def set_redfish_access_menu(ctx): + """Set redfish access commands""" + + +set_redfish_access_menu.add_command(set_redfish_access_fi_command) +set_redfish_access_menu.add_command(set_redfish_access_server_command) diff --git a/menu/set/redfish/access/server.py b/menu/set/redfish/access/server.py new file mode 100644 index 00000000..b8aaaa48 --- /dev/null +++ b/menu/set/redfish/access/server.py @@ -0,0 +1,226 @@ +import sys +import threading +import traceback +import click + +from progress.bar import Bar + +from lib.intersight import compute +from lib.redfish import endpoint +from lib.redfish import endpoint_settings + +from menu import defaults +from menu import common +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("server") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", default='', callback=validations.validate_filter_ip, help="Management IP address or subnet filter") +@click.option("--group", default='', callback=validations.validate_group_serials, help="Group name") +@click.option("--name", "name_filter", default='', help="Name loose match filter") +@click.option("--serial", "serial_filter", default='', callback=validations.validate_filter_serials, help="Serial strict match filter") +@click.option("--model", "model_filter", default='', help="Model loose match filter") +@click.option("--type", "endpoint_type", type=click.Choice(['ucsc', 'dell', 'hpe'], case_sensitive=False), default='ucsc', help="Redfish endpoint type") +@click.option("--redfish-ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Redfish endpoint IP address") +@click.option("--port", "endpoint_port", default=443, help="Redfish management TCP port") +@click.option("--username", default='', help="Redfish username") +@click.option("--password", default='', help="Redfish password") +@click.option("--ssl_verify", is_flag=True, default=False, help="SSL verify") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_redfish_access_server_command( + ctx, + iaccount, + ip_filter, + group, + name_filter, + serial_filter, + model_filter, + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + ssl_verify, + devel + ): + """Set redfish access for standalone servers""" + + # iserver set redfish servers + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if username == '': + ctx.my_output.error('Define Redfish access username') + raise ErrorExit + + if password == '': + ctx.my_output.error('Define Redfish access password') + raise ErrorExit + + if len(endpoint_ip) > 0: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + redfish_handler = endpoint.RedfishEndpoint( + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + get_timeout=30, + ssl_verify=ssl_verify, + log_id=ctx.run_id + ) + + if not redfish_handler.is_connected(): + ctx.busy = False + ctx.my_output.error('Redfish authentication failed') + raise ErrorExit + + identity = redfish_handler.endpoint_handler.get_template_identity_properties() + if identity is None: + ctx.busy = False + ctx.my_output.error('Failed to get server identity information') + raise ErrorExit + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + success = endpoint_settings_handler.set_redfish_endpoint_settings( + redfish_handler.endpoint_handler.get_endpoint_configuration(), + identity + ) + if not success: + ctx.busy = False + ctx.my_output.error('Failed to save server information locally') + raise ErrorExit + + ctx.busy = False + ctx.my_output.default('Redfish endpoints settings verified and saved') + + if len(endpoint_ip) == 0: + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + match_rules = compute_handler.get_mo_match_rules( + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serial_filter + group + ) + all_servers_mo = compute_handler.get_mo( + match_rules=match_rules, + include_rack=True, + include_blade=False + ) + + servers_mo = [] + for server_mo in all_servers_mo: + if server_mo['ManagementMode'] == 'IntersightStandalone': + servers_mo.append( + server_mo + ) + + ctx.busy = False + if servers_mo is None or len(servers_mo) == 0: + ctx.my_output.error('No servers found') + raise ErrorExit + + bar_handler = Bar('Rack servers in Intersight Standalone Management Mode', max=len(servers_mo)) + failed = [] + bar_handler.goto(0) + for item in servers_mo: + if item['ManagementIp'] is None: + failed.append( + dict( + name=item['Name'], + reason='No management IP' + ) + ) + bar_handler.next() + continue + + redfish_handler = endpoint.RedfishEndpoint( + endpoint_type, + item['ManagementIp'], + endpoint_port, + username, + password, + get_timeout=30, + ssl_verify=ssl_verify, + log_id=ctx.run_id + ) + + if not redfish_handler.is_connected(): + failed.append( + dict( + name=item['Name'], + reason='Redfish authentication failed' + ) + ) + bar_handler.next() + continue + + identity = redfish_handler.endpoint_handler.get_template_identity_properties() + if identity is None: + failed.append( + dict( + name=item['Name'], + reason='Failed to get redfish server identity' + ) + ) + bar_handler.next() + continue + + endpoint_settings_handler = endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + success = endpoint_settings_handler.set_redfish_endpoint_settings( + redfish_handler.endpoint_handler.get_endpoint_configuration(), + identity + ) + if not success: + failed.append( + dict( + name=item['Name'], + reason='Failed to save endpoint configuration' + ) + ) + bar_handler.next() + continue + + bar_handler.next() + + bar_handler.finish() + + if len(failed) == 0: + ctx.my_output.default('All redfish endpoints settings saved and access verified') + return + + ctx.my_output.error('Not all redfish endpoints settings saved') + for failure in failed: + ctx.my_output.default('- %s: %s' % (failure['name'], failure['reason'])) + + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/redfish/cache.py b/menu/set/redfish/cache.py new file mode 100644 index 00000000..a9a24897 --- /dev/null +++ b/menu/set/redfish/cache.py @@ -0,0 +1,160 @@ +import sys +import threading +import traceback +import click + +from lib.redfish import endpoint + +from menu import common +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cache") +@click.pass_obj +@click.option("--name", "custom_cache_name", default='', help="Cache entry name") +@click.option("--type", "endpoint_type", type=click.Choice(['standard', 'ucsc', 'fi', 'dell', 'hpe'], case_sensitive=False), default='standard', help="Redfish endpoint type") +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Redfish management IP") +@click.option("--port", "endpoint_port", default=443, help="Redfish management TCP port") +@click.option("--username", default='', help="Redfish username") +@click.option("--password", default='', help="Redfish password") +@click.option("--ssl_verify", is_flag=True, default=False, help="SSL verify") +@click.option("--inventory-type", default='', help="FI Inventory Type") +@click.option("--inventory-id", default='', help="FI Inventory Id") +@click.option("--exclusions", is_flag=True, show_default=True, default=False, help="No uri exclusions in deep search") +@click.option("--max", "tree_max_execution_time", is_flag=False, type=click.INT, default=0, help="Max execution time in seconds") +@click.option("--timeout", "get_timeout", is_flag=False, show_default=True, default=120, type=click.INT, help="Get uri timeout") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_redfish_cache_command( + ctx, + custom_cache_name, + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + ssl_verify, + inventory_type, + inventory_id, + exclusions, + tree_max_execution_time, + get_timeout, + devel + ): + """Cache redfish endpoint resources""" + + # iserver set redfish cache + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if endpoint_ip == '': + ctx.my_output.error('Define endpoint IP address') + raise ErrorExit + + if username == '': + ctx.my_output.error('Define Redfish access username') + raise ErrorExit + + if password == '': + ctx.my_output.error('Define Redfish access password') + raise ErrorExit + + if endpoint_type == 'fi': + if inventory_type == '': + ctx.my_output.error('Define FI inventory Type') + raise ErrorExit + + if inventory_id == '': + ctx.my_output.error('Define FI inentory ID') + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx,)).start() + + redfish_handler = endpoint.RedfishEndpoint( + endpoint_type, + endpoint_ip, + endpoint_port, + username, + password, + get_timeout=get_timeout, + ssl_verify=ssl_verify, + deep_search_exlusions=exclusions, + tree_max_execution_time=tree_max_execution_time, + log_id=ctx.run_id, + verbose=False, + debug=False + ) + + if not redfish_handler.is_connected(): + ctx.busy = False + ctx.my_output.error( + 'Redfish access failed' + ) + raise ErrorExit + + # --type fi + inventory = None + if endpoint_type == 'fi': + redfish_handler.endpoint_handler.set_inventory( + inventory_type, + inventory_id + ) + + endpoint_identity = redfish_handler.endpoint_handler.get_template_identity_properties() + endpoint_identity['EndpointType'] = endpoint_type + endpoint_identity['EndpointIp'] = endpoint_ip + endpoint_identity['EndpointInventoryType'] = inventory_type + endpoint_identity['EndpointInventoryId'] = inventory_id + + endpoint_resources = redfish_handler.get_tree( + '/' + ) + + extra_resources = None + if endpoint_type == 'fi': + if inventory_type == 'Server': + extra_resources = {} + extra_resources['Chassis'] = redfish_handler.endpoint_handler.get_chassis() + extra_resources['Servers'] = redfish_handler.endpoint_handler.get_servers() + extra_resources['Inventory'] = redfish_handler.endpoint_handler.get_inventory() + extra_resources['Power'] = redfish_handler.endpoint_handler.get_server_chassis_properties() + + ctx.busy = False + + cache_name = redfish_handler.set_redfish_cache_endpoint( + endpoint_identity, + endpoint_resources, + extra_resources=extra_resources, + custom_cache_name=custom_cache_name + ) + + if cache_name is None: + ctx.my_output.error('Cache set failed') + raise ErrorExit + + ctx.my_output.default( + 'Cache set successful: %s in file %s' % ( + cache_name, + endpoint_identity['CacheFileName'] + ) + ) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/redfish/main.py b/menu/set/redfish/main.py new file mode 100644 index 00000000..583bb1bc --- /dev/null +++ b/menu/set/redfish/main.py @@ -0,0 +1,24 @@ +import click + +from menu.set.redfish.settings import set_redfish_settings_command +from menu.set.redfish.cache import set_redfish_cache_command +from menu.set.redfish.access.main import set_redfish_access_menu +from menu.set.redfish.user import set_redfish_user_command +from menu.set.redfish.users import set_redfish_users_command + + +class Failure(Exception): + pass + + +@click.group("redfish") +@click.pass_obj +def set_redfish_menu(ctx): + """Set redfish commands""" + + +set_redfish_menu.add_command(set_redfish_settings_command) +set_redfish_menu.add_command(set_redfish_cache_command) +set_redfish_menu.add_command(set_redfish_access_menu) +set_redfish_menu.add_command(set_redfish_user_command) +set_redfish_menu.add_command(set_redfish_users_command) diff --git a/menu/set/redfish/settings.py b/menu/set/redfish/settings.py new file mode 100644 index 00000000..4b3ccd9c --- /dev/null +++ b/menu/set/redfish/settings.py @@ -0,0 +1,65 @@ +import os +import sys +import traceback +import click + +from lib.redfish import settings +from lib.redfish import output as redfish_output + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("settings") +@click.pass_obj +@click.option("--cache-enable", is_flag=True, show_default=True, default=False, help="Enable cache") +@click.option("--cache-disable", is_flag=True, show_default=True, default=False, help="Disable cache") +@click.option("--cache-dir", "cache_directory", is_flag=False, show_default=False, default='', type=click.STRING, help="Cache directory") +def set_redfish_settings_command(ctx, cache_directory, cache_enable, cache_disable): + """Set redfish settings""" + + # iserver get redfish settings + + try: + output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + settings_handler = settings.RedfishSettings() + + redfish_settings = settings_handler.get_redfish_settings() + if redfish_settings is None: + ctx.my_output.error('Settings get failed') + raise ErrorExit + + if len(cache_directory) > 0: + if not os.path.isabs(cache_directory): + ctx.my_output.error('Cache directory must be absolute path') + raise ErrorExit + + redfish_settings['CacheDirectory'] = cache_directory + if not os.path.isdir(cache_directory): + os.makedirs(cache_directory, exist_ok=True) + ctx.my_output.default('Cache directory created: %s' % (cache_directory)) + + if cache_enable: + redfish_settings['CacheEnabled'] = True + + if cache_disable: + redfish_settings['CacheEnabled'] = False + + if not settings_handler.set_redfish_settings(redfish_settings): + ctx.my_output.error('Settings set failed') + raise ErrorExit + + redfish_settings = settings_handler.get_redfish_settings() + output_handler.print_redfish_settings(redfish_settings) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/redfish/user.py b/menu/set/redfish/user.py new file mode 100644 index 00000000..3c9e0cb2 --- /dev/null +++ b/menu/set/redfish/user.py @@ -0,0 +1,120 @@ +import sys +import threading +import traceback +import click + +from lib.imc import endpoint as imc_endpoint +from lib.redfish import endpoint as redfish_endpoint +from lib.redfish import output as redfish_output + +from menu import progress +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("user") +@click.pass_obj +@click.option("--ip", "endpoint_ip", default='', callback=validations.validate_ip, help="Management IP address") +@click.option("--admin", "admin_password", default='', help="Admin password") +@click.option("--username", default='', help="Username") +@click.option("--password", default='', help="Password") +@click.option("--role", type=click.Choice(['admin', 'user', 'readonly'], case_sensitive=False), default='readonly', help="Role") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_redfish_user_command(ctx, endpoint_ip, admin_password, username, password, role, devel): + """Set redfish user accounts""" + + ctx.developer = devel + + try: + if len(admin_password) == 0: + ctx.my_output.error( + 'Define admin password' + ) + raise ErrorExit + + if len(username) == 0: + ctx.my_output.error( + 'Define username' + ) + raise ErrorExit + + if len(password) == 0: + ctx.my_output.error( + 'Define password' + ) + raise ErrorExit + + if len(password) > 20: + ctx.my_output.error( + 'Define password with maximum length of 20 characters' + ) + raise ErrorExit + + redfish_output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + endpoint_ip, + 443, + 'admin', + admin_password, + get_timeout=120, + auto_connect=True, + ssl_verify=False, + log_id=ctx.run_id + ) + + account = redfish_handler.endpoint_handler.get_account_by_username(username, cache_enabled=False) + if account is None: + ctx.my_output.error( + 'Username %s is not defined' % (username) + ) + raise ErrorExit + + ctx.busy = True + threading.Thread(target=progress.spinner_task, args=(ctx, False,)).start() + + imc_handler = imc_endpoint.ImcEndpoint( + endpoint_ip, + 22, + 'admin', + admin_password, + log_id=ctx.run_id + ) + + success = imc_handler.set_user( + account['id'], + password, + role + ) + if not success: + ctx.my_output.error( + 'User set failed' + ) + raise ErrorExit + + ctx.busy = False + + ctx.my_output.default( + 'User settings updated' + ) + + account = redfish_handler.endpoint_handler.get_account_by_username(username, cache_enabled=False) + redfish_output_handler.print_ucsc_properties( + 'account', + [account], + title=False + ) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/redfish/users.py b/menu/set/redfish/users.py new file mode 100644 index 00000000..0ea21ad0 --- /dev/null +++ b/menu/set/redfish/users.py @@ -0,0 +1,823 @@ +import sys +import copy +import traceback +import click + +from progress.bar import IncrementalBar + +from lib import file_helper +from lib import filter_helper +from lib.imc import endpoint as imc_endpoint +from lib.redfish import endpoint as redfish_endpoint +from lib.redfish import endpoint_settings as redfish_endpoint_settings +from lib.redfish import output as redfish_output +from lib.intersight.lcm import tag as lcm_server_tag +from lib.intersight import validations as intersight_validations + +from menu import defaults +from menu import common +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("users") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--ip", "ip_filter", multiple=True, help="Select by IP or subnet") +@click.option("--name", "name_filter", multiple=True, callback=intersight_validations.name_filter, help="Select by name") +@click.option("--serial", "serial_filter", multiple=True, callback=intersight_validations.serial_filter, help="Select by serial") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Group name") +@click.option("--file", "input_filename", is_flag=False, show_default=False, default='', type=click.STRING, help="Accounts Definition JSON") +@click.option("--verify", is_flag=True, show_default=True, default=False, help="Verify") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_redfish_users_command( + ctx, + iaccount, + group_filter, + serial_filter, + name_filter, + ip_filter, + input_filename, + verify, + devel + ): + """Set redfish users accounts (batch)""" + + ctx.developer = devel + + try: + redfish_output_handler = redfish_output.RedfishOutput(log_id=ctx.run_id) + content = file_helper.get_file_json(input_filename) + if content is None: + ctx.my_output.error( + 'Failed to read the file: %s' % (input_filename) + ) + raise ErrorExit + + ctx.my_output.default('Select target servers...') + + all_servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=intersight_validations.add_group_filter(serial_filter, group_filter), + include_rack=True, + include_blade=False, + show_progress=False + ) + if all_servers_mo is None or len(all_servers_mo) == 0: + ctx.my_output.error( + 'No servers matching search criteria' + ) + raise ErrorExit + + selected_servers_mo = [] + for server_mo in all_servers_mo: + exclude_server = False + + for exclude_tag in content['exclude']['tag']: + for server_tag in server_mo['Tags']: + if server_tag['Key'] == exclude_tag.split(':')[0]: + if server_tag['Value'] == exclude_tag.split(':')[1]: + exclude_server = True + + for exclude_name in content['exclude']['name']: + if filter_helper.match_string(exclude_name, server_mo['Name']): + exclude_server = True + + if not exclude_server: + selected_servers_mo.append( + server_mo + ) + + if len(selected_servers_mo) == 0: + ctx.my_output.error( + 'No servers matching search criteria' + ) + raise ErrorExit + + common.print_servers_mo_info( + ctx, + iaccount, + selected_servers_mo, + show_progress=True, + cache=False + ) + + if not common.get_confirmation(): + return + + if verify: + verified_mo = [] + + bar_handler = IncrementalBar('Verify users', max=len(selected_servers_mo)) + bar_handler.goto(0) + for server_mo in selected_servers_mo: + verified = True + accounts = [] + + if content['create_accounts']: + for account in content['account']: + accounts.append(account) + + if content['new_admin_password'] is None: + admin_account = {} + admin_account['username'] = content['admin_username'] + admin_account['password'] = content['admin_account'] + accounts.append(admin_account) + + if content['new_admin_password'] is not None: + admin_account = {} + admin_account['username'] = content['admin_username'] + admin_account['password'] = content['new_admin_password'] + accounts.append(admin_account) + + for account in accounts: + ctx.my_output.default( + 'Verify user %s on %s' % ( + account['username'], + server_mo['ManagementIp'] + ) + ) + + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + account['username'], + account['password'], + get_timeout=30, + auto_connect=True, + ssl_verify=False, + log_id=ctx.run_id + ) + + if not redfish_handler.is_connected(): + verified = False + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + + if not verified: + break + + if verified: + verified_mo.append( + server_mo + ) + + bar_handler.next() + + bar_handler.finish() + + if len(verified_mo) == 0: + ctx.my_output.default( + 'No servers verified' + ) + return + + common.print_servers_mo_info( + ctx, + iaccount, + verified_mo, + show_progress=True, + cache=False + ) + + if content['tag'] is not None: + if not common.get_confirmation(): + return + + ctx.my_output.default( + 'Update server tags in Intersight' + ) + + lcm_server_tag_handler = lcm_server_tag.LcmServerTag( + iaccount, + dry_run=False, + wait=True, + silent=False, + verbose=False, + debug=False, + log_id=ctx.run_id + ) + if not lcm_server_tag_handler.add(verified_mo, [content['tag']]): + raise ErrorExit + + return + + failed_servers_mo = [] + + for server_mo in selected_servers_mo: + servers_mo = [server_mo] + common.print_servers_mo_info( + ctx, + iaccount, + servers_mo, + show_progress=True, + cache=False, + title=False + ) + + if len(content['admin_passwords']) == 1: + server_admin_password = content['admin_passwords'][0] + else: + server_admin_password = None + + ctx.my_output.default('Verify current admin password...') + imc_handler = imc_endpoint.ImcEndpoint( + server_mo['ManagementIp'], + 22, + content['admin_username'], + content['admin_passwords'][0], + log_id=ctx.run_id + ) + version = imc_handler.get_version() + del imc_handler + + if version is not None: + server_admin_password = content['admin_passwords'][0] + ctx.my_output.default('Current admin password: %s' % (server_admin_password)) + + if version is None: + imc_handler = imc_endpoint.ImcEndpoint( + server_mo['ManagementIp'], + 22, + content['admin_username'], + content['admin_passwords'][1], + log_id=ctx.run_id + ) + version = imc_handler.get_version() + del imc_handler + + if version is not None: + server_admin_password = content['admin_passwords'][1] + ctx.my_output.default('Current admin password: %s' % (server_admin_password)) + + if server_admin_password is None: + ctx.my_output.error( + 'Admin password verification failed' + ) + failed_servers_mo.append(server_mo) + continue + + ctx.my_output.default('Enable redfish access...') + imc_handler = imc_endpoint.ImcEndpoint( + server_mo['ManagementIp'], + 22, + content['admin_username'], + server_admin_password, + log_id=ctx.run_id + ) + success = imc_handler.enable_redfish() + del imc_handler + + if not success: + ctx.my_output.error( + 'Failed to enable redfish on %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + ctx.my_output.default('Verify admin access via RedFish...') + if server_mo['ManagementIp'] is None: + ctx.my_output.error( + 'No management IP of server %s' % ( + server_mo['Moid'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=120, + auto_connect=True, + ssl_verify=False, + log_id=ctx.run_id + ) + account = redfish_handler.endpoint_handler.get_account_by_username(content['admin_username'], cache_enabled=False) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + + if account is None: + ctx.my_output.error( + 'Failed to get username %s from %s' % ( + content['admin_username'], + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + ctx.my_output.default('Update RedFish access settings...') + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + identity = redfish_handler.endpoint_handler.get_template_identity_properties() + + if identity is None: + ctx.my_output.error( + 'Failed to collect identity from %s' % ( + server_mo['ManagementIp'] + ) + ) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + failed_servers_mo.append(server_mo) + continue + + endpoint_settings_handler = redfish_endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + success = endpoint_settings_handler.set_redfish_endpoint_settings( + redfish_handler.endpoint_handler.get_endpoint_configuration(), + identity + ) + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del endpoint_settings_handler + + if not success: + ctx.my_output.error( + 'Failed to save endpoint identity from %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + if content['delete_non_admin_role']: + ctx.my_output.default('Delete non-admin role users') + + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + + imc_handler = imc_endpoint.ImcEndpoint( + server_mo['ManagementIp'], + 22, + content['admin_username'], + server_admin_password, + log_id=ctx.run_id + ) + + allowed_usernames = [] + for account in content['account']: + allowed_usernames.append( + account['username'] + ) + + usernames = redfish_handler.endpoint_handler.get_non_admin_role_usernames(allowed_usernames=allowed_usernames) + if usernames is None: + ctx.my_output.error( + 'Failed to get accounts from %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + if len(usernames) == 0: + ctx.my_output.default( + 'No non-admin users found' + ) + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + + if len(usernames) > 0: + user_delete_success = True + for username in usernames: + account = redfish_handler.endpoint_handler.get_account_by_username(username, cache_enabled=False) + if account is None: + ctx.my_output.error( + 'Failed to get account %s from %s' % ( + username, + server_mo['ManagementIp'] + ) + ) + user_delete_success = False + break + + success = imc_handler.delete_user( + account['id'] + ) + if not success: + ctx.my_output.error( + 'Failed to delete account %s from %s' % ( + username, + server_mo['ManagementIp'] + ) + ) + user_delete_success = False + break + + ctx.my_output.default( + 'User %s deleted' % (username) + ) + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + + if not user_delete_success: + failed_servers_mo.append(server_mo) + continue + + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + accounts = redfish_handler.endpoint_handler.get_template_properties('account', cache_enabled=False) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + + if accounts is None: + ctx.my_output.error( + 'Failed to get existing accounts from server: %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + redfish_output_handler.print_ucsc_properties( + 'account', + accounts, + title=False + ) + + if content['create_accounts']: + ctx.my_output.default('Create users') + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + + imc_handler = imc_endpoint.ImcEndpoint( + server_mo['ManagementIp'], + 22, + content['admin_username'], + server_admin_password, + log_id=ctx.run_id + ) + + ctx.my_output.default('Get unused account ids') + account_ids = redfish_handler.endpoint_handler.get_account_empty_ids(cache_enabled=False) + if account_ids is None: + ctx.my_output.error( + 'Failed to get empty account ids on server %s' % ( + server_mo['ManagementIp'] + ) + ) + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + failed_servers_mo.append(server_mo) + continue + + if len(account_ids) < len(content['account']): + ctx.my_output.error( + 'Failed to get enough account ids on server %s' % ( + server_mo['ManagementIp'] + ) + ) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + failed_servers_mo.append(server_mo) + continue + + index = 0 + create_user_success = True + for account in content['account']: + ctx.my_output.default('Create: %s' % (account)) + if redfish_handler.endpoint_handler.is_account_username(account['username']): + ctx.my_output.error( + 'Username %s is already defined on server %s' % ( + account['username'], + server_mo['ManagementIp'] + ) + ) + create_user_success = False + break + + if 'id' in account: + account_id = account['id'] + else: + account_id = account_ids[index] + + success = imc_handler.add_user( + account_id, + account['username'], + account['password'], + account['role'] + ) + if not success: + ctx.my_output.error( + 'Failed to create new account on server %s' % ( + server_mo['ManagementIp'] + ) + ) + create_user_success = False + break + + ctx.my_output.default( + 'User %s with id %s created on %s' % ( + account['username'], + account_id, + server_mo['ManagementIp'] + ) + ) + + index = index + 1 + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + + if not create_user_success: + failed_servers_mo.append(server_mo) + continue + + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + accounts = redfish_handler.endpoint_handler.get_template_properties('account', cache_enabled=False) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + + if accounts is None: + ctx.my_output.error( + 'Failed to get existing accounts from server: %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + continue + + redfish_output_handler.print_ucsc_properties( + 'account', + accounts, + title=False + ) + + if content['new_admin_password'] is not None and content['new_admin_password'] != server_admin_password: + ctx.my_output.default('Change admin password') + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + server_admin_password, + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + + imc_handler = imc_endpoint.ImcEndpoint( + server_mo['ManagementIp'], + 22, + content['admin_username'], + server_admin_password, + log_id=ctx.run_id + ) + + account = redfish_handler.endpoint_handler.get_account_by_username(content['admin_username'], cache_enabled=False) + if account is None: + ctx.my_output.error( + 'Failed to get admin account %s on server %s' % ( + content['admin_username'], + server_mo['ManagementIp'] + ) + ) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + failed_servers_mo.append(server_mo) + continue + + success = imc_handler.set_user( + account['id'], + content['new_admin_password'], + 'admin' + ) + if not success: + ctx.my_output.error( + 'Failed to set admin account %s password on server %s' % ( + content['admin_username'], + server_mo['ManagementIp'] + ) + ) + del redfish_handler + del imc_handler + failed_servers_mo.append(server_mo) + continue + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + del imc_handler + + ctx.my_output.default('Update RedFish access settings') + accounts = copy.deepcopy(content['account']) + if content['new_admin_password'] is not None: + admin_account = {} + admin_account['username'] = content['admin_username'] + admin_account['password'] = content['new_admin_password'] + admin_account['username'] = 'admin' + accounts.append(admin_account) + + users_verified = True + for account in accounts: + ctx.my_output.default( + 'Verify user %s on %s' % ( + account['username'], + server_mo['ManagementIp'] + ) + ) + + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + account['username'], + account['password'], + get_timeout=30, + auto_connect=True, + ssl_verify=False, + log_id=ctx.run_id + ) + + if not redfish_handler.is_connected(): + ctx.my_output.error( + 'Username %s not working on server %s' % ( + account['username'], + server_mo['ManagementIp'] + ) + ) + users_verified = False + break + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + + if not users_verified: + failed_servers_mo.append(server_mo) + continue + + if content['new_admin_password'] is not None and content['new_admin_password'] != server_admin_password: + ctx.my_output.default('Update RedFish access settings with new admin password') + redfish_handler = redfish_endpoint.RedfishEndpoint( + 'ucsc', + server_mo['ManagementIp'], + 443, + content['admin_username'], + content['new_admin_password'], + get_timeout=30, + ssl_verify=False, + log_id=ctx.run_id + ) + identity = redfish_handler.endpoint_handler.get_template_identity_properties() + + if identity is None: + ctx.my_output.error( + 'Failed to collect identity from %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + continue + + endpoint_settings_handler = redfish_endpoint_settings.RedfishEndpointSettings( + log_id=ctx.run_id + ) + success = endpoint_settings_handler.set_redfish_endpoint_settings( + redfish_handler.endpoint_handler.get_endpoint_configuration(), + identity + ) + if not success: + ctx.my_output.error( + 'Failed to save endpoint identity from %s' % ( + server_mo['ManagementIp'] + ) + ) + failed_servers_mo.append(server_mo) + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + continue + + redfish_handler.endpoint_handler.disconnect() + del redfish_handler + + if content['tag_success'] is not None: + ctx.my_output.default( + 'Update server tags in Intersight' + ) + + lcm_server_tag_handler = lcm_server_tag.LcmServerTag( + iaccount, + dry_run=False, + wait=True, + silent=False, + verbose=False, + debug=False, + log_id=ctx.run_id + ) + if not lcm_server_tag_handler.add([server_mo], [content['tag_success']]): + ctx.my_output.error( + 'Server tag failed' + ) + + if len(failed_servers_mo) > 0: + ctx.my_output.default( + 'Setting failed servers tag' + ) + for failed_server_mo in failed_servers_mo: + ctx.my_output.default( + '- %s' % (failed_server_mo['Name']) + ) + + lcm_server_tag_handler = lcm_server_tag.LcmServerTag( + iaccount, + dry_run=False, + wait=True, + silent=False, + verbose=False, + debug=False, + log_id=ctx.run_id + ) + if not lcm_server_tag_handler.add(failed_servers_mo, [content['tag_failure']]): + ctx.my_output.error( + 'Server tag failed' + ) + + common.print_servers_info( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=new_serial_filter, + include_rack=True, + include_blade=False, + show_progress=False + ) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/__init__.py b/menu/set/server/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/server/__pycache__/__init__.cpython-310.pyc b/menu/set/server/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..7611f7b2 Binary files /dev/null and b/menu/set/server/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/server/__pycache__/main.cpython-310.pyc b/menu/set/server/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..86ffeabc Binary files /dev/null and b/menu/set/server/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/server/__pycache__/os_image.cpython-310.pyc b/menu/set/server/__pycache__/os_image.cpython-310.pyc new file mode 100644 index 00000000..ebae5dba Binary files /dev/null and b/menu/set/server/__pycache__/os_image.cpython-310.pyc differ diff --git a/menu/set/server/__pycache__/scu.cpython-310.pyc b/menu/set/server/__pycache__/scu.cpython-310.pyc new file mode 100644 index 00000000..4c87a8e5 Binary files /dev/null and b/menu/set/server/__pycache__/scu.cpython-310.pyc differ diff --git a/menu/set/server/locator/__init__.py b/menu/set/server/locator/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/server/locator/__pycache__/__init__.cpython-310.pyc b/menu/set/server/locator/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..807e97c6 Binary files /dev/null and b/menu/set/server/locator/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/server/locator/__pycache__/main.cpython-310.pyc b/menu/set/server/locator/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..01b179cc Binary files /dev/null and b/menu/set/server/locator/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/server/locator/__pycache__/off.cpython-310.pyc b/menu/set/server/locator/__pycache__/off.cpython-310.pyc new file mode 100644 index 00000000..e8f42944 Binary files /dev/null and b/menu/set/server/locator/__pycache__/off.cpython-310.pyc differ diff --git a/menu/set/server/locator/__pycache__/on.cpython-310.pyc b/menu/set/server/locator/__pycache__/on.cpython-310.pyc new file mode 100644 index 00000000..45a7f018 Binary files /dev/null and b/menu/set/server/locator/__pycache__/on.cpython-310.pyc differ diff --git a/menu/set/server/locator/main.py b/menu/set/server/locator/main.py new file mode 100644 index 00000000..a2ac7f1c --- /dev/null +++ b/menu/set/server/locator/main.py @@ -0,0 +1,18 @@ +import click + +from menu.set.server.locator.on import set_server_locator_on_command +from menu.set.server.locator.off import set_server_locator_off_command + + +class Failure(Exception): + pass + + +@click.group("locator") +@click.pass_obj +def set_server_locator_menu(ctx): + """Set server locator commands""" + + +set_server_locator_menu.add_command(set_server_locator_on_command) +set_server_locator_menu.add_command(set_server_locator_off_command) diff --git a/menu/set/server/locator/off.py b/menu/set/server/locator/off.py new file mode 100644 index 00000000..06568cf8 --- /dev/null +++ b/menu/set/server/locator/off.py @@ -0,0 +1,144 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import locator as lcm_server_locator + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("off") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_locator_off_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Locator off""" + + # iserver set server locator off + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True, + rack_expand=['LocatorLed'], + blade_expand=['LocatorLed'] + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_locator_handler = lcm_server_locator.LcmServerLocator( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_locator_handler.locator_off(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/locator/on.py b/menu/set/server/locator/on.py new file mode 100644 index 00000000..45e8a4bf --- /dev/null +++ b/menu/set/server/locator/on.py @@ -0,0 +1,144 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import locator as lcm_server_locator + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("on") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_locator_on_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Locator on""" + + # iserver set server locator on + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True, + rack_expand=['LocatorLed'], + blade_expand=['LocatorLed'] + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_locator_handler = lcm_server_locator.LcmServerLocator( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_locator_handler.locator_on(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/main.py b/menu/set/server/main.py new file mode 100644 index 00000000..7d05f789 --- /dev/null +++ b/menu/set/server/main.py @@ -0,0 +1,24 @@ +import click + +from menu.set.server.locator.main import set_server_locator_menu +from menu.set.server.os_image import set_server_os_image_command +from menu.set.server.power.main import set_server_power_menu +from menu.set.server.scu import set_server_scu_command +from menu.set.server.tag import set_server_tag_command + + +class Failure(Exception): + pass + + +@click.group("server") +@click.pass_obj +def set_server_menu(ctx): + """Set server commands""" + + +set_server_menu.add_command(set_server_locator_menu) +set_server_menu.add_command(set_server_os_image_command) +set_server_menu.add_command(set_server_power_menu) +set_server_menu.add_command(set_server_scu_command) +set_server_menu.add_command(set_server_tag_command) diff --git a/menu/set/server/os_image.py b/menu/set/server/os_image.py new file mode 100644 index 00000000..0c50159d --- /dev/null +++ b/menu/set/server/os_image.py @@ -0,0 +1,126 @@ +import sys +import traceback +import click + +from progress.bar import Bar + +from lib.intersight import os_image + +from menu import user_inputs +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("os-image") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--file", "filename", is_flag=False, show_default=False, default='', type=click.STRING, help="Input yaml file") +@click.option("--id", "moid", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Id") +@click.option("--name", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Name") +@click.option("--vendor", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Vendor") +@click.option("--version", is_flag=False, show_default=False, default='', type=click.STRING, help="OS Version") +@click.option("--link", is_flag=False, show_default=False, default='', type=click.STRING, help="OS HTTP Link") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_os_image_command(ctx, filename, iaccount, moid, name, vendor, version, link, interactive, devel): + """Set os image objects from input yaml file""" + + # iwectl set server os-image + + ctx.developer = devel + + try: + image_handler = os_image.OsImage(iaccount, log_id=ctx.run_id) + + if len(filename) > 0: + ctx.my_output.default('Input file verification...') + images = validations.validate_yaml_file(ctx, filename) + if images is None: + raise ErrorExit + + if len(filename) == 0: + if len(moid) == 0: + interactive = True + + if interactive: + items = image_handler.get_all() + image_handler.print(items) + + moid = user_inputs.get_value(ctx, 'Image ID') + + ctx.my_output.default('Parameters to be modified (leave empty for no change)') + name = user_inputs.get_value(ctx, 'Image name', empty=True) + vendor = user_inputs.get_os_image_vendor(ctx, iaccount, empty=True) + if len(vendor) == 0: + for item in items: + if item['Moid'] == moid: + vendor = item['Vendor'] + + if len(vendor) == 0: + ctx.my_output.error('Image vendor not found: %s' % (moid)) + raise ErrorExit + + version = user_inputs.get_os_image_version(ctx, iaccount, vendor, empty=True) + if len(version) == 0: + for item in items: + if item['Moid'] == moid: + version = item['Version'] + + if len(version) == 0: + ctx.my_output.error('Image versions not found: %s' % (moid)) + raise ErrorExit + + link = user_inputs.get_value(ctx, 'Link', empty=True) + + images = [] + item = {} + item['Moid'] = moid + item['Name'] = name + item['Vendor'] = vendor + item['Version'] = version + item['Link'] = link + item['Type'] = 'url' + images.append(item) + + ctx.my_output.default('Input parameters verification...') + + success, reason = image_handler.validate_set(images) + if not success: + ctx.my_output.error('Input parameters validation failed') + ctx.my_output.default(reason) + raise ErrorExit + + ctx.my_output.default('Input parameters verified') + + bar_handler = Bar('Progress', max=len(images)) + bar_handler.goto(0) + failed = [] + for item in images: + if not image_handler.update(item['Moid'], item): + failed.append(item['Moid']) + bar_handler.next() + bar_handler.finish() + + if len(failed) > 0: + ctx.my_output.error('Some updates failed') + for item in failed: + ctx.my_output.default('- %s' % (item)) + raise ErrorExit + + images = image_handler.get_all() + image_handler.print(images) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/power/__init__.py b/menu/set/server/power/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/server/power/__pycache__/__init__.cpython-310.pyc b/menu/set/server/power/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c771f2ba Binary files /dev/null and b/menu/set/server/power/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/cycle.cpython-310.pyc b/menu/set/server/power/__pycache__/cycle.cpython-310.pyc new file mode 100644 index 00000000..bdd1771f Binary files /dev/null and b/menu/set/server/power/__pycache__/cycle.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/hard.cpython-310.pyc b/menu/set/server/power/__pycache__/hard.cpython-310.pyc new file mode 100644 index 00000000..644fc876 Binary files /dev/null and b/menu/set/server/power/__pycache__/hard.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/main.cpython-310.pyc b/menu/set/server/power/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..f99b3a34 Binary files /dev/null and b/menu/set/server/power/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/off.cpython-310.pyc b/menu/set/server/power/__pycache__/off.cpython-310.pyc new file mode 100644 index 00000000..a5ebcf36 Binary files /dev/null and b/menu/set/server/power/__pycache__/off.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/on.cpython-310.pyc b/menu/set/server/power/__pycache__/on.cpython-310.pyc new file mode 100644 index 00000000..b8100a2e Binary files /dev/null and b/menu/set/server/power/__pycache__/on.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/reboot.cpython-310.pyc b/menu/set/server/power/__pycache__/reboot.cpython-310.pyc new file mode 100644 index 00000000..526159f2 Binary files /dev/null and b/menu/set/server/power/__pycache__/reboot.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/restart.cpython-310.pyc b/menu/set/server/power/__pycache__/restart.cpython-310.pyc new file mode 100644 index 00000000..042a74b0 Binary files /dev/null and b/menu/set/server/power/__pycache__/restart.cpython-310.pyc differ diff --git a/menu/set/server/power/__pycache__/shut.cpython-310.pyc b/menu/set/server/power/__pycache__/shut.cpython-310.pyc new file mode 100644 index 00000000..89614390 Binary files /dev/null and b/menu/set/server/power/__pycache__/shut.cpython-310.pyc differ diff --git a/menu/set/server/power/cycle.py b/menu/set/server/power/cycle.py new file mode 100644 index 00000000..5c932502 --- /dev/null +++ b/menu/set/server/power/cycle.py @@ -0,0 +1,142 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import power as lcm_server_power + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("cycle") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_power_cycle_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Power cycle""" + + # iserver set server power cycle + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_power_handler.power_cycle(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/power/hard.py b/menu/set/server/power/hard.py new file mode 100644 index 00000000..9a686421 --- /dev/null +++ b/menu/set/server/power/hard.py @@ -0,0 +1,142 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import power as lcm_server_power + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("hard") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_power_hard_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Power hard""" + + # iserver set server power hard + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_power_handler.power_hard(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/power/main.py b/menu/set/server/power/main.py new file mode 100644 index 00000000..1b06d351 --- /dev/null +++ b/menu/set/server/power/main.py @@ -0,0 +1,26 @@ +import click + +from menu.set.server.power.on import set_server_power_on_command +from menu.set.server.power.off import set_server_power_off_command +from menu.set.server.power.cycle import set_server_power_cycle_command +from menu.set.server.power.hard import set_server_power_hard_command +from menu.set.server.power.shut import set_server_power_shut_command +from menu.set.server.power.reboot import set_server_power_reboot_command + + +class Failure(Exception): + pass + + +@click.group("power") +@click.pass_obj +def set_server_power_menu(ctx): + """Set server power commands""" + + +set_server_power_menu.add_command(set_server_power_on_command) +set_server_power_menu.add_command(set_server_power_off_command) +set_server_power_menu.add_command(set_server_power_cycle_command) +set_server_power_menu.add_command(set_server_power_hard_command) +set_server_power_menu.add_command(set_server_power_shut_command) +set_server_power_menu.add_command(set_server_power_reboot_command) diff --git a/menu/set/server/power/off.py b/menu/set/server/power/off.py new file mode 100644 index 00000000..ff029612 --- /dev/null +++ b/menu/set/server/power/off.py @@ -0,0 +1,142 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import power as lcm_server_power + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("off") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_power_off_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Power off""" + + # iserver set server power off + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_power_handler.power_off(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/power/on.py b/menu/set/server/power/on.py new file mode 100644 index 00000000..2dd1e329 --- /dev/null +++ b/menu/set/server/power/on.py @@ -0,0 +1,142 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import power as lcm_server_power + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("on") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_power_on_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Power on""" + + # iserver set server power on + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_power_handler.power_on(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/power/reboot.py b/menu/set/server/power/reboot.py new file mode 100644 index 00000000..ebc33c93 --- /dev/null +++ b/menu/set/server/power/reboot.py @@ -0,0 +1,142 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import power as lcm_server_power + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("reboot") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_power_reboot_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Power reboot""" + + # iserver set server power reboot + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_power_handler.power_reboot(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/power/shut.py b/menu/set/server/power/shut.py new file mode 100644 index 00000000..c6ac6f9b --- /dev/null +++ b/menu/set/server/power/shut.py @@ -0,0 +1,142 @@ +import sys +import traceback +import click + +from lib import ip_helper +from lib.intersight import compute +from lib.intersight import compute_output +from lib.intersight.lcm import power as lcm_server_power + +from menu import defaults +from menu import validations +from menu import common +from menu import user_inputs + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("shut") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--serial", "serial_filter", multiple=True, help="Serial numbers") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Select by group name") +@click.option("--name", "name_filter", multiple=True, help="Name loose match") +@click.option("--ip", "ip_filter", multiple=True, help="Management IP address or subnet filter") +@click.option("--confirm", is_flag=True, show_default=True, default=False, help="Confirmation mode") +@click.option("--no-wait", is_flag=True, show_default=True, default=False, help="Wait mode") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_power_shut_command( + ctx, + iaccount, + serial_filter, + group_filter, + name_filter, + ip_filter, + confirm, + no_wait, + dry_run, + verbose, + devel + ): + """Power shut""" + + # iserver set server power shut + + ctx.developer = devel + silent = False + debug = False + common.flags_fixup(ctx, silent, verbose, debug) + + try: + if len(name_filter) == 0 and len(ip_filter) == 0 and len(serial_filter) == 0 and len(group_filter) == 0: + server_selection_mode = user_inputs.get_selection( + ctx, + 'Select server selection type', + ['name', 'serial', 'ip'] + ) + + if server_selection_mode == 'name': + name_filter = [user_inputs.get_value(ctx, 'Server name')] + + if server_selection_mode == 'serial': + serial_filter=[user_inputs.get_value(ctx, 'Server serial number')] + + if server_selection_mode == 'ip': + ip_address = user_inputs.get_value(ctx, 'Server management IP address') + if not ip_helper.is_valid_ipv4_address(ip_address): + ctx.my_output.error('Invalid IPv4 address') + raise ErrorExit + + ip_filter = [ip_address] + + serials = [] + for item in serial_filter: + serials = serials + item.split(',') + for item in group_filter: + serials.append(item) + + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=serials, + show_progress=True, + include_rack=True, + include_blade=True + ) + if servers_mo is None or len(servers_mo) == 0: + raise ErrorExit + + compute_handler = compute.Compute(iaccount, log_id=ctx.run_id) + compute_output_handler = compute_output.ComputeOutput(log_id=ctx.run_id) + + settings = {} + settings['state'] = True + settings['locator'] = True + settings['workflow'] = None + servers_info = compute_handler.get_info( + servers_mo, + settings, + {}, + 1, + prepare_cache=False + ) + + compute_output_handler.print_summary_table( + servers_info, + title=True + ) + + ctx.my_output.default('') + + if confirm: + if not common.get_confirmation(): + raise ErrorExit + + lcm_server_power_handler = lcm_server_power.LcmServerPower( + iaccount, + dry_run=dry_run, + wait=not no_wait, + silent=silent, + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + if not lcm_server_power_handler.power_shut(servers_mo): + raise ErrorExit + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/scu.py b/menu/set/server/scu.py new file mode 100644 index 00000000..b6de2bec --- /dev/null +++ b/menu/set/server/scu.py @@ -0,0 +1,112 @@ +import sys +import json +import traceback +import click + +from progress.bar import Bar + +from lib.intersight import scu + +from menu import user_inputs +from menu import defaults +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("scu") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--file", "filename", is_flag=False, show_default=False, default='', type=click.STRING, help="Input yaml file") +@click.option("--id", "moid", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Id") +@click.option("--name", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Name") +@click.option("--version", is_flag=False, show_default=False, default='', type=click.STRING, help="SCU Version") +@click.option("--link", is_flag=False, show_default=False, default='', type=click.STRING, help="Link") +@click.option("--interactive", is_flag=True, show_default=True, default=False, help="Interactive mode") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_scu_command(ctx, filename, iaccount, moid, name, version, link, interactive, devel): + """Set software configuration utilities""" + + # iwectl set server scu + + ctx.developer = devel + + try: + scu_handler = scu.SoftwareConfigurationUtility(iaccount, log_id=ctx.run_id) + + if len(filename) > 0: + ctx.my_output.default('Input file verification...') + scus = validations.validate_yaml_file(ctx, filename) + if scus is None: + raise ErrorExit + + if len(filename) == 0: + if len(moid) == 0: + interactive = True + + if interactive: + scus = scu_handler.get_all() + scu_handler.print(scus) + + moid = user_inputs.get_value(ctx, 'SCU ID') + + ctx.my_output.default('Parameters to be modified (leave empty for no change)') + name = user_inputs.get_value(ctx, '- name', empty=True) + version = user_inputs.get_value(ctx, '- version', empty=True) + link = user_inputs.get_value(ctx, '- link', empty=True) + + scus = [] + item = {} + item['Moid'] = moid + item['Name'] = name + item['Version'] = version + item['Link'] = link + item['Type'] = '' + scus.append(item) + + ctx.my_output.default('Input parameters verification...') + ctx.my_output.debug( + json.dumps( + scus, + indent=4 + ) + ) + + success, reason = scu_handler.validate_set(scus) + if not success: + ctx.my_output.error('Input parameters validation failed') + ctx.my_output.default(reason) + raise ErrorExit + + ctx.my_output.default('Input parameters verified') + + bar_handler = Bar('Progress', max=len(scus)) + bar_handler.goto(0) + failed = [] + for item in scus: + if not scu_handler.update(item['Moid'], item): + failed.append(item['Moid']) + bar_handler.next() + bar_handler.finish() + + if len(failed) > 0: + ctx.my_output.error('Some updates failed') + for item in failed: + ctx.my_output.default('- %s' % (item)) + raise ErrorExit + + scus = scu_handler.get_all() + scu_handler.print(scus) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/server/tag.py b/menu/set/server/tag.py new file mode 100644 index 00000000..9238e26e --- /dev/null +++ b/menu/set/server/tag.py @@ -0,0 +1,153 @@ +import sys +import traceback +import click + +from lib.intersight.lcm import tag as lcm_server_tag +from lib.intersight import validations as intersight_validations +from lib.vc import vcenter +from lib.vc import settings as vc_settings + +from menu import defaults +from menu import validations +from menu import common + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("tag") +@click.pass_obj +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--add", "add_tag", multiple=True, callback=intersight_validations.tag, help="Tags to be added") +@click.option("--del", "del_tag", multiple=True, callback=intersight_validations.tag, help="Tags to be deleted") +@click.option("--except", "except_tag", multiple=True, callback=intersight_validations.tag, help="Do not delete") +@click.option("--ip", "ip_filter", multiple=True, help="Select server by IP or subnet") +@click.option("--name", "name_filter", multiple=True, callback=intersight_validations.name_filter, help="Select server by name") +@click.option("--serial", "serial_filter", multiple=True, callback=intersight_validations.serial_filter, help="Select server by serial") +@click.option("--group", "group_filter", default='', callback=validations.validate_group_serials, help="Server group name") +@click.option("--model", "model_filter", multiple=True, callback=intersight_validations.model_filter, help="Select by model") +@click.option("--tag", "tag_filter", multiple=True, callback=intersight_validations.tag_filter, help="Tag filter") +@click.option("--vc", "vcenter_name", default='', help="vCenter name") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_server_tag_command( + ctx, + iaccount, + add_tag, + del_tag, + except_tag, + ip_filter, + name_filter, + serial_filter, + group_filter, + model_filter, + tag_filter, + vcenter_name, + dry_run, + devel + ): + """Set server tag""" + + # iserver set server tag + + ctx.developer = devel + + try: + if len(add_tag) == 0 and len(del_tag) == 0: + ctx.my_output.error( + 'Define tag to be added or deleted' + ) + raise ErrorExit + + if len(vcenter_name) > 0: + vc_settings_handler = vc_settings.VcSettings(log_id=ctx.run_id) + vcenter_settings = vc_settings_handler.get_vc_instance(vcenter_name) + if vcenter_settings is None: + ctx.my_output.error('vcenter not found: %s' % (vcenter_name)) + raise ErrorExit + + vc_handler = vcenter.Vcenter( + vcenter_settings['ip'], + vcenter_settings['username'], + vcenter_settings['password'], + port=vcenter_settings['port'], + log_id=ctx.run_id + ) + + ctx.my_output.default('Get vcenter hosts...') + + hosts = vc_handler.get_hosts_summary() + if hosts is None: + ctx.my_output.error('No hosts found') + raise ErrorExit + + for host in hosts: + group_filter.append( + host['serial'] + ) + + ctx.my_output.default('Get servers...') + servers_mo = common.get_servers_mo( + ctx, + iaccount, + ip_filter=ip_filter, + name_filter=name_filter, + serial_filter=intersight_validations.add_group_filter(serial_filter, group_filter), + model_filter=model_filter, + tag_filter=tag_filter, + include_rack=True, + include_blade=True, + show_progress=True + ) + if servers_mo is None or len(servers_mo) == 0: + ctx.my_output.error( + 'No servers matching search criteria' + ) + raise ErrorExit + + common.print_servers_mo_info( + ctx, + iaccount, + servers_mo, + show_progress=True, + cache=False + ) + + if not common.get_confirmation(): + return + + lcm_server_tag_handler = lcm_server_tag.LcmServerTag( + iaccount, + dry_run=dry_run, + wait=True, + silent=False, + verbose=False, + debug=False, + log_id=ctx.run_id + ) + + if not lcm_server_tag_handler.set(servers_mo, add_tag, del_tag, except_tag): + raise ErrorExit + + if not dry_run: + common.print_servers_info( + ctx, + iaccount, + serial_filter=intersight_validations.get_serial_filter_from_mo(servers_mo), + include_rack=True, + include_blade=True, + show_progress=True, + cache=False + ) + + except ErrorExit: + sys.exit(1) + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ucsm/__init__.py b/menu/set/ucsm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/ucsm/__pycache__/__init__.cpython-310.pyc b/menu/set/ucsm/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5fd48bba Binary files /dev/null and b/menu/set/ucsm/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/ucsm/__pycache__/inventory.cpython-310.pyc b/menu/set/ucsm/__pycache__/inventory.cpython-310.pyc new file mode 100644 index 00000000..3a055a70 Binary files /dev/null and b/menu/set/ucsm/__pycache__/inventory.cpython-310.pyc differ diff --git a/menu/set/ucsm/__pycache__/main.cpython-310.pyc b/menu/set/ucsm/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..3a699582 Binary files /dev/null and b/menu/set/ucsm/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/ucsm/__pycache__/manager.cpython-310.pyc b/menu/set/ucsm/__pycache__/manager.cpython-310.pyc new file mode 100644 index 00000000..c3b21935 Binary files /dev/null and b/menu/set/ucsm/__pycache__/manager.cpython-310.pyc differ diff --git a/menu/set/ucsm/inventory.py b/menu/set/ucsm/inventory.py new file mode 100644 index 00000000..9294e18b --- /dev/null +++ b/menu/set/ucsm/inventory.py @@ -0,0 +1,117 @@ +import sys +import traceback +import click + +from progress.bar import Bar + +from lib.ucsm import manager +from lib.ucsm import endpoint_settings + +from menu import validations + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("inventory") +@click.pass_obj +@click.option("--manager", "ucsm", default='', callback=validations.validate_ucsm_name, help="UCSM manager name") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ucsm_inventory_command( + ctx, + ucsm, + devel + ): + """Set ucsm inventory access""" + + # iserver set ucsm inventory + + ctx.developer = devel + + try: + ucsm_handler = manager.UcsManager( + ucsm['ip'], + ucsm['username'], + ucsm['password'], + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + failed = [] + + chassiz = ucsm_handler.get_chassiz() + if chassiz is None: + ctx.my_output.error('No chassis found') + raise ErrorExit + + bar_handler = Bar('Chassis', max=len(chassiz)) + bar_handler.goto(0) + for chassis in chassiz: + endpoint_settings_handler = endpoint_settings.UcsmEndpointSettings() + success = endpoint_settings_handler.set_ucsm_endpoint_settings( + chassis, + ucsm + ) + if not success: + failed.append( + dict( + type='Chassis', + serial=chassis['serial'] + ) + ) + + bar_handler.next() + + bar_handler.finish() + + blades = ucsm_handler.get_blades() + if blades is None: + ctx.my_output.error('No blades found') + raise ErrorExit + + bar_handler = Bar('Blade', max=len(blades)) + bar_handler.goto(0) + for blade in blades: + endpoint_settings_handler = endpoint_settings.UcsmEndpointSettings() + success = endpoint_settings_handler.set_ucsm_endpoint_settings( + blade, + ucsm + ) + if not success: + failed.append( + dict( + type='Blade', + serial=blade['serial'] + ) + ) + + bar_handler.next() + + bar_handler.finish() + + if len(failed) == 0: + ctx.my_output.default('All UCSM-attached endpoints settings saved') + return + + ctx.my_output.default('') + ctx.my_output.error('Not all UCSM-attached endpoints settings saved') + for item in failed: + ctx.my_output.default('- Type [%s] Serial [%s]' % (item['type'], item['serial'])) + raise ErrorExit + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/ucsm/main.py b/menu/set/ucsm/main.py new file mode 100644 index 00000000..57e6c542 --- /dev/null +++ b/menu/set/ucsm/main.py @@ -0,0 +1,18 @@ +import click + +from menu.set.ucsm.manager import set_ucsm_manager_command +from menu.set.ucsm.inventory import set_ucsm_inventory_command + + +class Failure(Exception): + pass + + +@click.group("ucsm") +@click.pass_obj +def set_ucsm_menu(ctx): + """Set ucsm commands""" + + +set_ucsm_menu.add_command(set_ucsm_manager_command) +set_ucsm_menu.add_command(set_ucsm_inventory_command) diff --git a/menu/set/ucsm/manager.py b/menu/set/ucsm/manager.py new file mode 100644 index 00000000..a6a4b3c6 --- /dev/null +++ b/menu/set/ucsm/manager.py @@ -0,0 +1,91 @@ +import sys +import traceback +import click + +from menu import common + +from lib.ucsm import manager +from lib.ucsm import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("manager") +@click.pass_obj +@click.option("--name", "ucsm_name", default='', help="UCSM name") +@click.option("--ip", "ucsm_ip", default='', help="UCSM IP/FQDN") +@click.option("--username", "ucsm_username", default='', help="UCSM username") +@click.option("--password", "ucsm_password", default='', help="UCSM password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_ucsm_manager_command( + ctx, + ucsm_name, + ucsm_ip, + ucsm_username, + ucsm_password, + devel + ): + """Set ucsm access details""" + + # iserver set ucsm manager + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if len(ucsm_name) == 0: + ctx.my_output.error('Define ucsm entry name') + raise ErrorExit + + if len(ucsm_ip) == 0: + ctx.my_output.error('Define ucsm ip address') + raise ErrorExit + + if len(ucsm_username) == 0: + ctx.my_output.error('Define ucsm username') + raise ErrorExit + + if len(ucsm_password) == 0: + ctx.my_output.error('Define ucsm password') + raise ErrorExit + + ucsm_handler = manager.UcsManager( + ucsm_ip, + ucsm_username, + ucsm_password, + log_id=ctx.run_id + ) + + if not ucsm_handler.is_connected(): + ctx.my_output.error('Failed to connect to UCSM') + raise ErrorExit + + ctx.my_output.default('UCSM authentication successful') + + settings_handler = settings.UcsmSettings(log_id=ctx.run_id) + success = settings_handler.set_ucsm_manager( + ucsm_name, + ucsm_ip, + ucsm_username, + ucsm_password + ) + if not success: + ctx.my_output.error('Failed to define ucsm entry') + raise ErrorExit + + ctx.my_output.default('UCSM entry created: %s' % (ucsm_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/vc/__init__.py b/menu/set/vc/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/set/vc/__pycache__/__init__.cpython-310.pyc b/menu/set/vc/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..c8714117 Binary files /dev/null and b/menu/set/vc/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/set/vc/__pycache__/controller.cpython-310.pyc b/menu/set/vc/__pycache__/controller.cpython-310.pyc new file mode 100644 index 00000000..94bb20eb Binary files /dev/null and b/menu/set/vc/__pycache__/controller.cpython-310.pyc differ diff --git a/menu/set/vc/__pycache__/instance.cpython-310.pyc b/menu/set/vc/__pycache__/instance.cpython-310.pyc new file mode 100644 index 00000000..91998037 Binary files /dev/null and b/menu/set/vc/__pycache__/instance.cpython-310.pyc differ diff --git a/menu/set/vc/__pycache__/main.cpython-310.pyc b/menu/set/vc/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..eb1e3019 Binary files /dev/null and b/menu/set/vc/__pycache__/main.cpython-310.pyc differ diff --git a/menu/set/vc/instance.py b/menu/set/vc/instance.py new file mode 100644 index 00000000..2d3224aa --- /dev/null +++ b/menu/set/vc/instance.py @@ -0,0 +1,94 @@ +import sys +import traceback +import click + +from menu import common + +from lib.vc import vcenter +from lib.vc import settings + + +class Failure(Exception): + pass + + +class ErrorExit(Exception): + pass + + +@click.command("instance") +@click.pass_obj +@click.option("--name", "vc_name", default='', help="vcenter name") +@click.option("--ip", "vc_ip", default='', help="vcenter IP/FQDN") +@click.option("--port", "vc_port", default=443, help="vcenter port") +@click.option("--username", "vc_username", default='', help="vcenter username") +@click.option("--password", "vc_password", default='', help="vcenter password") +@click.option("--devel", is_flag=True, show_default=True, default=False, help="Developer output") +def set_vc_instance_command( + ctx, + vc_name, + vc_ip, + vc_port, + vc_username, + vc_password, + devel + ): + """Set vcenter access details""" + + # iserver set vc instance + + ctx.developer = devel + common.flags_fixup(ctx, False, False, False) + + try: + if len(vc_name) == 0: + ctx.my_output.error('Define vcenter entry name') + raise ErrorExit + + if len(vc_ip) == 0: + ctx.my_output.error('Define vcenter ip address or name') + raise ErrorExit + + if len(vc_username) == 0: + ctx.my_output.error('Define vcenter username') + raise ErrorExit + + if len(vc_password) == 0: + ctx.my_output.error('Define vcenter password') + raise ErrorExit + + vc_handler = vcenter.Vcenter( + vc_ip, + vc_username, + vc_password, + port=vc_port, + log_id=ctx.run_id + ) + + if not vc_handler.is_vc_connected(): + raise ErrorExit + + ctx.my_output.default('vcenter authentication successful') + + settings_handler = settings.VcSettings(log_id=ctx.run_id) + success = settings_handler.set_vc_instance( + vc_name, + vc_ip, + vc_port, + vc_username, + vc_password + ) + if not success: + ctx.my_output.error('Failed to define vcenter entry') + raise ErrorExit + + ctx.my_output.default('vcenter entry created: %s' % (vc_name)) + + except ErrorExit: + ctx.busy = False + sys.exit(1) + + except BaseException: + ctx.busy = False + ctx.my_output.traceback(traceback.format_exc()) + sys.exit(1) diff --git a/menu/set/vc/main.py b/menu/set/vc/main.py new file mode 100644 index 00000000..3ad2607d --- /dev/null +++ b/menu/set/vc/main.py @@ -0,0 +1,16 @@ +import click + +from menu.set.vc.instance import set_vc_instance_command + + +class Failure(Exception): + pass + + +@click.group("vc") +@click.pass_obj +def set_vc_menu(ctx): + """Set vCenter commands""" + + +set_vc_menu.add_command(set_vc_instance_command) diff --git a/menu/settings/__init__.py b/menu/settings/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/settings/__pycache__/__init__.cpython-310.pyc b/menu/settings/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..d1fa2053 Binary files /dev/null and b/menu/settings/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/settings/__pycache__/main.cpython-310.pyc b/menu/settings/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..441fa562 Binary files /dev/null and b/menu/settings/__pycache__/main.cpython-310.pyc differ diff --git a/menu/settings/defaults/__init__.py b/menu/settings/defaults/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/settings/defaults/__pycache__/__init__.cpython-310.pyc b/menu/settings/defaults/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..5bc4a32e Binary files /dev/null and b/menu/settings/defaults/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/settings/defaults/__pycache__/get.cpython-310.pyc b/menu/settings/defaults/__pycache__/get.cpython-310.pyc new file mode 100644 index 00000000..7a0f0a20 Binary files /dev/null and b/menu/settings/defaults/__pycache__/get.cpython-310.pyc differ diff --git a/menu/settings/defaults/__pycache__/main.cpython-310.pyc b/menu/settings/defaults/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..82891e81 Binary files /dev/null and b/menu/settings/defaults/__pycache__/main.cpython-310.pyc differ diff --git a/menu/settings/defaults/__pycache__/rfd.cpython-310.pyc b/menu/settings/defaults/__pycache__/rfd.cpython-310.pyc new file mode 100644 index 00000000..59c0489c Binary files /dev/null and b/menu/settings/defaults/__pycache__/rfd.cpython-310.pyc differ diff --git a/menu/settings/defaults/get.py b/menu/settings/defaults/get.py new file mode 100644 index 00000000..a4139c87 --- /dev/null +++ b/menu/settings/defaults/get.py @@ -0,0 +1,33 @@ +import sys +import json +import click + +from lib import settings_helper + + +@click.command("get") +@click.pass_obj +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +def settings_defaults_get_command(ctx, output): + """Show Default Settings""" + + # iwectl settings defaults get + + settings_handler = settings_helper.Settings() + values = settings_handler.get_settings() + if values is None: + ctx.my_output.error('Get settings failed') + sys.exit(1) + + if output == 'json': + ctx.my_output.default(json.dumps(values, indent=4)) + return + + ctx.my_output.dictionary( + values, + exclude=[], + title='Default Settings', + underline=True, + prefix='- ', + justify=True + ) diff --git a/menu/settings/defaults/main.py b/menu/settings/defaults/main.py new file mode 100644 index 00000000..b615b9f3 --- /dev/null +++ b/menu/settings/defaults/main.py @@ -0,0 +1,18 @@ +import click + +from menu.settings.defaults.get import settings_defaults_get_command +from menu.settings.defaults.rfd import settings_defaults_rfd_command + + +class Failure(Exception): + pass + + +@click.group("defaults") +@click.pass_obj +def settings_defaults_menu(ctx): + """Defaults""" + + +settings_defaults_menu.add_command(settings_defaults_get_command) +settings_defaults_menu.add_command(settings_defaults_rfd_command) diff --git a/menu/settings/defaults/rfd.py b/menu/settings/defaults/rfd.py new file mode 100644 index 00000000..02646d75 --- /dev/null +++ b/menu/settings/defaults/rfd.py @@ -0,0 +1,19 @@ +import sys +import click + +from lib import settings_helper + + +@click.command("rfd") +@click.pass_obj +def settings_defaults_rfd_command(ctx): + """Revert default settings to factory defaults""" + + # iwectl settings defaults rfd + + settings_handler = settings_helper.Settings() + if not settings_handler.rfd_settings(): + ctx.my_output.error('Set settings failed') + sys.exit(1) + + ctx.my_output.default('Done') diff --git a/menu/settings/groups/__init__.py b/menu/settings/groups/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/settings/groups/__pycache__/__init__.cpython-310.pyc b/menu/settings/groups/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..94e89755 Binary files /dev/null and b/menu/settings/groups/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/settings/groups/__pycache__/clear.cpython-310.pyc b/menu/settings/groups/__pycache__/clear.cpython-310.pyc new file mode 100644 index 00000000..f86cb74f Binary files /dev/null and b/menu/settings/groups/__pycache__/clear.cpython-310.pyc differ diff --git a/menu/settings/groups/__pycache__/delete.cpython-310.pyc b/menu/settings/groups/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..56a4b050 Binary files /dev/null and b/menu/settings/groups/__pycache__/delete.cpython-310.pyc differ diff --git a/menu/settings/groups/__pycache__/get.cpython-310.pyc b/menu/settings/groups/__pycache__/get.cpython-310.pyc new file mode 100644 index 00000000..154b156d Binary files /dev/null and b/menu/settings/groups/__pycache__/get.cpython-310.pyc differ diff --git a/menu/settings/groups/__pycache__/main.cpython-310.pyc b/menu/settings/groups/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..033ebba8 Binary files /dev/null and b/menu/settings/groups/__pycache__/main.cpython-310.pyc differ diff --git a/menu/settings/groups/clear.py b/menu/settings/groups/clear.py new file mode 100644 index 00000000..5be4eb9e --- /dev/null +++ b/menu/settings/groups/clear.py @@ -0,0 +1,19 @@ +import sys +import click + +from lib import my_servers_helper + + +@click.command("clear") +@click.pass_obj +def settings_groups_clear_command(ctx): + """Clear servers groups settings""" + + # iserver settings groups clear + + my_servers_handler = my_servers_helper.MyServers() + if not my_servers_handler.clear_my_servers(): + ctx.my_output.error('Failed') + sys.exit(1) + + ctx.my_output.default('Cleared') diff --git a/menu/settings/groups/delete.py b/menu/settings/groups/delete.py new file mode 100644 index 00000000..c0bc9d51 --- /dev/null +++ b/menu/settings/groups/delete.py @@ -0,0 +1,21 @@ +import sys +import click + +from lib import my_servers_helper + + +@click.command("delete") +@click.pass_obj +@click.argument("name", required=True, type=click.STRING) +def settings_groups_delete_command(ctx, name): + """Delete servers group""" + + # iserver settings groups delete + + my_servers_handler = my_servers_helper.MyServers() + + if not my_servers_handler.del_group(name): + ctx.my_output.error('Failed') + sys.exit(1) + + ctx.my_output.default('Deleted') diff --git a/menu/settings/groups/get.py b/menu/settings/groups/get.py new file mode 100644 index 00000000..62d8476a --- /dev/null +++ b/menu/settings/groups/get.py @@ -0,0 +1,58 @@ +import sys +import json +import click + +from lib import my_servers_helper + + +@click.command("get") +@click.pass_obj +@click.option("--name", type=click.STRING, default='', show_default=False) +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +def settings_groups_get_command(ctx, name, output): + """Show servers groups""" + + # iserver settings groups get + + my_servers_handler = my_servers_helper.MyServers() + servers = my_servers_handler.get_my_servers() + if servers is None: + ctx.my_output.error('My servers not found') + sys.exit(1) + if len(servers) == 0: + ctx.my_output.default('My servers not defined') + return + + servers_list = [] + for group_name in servers: + if len(name) > 0 and name != group_name: + continue + + for group_server in servers[group_name]: + server = {} + server['Group'] = group_name + for key in group_server: + server[key] = group_server[key] + servers_list.append(server) + + if output == 'json': + ctx.my_output.default(json.dumps(servers_list, indent=4)) + else: + ctx.my_output.my_table( + servers_list, + order=[ + 'Group', + 'Name', + 'Serial', + 'Model', + 'ManagementIp' + ], + headers=[ + 'Group', + 'Name', + 'Serial', + 'Model', + 'Management IP' + ], + table=True + ) diff --git a/menu/settings/groups/main.py b/menu/settings/groups/main.py new file mode 100644 index 00000000..c7eb3225 --- /dev/null +++ b/menu/settings/groups/main.py @@ -0,0 +1,16 @@ +import click + +from menu.settings.groups.get import settings_groups_get_command +from menu.settings.groups.clear import settings_groups_clear_command +from menu.settings.groups.delete import settings_groups_delete_command + + +@click.group("groups") +@click.pass_obj +def settings_groups_menu(ctx): + """Servers groups""" + + +settings_groups_menu.add_command(settings_groups_get_command) +settings_groups_menu.add_command(settings_groups_clear_command) +settings_groups_menu.add_command(settings_groups_delete_command) diff --git a/menu/settings/iaccounts/__init__.py b/menu/settings/iaccounts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/settings/iaccounts/__pycache__/__init__.cpython-310.pyc b/menu/settings/iaccounts/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..85805fde Binary files /dev/null and b/menu/settings/iaccounts/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/settings/iaccounts/__pycache__/add.cpython-310.pyc b/menu/settings/iaccounts/__pycache__/add.cpython-310.pyc new file mode 100644 index 00000000..5c455f6a Binary files /dev/null and b/menu/settings/iaccounts/__pycache__/add.cpython-310.pyc differ diff --git a/menu/settings/iaccounts/__pycache__/default.cpython-310.pyc b/menu/settings/iaccounts/__pycache__/default.cpython-310.pyc new file mode 100644 index 00000000..7c01b4c0 Binary files /dev/null and b/menu/settings/iaccounts/__pycache__/default.cpython-310.pyc differ diff --git a/menu/settings/iaccounts/__pycache__/delete.cpython-310.pyc b/menu/settings/iaccounts/__pycache__/delete.cpython-310.pyc new file mode 100644 index 00000000..3146559f Binary files /dev/null and b/menu/settings/iaccounts/__pycache__/delete.cpython-310.pyc differ diff --git a/menu/settings/iaccounts/__pycache__/get.cpython-310.pyc b/menu/settings/iaccounts/__pycache__/get.cpython-310.pyc new file mode 100644 index 00000000..205356e1 Binary files /dev/null and b/menu/settings/iaccounts/__pycache__/get.cpython-310.pyc differ diff --git a/menu/settings/iaccounts/__pycache__/main.cpython-310.pyc b/menu/settings/iaccounts/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..6d80d0b6 Binary files /dev/null and b/menu/settings/iaccounts/__pycache__/main.cpython-310.pyc differ diff --git a/menu/settings/iaccounts/add.py b/menu/settings/iaccounts/add.py new file mode 100644 index 00000000..ed781ea0 --- /dev/null +++ b/menu/settings/iaccounts/add.py @@ -0,0 +1,51 @@ +import os +import sys +import click + +from lib import iaccount_helper + + +@click.command("add") +@click.pass_obj +@click.option("--name", default='', help="Name") +@click.option("--pem", default='', help="PEM filename") +@click.option("--key", default='', help="Key") +@click.option("--server", default='intersight.com', help="Server") +def settings_iaccount_add_command(ctx, name, pem, key, server): + """Create Intersight Account""" + + # iserver settings iaccount add + + if len(name) == 0: + ctx.my_output.error('Define iaccount name') + sys.exit(1) + + if len(pem) == 0: + ctx.my_output.error('Define pem filename') + sys.exit(1) + + if not os.path.isfile(pem): + ctx.my_output.error('pem file not found: %s' % (pem)) + sys.exit(1) + + if len(key) == 0: + ctx.my_output.error('Define key') + sys.exit(1) + + iaccount_handler = iaccount_helper.IntersightAccount() + + if iaccount_handler.is_iaccount(name): + ctx.my_output.error('iaccount %s already defined' % (name)) + sys.exit(1) + + configuration = {} + configuration['keyfile'] = pem + configuration['keyid'] = key + configuration['output'] = 'default' + configuration['server'] = server + + if not iaccount_handler.create_iaccount(name, configuration): + ctx.my_output.error('Intersight Account create failed') + sys.exit(1) + + ctx.my_output.default('Added') diff --git a/menu/settings/iaccounts/cache.py b/menu/settings/iaccounts/cache.py new file mode 100644 index 00000000..8a9dbd60 --- /dev/null +++ b/menu/settings/iaccounts/cache.py @@ -0,0 +1,44 @@ +import json +import click + +from lib.intersight import settings + + +@click.command("cache") +@click.pass_obj +@click.option("--enabled", default=None, help="Enable cache") +@click.option("--ttl", default=0, type=click.INT, help="Cache ttl in seconds") +def settings_iaccount_cache_command(ctx, enabled, ttl): + """Cache settings""" + + settings_handler = settings.IntersightSettings() + + if enabled is not None: + if enabled.lower() not in ['true', 'false']: + ctx.my_output.error( + 'enabled must be true or false' + ) + return + + if enabled.lower() == 'true': + if not settings_handler.set_cache_enabled(): + ctx.my_output.error( + 'cache enable failed' + ) + return + + if enabled.lower() == 'false': + if not settings_handler.set_cache_disabled(): + ctx.my_output.error( + 'cache disable failed' + ) + return + + if ttl > 0: + if not settings_handler.set_cache_ttl(ttl): + ctx.my_output.error( + 'cache ttl set failed' + ) + return + + settings_handler.print_intersight_settings() diff --git a/menu/settings/iaccounts/default.py b/menu/settings/iaccounts/default.py new file mode 100644 index 00000000..80dc2b15 --- /dev/null +++ b/menu/settings/iaccounts/default.py @@ -0,0 +1,20 @@ +import sys +import click + +from lib import iaccount_helper + + +@click.command("default") +@click.pass_obj +@click.argument("iaccount", required=True, type=click.STRING) +def settings_iaccount_default_command(ctx, iaccount): + """Set Intersight Account as default""" + + # iserver settings iaccount default + + iaccount_handler = iaccount_helper.IntersightAccount() + if not iaccount_handler.set_default_iaccount(iaccount): + ctx.my_output.error('Failed') + sys.exit(1) + + ctx.my_output.default('Set as default') diff --git a/menu/settings/iaccounts/delete.py b/menu/settings/iaccounts/delete.py new file mode 100644 index 00000000..a035a95a --- /dev/null +++ b/menu/settings/iaccounts/delete.py @@ -0,0 +1,21 @@ +import sys +import click + +from lib import iaccount_helper + + +@click.command("delete") +@click.pass_obj +@click.argument("iaccount", required=True, type=click.STRING) +def settings_iaccount_delete_command(ctx, iaccount): + """Delete Intersight Account""" + + # iwectl settings iaccount delete + + iaccount_handler = iaccount_helper.IntersightAccount() + success, reason = iaccount_handler.delete_iaccount(iaccount) + if not success: + ctx.my_output.error(reason) + sys.exit(1) + + ctx.my_output.default('Deleted') diff --git a/menu/settings/iaccounts/get.py b/menu/settings/iaccounts/get.py new file mode 100644 index 00000000..68b9bb39 --- /dev/null +++ b/menu/settings/iaccounts/get.py @@ -0,0 +1,35 @@ +import json +import click + +from lib import iaccount_helper + + +@click.command("get") +@click.pass_obj +@click.option("--output", "-o", type=click.Choice(['default', 'json'], case_sensitive=False), default='default', show_default=True) +@click.option("--show-key", is_flag=True, show_default=True, default=False, help="Show key") +def settings_iaccount_get_command(ctx, output, show_key): + """Show Intersight Accounts""" + + # iwectl settings iaccount get + + iaccount_handler = iaccount_helper.IntersightAccount() + accounts = iaccount_handler.get_iaccounts() + + if not show_key: + new_accounts = [] + for account in accounts: + account['keyid'] = '*****' + new_accounts.append(account) + accounts = new_accounts + + if output == 'json': + ctx.my_output.default(json.dumps(accounts, indent=4)) + return + + ctx.my_output.my_table( + accounts, + order=['name', 'keyfile', 'server', 'keyid'], + headers=['iaccount', 'key file', 'server', 'key id'], + table=True + ) diff --git a/menu/settings/iaccounts/main.py b/menu/settings/iaccounts/main.py new file mode 100644 index 00000000..77509ac0 --- /dev/null +++ b/menu/settings/iaccounts/main.py @@ -0,0 +1,20 @@ +import click + +from menu.settings.iaccounts.add import settings_iaccount_add_command +from menu.settings.iaccounts.cache import settings_iaccount_cache_command +from menu.settings.iaccounts.get import settings_iaccount_get_command +from menu.settings.iaccounts.delete import settings_iaccount_delete_command +from menu.settings.iaccounts.default import settings_iaccount_default_command + + +@click.group("iaccounts") +@click.pass_obj +def settings_iaccounts_menu(ctx): + """Intersight Accounts""" + + +settings_iaccounts_menu.add_command(settings_iaccount_add_command) +settings_iaccounts_menu.add_command(settings_iaccount_cache_command) +settings_iaccounts_menu.add_command(settings_iaccount_get_command) +settings_iaccounts_menu.add_command(settings_iaccount_delete_command) +settings_iaccounts_menu.add_command(settings_iaccount_default_command) diff --git a/menu/settings/main.py b/menu/settings/main.py new file mode 100644 index 00000000..cd4fe67d --- /dev/null +++ b/menu/settings/main.py @@ -0,0 +1,20 @@ +import click + +from menu.settings.defaults.main import settings_defaults_menu +from menu.settings.groups.main import settings_groups_menu +from menu.settings.iaccounts.main import settings_iaccounts_menu + + +class Failure(Exception): + pass + + +@click.group("settings") +@click.pass_obj +def settings_menu(ctx): + """Settings""" + + +settings_menu.add_command(settings_defaults_menu) +settings_menu.add_command(settings_groups_menu) +settings_menu.add_command(settings_iaccounts_menu) diff --git a/menu/user_inputs.py b/menu/user_inputs.py new file mode 100644 index 00000000..7c8ea6b0 --- /dev/null +++ b/menu/user_inputs.py @@ -0,0 +1,152 @@ +from lib import ip_helper + +from lib.intersight import scu +from lib.intersight import os_image +from lib.intersight import organization +from lib.intersight import hcl_operating_system_vendor +from lib.intersight import hcl_operating_system + + +def string_fixup(value): + value = value.strip() + return value + + +def get_scu_name(ctx, iaccount): + scu_handler = scu.SoftwareConfigurationUtility(iaccount, log_id=ctx.run_id) + items = scu_handler.get_all() + scu_handler.print(items) + + value = '' + while len(value) == 0: + value = input('SCU name: ') + + return string_fixup(value) + + +def get_os_image_vendor(ctx, iaccount, empty=False): + handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=ctx.run_id) + vendors = handler.get_all() + + ctx.my_output.default('OS Vendors:') + for vendor in vendors: + ctx.my_output.default('- %s' % (vendor['Name'])) + + value = '' + while len(value) == 0: + value = input('OS Vendor name: ') + if empty: + break + + return string_fixup(value) + + +def get_os_image_version(ctx, iaccount, vendor_name, empty=False): + vendor_handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=ctx.run_id) + vendor_attributes = vendor_handler.get_by_name(vendor_name) + if vendor_attributes is None: + ctx.my_output.error('Vendor not found: %s' % (vendor_name)) + return None + + version_handler = hcl_operating_system.HclOperatingSystem(iaccount, log_id=ctx.run_id) + versions = version_handler.get_vendor_versions(vendor_attributes['Moid']) + + ctx.my_output.default('OS Versions:') + for version in versions: + ctx.my_output.default('- %s' % (version['Version'])) + + value = '' + while len(value) == 0: + value = input('OS Version name: ') + if empty: + break + + return string_fixup(value) + + +def get_os_image_name(ctx, iaccount): + image_handler = os_image.OsImage(iaccount, log_id=ctx.run_id) + items = image_handler.get_all() + image_handler.print(items) + + value = '' + while len(value) == 0: + value = input('OS Image name: ') + + return string_fixup(value) + + +def get_organization_name(ctx, iaccount): + organization_handler = organization.Organization(iaccount, log_id=ctx.run_id) + + organizations = organization_handler.get_moids_dict() + if len(organizations) == 0: + ctx.my_output.error('No organizations found') + return None + + if len(organizations) == 1: + for key in organizations: + return organizations[key] + + ctx.my_output.default('Intersight Organizations') + for key in organizations: + ctx.my_output.default('- %s' % (organizations[key])) + + value = '' + while len(value) == 0: + value = input('Organization name: ') + + return string_fixup(value) + + +def get_value(ctx, prompt, empty=False): + value = '' + while len(value) == 0: + value = input('%s: ' % (prompt)) + if empty: + break + + return string_fixup(value) + + +def get_ip_address(ctx, prompt, empty=False): + value = '' + while len(value) == 0: + value = input('%s: ' % (prompt)) + + if len(value) == 0 and empty: + break + + if not ip_helper.is_valid_ipv4_address(value): + value = '' + + return string_fixup(value) + + +def get_prefix_length(ctx, prompt, empty=False): + value = '' + while len(value) == 0: + value = input('%s: ' % (prompt)) + + if len(value) == 0 and empty: + break + + try: + if int(value) < 8 or int(value) > 30: + value = '' + except BaseException: + value = '' + + return int(value) + + +def get_selection(ctx, prompt, options): + ctx.my_output.default('%s:' % (prompt)) + for allowed_value in options: + ctx.my_output.default('- %s' % (allowed_value)) + + value = '' + while len(value) == 0 or value not in options: + value = input('Value: ') + + return string_fixup(value) diff --git a/menu/utils/__init__.py b/menu/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/utils/__pycache__/__init__.cpython-310.pyc b/menu/utils/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..cf33be4b Binary files /dev/null and b/menu/utils/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/utils/__pycache__/doc.cpython-310.pyc b/menu/utils/__pycache__/doc.cpython-310.pyc new file mode 100644 index 00000000..233bf3e2 Binary files /dev/null and b/menu/utils/__pycache__/doc.cpython-310.pyc differ diff --git a/menu/utils/__pycache__/main.cpython-310.pyc b/menu/utils/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..8cd6e619 Binary files /dev/null and b/menu/utils/__pycache__/main.cpython-310.pyc differ diff --git a/menu/utils/cli/__init__.py b/menu/utils/cli/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/utils/cli/__pycache__/__init__.cpython-310.pyc b/menu/utils/cli/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..a075ef6c Binary files /dev/null and b/menu/utils/cli/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/utils/cli/__pycache__/bug.cpython-310.pyc b/menu/utils/cli/__pycache__/bug.cpython-310.pyc new file mode 100644 index 00000000..cc688bfc Binary files /dev/null and b/menu/utils/cli/__pycache__/bug.cpython-310.pyc differ diff --git a/menu/utils/cli/__pycache__/list.cpython-310.pyc b/menu/utils/cli/__pycache__/list.cpython-310.pyc new file mode 100644 index 00000000..45716737 Binary files /dev/null and b/menu/utils/cli/__pycache__/list.cpython-310.pyc differ diff --git a/menu/utils/cli/__pycache__/main.cpython-310.pyc b/menu/utils/cli/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..0bf3a21d Binary files /dev/null and b/menu/utils/cli/__pycache__/main.cpython-310.pyc differ diff --git a/menu/utils/cli/bug.py b/menu/utils/cli/bug.py new file mode 100644 index 00000000..e3bb1029 --- /dev/null +++ b/menu/utils/cli/bug.py @@ -0,0 +1,15 @@ +import click + +from lib import log_helper + + +@click.command("bug") +@click.pass_obj +@click.argument("name", required=True, type=click.STRING) +def utils_cli_bug_command(ctx, name): + """Submit bug report""" + + # iserver utils devel cli bug + + log_handler = log_helper.Log() + log_handler.bug_report(name) diff --git a/menu/utils/cli/list.py b/menu/utils/cli/list.py new file mode 100644 index 00000000..e05b7382 --- /dev/null +++ b/menu/utils/cli/list.py @@ -0,0 +1,14 @@ +import click + +from lib import log_helper + + +@click.command("list") +@click.pass_obj +def utils_cli_list_command(ctx): + """Show last commands history""" + + # iserver utils cli list + + log_handler = log_helper.Log() + log_handler.show_last_logs() diff --git a/menu/utils/cli/main.py b/menu/utils/cli/main.py new file mode 100644 index 00000000..d03e97fd --- /dev/null +++ b/menu/utils/cli/main.py @@ -0,0 +1,18 @@ +import click + +from menu.utils.cli.list import utils_cli_list_command +from menu.utils.cli.bug import utils_cli_bug_command + + +class Failure(Exception): + pass + + +@click.group("cli") +@click.pass_obj +def utils_cli_menu(ctx): + """Command line""" + + +utils_cli_menu.add_command(utils_cli_list_command) +utils_cli_menu.add_command(utils_cli_bug_command) diff --git a/menu/utils/doc.py b/menu/utils/doc.py new file mode 100644 index 00000000..ccf5a578 --- /dev/null +++ b/menu/utils/doc.py @@ -0,0 +1,36 @@ +import sys +import click + +from lib import self_doc + + +@click.command("doc") +@click.pass_obj +@click.option("--results", "directory", is_flag=False, show_default=False, default='results', help="Results directory") +@click.option("--template", "template_names", multiple=True, help="Select template") +@click.option("--no-redfish", is_flag=True, show_default=True, default=False, help="Disable redfish tests") +@click.option("--generate", is_flag=True, show_default=True, default=False, help="Generate template from template") +@click.option("--replace", multiple=True, help="Replace pattern:value") +def utils_doc_command(ctx, directory, template_names, no_redfish, generate, replace): + """Generate documentation""" + + # iserver utils doc + + if generate: + success = self_doc.generate_template_docs( + template_names + ) + + replace_dir = {} + for item in replace: + replace_dir[item.split(':')[0]] = item.split(':')[1] + + success = self_doc.generate_docs( + directory, + template_names, + redfish_tests=not no_redfish, + replace=replace_dir + ) + + if not success: + sys.exit(1) diff --git a/menu/utils/main.py b/menu/utils/main.py new file mode 100644 index 00000000..434bb57a --- /dev/null +++ b/menu/utils/main.py @@ -0,0 +1,20 @@ +import click + +from menu.utils.cli.main import utils_cli_menu +from menu.utils.test.main import utils_test_menu +from menu.utils.doc import utils_doc_command + + +class Failure(Exception): + pass + + +@click.group("utils") +@click.pass_obj +def utils_menu(ctx): + """Developer utilities""" + + +utils_menu.add_command(utils_cli_menu) +utils_menu.add_command(utils_test_menu) +utils_menu.add_command(utils_doc_command) diff --git a/menu/utils/test/__init__.py b/menu/utils/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/utils/test/__pycache__/__init__.cpython-310.pyc b/menu/utils/test/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..f79a47e4 Binary files /dev/null and b/menu/utils/test/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/utils/test/__pycache__/main.cpython-310.pyc b/menu/utils/test/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..5fd88ec7 Binary files /dev/null and b/menu/utils/test/__pycache__/main.cpython-310.pyc differ diff --git a/menu/utils/test/__pycache__/run.cpython-310.pyc b/menu/utils/test/__pycache__/run.cpython-310.pyc new file mode 100644 index 00000000..dbb0e617 Binary files /dev/null and b/menu/utils/test/__pycache__/run.cpython-310.pyc differ diff --git a/menu/utils/test/get/__init__.py b/menu/utils/test/get/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/menu/utils/test/get/__pycache__/__init__.cpython-310.pyc b/menu/utils/test/get/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3acf9d34 Binary files /dev/null and b/menu/utils/test/get/__pycache__/__init__.cpython-310.pyc differ diff --git a/menu/utils/test/get/__pycache__/collection.cpython-310.pyc b/menu/utils/test/get/__pycache__/collection.cpython-310.pyc new file mode 100644 index 00000000..29c5e346 Binary files /dev/null and b/menu/utils/test/get/__pycache__/collection.cpython-310.pyc differ diff --git a/menu/utils/test/get/__pycache__/collections.cpython-310.pyc b/menu/utils/test/get/__pycache__/collections.cpython-310.pyc new file mode 100644 index 00000000..6ed0795e Binary files /dev/null and b/menu/utils/test/get/__pycache__/collections.cpython-310.pyc differ diff --git a/menu/utils/test/get/__pycache__/main.cpython-310.pyc b/menu/utils/test/get/__pycache__/main.cpython-310.pyc new file mode 100644 index 00000000..48199602 Binary files /dev/null and b/menu/utils/test/get/__pycache__/main.cpython-310.pyc differ diff --git a/menu/utils/test/get/__pycache__/name.cpython-310.pyc b/menu/utils/test/get/__pycache__/name.cpython-310.pyc new file mode 100644 index 00000000..d204d2cd Binary files /dev/null and b/menu/utils/test/get/__pycache__/name.cpython-310.pyc differ diff --git a/menu/utils/test/get/__pycache__/names.cpython-310.pyc b/menu/utils/test/get/__pycache__/names.cpython-310.pyc new file mode 100644 index 00000000..aca1d986 Binary files /dev/null and b/menu/utils/test/get/__pycache__/names.cpython-310.pyc differ diff --git a/menu/utils/test/get/__pycache__/summary.cpython-310.pyc b/menu/utils/test/get/__pycache__/summary.cpython-310.pyc new file mode 100644 index 00000000..475468e3 Binary files /dev/null and b/menu/utils/test/get/__pycache__/summary.cpython-310.pyc differ diff --git a/menu/utils/test/get/collection.py b/menu/utils/test/get/collection.py new file mode 100644 index 00000000..0dd5f99e --- /dev/null +++ b/menu/utils/test/get/collection.py @@ -0,0 +1,15 @@ +import click + +from lib import self_testing + + +@click.command("collection") +@click.pass_obj +@click.argument("name", required=True, type=click.STRING) +@click.option("--directory", is_flag=False, show_default=False, default='tests', type=click.STRING, help="Test definitions") +def utils_test_get_collection_command(ctx, name, directory): + """get iserver test collection info""" + + # iserver utils test get collection + + self_testing.get_tests_collection_info(name, directory) diff --git a/menu/utils/test/get/collections.py b/menu/utils/test/get/collections.py new file mode 100644 index 00000000..cc7f2c3d --- /dev/null +++ b/menu/utils/test/get/collections.py @@ -0,0 +1,16 @@ +import click + +from lib import self_testing + + +@click.command("test-collections") +@click.pass_obj +@click.option("--directory", is_flag=False, show_default=False, default='tests', type=click.STRING, help="Test definitions") +def utils_test_get_collections_command(ctx, directory): + """get iserver test collections""" + + # iserver utils test get collections + + tests = self_testing.get_tests_collections(directory, names=True) + for test in tests: + print(test) diff --git a/menu/utils/test/get/main.py b/menu/utils/test/get/main.py new file mode 100644 index 00000000..0fbf3353 --- /dev/null +++ b/menu/utils/test/get/main.py @@ -0,0 +1,24 @@ +import click + +from menu.utils.test.get.name import utils_test_get_name_command +from menu.utils.test.get.names import utils_test_get_names_command +from menu.utils.test.get.collection import utils_test_get_collection_command +from menu.utils.test.get.collections import utils_test_get_collections_command +from menu.utils.test.get.summary import utils_test_get_summary_command + + +class Failure(Exception): + pass + + +@click.group("get") +@click.pass_obj +def utils_test_get_menu(ctx): + """Test""" + + +utils_test_get_menu.add_command(utils_test_get_name_command) +utils_test_get_menu.add_command(utils_test_get_names_command) +utils_test_get_menu.add_command(utils_test_get_collection_command) +utils_test_get_menu.add_command(utils_test_get_collections_command) +utils_test_get_menu.add_command(utils_test_get_summary_command) diff --git a/menu/utils/test/get/name.py b/menu/utils/test/get/name.py new file mode 100644 index 00000000..25ccf8df --- /dev/null +++ b/menu/utils/test/get/name.py @@ -0,0 +1,21 @@ +import json +import click + +from lib import self_testing + + +@click.command("name") +@click.pass_obj +@click.argument("name", required=True, type=click.STRING) +@click.option("--directory", is_flag=False, show_default=False, default='tests', type=click.STRING, help="Test definitions") +def utils_test_get_name_command(ctx, name, directory): + """get iserver test name""" + + # iserver utils test get name + + test = self_testing.get_test(name, directory) + if test is None: + print('Test not found') + return + + print(json.dumps(test, indent=4)) diff --git a/menu/utils/test/get/names.py b/menu/utils/test/get/names.py new file mode 100644 index 00000000..cd146872 --- /dev/null +++ b/menu/utils/test/get/names.py @@ -0,0 +1,20 @@ +import click + +from lib import self_testing + + +@click.command("names") +@click.pass_obj +@click.option("--directory", is_flag=False, show_default=False, default='tests', type=click.STRING, help="Test definitions") +def utils_test_get_names_command(ctx, directory): + """get iserver test names""" + + # iserver utils test get names + + names = self_testing.get_tests(directory, names=True) + if names is None: + print('No tests found') + return + + for name in names: + print(name) diff --git a/menu/utils/test/get/summary.py b/menu/utils/test/get/summary.py new file mode 100644 index 00000000..ce06f8ba --- /dev/null +++ b/menu/utils/test/get/summary.py @@ -0,0 +1,14 @@ +import click + +from lib import self_testing + + +@click.command("summary") +@click.pass_obj +@click.option("--directory", is_flag=False, show_default=False, default='tests', type=click.STRING, help="Test definitions") +def utils_test_get_summary_command(ctx, directory): + """get iserver test summary""" + + # iserver utils test get summary + + self_testing.get_summary(directory, replace=True) diff --git a/menu/utils/test/main.py b/menu/utils/test/main.py new file mode 100644 index 00000000..0fc98c2e --- /dev/null +++ b/menu/utils/test/main.py @@ -0,0 +1,18 @@ +import click + +from menu.utils.test.get.main import utils_test_get_menu +from menu.utils.test.run import utils_test_run_command + + +class Failure(Exception): + pass + + +@click.group("test") +@click.pass_obj +def utils_test_menu(ctx): + """Self Testing""" + + +utils_test_menu.add_command(utils_test_get_menu) +utils_test_menu.add_command(utils_test_run_command) diff --git a/menu/utils/test/run.py b/menu/utils/test/run.py new file mode 100644 index 00000000..361488c3 --- /dev/null +++ b/menu/utils/test/run.py @@ -0,0 +1,104 @@ +import sys +import click + +from lib import self_testing +from lib import self_doc +from menu import defaults +from menu import validations + + +@click.command("run") +@click.pass_obj +@click.option("--test-name", is_flag=False, show_default=False, default=None, type=click.STRING, help="Specific test selected by name") +@click.option("--test-collection", is_flag=False, show_default=False, default=None, type=click.STRING, help="Filename with test names") +@click.option("--tests", "tests_directory", is_flag=False, show_default=False, default='tests', type=click.STRING, help="Test definitions") +@click.option("--results", "results_directory", is_flag=False, show_default=False, default='results', type=click.STRING, help="Results location") +@click.option("--environment", is_flag=False, show_default=False, default='', type=click.STRING, help="Test environment") +@click.option("--iaccount", is_flag=False, show_default=True, cls=defaults.default_from_context('iaccount'), callback=validations.validate_iaccount, type=click.STRING, help="Intersight account") +@click.option("--enforce", is_flag=True, show_default=True, default=False, help="Enforce cli iaccount/enviornment") +@click.option("--honor", is_flag=True, show_default=True, default=False, help="Prefer test iaccount/enviornment over collection/cli") +@click.option("--doc", is_flag=True, show_default=True, default=False, help="Documentation generation when tests are successful") +@click.option("--no-redfish", is_flag=True, show_default=True, default=False, help="Disable redfish tests doc") +@click.option("--wait", is_flag=True, show_default=True, default=False, help="Wait for keypress between tests") +@click.option("--verbose", is_flag=True, show_default=True, default=False, help="Verbose output") +@click.option("--debug", is_flag=True, show_default=True, default=False, help="Debug output") +@click.option("--dry-run", is_flag=True, show_default=True, default=False, help="Dry run") +def utils_test_run_command(ctx, test_name, test_collection, tests_directory, results_directory, environment, iaccount, enforce, honor, doc, no_redfish, wait, verbose, debug, dry_run): + """run iserver tests""" + + # iserver utils devel self-test run + + if debug: + verbose = True + + if test_collection is None and test_name is None: + print('Define the scope of tests') + sys.exit(1) + + if test_collection is not None: + selected_tests, tests_count = self_testing.get_tests_collection(test_collection, tests_directory) + if not enforce: + test_iaccount = self_testing.get_test_iaccount(test_collection, tests_directory) + if test_iaccount is not None: + iaccount = test_iaccount + + test_environment = self_testing.get_test_environment(test_collection, tests_directory) + if test_environment is not None: + environment = test_environment + + else: + selected_tests, tests_count = self_testing.get_test_by_name(test_name, tests_directory) + if not enforce: + test_iaccount = self_testing.get_test_iaccount(test_name, tests_directory) + if test_iaccount is not None: + iaccount = test_iaccount + + test_environment = self_testing.get_test_environment(test_name, tests_directory) + if test_environment is not None: + environment = test_environment + + if selected_tests is None: + print('Test collection failed') + sys.exit(1) + + if not honor: + print('iaccount: %s' % (iaccount)) + if len(environment) > 0: + print('environment: %s' % (environment)) + + results = self_testing.run_tests( + selected_tests, + tests_count, + tests_directory, + results_directory, + environment, + iaccount, + honor, + verbose, + debug, + dry_run, + wait=wait + ) + success = 0 + for result in results: + if result['success']: + print("OK\t%s" % (result['command'])) + success = success + 1 + else: + print("NOK\t%s" % (result['command'])) + + print('\nSummary') + print('- Tests: %s' % (len(results))) + print('- Success: %s' % (success)) + + failed = len(results) - success + print('- Failed: %s' % (failed)) + + if failed == 0 and doc: + success = self_doc.generate_docs( + results_directory, + redfish_tests=not no_redfish + ) + + if not success: + sys.exit(1) diff --git a/menu/validations.py b/menu/validations.py new file mode 100644 index 00000000..0d869fa5 --- /dev/null +++ b/menu/validations.py @@ -0,0 +1,2140 @@ +import os +import socket +import traceback + +import click + +from lib import context +from lib import file_helper +from lib import iaccount_helper +from lib import ip_helper +from lib import my_servers_helper +from lib import settings_helper + +from lib.intersight import organization +from lib.intersight import scu +from lib.intersight import os_image +from lib.intersight import hcl_operating_system +from lib.intersight import hcl_operating_system_vendor + +from lib.aci import apic +from lib.aci import settings as aci_settings +from lib.k8s import settings as k8s_settings +from lib.k8s import main as k8s +from lib.kubevirt import main as kubevirt +from lib.osp import settings as osp_settings +from lib.osp import main as osp + +from lib.nexus import settings as nexus_settings +from lib.nexus import nxapi +from lib.nso import settings as nso_settings +from lib.nso import main as nso +from lib.ocp import settings as ocp_settings +from lib.ocp import main as ocp +from lib.ocp.vm import validate as ocp_deployment_validate +from lib.ucsm import settings as ucsm_settings +from lib.vc import vcenter +from lib.vc import settings as vc_settings +from lib.linux import main as linux +from lib.linux import settings as linux_settings + + +def validate_iaccount(ctx, param, value): + iaccount_handler = iaccount_helper.IntersightAccount() + if not iaccount_handler.is_isctl(): + raise click.BadParameter('isctl not found') + + if value is None: + raise click.BadParameter('Define iaccount value') + + + if not iaccount_handler.is_iaccount_valid(value): + iaccounts = iaccount_handler.get_iaccounts() + print('Defined iaccounts:') + for iaccount in iaccounts: + print(iaccount['name']) + + raise click.BadParameter('Invalid iaccount value') + + iaccount_handler.set_default_iaccount(value) + + return value + + +def validate_organization(ctx, iaccount, organization_name): + organization_handler = organization.Organization(iaccount, log_id=ctx.run_id) + + if len(organization_name) == 0: + organizations = organization_handler.get_moids_dict() + if len(organizations) == 0: + ctx.busy = False + ctx.my_output.error('No organizations found') + return None + + if len(organizations) > 0: + ctx.busy = False + ctx.my_output.error('Multiple organizations found. Select single one') + for key in organizations: + ctx.my_output.default('- %s' % (organizations[key])) + return None + + return list(organizations.keys())[0] + + organization_details = organization_handler.get_by_name(organization_name) + if organization_details is None: + ctx.busy = False + ctx.my_output.error('Organization not found: %s' % (organization_name)) + return None + + return organization_details['Moid'] + + +def validate_fqdn(value): + try: + address = socket.gethostbyname(value) + if ip_helper.is_valid_ipv4_address(address): + return True + + except BaseException: + pass + + return False + + +def validate_ip(ctx, param, value): + if value is not None and len(value) > 0: + if not ip_helper.is_valid_ipv4_address(value): + if not validate_fqdn(value): + raise click.BadParameter('Invalid IPv4 address: %s' % (value)) + + return value + + +def validate_ips(ctx, param, values): + context_handler = context.Context() + ips = [] + + for value in values: + if value is not None and len(value) > 0: + + if len(value.split('ctx:')) == 2: + context_ips = context_handler.get( + value.split('ctx:')[1] + ) + if context_ips is None: + raise click.BadParameter('Unknown context: %s' % (value.split('ctx:')[1])) + + for item in context_ips: + if not ip_helper.is_valid_ipv4_address(item): + if not validate_fqdn(item): + raise click.BadParameter('Invalid IPv4 address: %s' % (item)) + + ips.append(item) + else: + if not ip_helper.is_valid_ipv4_address(value): + if not validate_fqdn(value): + raise click.BadParameter('Invalid IPv4 address: %s' % (value)) + + ips.append(value) + + return ips + + +def validate_ip_subnet(ctx, param, value): + if len(value) > 0: + if ip_helper.is_valid_ipv4_address(value): + return value + + if ip_helper.is_valid_ipv4_cidr(value): + return value + + raise click.BadParameter('Invalid IPv4 address or subnet: %s' % (value)) + + return value + + +def validate_subnet(ctx, param, value): + if len(value) > 0: + if ip_helper.is_valid_ipv4_cidr(value): + return value + + raise click.BadParameter('Invalid subnet: %s' % (value)) + + return value + + +def validate_prefix_length(ctx, param, value): + if value <= 0 or value >= 30: + raise click.BadParameter('Invalid prefix length') + return value + + +def validate_file_content(ctx, filename): + if not os.path.isfile(filename): + ctx.my_output.error('File %s not found' % (filename)) + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + return None + + return content + + +def validate_file(ctx, param, filename): + if len(filename) == 0: + raise click.BadParameter('Define filename') + + if not os.path.isfile(filename): + raise click.BadParameter('File %s not found' % (filename)) + + return filename + + +def validate_optional_file(ctx, param, filename): + if len(filename) == 0: + return None + + if not os.path.isfile(filename): + raise click.BadParameter('File %s not found' % (filename)) + + return filename + + +def validate_int_oper(ctx, param, value): + if len(value) == 0: + return value + + for prefix in ['ge', '>=', 'le', '<=', 'gt', '>', 'lt', '<', 'ne', '!=']: + if value.startswith(prefix): + try: + int_value = int(value.lstrip(prefix)) + return value + except BaseException: + pass + raise click.BadParameter('Wrong value: %s' % (value)) + + try: + int_value = int(value) + return value + except BaseException: + pass + + raise click.BadParameter('Wrong value: %s' % (value)) + + +def validate_group(ctx, param, value): + my_servers_handler = my_servers_helper.MyServers() + if not my_servers_handler.is_group(value): + raise click.BadParameter('Group not found: %s' % (value)) + return value + + +def validate_group_serials(ctx, param, value): + if len(value) == 0: + return [] + + my_servers_handler = my_servers_helper.MyServers() + if not my_servers_handler.is_group(value): + raise click.BadParameter('Group not found: %s' % (value)) + + serials = my_servers_handler.get_group_serials(value) + if serials is None or len(serials) == 0: + raise click.BadParameter('No group members found: %s' % (value)) + + return serials + + +def validate_group_oper(ctx, param, value): + my_servers_handler = my_servers_helper.MyServers() + if len(value) == 0: + return None + + group_oper = {} + if value.startswith('+'): + group_oper['oper'] = 'add' + group_oper['group'] = value.lstrip('+') + + if value.startswith('-'): + group_oper['oper'] = 'del' + group_oper['group'] = value.lstrip('-') + + if not value.startswith('-') and not value.startswith('+'): + group_oper['oper'] = 'set' + group_oper['group'] = value + return group_oper + + if not my_servers_handler.is_group(group_oper['group']): + raise click.BadParameter('Group not found: %s' % (value)) + + return group_oper + + +def validate_filter_serials(ctx, param, value): + if len(value) == 0: + return [] + return value.split(',') + + +def validate_filter_ip(ctx, param, value): + if len(value) == 0: + return [] + + ip_filter = [] + for item in value.split(','): + if ip_helper.is_valid_ipv4_address(item): + ip_filter.append( + dict( + type='address', + value=item + ) + ) + continue + + if ip_helper.is_valid_ipv4_cidr(item): + ip_filter.append( + dict( + type='subnet', + value=item + ) + ) + continue + + raise click.BadParameter('Invalid IP address or subnet value: %s' % (item)) + + return ip_filter + + +def validate_scu(ctx, iaccount, scu_name, required=True): + if len(scu_name) == 0: + if required: + ctx.my_output.error('SCU value required') + return None + return scu_name + + scu_handler = scu.SoftwareConfigurationUtility(iaccount, log_id=ctx.run_id) + scu_item = scu_handler.get_by_name(scu_name) + if scu_item is None: + ctx.my_output.error('SCU not found: %s' % (scu_name)) + return None + + return scu_item + + +def validate_os_image(ctx, iaccount, image_name, required=True): + if len(image_name) == 0: + if required: + ctx.my_output.error('OS image value required') + return None + return image_name + + image_handler = os_image.OsImage(iaccount, log_id=ctx.run_id) + image_item = image_handler.get_by_name(image_name) + if image_item is None: + ctx.my_output.error('Image not found: %s' % (image_name)) + return None + + vendor_handler = hcl_operating_system_vendor.HclOperatingSystemVendor(iaccount, log_id=ctx.run_id) + vendor_item = vendor_handler.get_by_name(image_item['Vendor']) + if vendor_item is None: + ctx.my_output.error('Image vendor not found: %s' % (image_item['Vendor'])) + return None + image_item['VendorId'] = vendor_item['Moid'] + + version_handler = hcl_operating_system.HclOperatingSystem(iaccount, log_id=ctx.run_id) + version_item = version_handler.get_vendor_version(vendor_item['Moid'], image_item['Version']) + if version_item is None: + ctx.my_output.error('Image version not found: %s' % (image_item['Version'])) + return None + + image_item['VersionId'] = version_item['Moid'] + + return image_item + + +def validate_chassis_ifm_filter(ctx, param, value): + if value is None: + ifm_filter = {} + ifm_filter['enabled'] = False + return ifm_filter + + if value.lower() in ['all', '.', '*']: + ifm_filter = {} + ifm_filter['enabled'] = True + ifm_filter['path'] = None + ifm_filter['id'] = None + return ifm_filter + + if len(value.split(',')) > 1: + raise click.BadParameter('Select module by ID or Path') + + if value.lower() == 'a': + ifm_filter = {} + ifm_filter['enabled'] = True + ifm_filter['path'] = 'A' + ifm_filter['id'] = None + return ifm_filter + + if value.lower() == 'b': + ifm_filter = {} + ifm_filter['enabled'] = True + ifm_filter['path'] = 'B' + ifm_filter['id'] = None + return ifm_filter + + try: + ifm_module_id = int(value) + except BaseException: + ifm_module_id = None + + if ifm_module_id is None: + raise click.BadParameter('Select path A or B') + + if ifm_module_id not in [1, 2]: + raise click.BadParameter('Select module id 1 or 2') + + ifm_filter = {} + ifm_filter['enabled'] = True + ifm_filter['path'] = None + ifm_filter['id'] = ifm_module_id + + return ifm_filter + + +def validate_chassis_fan_filter(ctx, param, value): + fan_filter = {} + fan_filter['enabled'] = value + return fan_filter + + +def validate_chassis_power_filter(ctx, param, value): + power_filter = {} + power_filter['enabled'] = value + return power_filter + + +def validate_chassis_node_filter(ctx, param, value): + node_filter = {} + node_filter['enabled'] = value + return node_filter + + +def validate_chassis_port_filter(ctx, param, value): + if len(value) == 0: + port_filter = {} + port_filter['enabled'] = False + return port_filter + + port_filter = {} + port_filter['enabled'] = True + port_filter['type'] = None + port_filter['state'] = None + port_filter['module'] = None + port_filter['node'] = None + + for parameter in value: + if parameter.lower() in ['all', '.', '*']: + return port_filter + + if len(parameter.split(':')) != 2: + continue + + (param_type, param_value) = parameter.split(':') + + if param_type.lower() in ['t', 'type']: + if param_value.lower() not in ['host', 'net']: + raise click.BadParameter('Port type host or net') + port_filter['type'] = param_value.lower() + + if param_type.lower() in ['s', 'state']: + if param_value.lower() not in ['up', 'down']: + raise click.BadParameter('Port state up or down') + port_filter['state'] = param_value.lower() + + if param_type.lower() in ['m', 'module']: + if param_value.lower() not in ['a', 'b', '1', '2']: + raise click.BadParameter('Port path a/b or 1/2') + port_filter['module'] = param_value.lower() + + if param_type.lower() in ['n', 'node']: + if param_value.lower() in ['.', '*', 'all']: + port_filter['node'] = -1 + else: + node_id = None + try: + node_id = int(param_value) + except BaseException: + pass + + if node_id is None: + raise click.BadParameter('Node all or index') + + port_filter['node'] = node_id + + return port_filter + + +def validate_redfish_path(ctx, param, value): + if value == '': + return value + + if value.startswith('/redfish/v1/'): + value = value.lstrip('/redfish/v1/') + + if value.startswith('/api-explorer/resources/redfish/v1/'): + value = value.lstrip('/api-explorer/resources/redfish/v1/') + + return value + + +def validate_apic_name(ctx, param, value): + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + if len(value) == 0: + default_controller_name = aci_settings_handler.get_default_controller() + if default_controller_name is None: + return None + + return aci_settings_handler.get_apic_controller(default_controller_name) + + controller = aci_settings_handler.get_apic_controller(value) + if controller is None: + controllers = aci_settings_handler.get_apic_controller_names() + if controllers is None: + raise click.BadParameter('Invalid apic name') + raise click.BadParameter('Invalid apic name. Define one of %s' % (','.join(controllers))) + + return controller + + +def validate_apic_any_name(ctx, param, value): + if len(value) == 0: + return [] + + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + selected_controllers = [] + names = [] + + for parameter in value.split(','): + if parameter.lower() in ['any', 'all']: + all_controllers = aci_settings_handler.get_apic_controllers() + if all_controllers is not None: + for controller in all_controllers: + if controller['name'] not in names: + names.append( + controller['name'] + ) + selected_controllers.append( + controller + ) + + continue + + if parameter.startswith('dom:'): + domain_controllers = aci_settings_handler.get_apic_domain_controllers( + parameter[4:] + ) + if domain_controllers is not None: + for domain_controller in domain_controllers: + if domain_controller['name'] not in names: + names.append( + domain_controller['name'] + ) + selected_controllers.append( + domain_controller + ) + + continue + + controller = aci_settings_handler.get_apic_controller(parameter) + if controller is not None: + aci_settings_handler.set_default_controller( + controller['name'] + ) + + if controller is None: + controllers = aci_settings_handler.get_apic_controller_names() + if controllers is None: + raise click.BadParameter('Invalid apic name') + controllers.append('any') + raise click.BadParameter('Invalid apic name. Define one of %s' % (','.join(controllers))) + + if controller['name'] not in names: + names.append( + controller['name'] + ) + selected_controllers.append( + controller + ) + + return selected_controllers + + +def validate_apic_controller(ctx, controller_obj, controller_ip, controller_port, controller_username, controller_password, show_selected=True, auto_connect=False, no_cache=False, debug=False): + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + + if controller_obj is None and len(controller_ip) == 0 and len(controller_username) == 0 and len(controller_password) == 0: + controller_name = aci_settings_handler.get_default_controller() + if controller_name is not None: + controller_obj = aci_settings_handler.get_apic_controller(controller_name) + + if len(controller_ip) > 0 or len(controller_username) > 0 or len(controller_password) > 0: + if len(controller_ip) == 0 or len(controller_username) == 0 or len(controller_password) == 0: + ctx.my_output.error('Define controller name or ip/username/password') + return None + else: + controller_ip = controller_obj['ip'] + controller_port = controller_obj['port'] + controller_username = controller_obj['username'] + controller_password = controller_obj['password'] + aci_settings_handler.set_default_controller( + controller_obj['name'] + ) + + if show_selected and ctx.output == 'default': + ctx.my_output.default( + aci_settings_handler.get_apic_controller_label( + controller_obj['name'] + ) + ) + + apic_handler = apic.Apic( + controller_ip, + controller_port, + controller_username, + controller_password, + apic_name=controller_obj['name'], + log_id=ctx.run_id, + no_cache=no_cache, + debug=debug + ) + + if auto_connect: + if not apic_handler.is_connected(): + ctx.my_output.error('Failed to connect to APIC') + return None + + return apic_handler + + +def validate_apic_controllers(ctx, controller_objs, controller_ip, controller_port, controller_username, controller_password, show_selected=True, auto_connect=False, no_cache=False): + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + + if len(controller_objs) == 0 and len(controller_ip) == 0 and len(controller_username) == 0 and len(controller_password) == 0: + controller_name = aci_settings_handler.get_default_controller() + if controller_name is not None: + controller_objs.append( + aci_settings_handler.get_apic_controller(controller_name) + ) + + if len(controller_ip) > 0 and len(controller_username) > 0 and len(controller_password) > 0: + controller_objs.append( + dict( + name=controller_ip, + ip=controller_ip, + port=controller_port, + username=controller_username, + password=controller_password + ) + ) + + if len(controller_objs) == 0: + ctx.my_output.error('Select at least on APIC') + return None + + apic_handlers = [] + names = [] + for controller_obj in controller_objs: + controller_ip = controller_obj['ip'] + controller_port = controller_obj['port'] + controller_username = controller_obj['username'] + controller_password = controller_obj['password'] + + apic_handler = apic.Apic( + controller_ip, + controller_port, + controller_username, + controller_password, + apic_name=controller_obj['name'], + log_id=ctx.run_id, + no_cache=no_cache + ) + + if auto_connect: + if not apic_handler.is_connected(): + ctx.my_output.error('Failed to connect to APIC') + return None + + names.append(controller_obj['name']) + apic_handlers.append( + dict( + name=controller_obj['name'], + handler=apic_handler + ) + ) + + if show_selected and ctx.output == 'default': + if len(names) > 0: + for name in names: + ctx.my_output.default( + aci_settings_handler.get_apic_controller_label( + name + ) + ) + + return apic_handlers + + +def validate_apic_controllers_with_context_interfaces(ctx, context_interfaces): + controller_names = [] + for context_interface in context_interfaces: + apic_name = context_interface.split(':')[1] + if apic_name not in controller_names: + controller_names.append(apic_name) + + controller_objs = validate_apic_any_name(ctx, 'apic', ','.join(controller_names)) + apic_handlers = validate_apic_controllers( + ctx, + controller_objs, + '', + '', + '', + '', + show_selected=False + ) + if apic_handlers is None: + return None + + for apic_handler in apic_handlers: + node_names = [] + for context_interface in context_interfaces: + if apic_handler['name'] == context_interface.split(':')[1]: + node_name = apic_handler['handler'].get_node_name( + context_interface.split(':')[3].split('-')[1], + pod_id=context_interface.split(':')[2].split('-')[1] + ) + if node_name not in node_names: + node_names.append( + node_name + ) + + apic_handler['nodes'] = validate_apic_node_names( + ctx, + apic_handler['handler'], + node_names, + node_role='any' + ) + if apic_handler['nodes'] is None: + return None + + return apic_handlers + + +def validate_apic_controllers_with_nodes(ctx, controller_objs, controller_ip, controller_port, controller_username, controller_password, node_names, node_role, pod_id=None, no_cache=False): + apic_handlers = validate_apic_controllers( + ctx, + controller_objs, + controller_ip, + controller_port, + controller_username, + controller_password, + show_selected=False, + no_cache=no_cache + ) + if apic_handlers is None: + return None + + if len(apic_handlers) > 1: + if len(node_names) == 0: + node_names = ['any'] + + if len(apic_handlers) == 1: + if len(node_names) == 0 and node_role == 'any': + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + node_name = aci_settings_handler.get_default_node( + apic_handlers[0]['handler'].get_apic_ip() + ) + if node_name is None: + ctx.my_output.error('Define node name') + return None + node_names = [node_name] + + for apic_handler in apic_handlers: + apic_handler['nodes'] = validate_apic_node_names( + ctx, + apic_handler['handler'], + node_names, + node_role, + pod_id=pod_id + ) + if apic_handler['nodes'] is None: + return None + + return apic_handlers + + +def validate_apic_node_name(ctx, apic_handler, node_name, pod_id=None): + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + + if node_name is None: + node_name = aci_settings_handler.get_default_node( + apic_handler.get_apic_ip() + ) + if node_name is None: + ctx.my_output.error('Define node name') + return None + + node_filter = [] + if pod_id is not None: + node_filter.append( + 'pod:%s' % (pod_id) + ) + + node_filter.append( + 'name:*%s*' % (node_name.replace('*', '')) + ) + + nodes_info = apic_handler.get_nodes( + node_filter=node_filter + ) + + if nodes_info is None or len(nodes_info) != 1: + ctx.my_output.error( + 'Unique node name match failed: %s' % (node_name) + ) + + node_names = apic_handler.get_node_names(pod_id=pod_id) + if node_names is not None: + ctx.my_output.default('\nNode names:') + for name in node_names: + ctx.my_output.default('- %s' % (name)) + + return None + + aci_settings_handler.set_default_node( + apic_handler.get_apic_ip(), + nodes_info[0]['name'] + ) + if ctx.output == 'default': + ctx.my_output.default('Pod: %s' % (nodes_info[0]['podId'])) + ctx.my_output.default('Node: %s' % (nodes_info[0]['name'])) + + return nodes_info[0] + + +def validate_apic_node_names(ctx, apic_handler, node_names, node_role, pod_id=None, silent=False): + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + + # Check default node name + if len(node_names) == 0 and node_role == 'any': + node_name = aci_settings_handler.get_default_node( + apic_handler.get_apic_ip() + ) + if node_name is None: + ctx.my_output.error('Define node name') + return None + + node_names = [node_name] + + node_filter = [] + role_filter = True + + if pod_id is not None: + role_filter = False + node_filter.append( + 'pod:%s' % (pod_id) + ) + + if node_role != 'any': + node_filter.append( + 'role:%s' % (node_role) + ) + else: + role_filter = False + node_filter.append( + 'role:!controller' + ) + + if 'any' not in node_names and len(node_names) > 0: + role_filter = False + new_node_names = [] + for node_name in node_names: + new_node_names.append( + '*%s*' % (node_name.replace('*', '')) + ) + + node_filter.append( + 'names:%s' % (','.join(new_node_names)) + ) + + nodes_info = apic_handler.get_nodes( + node_filter=node_filter + ) + + if nodes_info is None: + ctx.my_output.error( + 'Failed to get nodes' + ) + return None + + if len(nodes_info) == 0: + ctx.my_output.error( + 'No node name match' + ) + + node_names = apic_handler.get_node_names(pod_id=pod_id) + if node_names is not None and not silent: + ctx.my_output.default('\nNode names:') + for name in node_names: + ctx.my_output.default('- %s' % (name)) + + return None + + if len(nodes_info) == 1: + aci_settings_handler.set_default_node( + apic_handler.get_apic_ip(), + nodes_info[0]['name'] + ) + if ctx.output == 'default' and not silent: + ctx.my_output.default( + aci_settings_handler.get_apic_controller_label( + apic_handler.get_apic_name() + ) + ) + ctx.my_output.default('Pod: %s' % (nodes_info[0]['podId'])) + ctx.my_output.default('Node: %s' % (nodes_info[0]['name'])) + + if len(nodes_info) > 1: + if ctx.output == 'default' and not silent: + nodes_count = apic_handler.get_node_count() + ctx.my_output.default( + aci_settings_handler.get_apic_controller_label( + apic_handler.get_apic_name() + ) + ) + ctx.my_output.default('Pod: %s' % (nodes_info[0]['podId'])) + if len(nodes_info) == nodes_count: + ctx.my_output.default('Node: all (#%s)' % (nodes_count)) + return nodes_info + + if role_filter: + if node_role == 'spine': + ctx.my_output.default('Node: all spines (#%s)' % (len(nodes_info))) + return nodes_info + + if node_role == 'leaf': + ctx.my_output.default('Node: all leaves (#%s)' % (len(nodes_info))) + return nodes_info + + for node_info in nodes_info: + ctx.my_output.default('- node: %s' % (node_info['name'])) + + return nodes_info + + +def validate_apic_tenant_name(ctx, param, value): + if len(value) == 0: + return None + + tenant_name = {} + if len(value.split('/')) == 1: + tenant_name['tenant'] = None + tenant_name['name'] = value + return tenant_name + + if len(value.split('/')) == 2: + tenant_name['tenant'] = value.split('/')[0] + tenant_name['name'] = value.split('/')[1] + return tenant_name + + raise click.BadParameter('Invalid name syntax') + + +def validate_apic_tenant_ap_name(ctx, param, value): + if len(value) == 0: + return None + + tenant_name = {} + if len(value.split('/')) == 1: + tenant_name['tenant'] = None + tenant_name['ap'] = None + tenant_name['name'] = value + return tenant_name + + if len(value.split('/')) == 2: + tenant_name['tenant'] = None + tenant_name['ap'] = value.split('/')[0] + tenant_name['name'] = value.split('/')[1] + return tenant_name + + if len(value.split('/')) == 3: + tenant_name['tenant'] = value.split('/')[0] + tenant_name['ap'] = value.split('/')[1] + tenant_name['name'] = value.split('/')[2] + return tenant_name + + raise click.BadParameter('Invalid name syntax') + + +def validate_context(ctx, param, value): + if len(value) == 0: + return None + + context_handler = context.Context() + user_context = {} + user_context['key'] = value + user_context['value'] = context_handler.get(value) + if user_context['value'] is None: + return None + + return user_context + + +def validate_nexus_name(ctx, param, value): + if len(value) == 0: + return None + + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + nexus_device = nexus_settings_handler.get_nexus_device(value) + if nexus_device is None: + devices = nexus_settings_handler.get_nexus_device_names() + if devices is None: + raise click.BadParameter('Invalid device name') + raise click.BadParameter('Invalid device name. Define one of %s' % (','.join(devices))) + + return nexus_device + + +def validate_nexus_any_name(ctx, param, value): + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + selected_devices = [] + names = [] + + if len(value) == 0: + default_nexus = nexus_settings_handler.get_default_nexus_device() + if default_nexus is not None: + value = default_nexus + + for parameter in value.split(','): + if parameter.lower() in ['any', 'all']: + all_devices = nexus_settings_handler.get_nexus_devices() + if all_devices is not None: + for device in all_devices: + if device['name'] not in names: + names.append( + device['name'] + ) + selected_devices.append( + device + ) + + continue + + if parameter.startswith('dom:'): + domain_devices = nexus_settings_handler.get_nexus_domain_devices( + parameter[4:] + ) + if domain_devices is not None: + for domain_device in domain_devices: + if domain_device['name'] not in names: + names.append( + domain_device['name'] + ) + selected_devices.append( + domain_device + ) + + continue + + device = nexus_settings_handler.get_nexus_device(parameter) + if device is not None: + nexus_settings_handler.set_default_nexus_device( + device['name'] + ) + + if device is None: + devices = nexus_settings_handler.get_nexus_device_names() + if devices is None: + raise click.BadParameter('Invalid nexus name') + devices.append('any') + raise click.BadParameter('Invalid nexus name. Define one of %s' % (','.join(devices))) + + if device['name'] not in names: + names.append( + device['name'] + ) + selected_devices.append( + device + ) + + return selected_devices + + +def validate_nexus_device(ctx, device_obj, device_ip, device_username, device_password, debug=False): + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + + if device_obj is None and len(device_ip) == 0 and len(device_username) == 0 and len(device_password) == 0: + device_name = nexus_settings_handler.get_default_nexus_device() + if device_name is not None: + device_obj = nexus_settings_handler.get_nexus_device(device_name) + + device_name = None + if device_obj is not None: + device_ip = device_obj['ip'] + device_username = device_obj['username'] + device_password = device_obj['password'] + device_name = device_obj['name'] + nexus_settings_handler.set_default_nexus_device( + device_obj['name'] + ) + + if ctx.output == 'default': + ctx.my_output.default('Switch: %s' % (device_obj['name'])) + + if device_obj is None: + if len(device_ip) == 0 or len(device_username) == 0 or len(device_password) == 0: + ctx.my_output.error('Define device name or ip/username/password') + return None + + nexus_handler = nxapi.NxApi( + device_ip, + device_username, + device_password, + name=device_name, + log_id=ctx.run_id, + debug=debug + ) + + if not nexus_handler.is_connected(autoconnect=True): + ctx.my_output.error('Failed to connect to device') + return None + + return nexus_handler + + +def validate_nexus_devices(ctx, device_objs, device_ip, device_username, device_password, show_selected=True, debug=False, cache_enabled=False): + nexus_settings_handler = nexus_settings.NexusSettings(log_id=None) + + if len(device_objs) == 0 and len(device_ip) == 0 and len(device_username) == 0 and len(device_password) == 0: + device_name = nexus_settings_handler.get_default_nexus_device() + if device_name is not None: + device_objs.append( + nexus_settings_handler.get_nexus_device(device_name) + ) + + if len(device_ip) > 0 and len(device_username) > 0 and len(device_password) > 0: + device_objs.append( + dict( + name=device_ip, + ip=device_ip, + username=device_username, + password=device_password + ) + ) + + if len(device_objs) == 0: + ctx.my_output.error('Select at least one device') + return None + + device_handlers = [] + names = [] + for device_obj in device_objs: + device_name = device_obj['name'] + device_ip = device_obj['ip'] + device_username = device_obj['username'] + device_password = device_obj['password'] + + nexus_handler = nxapi.NxApi( + device_ip, + device_username, + device_password, + name=device_name, + log_id=ctx.run_id, + debug=debug, + cache_enabled=cache_enabled + ) + + names.append(device_obj['name']) + device_handlers.append( + dict( + name=device_obj['name'], + handler=nexus_handler + ) + ) + + if show_selected and ctx.output == 'default': + if len(names) > 0: + ctx.my_output.default('Device: %s' % (','.join(names))) + + return device_handlers + + +def validate_ucsm_name(ctx, param, value): + if len(value) == 0: + raise click.BadParameter('Define ucsm name') + + ucsm_settings_handler = ucsm_settings.UcsmSettings(log_id=None) + ucsm_manager = ucsm_settings_handler.get_ucsm_manager(value) + if ucsm_manager is None: + raise click.BadParameter('Invalid ucsm name') + + return ucsm_manager + + +def validate_vc_name(ctx, param, value): + if len(value) == 0: + return None + + vc_settings_handler = vc_settings.VcSettings(log_id=None) + instance = vc_settings_handler.get_vc_instance(value) + if instance is None: + raise click.BadParameter('Invalid vcenter name') + + return instance + + +def validate_vc_any_name(ctx, param, value): + if len(value) == 0: + return None + + vc_settings_handler = vc_settings.VcSettings(log_id=None) + + if value.lower() in ['any', 'all']: + return vc_settings_handler.get_vc_instances() + + instance = vc_settings_handler.get_vc_instance(value) + if instance is None: + raise click.BadParameter('Invalid vcenter name') + + return instance + + +def validate_vcenter(ctx, vcenter_obj, vcenter_ip, vcenter_username, vcenter_password, vcenter_port=443): + vc_settings_handler = vc_settings.VcSettings(log_id=ctx.run_id) + + if vcenter_obj is None and len(vcenter_ip) == 0 and len(vcenter_username) == 0 and len(vcenter_password) == 0: + instance_name = vc_settings_handler.get_default_instance() + if instance_name is not None: + vcenter_obj = vc_settings_handler.get_vc_instance(instance_name) + + if vcenter_obj is not None: + vcenter_ip = vcenter_obj['ip'] + vcenter_port = vcenter_obj['port'] + vcenter_username = vcenter_obj['username'] + vcenter_password = vcenter_obj['password'] + vc_settings_handler.set_default_instance( + vcenter_obj['name'] + ) + + if ctx.output == 'default': + ctx.my_output.default('vcenter: %s' % (vcenter_obj['name'])) + + if vcenter_obj is None: + if len(vcenter_ip) == 0 or len(vcenter_username) == 0 or len(vcenter_password) == 0: + ctx.my_output.error('Define vcenter name or ip/username/password') + return None + + vc_handler = vcenter.Vcenter( + vcenter_ip, + vcenter_username, + vcenter_password, + port=vcenter_port, + log_id=ctx.run_id + ) + + if not vc_handler.is_vc_connected(): + ctx.my_output.error('Failed to connect to vcenter') + return None + + return vc_handler + + +def validate_vcenters(ctx, vcenter_objs): + vc_settings_handler = vc_settings.VcSettings(log_id=None) + + vc_handlers = [] + for vcenter_obj in vcenter_objs: + vcenter_ip = vcenter_obj['ip'] + vcenter_port = vcenter_obj['port'] + vcenter_username = vcenter_obj['username'] + vcenter_password = vcenter_obj['password'] + + vcenter_handler = vcenter.Vcenter( + vcenter_ip, + vcenter_username, + vcenter_password, + port=vcenter_port, + log_id=ctx.run_id + ) + + if not vcenter_handler.is_vc_connected(): + ctx.my_output.error('Failed to connect to vcenter') + return None + + vc_handlers.append( + dict( + name=vcenter_obj['name'], + handler=vcenter_handler + ) + ) + + return vc_handlers + + +def empty_string_to_none(ctx, param, value): + if len(value) == 0: + return None + + return value + + +def validate_ocp_cluster(ctx, cluster_name, verbose=False, debug=False, silent=False): + ocp_settings_handler = ocp_settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None or cluster_name == '': + cluster_name = ocp_settings_handler.get_default_cluster() + if cluster_name is None: + ctx.my_output.error('Define ocp cluster name') + return None + + if ctx.output == 'default' and not silent: + ctx.my_output.default('Cluster: %s' % (cluster_name)) + + cluster_obj = ocp_settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if cluster_obj is None: + ctx.my_output.error('Define valid ocp cluster name') + names = ocp_settings_handler.get_ocp_cluster_names() + if names is not None: + for name in names: + ctx.my_output.default('- %s' % (name)) + + return None + + ocp_settings_handler.set_default_cluster( + cluster_obj['name'] + ) + + ocp_handler = ocp.Ocp( + cluster_obj['name'], + verbose=verbose, + debug=debug, + log_id=ctx.run_id + ) + + return ocp_handler + + +def get_ocp_cluster_settings(ctx, cluster_name, silent=False): + ocp_settings_handler = ocp_settings.OcpSettings(log_id=ctx.run_id) + + if cluster_name is None or cluster_name == '': + cluster_name = ocp_settings_handler.get_default_cluster() + if cluster_name is None: + ctx.my_output.error('Define ocp cluster name') + names = ocp_settings_handler.get_ocp_cluster_names() + if names is not None: + for name in names: + ctx.my_output.default('- %s' % (name)) + return None + + if ctx.output == 'default' and not silent: + ctx.my_output.default('Cluster: %s' % (cluster_name)) + + settings = ocp_settings_handler.get_ocp_cluster(cluster_name) + return settings + + settings = ocp_settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if settings is None: + ctx.my_output.error('Define valid ocp cluster name') + names = ocp_settings_handler.get_ocp_cluster_names() + if names is not None: + for name in names: + ctx.my_output.default('- %s' % (name)) + return None + + ocp_settings_handler.set_default_cluster( + settings['name'] + ) + + return settings + + +def validate_ocp_cluster_settings(ctx, cluster_name, silent=False, mandatory=[]): + settings = get_ocp_cluster_settings( + ctx, + cluster_name, + silent=silent + ) + if settings is None: + return None + + for item in mandatory: + if item not in settings: + ctx.my_output.error('%s not defined for cluster %s' % (item, settings['name'])) + return None + + return settings + + +def validate_ocp_node(ctx, ocp_handler, node_name): + if node_name == '': + ctx.my_output.error('Define ocp cluster node name') + return False + + if not ocp_handler.is_node(node_name): + ctx.my_output.error('Define valid ocp cluster node name') + names = ocp_handler.get_nodes_name() + if names is not None: + for name in names: + ctx.my_output.default('- %s' % (name)) + + return False + + return True + + +def validate_ocp_cluster_name(ctx, param, cluster_name): + ocp_settings_handler = ocp_settings.OcpSettings(log_id=None) + if cluster_name == '': + cluster_name = ocp_settings_handler.get_default_cluster() + if cluster_name is None: + raise click.BadParameter('Define OCP cluster name') + + cluster_obj = ocp_settings_handler.get_ocp_cluster(cluster_name, strict_match=False) + if cluster_obj is None: + raise click.BadParameter('Define valid OCP cluster name') + + return cluster_obj['name'] + + +def select_ocp_name(ctx): + ocp_settings_handler = ocp_settings.OcpSettings(log_id=None) + names = ocp_settings_handler.get_ocp_cluster_names() + if len(names) == 0: + ctx.my_output.error('No OpenShift cluster defined') + return None + + ctx.my_output.default('Select OpenShift Cluster', underline=True) + for name in names: + ctx.my_output.default('- %s' % (name)) + + selected = input('Value: ') + if len(selected) == 0: + return None + + if selected not in names: + return None + + return selected + + +def validate_ocp_namespace_name(ctx, param, value): + if len(value) == 0: + return None + + namespace_name = {} + if len(value.split('/')) == 1: + namespace_name['namespace'] = None + namespace_name['name'] = value + return namespace_name + + if len(value.split('/')) == 2: + namespace_name['namespace'] = value.split('/')[0] + namespace_name['name'] = value.split('/')[1] + return namespace_name + + raise click.BadParameter('Invalid name syntax') + + +def validate_ocp_vm_namespace(ctx, ocp_handler, namespace, vm_name): + if namespace == '': + vm_filter = ['name:%s' % (vm_name)] + vms_mo = ocp_handler.k8s_handler.get_virtual_machines( + object_filter=vm_filter, + return_mo=True, + cache_enabled=False + ) + if vms_mo is None or len(vms_mo) == 0: + ctx.busy = False + ctx.my_output.error( + 'Virtual machine %s not found in any namespace' % (vm_name) + ) + return None + + if len(vms_mo) > 1: + ctx.busy = False + ctx.my_output.error( + 'Multiple virtual machines found - define namespace' + ) + for vm_mo in vms_mo: + ctx.my_output.default( + '- %s' % (vm_mo['metadata']['namespace']) + ) + return None + + namespace = vms_mo[0]['metadata']['namespace'] + else: + if not ocp_handler.k8s_handler.is_virtual_machine(namespace, vm_name, cache_enabled=False): + ctx.busy = False + ctx.my_output.error( + 'Virtual machine %s/%s not found' % ( + namespace, + vm_name + ) + ) + return None + + ctx.busy = False + + ctx.my_output.default( + 'Virtual machine %s/%s found' % ( + namespace, + vm_name + ) + ) + + return namespace + + +def validate_ocp_vm_yaml_file(ctx, filename): + if filename == '': + ctx.my_output.error('Define virtual machine deployment yaml filename') + return None + + content = file_helper.get_file_yaml( + filename + ) + if content is None: + ctx.my_output.error( + 'File read failed: %s' % (filename) + ) + return None + + if 'kind' not in content: + ctx.my_output.error('Invalid yaml file content') + return None + + if content['kind'] not in ['VirtualMachineDeployment', 'VirtualMachine']: + ctx.my_output.error('Unsupported kind property') + return None + + ocp_deployment_validate_handler = ocp_deployment_validate.OcpDeploymentValidate(log_id=ctx.run_id) + + if content['kind'] == 'VirtualMachineDeployment': + return ocp_deployment_validate_handler.validate(filename) + + if content['kind'] == 'VirtualMachine': + deployment = 'kind: VirtualMachineDeployment' + deployment = '%s\ndeployment:' % (deployment) + deployment = '%s\n name: %s' % (deployment, content['metadata']['name']) + deployment = '%s\n namespace: %s' % (deployment, content['metadata']['namespace']) + deployment = '%s\n vm: %s' % (deployment, os.path.basename(filename)) + new_filename = file_helper.set_tmp_file(deployment) + if new_filename is None: + ctx.my_output.error('Failed to prepare deployment file') + return None + + return ocp_deployment_validate_handler.validate( + new_filename, + chdir=os.path.dirname(filename) + ) + + return None + + +def validate_ncs_name(ctx, param, value): + if len(value) == 0: + return None + + nso_settings_handler = nso_settings.NsoSettings(log_id=None) + controller = nso_settings_handler.get_nso_ncs(value) + if controller is None: + raise click.BadParameter('Invalid ncs name') + + return controller + + +def validate_nso_nfvo(ctx, ncs_obj, ncs_protocol, ncs_ip, ncs_port, ncs_username, ncs_password, restconf_enabled, nfvo): + nso_settings_handler = nso_settings.NsoSettings(log_id=ctx.run_id) + + if ncs_obj is None and len(ncs_ip) == 0 and len(ncs_username) == 0 and len(ncs_password) == 0: + ncs_name = nso_settings_handler.get_default_ncs() + if ncs_name is not None: + ncs_obj = nso_settings_handler.get_nso_ncs(ncs_name) + + if ncs_obj is not None: + ncs_protocol = ncs_obj['protocol'] + ncs_ip = ncs_obj['ip'] + ncs_port = ncs_obj['port'] + ncs_username = ncs_obj['username'] + ncs_password = ncs_obj['password'] + restconf_enabled = ncs_obj['restconf_enabled'] + nfvo = ncs_obj['nfvo'] + nso_settings_handler.set_default_ncs( + ncs_obj['name'] + ) + + if ctx.output == 'default': + ctx.my_output.default('NCS: %s' % (ncs_obj['name'])) + + if ncs_obj is None: + if len(ncs_ip) == 0 or len(ncs_username) == 0 or len(ncs_password) == 0: + ctx.my_output.error('Define ncs name or ip/username/password') + return None + + nso_handler = nso.Nso( + ncs_protocol, + ncs_ip, + ncs_port, + username=ncs_username, + password=ncs_password, + restconf_enabled=restconf_enabled, + nfvo=nfvo, + log_id=ctx.run_id + ) + + if not nso_handler.is_connected(): + ctx.my_output.error('Failed to connect to NCS') + return None + + return nso_handler + + +def validate_nso(ctx, ncs_obj, ncs_protocol, ncs_ip, ncs_port, ncs_username, ncs_password, restconf_enabled): + nso_settings_handler = nso_settings.NsoSettings(log_id=ctx.run_id) + + if ncs_obj is None and len(ncs_ip) == 0 and len(ncs_username) == 0 and len(ncs_password) == 0: + ncs_name = nso_settings_handler.get_default_ncs() + if ncs_name is not None: + ncs_obj = nso_settings_handler.get_nso_ncs(ncs_name) + + if ncs_obj is not None: + ncs_protocol = ncs_obj['protocol'] + ncs_ip = ncs_obj['ip'] + ncs_port = ncs_obj['port'] + ncs_username = ncs_obj['username'] + ncs_password = ncs_obj['password'] + restconf_enabled = ncs_obj['restconf_enabled'] + nso_settings_handler.set_default_ncs( + ncs_obj['name'] + ) + + if ctx.output == 'default': + ctx.my_output.default('NCS: %s' % (ncs_obj['name'])) + + if ncs_obj is None: + if len(ncs_ip) == 0 or len(ncs_username) == 0 or len(ncs_password) == 0: + ctx.my_output.error('Define ncs name or ip/username/password') + return None + + nso_handler = nso.Nso( + ncs_protocol, + ncs_ip, + ncs_port, + username=ncs_username, + password=ncs_password, + restconf_enabled=restconf_enabled, + log_id=ctx.run_id + ) + + if not nso_handler.is_connected(): + ctx.my_output.error('Failed to connect to NCS') + return None + + return nso_handler + + +def validate_xml_file(ctx, filename): + if not os.path.isfile(filename): + ctx.my_output.error('File %s not found' % (filename)) + return None + + try: + with open(filename, 'r', encoding='utf-8') as file_handler: + content = file_handler.read() + + except BaseException: + ctx.my_output.traceback(traceback.format_exc()) + return None + + return content + + +def validate_fabric(ctx, param, value): + if len(value) == 0: + return None + + aci_settings_handler = aci_settings.ApicSettings(log_id=None) + fabrics = [] + for item in value: + if len(item.split(':')) != 2: + raise click.BadParameter('Expected fabric syntax is :') + + fabric_hint = {} + fabric_hint['type'] = item.split(':')[0] + if fabric_hint['type'] not in ['aci']: + raise click.BadParameter('Unsupported fabric type') + + if fabric_hint['type'] == 'aci': + fabric_hint['controller'] = item.split(':')[1] + + if aci_settings_handler.get_apic_controller(fabric_hint['controller']) is None: + raise click.BadParameter('Undefined apic: %s' % (fabric_hint['controller'])) + + fabrics.append( + fabric_hint + ) + + return fabrics + + +def validate_timestamp_filter(ctx, param, value): + if len(value) == 0: + return None + + if value in ['any', 'all', '*']: + return '10y' + + if value.endswith('m'): + try: + reference = int(value[:-1]) + except BaseException: + click.BadParameter('Unsupported time filter. Use [m|h|d|y] syntax.') + return value + + if value.endswith('h'): + try: + reference = int(value[:-1]) + except BaseException: + click.BadParameter('Unsupported time filter. Use [m|h|d|y] syntax.') + return value + + if value.endswith('d'): + try: + reference = int(value[:-1]) + except BaseException: + click.BadParameter('Unsupported time filter. Use [m|h|d|y] syntax.') + return value + + if value.endswith('y'): + try: + reference = int(value[:-1]) + except BaseException: + click.BadParameter('Unsupported time filter. Use [m|h|d|y] syntax.') + return value + + click.BadParameter('Unsupported time filter. Use [m|h|d|y] syntax.') + return None + + +def validate_view(ctx, user_input, all_views, default, resolve): + views = [] + + if len(user_input) == 0: + view = [default] + return view + + user_views = [] + for item in user_input: + user_views = user_views + item.split(',') + + defined_views = all_views.split('|') + resolve_views = {} + for item in resolve: + (resolve_name, resolve_view) = item.split(':') + resolve_views[resolve_name] = resolve_view + + for user_view in user_views: + if user_view not in defined_views: + ctx.my_output.error('Supported views: %s' % ','.join(defined_views)) + return None + + if user_view == 'all': + for defined_view in defined_views: + if defined_view not in ['all', 'verbose'] and defined_view not in views and defined_view not in resolve_views: + views.append( + defined_view + ) + continue + + if user_view in resolve_views: + for resolve_view in resolve_views[user_view].split(','): + if resolve_view not in views: + views.append( + resolve_view + ) + + continue + + if user_view not in views: + views.append( + user_view + ) + + return views + + +def validate_kubernetes_name(ctx, value, cluster_type=None, silent=False): + k8s_settings_handler = k8s_settings.K8sSettings(log_id=None) + if value is None or len(value) == 0: + default_cluster_name = k8s_settings_handler.get_default_cluster() + if default_cluster_name is not None: + if not silent: + ctx.my_output.default( + 'Cluster: %s (type: %s)' % ( + default_cluster_name, + k8s_settings_handler.get_k8s_cluster(default_cluster_name)['type'] + ) + ) + kubeconfig = k8s_settings_handler.get_k8s_cluster(default_cluster_name)['kubeconfig'] + + cluster = k8s_settings_handler.get_k8s_cluster(default_cluster_name) + if cluster_type is not None: + if cluster['type'] != cluster_type: + ctx.my_output.error( + 'Required cluster type: %s' % (cluster_type) + ) + return None + + return k8s.K8s(kubeconfig_filename=kubeconfig, cluster_type=cluster['type'], log_id=ctx.run_id) + + if len(value) > 0: + cluster = k8s_settings_handler.get_k8s_cluster(value, strict_match=False) + if cluster is not None: + if cluster_type is not None: + if cluster['type'] != cluster_type: + ctx.my_output.error( + 'Required cluster type: %s' % (cluster_type) + ) + return None + + if not silent: + ctx.my_output.default( + 'Cluster: %s (type: %s)' % (cluster['name'], cluster['type']) + ) + success = k8s_settings_handler.set_default_cluster(cluster['name']) + if not success: + ctx.my_output.default( + '[Warning] Default k8s cluster name set failed' + ) + + return k8s.K8s(kubeconfig_filename=cluster['kubeconfig'], cluster_type=cluster['type'], log_id=ctx.run_id) + + clusters = k8s_settings_handler.get_k8s_clusters() + if len(clusters) == 0: + ctx.my_output.error('No cluster defined') + else: + ctx.my_output.error('Define cluster name') + for cluster in clusters: + ctx.my_output.default('- %s (type: %s)' % (cluster['name'], cluster['type'])) + + return None + + +def validate_kubevirt_name(ctx, value): + k8s_settings_handler = k8s_settings.K8sSettings(log_id=None) + if len(value) == 0: + default_cluster_name = k8s_settings_handler.get_default_cluster() + if default_cluster_name is not None: + ctx.my_output.default( + 'Cluster: %s' % (default_cluster_name) + ) + kubeconfig = k8s_settings_handler.get_k8s_cluster(default_cluster_name)['kubeconfig'] + return kubevirt.Kubevirt(kubeconfig_filename=kubeconfig) + + if len(value) > 0: + cluster = k8s_settings_handler.get_k8s_cluster(value) + if cluster is not None: + ctx.my_output.default( + 'Cluster: %s' % (cluster['name']) + ) + k8s_settings_handler.set_default_cluster(cluster['name']) + return kubevirt.Kubevirt(kubeconfig_filename=cluster['kubeconfig']) + + cluster_names = k8s_settings_handler.get_k8s_cluster_names() + if len(cluster_names) == 0: + ctx.my_output.error('No cluster defined') + else: + ctx.my_output.error('Define cluster name') + for cluster_name in cluster_names: + ctx.my_output.default('- %s' % (cluster_name)) + + return None + + +def validate_linux_name(ctx, server_name, no_cache=False): + linux_settings_handler = linux_settings.LinuxSettings(log_id=None) + if server_name is None: + default_server_name = linux_settings_handler.get_default_server() + if default_server_name is not None: + ctx.my_output.default( + 'Server: %s' % ( + default_server_name + ) + ) + server = linux_settings_handler.get_linux_server(default_server_name) + if server is None: + ctx.my_output.error('Default server not found') + return None + + return linux.Linux( + server['address'], + server['username'], + password=server['password'], + key_filename=server['key'], + server_name=server['name'], + no_cache=no_cache + ) + + if server_name is not None and len(server_name) > 0: + server = linux_settings_handler.get_linux_server(server_name, strict_match=False) + if server is not None: + ctx.my_output.default( + 'Server: %s' % (server['name']) + ) + success = linux_settings_handler.set_default_server(server['name']) + if not success: + ctx.my_output.default( + '[Warning] Default server name set failed' + ) + + return linux.Linux( + server['address'], + server['username'], + password=server['password'], + key_filename=server['key'], + server_name=server['name'], + no_cache=no_cache + ) + + servers = linux_settings_handler.get_linux_servers() + if len(servers) == 0: + ctx.my_output.error('No linux server defined') + return None + + ctx.my_output.error('Define linux server') + for server in servers: + ctx.my_output.default('- %s' % (server['name'])) + + return None + + +def validate_linux_names(ctx, server_names, no_cache=False): + linux_settings_handler = linux_settings.LinuxSettings(log_id=None) + if len(server_names) == 0: + default_server_name = linux_settings_handler.get_default_server() + if default_server_name is not None: + ctx.my_output.default( + 'Server: %s' % ( + default_server_name + ) + ) + default_server = linux_settings_handler.get_linux_server(default_server_name) + if default_server is None: + ctx.my_output.error('Default server not found') + return None + + server_handler = linux.Linux( + default_server['address'], + default_server['username'], + password=default_server['password'], + key_filename=default_server['key'], + server_name=default_server['name'], + no_cache=no_cache, + log_id=ctx.run_id + ) + return [server_handler] + + all_servers = linux_settings_handler.get_linux_servers() + if len(all_servers) == 0: + ctx.my_output.error('No linux server defined') + return None + + selected_server_names = [] + for server_name in server_names: + for server in all_servers: + if server_name in server['name']: + if server['name'] not in selected_server_names: + selected_server_names.append(server['name']) + + if len(selected_server_names) == 0: + ctx.my_output.error('Define linux server') + for server in all_servers: + ctx.my_output.default('- %s' % (server['name'])) + return None + + server_handlers = [] + server_handler_names = [] + for server_name in selected_server_names: + server = linux_settings_handler.get_linux_server(server_name, strict_match=False) + if server is not None: + server_handler_names.append(server_name) + server_handler = linux.Linux( + server['address'], + server['username'], + password=server['password'], + key_filename=server['key'], + server_name=server['name'], + no_cache=no_cache, + log_id=ctx.run_id + ) + server_handlers.append(server_handler) + + if len(selected_server_names) == 0: + ctx.my_output.error('Define linux server') + for server in all_servers: + ctx.my_output.default('- %s' % (server['name'])) + return None + + if len(selected_server_names) == 1: + success = linux_settings_handler.set_default_server(server['name']) + if not success: + ctx.my_output.default( + '[Warning] Default server name set failed' + ) + + ctx.my_output.default( + 'Server: %s' % ( + ','.join(selected_server_names) + ) + ) + return server_handlers + + +def validate_helm_chart(ctx, values_filename): + chart_info = {} + chart_info['directory'] = os.path.dirname(values_filename) + chart_info['values'] = values_filename + + if not os.path.isfile(chart_info['values']): + ctx.my_output.error('Values file not found: %s' % (chart_info['values'])) + return None + + if file_helper.get_file_yaml(chart_info['values']) is None: + ctx.my_output.error('File should be YAML: %s' % (chart_info['values'])) + return None + + chart_filename = os.path.join( + chart_info['directory'], + 'Chart.yaml' + ) + + if not os.path.isfile(chart_filename): + ctx.my_output.error('Chart file not found: %s' % (chart_filename)) + return None + + chart_definition = file_helper.get_file_yaml(chart_filename) + if chart_definition is None: + ctx.my_output.error('File should be YAML: %s' % (chart_filename)) + return None + + chart_info['chart'] = chart_definition['name'] + chart_info['version'] = chart_definition['version'] + chart_info['appVersion'] = chart_definition['appVersion'] + + templates_directory = os.path.join(chart_info['directory'], 'templates') + if not os.path.isdir(templates_directory): + ctx.my_output.error('Templates directory not found: %s' % (templates_directory)) + return None + + charts_directory = os.path.join(chart_info['directory'], 'charts') + if not os.path.isdir(charts_directory): + ctx.my_output.error('Charts directory not found: %s' % (charts_directory)) + return None + + return chart_info + + +def select_osp_name(ctx): + osp_settings_handler = osp_settings.OspSettings(log_id=None) + names = osp_settings_handler.get_openstack_cluster_names() + if len(names) == 0: + ctx.my_output.error('No openstack cluster defined') + return None + + ctx.my_output.default('Select OpenStack Cluster', underline=True) + for name in names: + ctx.my_output.default('- %s' % (name)) + + selected = input('Value: ') + if len(selected) == 0: + return None + + if selected not in names: + return None + + return selected + + +def validate_osp_name(ctx, value, silent=False): + osp_settings_handler = osp_settings.OspSettings(log_id=None) + if value is None or len(value) == 0: + default_cluster_name = osp_settings_handler.get_default_cluster() + if default_cluster_name is not None: + if not silent: + ctx.my_output.default( + 'Cluster: %s (type: %s)' % ( + default_cluster_name, + osp_settings_handler.get_openstack_cluster(default_cluster_name)['type'] + ) + ) + openrc = osp_settings_handler.get_openstack_cluster(default_cluster_name)['openrc'] + cert = osp_settings_handler.get_openstack_cluster(default_cluster_name)['cert'] + return osp.Osp(openrc_filename=openrc, cert_filename=cert, log_id=ctx.run_id) + + if len(value) > 0: + cluster = osp_settings_handler.get_openstack_cluster(value, strict_match=False) + if cluster is not None: + if not silent: + ctx.my_output.default( + 'Cluster: %s' % (cluster['name']) + ) + success = osp_settings_handler.set_default_cluster(cluster['name']) + if not success: + ctx.my_output.default( + '[Warning] Default osp cluster name set failed' + ) + + return osp.Osp(openrc_filename=cluster['openrc'], cert_filename=cluster['cert'], log_id=ctx.run_id) + + clusters = osp_settings_handler.get_openstack_clusters() + if len(clusters) == 0: + ctx.my_output.error('No cluster defined') + else: + ctx.my_output.error('Define cluster name') + for cluster in clusters: + ctx.my_output.default('- %s' % (cluster['name'])) + + return None + +def validate_bot(ctx, param, value): + if len(value) == 0: + return None + + settings_handler = settings_helper.Settings() + bot_main_directory = os.path.join( + settings_handler.get_settings_dir(), + 'bot' + ) + bot_directory = os.path.join( + bot_main_directory, + value + ) + + if not os.path.isfile(bot_directory): + raise click.BadParameter('bot not found: %s' % (value)) + + return file_helper.get_file_json(bot_directory) + + +def validate_bot_group(users, group_name): + group_users = [] + for user in users: + if 'group' in user and 'title' in user: + for user_group in user['group']: + if user_group == group_name: + group_users.append(user) + return group_users diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..3553b860 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,26 @@ +paramiko +cffi +pyyaml +click +requests +validators +progress +ucsmsdk +colorama +inputimeout +sshpubkeys +pyVmomi +intersight +kubernetes +openshift-client +git+https://github.com/kubevirt/client-python.git +openshift +ncclient +pysnmp +python-openstackclient +python-neutronclient +python-glanceclient +python-cinderclient +pycodestyle +xlsxwriter +websocket-client \ No newline at end of file diff --git a/version b/version new file mode 100644 index 00000000..fc54e00f --- /dev/null +++ b/version @@ -0,0 +1 @@ +0.24 \ No newline at end of file